Skip to content

Commit c222196

Browse files
authored
fix: Escape html in code blocks (#263)
* fix: Escape html in code blocks * only do this for non-grain code
1 parent b8bd346 commit c222196

File tree

1 file changed

+51
-28
lines changed

1 file changed

+51
-28
lines changed

scripts/syntaxHighlight.js

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,95 @@
1-
const fs = require('fs');
2-
const vsctm = require('vscode-textmate');
3-
const onig = require('onigasm');
4-
const onigWasm = require.resolve('onigasm/lib/onigasm.wasm');
1+
const fs = require("fs");
2+
const vsctm = require("vscode-textmate");
3+
const onig = require("onigasm");
4+
const onigWasm = require.resolve("onigasm/lib/onigasm.wasm");
55

66
const wasm = fs.readFileSync(onigWasm).buffer;
77

8-
hexo.extend.filter.register('after_init', initialize);
9-
hexo.extend.filter.register('marked:renderer', hookRenderer);
8+
hexo.extend.filter.register("after_init", initialize);
9+
hexo.extend.filter.register("marked:renderer", hookRenderer);
10+
11+
function escapeHTML(str) {
12+
return str.replace(
13+
/[&<>'"]/g,
14+
(tag) =>
15+
({
16+
"&": "&amp;",
17+
"<": "&lt;",
18+
">": "&gt;",
19+
"'": "&#39;",
20+
'"': "&quot;",
21+
}[tag] || tag)
22+
);
23+
}
1024

1125
async function initialize() {
1226
await onig.loadWASM(wasm);
1327

1428
const registry = new vsctm.Registry({
1529
onigLib: Promise.resolve({
1630
createOnigScanner: (sources) => new onig.OnigScanner(sources),
17-
createOnigString: (str) => new onig.OnigString(str)
31+
createOnigString: (str) => new onig.OnigString(str),
1832
}),
1933
loadGrammar: async (scopeName) => {
20-
if (scopeName === 'source.grain') {
21-
let path = './grain-language-server/editor-extensions/vscode/syntaxes/grain.json'
22-
let grammar = fs.readFileSync(path)
23-
return vsctm.parseRawGrammar(grammar.toString(), path)
34+
if (scopeName === "source.grain") {
35+
let path =
36+
"./grain-language-server/editor-extensions/vscode/syntaxes/grain.json";
37+
let grammar = fs.readFileSync(path);
38+
return vsctm.parseRawGrammar(grammar.toString(), path);
2439
}
2540
console.log(`Unknown scope name: ${scopeName}`);
2641
return null;
27-
}
42+
},
2843
});
2944

30-
const grammar = await registry.loadGrammar('source.grain');
45+
const grammar = await registry.loadGrammar("source.grain");
3146

3247
this.grain = { registry, grammar };
3348
}
3449

3550
function makeGutter(numLines) {
36-
let line = (num) => `<span class="line">${num}</span><br>`
37-
let lines = []
51+
let line = (num) => `<span class="line">${num}</span><br>`;
52+
let lines = [];
3853
for (let i = 1; i <= numLines; i++) {
39-
lines.push(line(i))
54+
lines.push(line(i));
4055
}
41-
return `<td class="gutter"><pre>${lines.join('')}</pre></td>`
56+
return `<td class="gutter"><pre>${lines.join("")}</pre></td>`;
4257
}
4358

4459
function hookRenderer(renderer) {
4560
const { grammar } = this.grain;
4661

4762
renderer.code = function (code, lang) {
48-
let result = []
49-
let text = code.split('\n')
63+
let result = [];
64+
let text = code.split("\n");
5065

51-
if (lang === 'grain' || lang === 'gr') {
66+
if (lang === "grain" || lang === "gr") {
5267
let ruleStack = vsctm.INITIAL;
5368
for (let i = 0; i < text.length; i++) {
5469
const line = text[i];
5570
const lineTokens = grammar.tokenizeLine(line, ruleStack);
56-
const lineRes = []
71+
const lineRes = [];
5772
for (let j = 0; j < lineTokens.tokens.length; j++) {
5873
const token = lineTokens.tokens[j];
59-
const tokenString = line.substring(token.startIndex, token.endIndex)
60-
const classString = token.scopes.map(scope => scope.replace(/\./g, ' ')).join(' ')
61-
lineRes.push(`<span class="${classString}">${tokenString}</span>`)
74+
const tokenString = line.substring(token.startIndex, token.endIndex);
75+
const classString = token.scopes
76+
.map((scope) => scope.replace(/\./g, " "))
77+
.join(" ");
78+
lineRes.push(`<span class="${classString}">${tokenString}</span>`);
6279
}
63-
result.push(`<span class="line">${lineRes.join('')}</span><br>`)
80+
result.push(`<span class="line">${lineRes.join("")}</span><br>`);
6481
ruleStack = lineTokens.ruleStack;
6582
}
6683
} else {
67-
result = text.map(line => `<span class="line">${line}</span><br>`)
84+
result = text.map(
85+
(line) => `<span class="line">${escapeHTML(line)}</span><br>`
86+
);
6887
}
6988

70-
return `<figure class="tm-highlight"><table><tbody><tr>${makeGutter(text.length)}<td class="code"><pre>${result.join('')}</pre></td><td class="code-tools"><a class="code-copy" role="button" alt="copy code"><i class="far fa-clone"></i></a></td></tr></tbody></table></figure>`;
71-
}
89+
return `<figure class="tm-highlight"><table><tbody><tr>${makeGutter(
90+
text.length
91+
)}<td class="code"><pre>${result.join(
92+
""
93+
)}</pre></td><td class="code-tools"><a class="code-copy" role="button" alt="copy code"><i class="far fa-clone"></i></a></td></tr></tbody></table></figure>`;
94+
};
7295
}

0 commit comments

Comments
 (0)