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

Commit aa4b5be

Browse files
committed
Add: support for Prism.js code highlighting for PTX
1 parent f15c831 commit aa4b5be

File tree

7 files changed

+103
-57
lines changed

7 files changed

+103
-57
lines changed

runestone/activecode/js/activecode.js

Lines changed: 75 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,19 @@ import embed from "vega-embed";
3636
window.vegaEmbed = embed;
3737

3838
var isMouseDown = false;
39-
document.onmousedown = function() {
39+
document.onmousedown = function () {
4040
isMouseDown = true;
4141
};
4242

43-
document.onmouseup = function() {
43+
document.onmouseup = function () {
4444
isMouseDown = false;
4545
};
4646
window.edList = {};
4747

4848
var socket, connection, doc;
4949
var chatcodesServer = "chat.codes";
5050

51-
CodeMirror.commands.autocomplete = function(cm) {
51+
CodeMirror.commands.autocomplete = function (cm) {
5252
cm.showHint({ hint: CodeMirror.hint.anyword });
5353
};
5454

@@ -135,7 +135,7 @@ export class ActiveCode extends RunestoneBase {
135135
}
136136
this.addCaption("runestone");
137137
setTimeout(
138-
function() {
138+
function () {
139139
this.editor.refresh();
140140
}.bind(this),
141141
1000
@@ -145,6 +145,9 @@ export class ActiveCode extends RunestoneBase {
145145
$(this.runButtonHandler.bind(this));
146146
}
147147
this.indicate_component_ready();
148+
if (typeof Prism !== "undefined") {
149+
Prism.highlightElement(this.containerDiv);
150+
}
148151
}
149152

150153
createEditor(index) {
@@ -190,15 +193,15 @@ export class ActiveCode extends RunestoneBase {
190193
});
191194
// Make the editor resizable
192195
$(editor.getWrapperElement()).resizable({
193-
resize: function() {
196+
resize: function () {
194197
editor.setSize($(this).width(), $(this).height());
195198
editor.refresh();
196199
},
197200
});
198201
// give the user a visual cue that they have changed but not saved
199202
editor.on(
200203
"change",
201-
function(ev) {
204+
function (ev) {
202205
if (
203206
editor.acEditEvent == false ||
204207
editor.acEditEvent === undefined
@@ -207,8 +210,10 @@ export class ActiveCode extends RunestoneBase {
207210
// this avoids unneccsary log events and updates to the activity counter
208211
// offsetParent === null means that the element is not on the screen and so can't change
209212
// this.controlDiv.offsetParent
210-
if (this.origText === editor.getValue() ||
211-
this.addingScrubber) {
213+
if (
214+
this.origText === editor.getValue() ||
215+
this.addingScrubber
216+
) {
212217
console.log("Fake change event, skipping the log");
213218
return;
214219
}
@@ -232,16 +237,16 @@ export class ActiveCode extends RunestoneBase {
232237
}.bind(this)
233238
); // use bind to preserve *this* inside the on handler.
234239
//Solving Keyboard Trap of ActiveCode: If user use tab for navigation outside of ActiveCode, then change tab behavior in ActiveCode to enable tab user to tab out of the textarea
235-
$(window).keydown(function(e) {
240+
$(window).keydown(function (e) {
236241
var code = e.keyCode ? e.keyCode : e.which;
237242
if (code == 9 && $("textarea:focus").length === 0) {
238243
editor.setOption("extraKeys", {
239-
Tab: function(cm) {
244+
Tab: function (cm) {
240245
$(document.activeElement)
241246
.closest(".tab-content")
242247
.nextSibling.focus();
243248
},
244-
"Shift-Tab": function(cm) {
249+
"Shift-Tab": function (cm) {
245250
$(document.activeElement)
246251
.closest(".tab-content")
247252
.previousSibling.focus();
@@ -361,7 +366,7 @@ export class ActiveCode extends RunestoneBase {
361366
this.showHideButt = butt;
362367
ctrlDiv.appendChild(butt);
363368
$(butt).click(
364-
function() {
369+
function () {
365370
$(this.codeDiv).toggle();
366371
if (this.historyScrubber == null) {
367372
this.addHistoryScrubber(true);
@@ -407,7 +412,7 @@ export class ActiveCode extends RunestoneBase {
407412
this.atButton = butt;
408413
ctrlDiv.appendChild(butt);
409414
$(butt).click(
410-
function() {
415+
function () {
411416
new AudioTour(
412417
this.divid,
413418
this.code,
@@ -426,7 +431,7 @@ export class ActiveCode extends RunestoneBase {
426431
this.shareButt = butt;
427432
ctrlDiv.appendChild(butt);
428433
$(butt).click(
429-
async function() {
434+
async function () {
430435
if (
431436
!confirm(
432437
"You are about to share this code with ALL of your students. Are you sure you want to continue?"
@@ -440,7 +445,8 @@ export class ActiveCode extends RunestoneBase {
440445
lang: this.language,
441446
};
442447
let request = new Request(
443-
eBookConfig.ajaxURL + "broadcast_code.json", {
448+
eBookConfig.ajaxURL + "broadcast_code.json",
449+
{
444450
method: "POST",
445451
headers: this.jsonHeaders,
446452
body: JSON.stringify(data),
@@ -467,7 +473,7 @@ export class ActiveCode extends RunestoneBase {
467473
$(plabel).text("Pair?");
468474
ctrlDiv.appendChild(plabel);
469475
$(checkPartner).click(
470-
function() {
476+
function () {
471477
if (this.partner) {
472478
this.partner = false;
473479
$(partnerTextBox).hide();
@@ -479,8 +485,8 @@ export class ActiveCode extends RunestoneBase {
479485
if (!didAgree) {
480486
didAgree = confirm(
481487
"Pair Programming should only be used with the consent of your instructor." +
482-
"Your partner must be a registered member of the class and have agreed to pair with you." +
483-
"By clicking OK you certify that both of these conditions have been met."
488+
"Your partner must be a registered member of the class and have agreed to pair with you." +
489+
"By clicking OK you certify that both of these conditions have been met."
484490
);
485491
if (didAgree) {
486492
localStorage.setItem("partnerAgree", "true");
@@ -499,7 +505,7 @@ export class ActiveCode extends RunestoneBase {
499505
ctrlDiv.appendChild(partnerTextBox);
500506
$(partnerTextBox).hide();
501507
$(partnerTextBox).change(
502-
function() {
508+
function () {
503509
this.partner = partnerTextBox.value;
504510
}.bind(this)
505511
);
@@ -523,21 +529,21 @@ export class ActiveCode extends RunestoneBase {
523529
$(butt).attr(
524530
"href",
525531
"http://" +
526-
chatcodesServer +
527-
"/new?" +
528-
$.param({
529-
topic: window.location.host + "-" + this.divid,
530-
code: this.editor.getValue(),
531-
lang: "Python",
532-
})
532+
chatcodesServer +
533+
"/new?" +
534+
$.param({
535+
topic: window.location.host + "-" + this.divid,
536+
code: this.editor.getValue(),
537+
lang: "Python",
538+
})
533539
);
534540
this.chatButton = butt;
535541
chatBar.appendChild(butt);
536-
var updateChatCodesChannels = function() {
542+
var updateChatCodesChannels = function () {
537543
var data = doc.data;
538544
var i = 1;
539545
$(channels).html("");
540-
data["channels"].forEach(function(channel) {
546+
data["channels"].forEach(function (channel) {
541547
if (!channel.archived && topic === channel.topic) {
542548
var link = $("<a />");
543549
var href =
@@ -580,14 +586,16 @@ export class ActiveCode extends RunestoneBase {
580586
}
581587
console.log("before get hist");
582588
if (
583-
eBookConfig.practice_mode || !eBookConfig.isLoggedIn ||
589+
eBookConfig.practice_mode ||
590+
!eBookConfig.isLoggedIn ||
584591
(this.isTimed && !this.assessmentTaken)
585592
) {
586593
// If this is timed and already taken we should restore history info
587594
this.renderScrubber();
588595
} else {
589596
let request = new Request(
590-
`${eBookConfig.new_server_prefix}/assessment/gethist`, {
597+
`${eBookConfig.new_server_prefix}/assessment/gethist`,
598+
{
591599
method: "POST",
592600
headers: this.jsonHeaders,
593601
body: JSON.stringify(reqData),
@@ -631,7 +639,7 @@ export class ActiveCode extends RunestoneBase {
631639
});
632640
var scrubber = document.createElement("div");
633641
this.timestampP = document.createElement("span");
634-
this.slideit = function(ev, el) {
642+
this.slideit = function (ev, el) {
635643
this.editor.setValue(this.history[$(scrubber).slider("value")]);
636644
var curVal = this.timestamps[$(scrubber).slider("value")];
637645
let pos = $(scrubber).slider("value");
@@ -705,7 +713,7 @@ export class ActiveCode extends RunestoneBase {
705713
$(this.graphics).on(
706714
"DOMNodeInserted",
707715
"canvas",
708-
function() {
716+
function () {
709717
$(this.graphics).addClass("visible-ac-canvas");
710718
}.bind(this)
711719
);
@@ -745,10 +753,10 @@ export class ActiveCode extends RunestoneBase {
745753
fnb +
746754
"_" +
747755
d
748-
.toJSON()
749-
.substring(0, 10) // reverse date format
750-
.split("-")
751-
.join("") +
756+
.toJSON()
757+
.substring(0, 10) // reverse date format
758+
.split("-")
759+
.join("") +
752760
"." +
753761
languageExtensions[lang];
754762
var code = this.editor.getValue();
@@ -1025,10 +1033,10 @@ Yet another is that there is an internal error. The internal error message is:
10251033
$.ajax({
10261034
async: false,
10271035
url: `/runestone/ajax/get_datafile?course_id=${eBookConfig.course}&acid=${divid}`,
1028-
success: function(data) {
1036+
success: function (data) {
10291037
result = JSON.parse(data).data;
10301038
},
1031-
error: function(err) {
1039+
error: function (err) {
10321040
result = null;
10331041
},
10341042
});
@@ -1042,17 +1050,25 @@ Yet another is that there is an internal error. The internal error message is:
10421050
$.i18n("msg_activecode_no_file_or_dir", divid)
10431051
);
10441052
} else {
1053+
// for backward compatibility - early on we had textarea with the divid on it.
1054+
// but later this switched to a runestone wrapper. So we may need to dig for a pre
1055+
// or a textarea?
10451056
if (elem.nodeName.toLowerCase() == "textarea") {
10461057
data = elem.value;
10471058
} else {
1048-
data = elem.textContent;
1059+
let pre = elem.querySelector("pre");
1060+
if (pre) {
1061+
data = pre.textContent;
1062+
} else {
1063+
data = elem.textContent;
1064+
}
10491065
}
10501066
}
10511067
return data;
10521068
}
10531069
outputfun(text) {
10541070
// bnm python 3
1055-
var pyStr = function(x) {
1071+
var pyStr = function (x) {
10561072
if (x instanceof Array) {
10571073
return "[" + x.join(", ") + "]";
10581074
} else {
@@ -1078,9 +1094,9 @@ Yet another is that there is an internal error. The internal error message is:
10781094
.replace(/>/g, "&gt;")
10791095
.replace(/\n/g, "<br/>");
10801096
return Promise.resolve().then(
1081-
function() {
1097+
function () {
10821098
setTimeout(
1083-
function() {
1099+
function () {
10841100
$(this.output).append(text);
10851101
}.bind(this),
10861102
0
@@ -1124,7 +1140,8 @@ Yet another is that there is an internal error. The internal error message is:
11241140
return window.edList[divid].editor.getValue();
11251141
} else {
11261142
let request = new Request(
1127-
`/runestone/ajax/get_datafile?course_id=${eBookConfig.course}&acid=${divid}`, {
1143+
`/runestone/ajax/get_datafile?course_id=${eBookConfig.course}&acid=${divid}`,
1144+
{
11281145
method: "GET",
11291146
headers: this.jsonHeaders,
11301147
}
@@ -1171,7 +1188,7 @@ Yet another is that there is an internal error. The internal error message is:
11711188
if (
11721189
this.historyScrubber &&
11731190
this.history[$(this.historyScrubber).slider("value")] !=
1174-
this.editor.getValue()
1191+
this.editor.getValue()
11751192
) {
11761193
saveCode = "True";
11771194
this.history.push(this.editor.getValue());
@@ -1254,7 +1271,7 @@ Yet another is that there is an internal error. The internal error message is:
12541271
if (
12551272
$(this.outerDiv).find(`#${urDivid}`).length == 0 &&
12561273
$(this.outerDiv).find(`#${urDivid}_offscreen_unit_results`)
1257-
.length == 0
1274+
.length == 0
12581275
) {
12591276
let urResults = document.getElementById(urDivid);
12601277
this.outerDiv.appendChild(urResults);
@@ -1265,13 +1282,20 @@ Yet another is that there is an internal error. The internal error message is:
12651282

12661283
toggleAlert() {
12671284
if (this.is_toggle && this.runCount == 3) {
1268-
if (this.errinfo != "success" || this.unit_results.substring(8, 11) != 100.0) {
1269-
setTimeout(function() { alert("Help is Available Using the Toggle Question Selector! You can try the Mixed-up Question first."); }, 500);
1285+
if (
1286+
this.errinfo != "success" ||
1287+
this.unit_results.substring(8, 11) != 100.0
1288+
) {
1289+
setTimeout(function () {
1290+
alert(
1291+
"Help is Available Using the Toggle Question Selector! You can try the Mixed-up Question first."
1292+
);
1293+
}, 500);
12701294
this.logBookEvent({
12711295
event: "togglealert",
12721296
act: "Help is Available Using the Toggle Question Selector",
12731297
div_id: this.divid,
1274-
})
1298+
});
12751299
}
12761300
}
12771301
}
@@ -1341,7 +1365,7 @@ Yet another is that there is an internal error. The internal error message is:
13411365
});
13421366
}
13431367
try {
1344-
await Sk.misceval.asyncToPromise(function() {
1368+
await Sk.misceval.asyncToPromise(function () {
13451369
return Sk.importMainWithBody("<stdin>", false, prog, true);
13461370
});
13471371
if (!noUI) {
@@ -1368,7 +1392,7 @@ Yet another is that there is an internal error. The internal error message is:
13681392
} finally {
13691393
$(this.runButton).removeAttr("disabled");
13701394
if (typeof window.allVisualizers != "undefined") {
1371-
$.each(window.allVisualizers, function(i, e) {
1395+
$.each(window.allVisualizers, function (i, e) {
13721396
e.redrawConnectors();
13731397
});
13741398
}
@@ -1441,6 +1465,6 @@ errorText.KeyErrorFix = $.i18n("msg_activecode_key_error_fix");
14411465
errorText.AssertionError = $.i18n("msg_activecode_assertion_error");
14421466
errorText.AssertionErrorFix = $.i18n("msg_activecode_assertion_error_fix");
14431467

1444-
String.prototype.replaceAll = function(target, replacement) {
1468+
String.prototype.replaceAll = function (target, replacement) {
14451469
return this.split(target).join(replacement);
14461470
};

runestone/clickableArea/js/clickable.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ export default class ClickableArea extends RunestoneBase {
4646
this.caption = "Clickable";
4747
this.addCaption("runestone");
4848
this.checkServer("clickableArea", true);
49+
if (typeof Prism !== "undefined") {
50+
Prism.highlightElement(this.containerDiv);
51+
}
4952
}
5053
/*===========================
5154
== Update basic attributes ==

0 commit comments

Comments
 (0)