104 lines
3.4 KiB
TypeScript
104 lines
3.4 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,
|
|
dirComponents: string[],
|
|
): string {
|
|
const breadcrumbs = [];
|
|
|
|
if (name !== "index") {
|
|
dirComponents.push(`${name}.html`);
|
|
}
|
|
if (dirComponents.length > 0) {
|
|
breadcrumbs.push(`<a href="/docs/-/">root</a>`);
|
|
} else {
|
|
breadcrumbs.push(`<span>root</span>`);
|
|
}
|
|
for (let i = 0; i < dirComponents.length; ++i) {
|
|
const component = dirComponents[i];
|
|
const href = "/docs/-/" + dirComponents.filter((_, idx) => idx <= i).join("/");
|
|
if (i < dirComponents.length - 1) {
|
|
breadcrumbs.push(`<a href="${href}">${component}</a>`);
|
|
} else {
|
|
breadcrumbs.push(`<span>${component}</a>`);
|
|
}
|
|
}
|
|
|
|
let content = [
|
|
"<!DOCTYPE html>",
|
|
"<html>",
|
|
"<head>",
|
|
[
|
|
`<title>Docs: ${name}</title>`,
|
|
'<meta charset="UTF-8">',
|
|
'<meta name="viewport" content="width=device-width, initial-scale=1.0">',
|
|
'<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">',
|
|
'<meta name="color-scheme" content="dark">',
|
|
'<link rel="shortcut icon" href="/favicon.ico">',
|
|
'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/base16/gruvbox-dark-hard.css">',
|
|
'<link rel="stylesheet" href="/docs/-/style.css">',
|
|
'<script src="/docs/-/headers.js" defer></script>',
|
|
],
|
|
"</head>",
|
|
"<body>",
|
|
[
|
|
`<nav><a href="/">Back to playground</a> | ${breadcrumbs.join(" / ")}</nav>`,
|
|
rendered,
|
|
],
|
|
"</body>",
|
|
"</html>",
|
|
];
|
|
while (content.some((x) => Array.isArray(x))) {
|
|
content = content.flat();
|
|
}
|
|
return content.join("");
|
|
}
|
|
|
|
async function renderMarkdown() {
|
|
const renderer = await Renderer.with({
|
|
plugins: [HighlightPlugin],
|
|
});
|
|
for await (
|
|
const entry of walk("src", { exts: [".md"], includeDirs: false })
|
|
) {
|
|
const parsed = pathTools.parse(entry.path);
|
|
const dirComponents = parsed.dir.split(pathTools.SEPARATOR_PATTERN);
|
|
dirComponents.shift();
|
|
parsed.dir = pathTools.join("-", ...dirComponents);
|
|
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, dirComponents),
|
|
);
|
|
}
|
|
}
|
|
|
|
async function copyStaticFiles() {
|
|
for await (const entry of walk("static", { includeDirs: false })) {
|
|
const parsed = pathTools.parse(entry.path);
|
|
const dirComponents = parsed.dir.split(pathTools.SEPARATOR_PATTERN);
|
|
dirComponents.shift();
|
|
parsed.dir = pathTools.join("-", ...dirComponents);
|
|
|
|
await Deno.mkdir(parsed.dir, { recursive: true });
|
|
await Deno.copyFile(entry.path, pathTools.format(parsed));
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
await renderMarkdown();
|
|
await copyStaticFiles();
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
main();
|
|
}
|