87 lines
2.7 KiB
TypeScript
87 lines
2.7 KiB
TypeScript
import { Renderer } from "@libs/markdown";
|
|
import HighlightPlugin from "@libs/markdown/plugins/highlighting";
|
|
import { walk } from "@std/fs";
|
|
import * as pathTools from "@std/path";
|
|
|
|
function injectIntoTemplate(name: string, rendered: string): string {
|
|
let content = [
|
|
"<!DOCTYPE html>",
|
|
"<html>",
|
|
"<head>",
|
|
[
|
|
`<title>${name}</title>`,
|
|
],
|
|
"</head>",
|
|
"<body>",
|
|
[
|
|
rendered,
|
|
"<script>",
|
|
[
|
|
"function slugify(elements) {",
|
|
`return elements
|
|
.map((element, i) => {
|
|
if (i === 0) return null;
|
|
const content = element.textContent.trim();
|
|
if (content.startsWith("lib.")) {
|
|
const [name] = content.match(/^lib\\.[^\(]+/);
|
|
return name.trim();
|
|
}
|
|
return content;
|
|
})
|
|
.filter(x => x !== null)
|
|
.join("-");`,
|
|
"}",
|
|
'const headers = document.querySelectorAll("h1,h2,h3,h4,h5,h6");',
|
|
"const ancestors = [];",
|
|
"for (const header of headers) {",
|
|
[
|
|
"const depth = parseInt(header.tagName.slice(1));",
|
|
"while (ancestors.length >= depth) {",
|
|
[
|
|
"ancestors.pop();",
|
|
],
|
|
"}",
|
|
"ancestors.push(header);",
|
|
"if (depth > 1) header.id = slugify(ancestors);",
|
|
],
|
|
"}",
|
|
],
|
|
"</script>",
|
|
],
|
|
"</body>",
|
|
"</html>",
|
|
];
|
|
while (content.some((x) => Array.isArray(x))) {
|
|
content = content.flat();
|
|
}
|
|
return content.join("");
|
|
}
|
|
|
|
async function main() {
|
|
const renderer = await Renderer.with({
|
|
plugins: [HighlightPlugin],
|
|
});
|
|
for await (
|
|
const entry of walk("src", {
|
|
exts: [".md"],
|
|
})
|
|
) {
|
|
const parsed = pathTools.parse(entry.path);
|
|
parsed.dir = parsed.dir.replace(/^src[\\/]?/, "");
|
|
parsed.dir = pathTools.join("-", parsed.dir);
|
|
parsed.ext = ".html";
|
|
parsed.base = `${parsed.name}${parsed.ext}`;
|
|
|
|
await Deno.mkdir(parsed.dir, { recursive: true });
|
|
const content = await renderer.render(await Deno.readTextFile(entry.path));
|
|
await Deno.writeTextFile(
|
|
pathTools.format(parsed),
|
|
injectIntoTemplate(parsed.name, content),
|
|
);
|
|
}
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
main();
|
|
}
|