statics, table of contents
This commit is contained in:
parent
6663c46f71
commit
544a9f3663
70
docs/build.ts
Normal file
70
docs/build.ts
Normal file
@ -0,0 +1,70 @@
|
||||
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>`,
|
||||
'<script src="header_ids.js" defer></script>',
|
||||
'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">',
|
||||
],
|
||||
"</head>",
|
||||
"<body>",
|
||||
[
|
||||
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);
|
||||
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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function copyStaticFiles() {
|
||||
for await (const entry of walk("static", { includeDirs: false })) {
|
||||
const parsed = pathTools.parse(entry.path);
|
||||
parsed.dir = parsed.dir.replace(/^static[\\/]?/, "");
|
||||
parsed.dir = pathTools.join("-", parsed.dir);
|
||||
|
||||
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();
|
||||
}
|
@ -7,5 +7,8 @@
|
||||
"@libs/markdown": "jsr:@libs/markdown@^2.0.4",
|
||||
"@std/fs": "jsr:@std/fs@^1.0.19",
|
||||
"@std/path": "jsr:@std/path@^1.1.2"
|
||||
},
|
||||
"tasks": {
|
||||
"build": "deno run -A build.ts"
|
||||
}
|
||||
}
|
||||
|
@ -1,86 +0,0 @@
|
||||
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();
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
# Gamelib
|
||||
|
||||
## Contents
|
||||
|
||||
<table-of-contents></table-of-contents>
|
||||
|
||||
## Models
|
||||
|
||||
### `Color`
|
||||
@ -22,8 +26,8 @@ lib.drawRect(100, 0, 100, 100, lib.rgb(192, 127, 172));
|
||||
|
||||
A type of string.
|
||||
|
||||
Represents JavaScript's `KeyboardEvent.key`
|
||||
([link](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)) property.
|
||||
Represents JavaScript's
|
||||
[`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) property.
|
||||
|
||||
Example:
|
||||
|
||||
|
61
docs/static/header_ids.js
vendored
Normal file
61
docs/static/header_ids.js
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
function renderTableOfContents() {
|
||||
const root = document.querySelector("table-of-contents");
|
||||
|
||||
const list = document.createElement("ul");
|
||||
|
||||
const headers = document.querySelectorAll("h2,h3,h4,h5,h6");
|
||||
|
||||
const ancestors = [];
|
||||
for (const header of headers) {
|
||||
const depth = parseInt(header.tagName.slice(1)) - 1;
|
||||
while (ancestors.length >= depth) {
|
||||
ancestors.pop();
|
||||
}
|
||||
const li = document.createElement("li");
|
||||
const a = document.createElement("a");
|
||||
a.textContent = header.textContent;
|
||||
a.href = `#${header.id}`;
|
||||
const ul = document.createElement("ul");
|
||||
li.replaceChildren(a, ul);
|
||||
const mostRecent = ancestors[ancestors.length - 1];
|
||||
if (mostRecent === undefined) {
|
||||
list.appendChild(li);
|
||||
} else {
|
||||
mostRecent.appendChild(li);
|
||||
}
|
||||
ancestors.push(ul);
|
||||
}
|
||||
|
||||
root.replaceChildren(list);
|
||||
}
|
||||
|
||||
function slugify(elements) {
|
||||
console.log(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("-");
|
||||
}
|
||||
function attachIdToHeaders() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
attachIdToHeaders();
|
||||
renderTableOfContents();
|
Loading…
x
Reference in New Issue
Block a user