-
Notifications
You must be signed in to change notification settings - Fork 0
/
modifyCodeblocks.js
102 lines (86 loc) · 2.76 KB
/
modifyCodeblocks.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import prism from "prismjs";
import loadLanguages from "prismjs/components/index.js";
import { langNames } from "./lang-names.js";
const csharp = ["csharp", "t4-cs", "cshtml"];
const fsharp = ["fsharp"];
const vbnet = ["vbnet", "vb", "t4-vb"];
const dotnet = ["qsharp", "xml-doc"];
const shell = ["powershell", "bash", "batch", "shell", "shell-session"];
const config = ["yaml", "toml", "json", "json5", "docker"];
const misc = [
"regex",
"t4-templating",
"sql",
"mongodb",
"log",
"latex",
"md",
"markdown",
"http",
"git",
"diff",
];
/** @type {import("unified").Plugin} */
const modifyCodeblocks = () => {
loadLanguages([
...csharp,
...fsharp,
...vbnet,
...dotnet,
...shell,
...config,
...misc,
]);
return async (root) => {
return { ...root, children: root.children.map(modifyCodeNode) };
};
};
// Changes code to HTML
function modifyCodeNode(node) {
// Ignore non-code
if (node.type !== "code") return node;
const { position } = node;
return { type: "html", value: generateCodeBlock(node), position };
}
// Wrap it in HTML
const generateCodeBlock = (node) => {
const meta = JSON.parse(node.meta);
return wrapCodeBlock(
wrapCode(lineifyCode(highlightNode(node), meta), node.lang),
node.lang,
meta
);
};
const wrapCodeBlock = (codeblockHtml, lang, meta) =>
`<div class="code-block container">${createCodeBlockHeader(
lang,
meta
)}${codeblockHtml}</div>`;
const createCodeBlockHeader = (lang, meta) =>
`<header class="code-block header"><div class="code-block lang">${
langNames[lang]
}</div>${meta ? createCodeBlockMeta(meta) : ""}</header>`;
const createCodeBlockMeta = (meta) =>
`<section class="code-block meta">${
meta?.file ? createCodeBlockMetaProp("File", meta.file) : ""
}</section>`;
const createCodeBlockMetaProp = (name, value) =>
`<div class="code-block-meta-prop container"><span class="code-block-meta-prop key">${name}: </span><span class="code-block-meta-prop value">${value}</span></div>`;
const wrapCode = (code, lang) =>
`<pre class="code-block code-wrapper language-${lang} ${lang}"><code class="code-block code-container language-${lang} ${lang}">${code}</code></pre>`;
const lineifyCode = (code, meta) =>
code
.split("\n")
.map(
(line, i) =>
`<codeline class="code-block line${
meta?.insert && meta.insert.includes(i) ? " inserted" : ""
}${meta?.delete && meta.delete.includes(i) ? " deleted" : ""}${
meta?.highlight && meta.highlight.includes(i) ? " highlighted" : ""
}">${line}</codeline>`
)
.join("");
// Highlights raw code with colour
const highlightNode = ({ lang, value }) =>
prism.highlight(value, prism.languages[lang], lang).replace(/[{]/g, "{");
export default modifyCodeblocks;