diff --git a/package-lock.json b/package-lock.json
index aa315f782..6b09bf7cc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,7 +15,7 @@
"handsontable": "7.2.2",
"jexcel": "^3.9.1",
"jquery-ui": "1.10.4",
- "micro-parsons": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.4/micro-parsons-0.1.4.tgz",
+ "micro-parsons": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.6/micro-parsons-0.1.6.tgz",
"select2": "^4.1.0-rc.0",
"sql.js": "1.5.0",
"vega-embed": "3.14.0",
@@ -2715,9 +2715,9 @@
}
},
"node_modules/micro-parsons": {
- "version": "0.1.4",
- "resolved": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.4/micro-parsons-0.1.4.tgz",
- "integrity": "sha512-3hg55GJpg779Vhyzk2Ij3Jz/e6UKZGltwpA60EegQrT4C0XR1ioWBoZutNy2BZ5bR6LCC8RXCky4gF9qxl7/ew==",
+ "version": "0.1.6",
+ "resolved": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.6/micro-parsons-0.1.6.tgz",
+ "integrity": "sha512-OEuMXyEnSN6o2rRvHhIkKTuGzwv0zlzJLjtyTF9X7cYgUff7iyH/gwNQmd0WifBw4x2eVs8gv7a/jE2YRERnvQ==",
"license": "MIT",
"dependencies": {
"highlight.js": "^11.7.0",
@@ -7844,8 +7844,8 @@
"dev": true
},
"micro-parsons": {
- "version": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.4/micro-parsons-0.1.4.tgz",
- "integrity": "sha512-3hg55GJpg779Vhyzk2Ij3Jz/e6UKZGltwpA60EegQrT4C0XR1ioWBoZutNy2BZ5bR6LCC8RXCky4gF9qxl7/ew==",
+ "version": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.6/micro-parsons-0.1.6.tgz",
+ "integrity": "sha512-OEuMXyEnSN6o2rRvHhIkKTuGzwv0zlzJLjtyTF9X7cYgUff7iyH/gwNQmd0WifBw4x2eVs8gv7a/jE2YRERnvQ==",
"requires": {
"highlight.js": "^11.7.0",
"sortablejs": "^1.14.0"
diff --git a/package.json b/package.json
index 952b4d372..df945aea0 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
"handsontable": "7.2.2",
"jexcel": "^3.9.1",
"jquery-ui": "1.10.4",
- "micro-parsons": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.4/micro-parsons-0.1.4.tgz",
+ "micro-parsons": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.6/micro-parsons-0.1.6.tgz",
"select2": "^4.1.0-rc.0",
"sql.js": "1.5.0",
"vega-embed": "3.14.0",
diff --git a/runestone/hparsons/js/BlockFeedback.js b/runestone/hparsons/js/BlockFeedback.js
index 3a779a42e..f158c2280 100644
--- a/runestone/hparsons/js/BlockFeedback.js
+++ b/runestone/hparsons/js/BlockFeedback.js
@@ -18,12 +18,17 @@ export default class BlockFeedback extends HParsonsFeedback {
this.solved = false;
// TODO: not sure what is the best way to do this
this.grader = new BlockBasedGrader();
- let solutionBlocks = [];
+ let solutionContent = [];
for (let i = 0; i < this.hparsons.blockAnswer.length; ++i) {
- solutionBlocks.push(this.hparsons.originalBlocks[this.hparsons.blockAnswer[i]]);
+ if (this.hparsons.renderRaw) {
+ // if rendering raw (html): answer is text content instead of the original string
+ solutionContent.push(this.getContentFromRawString(this.hparsons.originalBlocks[this.hparsons.blockAnswer[i]]));
+ } else {
+ solutionContent.push(this.hparsons.originalBlocks[this.hparsons.blockAnswer[i]]);
+ }
}
- this.solution = solutionBlocks;
- this.grader.solution = solutionBlocks;
+ this.solution = solutionContent;
+ this.grader.solution = solutionContent;
this.answerArea = this.hparsons.hparsonsInput.querySelector('.drop-area');
}
@@ -57,7 +62,14 @@ export default class BlockFeedback extends HParsonsFeedback {
if (!this.solved) {
this.checkCount++;
this.clearFeedback();
- this.grader.answer = this.hparsons.hparsonsInput.getParsonsTextArray();
+ if (this.hparsons.renderRaw) {
+ // when rendering raw: the answer is actually the text content.
+ this.grader.answer = this.hparsons.hparsonsInput.getParsonsTextArray().map((blockHTML) => {
+ return this.getContentFromRawString(blockHTML);
+ });
+ } else {
+ this.grader.answer = this.hparsons.hparsonsInput.getParsonsTextArray();
+ }
this.grade = this.grader.grade();
if (this.grade == "correct") {
$(this.hparsons.runButton).prop("disabled", true);
@@ -101,7 +113,9 @@ export default class BlockFeedback extends HParsonsFeedback {
var notInSolution = [];
for (let i = 0; i < answerBlocks.length; i++) {
var block = answerBlocks[i];
- var index = this.solution.indexOf(block.textContent);
+ var index = this.hparsons.renderRaw ?
+ this.solution.indexOf(this.getContentFromRawString(block.innerHTML))
+ : this.solution.indexOf(block.textContent);
if (index == -1) {
notInSolution.push(block);
} else {
@@ -122,6 +136,11 @@ export default class BlockFeedback extends HParsonsFeedback {
feedbackArea.html($.i18n("msg_parson_wrong_order"));
}
}
+
+ getContentFromRawString(html) {
+ let doc = new DOMParser().parseFromString(html, "text/html");
+ return doc.body.textContent;
+ }
// Feedback UI for Block-based Feedback
clearFeedback() {
diff --git a/runestone/hparsons/js/hparsons.js b/runestone/hparsons/js/hparsons.js
index 40c9c1288..dfb09e703 100644
--- a/runestone/hparsons/js/hparsons.js
+++ b/runestone/hparsons/js/hparsons.js
@@ -26,6 +26,7 @@ export default class HParsons extends RunestoneBase {
this.randomize = $(orig).data("randomize") ? true : false;
this.isBlockGrading = $(orig).data("blockanswer") ? true : false;
this.language = $(orig).data("language");
+ this.renderRaw = false;
if (this.isBlockGrading) {
this.blockAnswer = $(orig).data("blockanswer").split(" ");
}
@@ -80,6 +81,22 @@ export default class HParsons extends RunestoneBase {
this.originalBlocks = this.processSingleContent(code, '--blocks--').split('\n').slice(1,-1);
this.hiddenSuffix = this.processSingleContent(code, '--hiddensuffix--');
this.unittest = this.processSingleContent(code, '--unittest--');
+ // (for pretext) if all blocks can be parsed as html but language is not html,
+ // ask micro parsons to render raw
+ if (this.language != 'html') {
+ this.renderRaw = true;
+ for (let i = 0; i < this.originalBlocks.length; ++i) {
+ if (!this.isHTML(this.originalBlocks[i])) {
+ this.renderRaw = false;
+ break;
+ }
+ }
+ }
+ }
+
+ isHTML(block) {
+ let doc = new DOMParser().parseFromString(block, "text/html");
+ return Array.from(doc.body.childNodes).some(node => node.nodeType === 1);
}
processSingleContent(code, delimitier) {
@@ -116,7 +133,7 @@ export default class HParsons extends RunestoneBase {
reuse: this.reuse,
randomize: this.randomize,
parsonsBlocks: [...this.originalBlocks],
- language: this.language
+ language: this.renderRaw ? 'raw' : this.language
}
InitMicroParsons(props);
this.hparsonsInput = $(this.outerDiv).find("micro-parsons")[0];
diff --git a/runestone/hparsons/test/_sources/index.rst b/runestone/hparsons/test/_sources/index.rst
index 6ffa966cd..7b0e406b3 100644
--- a/runestone/hparsons/test/_sources/index.rst
+++ b/runestone/hparsons/test/_sources/index.rst
@@ -171,3 +171,54 @@ Randomized Block with Execution Based Feedback and Hidden Code + error in prefix
assert 1,1 == final
assert 1,3 == 90
assert 3,3 == 99
+
+
+Testing rendering raw blocks (pretext)
+------------------------------------------
+.. hparsons:: test_hparsons_block_raw_render
+ :language: sql
+ :randomize:
+ :blockanswer: 0 1 2 3
+
+ Testing rendering raw blocks.
+
+ Raw blocks will be rendered when:
+
+ 1. the langauge is not html
+
+ 2. all blocks contain html nodes
+
+ In this case, it renders html as-is.
+ ~~~~
+ --blocks--
+ SELECT
+ *
+ FROM
+
abc'`` in python.
+
+ ~~~~
+ --blocks--
+ SELECT
+ *
+ FROM
+