Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit d9d8f9a

Browse files
Merge branch 'python-check'
2 parents 7edee14 + 3448b6e commit d9d8f9a

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

runestone/activecode/css/activecode.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@
7575
background-color: lightgray;
7676
}
7777

78+
.python_check_results {
79+
margin-top: 20px;
80+
padding-top: 0px;
81+
padding-bottom: 0px;
82+
}
83+
84+
.python_check_results pre {
85+
background-color: #f5f5f5;
86+
}
87+
7888
.ac_caption {
7989
text-align: center;
8090
font-weight: bold;

runestone/activecode/js/activecode.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,61 @@ Yet another is that there is an internal error. The internal error message is:
12951295
}
12961296
}
12971297

1298+
async checkPythonSyntax() {
1299+
let checkDiv = this.outerDiv.querySelector("div.python_check_results");
1300+
if( checkDiv != null )
1301+
checkDiv.remove();
1302+
1303+
let code = this.editor.getValue();
1304+
1305+
fetch('/ns/books/python_check', {
1306+
method: 'POST',
1307+
body: code
1308+
})
1309+
.then((response) => {
1310+
return response.json();
1311+
})
1312+
.then((data) => {
1313+
if(data.trim() !== '') {
1314+
//clean up returned text
1315+
let errorLines = data.split("\n");
1316+
let codeLines = code.split("\n");
1317+
let message = "";
1318+
for(let line of errorLines) {
1319+
if(line.indexOf(".py:") != -1) {
1320+
//old pyflakes returns "file:line:col error"
1321+
//new pyflakes returns "file:line:col: error"
1322+
//handle either
1323+
const cleaner = /[^.]*.py:(\d+):(\d+):? (.*)/i;
1324+
let lineParts = line.match(cleaner)
1325+
message += "Line " + lineParts[1] + ": " + lineParts[3] + "\n";
1326+
message += codeLines[lineParts[1] - 1] + "\n";
1327+
message += " ".repeat(lineParts[2] - 1) + "^\n";
1328+
} else {
1329+
message += line + "\n";
1330+
}
1331+
}
1332+
message = message.slice(0,-1); //remove trailing newline
1333+
1334+
//Render
1335+
checkDiv = document.createElement("div");
1336+
checkDiv.classList.add("python_check_results","alert", "alert-warning");
1337+
let checkHead = checkDiv.appendChild(document.createElement("h3"));
1338+
checkHead.textContent = "Syntax Tips";
1339+
let checkPre = checkDiv.appendChild(document.createElement("pre"));
1340+
//checkPre.classList.add("alert-warning");
1341+
checkPre.textContent = message;
1342+
1343+
//Squeeze check_results right before output pane
1344+
const outDiv = this.outDiv;
1345+
outDiv.parentNode.insertBefore(checkDiv, outDiv);
1346+
}
1347+
})
1348+
.catch(err => {
1349+
console.log("Error with ajax python check:", err);
1350+
});
1351+
}
1352+
12981353
/* runProg has several async elements to it.
12991354
* 1. Skulpt runs the python program asynchronously
13001355
* 2. The history is restored asynchronously
@@ -1361,6 +1416,9 @@ Yet another is that there is an internal error. The internal error message is:
13611416
queue: false,
13621417
});
13631418
}
1419+
if (this.language == "python" || this.language == "python3") {
1420+
this.checkPythonSyntax();
1421+
}
13641422
try {
13651423
await Sk.misceval.asyncToPromise(function () {
13661424
return Sk.importMainWithBody("<stdin>", false, prog, true);

0 commit comments

Comments
 (0)