|
|
@@ -1447,13 +1447,15 @@ class MDFencedCodeBlockReader extends MDReader {
|
|
1447
|
1447
|
let openFenceLine = state.lines[p++];
|
|
1448
|
1448
|
var modifier;
|
|
1449
|
1449
|
[openFenceLine, modifier] = MDTagModifier.fromLine(openFenceLine);
|
|
1450
|
|
- if (openFenceLine.trim() != '```') return null;
|
|
|
1450
|
+ const match = /^```\s*([a-z0-9]*)\s*$/.exec(openFenceLine);
|
|
|
1451
|
+ if (match === null) return null;
|
|
|
1452
|
+ const language = match[1].length > 0 ? match[1] : null;
|
|
1451
|
1453
|
var codeLines = [];
|
|
1452
|
1454
|
while (state.hasLines(1, p)) {
|
|
1453
|
1455
|
let line = state.lines[p++];
|
|
1454
|
1456
|
if (line.trim() == '```') {
|
|
1455
|
1457
|
state.p = p;
|
|
1456
|
|
- let block = new MDCodeBlockNode(codeLines.join("\n"));
|
|
|
1458
|
+ let block = new MDCodeBlockNode(codeLines.join("\n"), language);
|
|
1457
|
1459
|
if (modifier) modifier.applyTo(block);
|
|
1458
|
1460
|
return block;
|
|
1459
|
1461
|
}
|
|
|
@@ -2594,16 +2596,22 @@ class MDCodeBlockNode extends MDBlockNode {
|
|
2594
|
2596
|
/** @type {string} */
|
|
2595
|
2597
|
text;
|
|
2596
|
2598
|
|
|
|
2599
|
+ /** @type {string|null} */
|
|
|
2600
|
+ language;
|
|
|
2601
|
+
|
|
2597
|
2602
|
/**
|
|
2598
|
2603
|
* @param {string} text
|
|
|
2604
|
+ * @param {string|null} language
|
|
2599
|
2605
|
*/
|
|
2600
|
|
- constructor(text) {
|
|
|
2606
|
+ constructor(text, language=null) {
|
|
2601
|
2607
|
super([]);
|
|
2602
|
2608
|
this.text = text;
|
|
|
2609
|
+ this.language = language;
|
|
2603
|
2610
|
}
|
|
2604
|
2611
|
|
|
2605
|
2612
|
toHTML(state) {
|
|
2606
|
|
- return `<pre${this._htmlAttributes()}><code>${MDUtils.escapeHTML(this.text)}</code></pre>\n`;
|
|
|
2613
|
+ const languageModifier = (this.language !== null) ? ` class="language-${this.language}"` : '';
|
|
|
2614
|
+ return `<pre${this._htmlAttributes()}><code${languageModifier}>${MDUtils.escapeHTML(this.text)}</code></pre>\n`;
|
|
2607
|
2615
|
}
|
|
2608
|
2616
|
}
|
|
2609
|
2617
|
|