mirror of
https://github.com/TautvydasDerzinskas/Thingport.git
synced 2026-10-21 22:22:24 -05:00
113 lines
4.1 KiB
JavaScript
113 lines
4.1 KiB
JavaScript
// Builds the GitHub wiki from the repo's Markdown so it can't drift from the docs. Run by
|
|
// .github/workflows/wiki.yml; locally:
|
|
//
|
|
// node .github/wiki/build.mjs <out-dir>
|
|
//
|
|
// Home is the README minus its install section, Installation is that section, and every doc in
|
|
// site.mjs's DOCS with a `source` gets a page.
|
|
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { BRANCH, DOCS, REPO, REPO_URL } from "../../web/src/lib/site.mjs";
|
|
|
|
const ROOT = fileURLToPath(new URL("../../", import.meta.url));
|
|
const outDir = path.resolve(process.argv[2] ?? "wiki-out");
|
|
|
|
const read = (file) => fs.readFileSync(path.join(ROOT, file), "utf8");
|
|
const pageName = (title) => title.replace(/[\s/]+/g, "-");
|
|
|
|
const readme = read("README.md");
|
|
const installStart = readme.indexOf("\n## Installation\n");
|
|
const installEnd = readme.indexOf("\n## ", installStart + 1);
|
|
if (installStart < 0 || installEnd < 0) throw new Error("README.md has no '## Installation' section");
|
|
|
|
const pages = [
|
|
{
|
|
name: "Home",
|
|
source: "README.md",
|
|
body:
|
|
readme.slice(0, installStart) +
|
|
"\n## Installation\n\nSee **[Installation](Installation)** for Docker Compose, and the sidebar for Unraid, TrueNAS SCALE and CasaOS.\n" +
|
|
readme.slice(installEnd),
|
|
},
|
|
{
|
|
name: "Installation",
|
|
group: "Getting started",
|
|
source: "README.md",
|
|
body: readme.slice(installStart + 1, installEnd),
|
|
},
|
|
...DOCS.filter((d) => d.source).map((d) => ({
|
|
name: pageName(d.title),
|
|
nav: d.nav,
|
|
group: d.unlisted ? undefined : d.group,
|
|
source: d.source,
|
|
body: read(d.source),
|
|
})),
|
|
];
|
|
|
|
const pageBySource = {
|
|
"README.md": "Home",
|
|
...Object.fromEntries(pages.slice(2).map((p) => [p.source, p.name])),
|
|
};
|
|
const pageNames = new Set(pages.map((p) => p.name));
|
|
|
|
function rewrite(attr, value, dir) {
|
|
if (!value || /^[a-z][a-z0-9+.-]*:|^#|^\//i.test(value)) return value;
|
|
const [target, hash] = value.split("#");
|
|
if (pageNames.has(target)) return value;
|
|
const repoPath = path.posix.normalize(path.posix.join(dir, target));
|
|
const anchor = hash ? `#${hash}` : "";
|
|
if (attr === "src") return `https://raw.githubusercontent.com/${REPO}/${BRANCH}/${repoPath}`;
|
|
if (repoPath in pageBySource) return pageBySource[repoPath] + anchor;
|
|
const isFile = fs.statSync(path.join(ROOT, repoPath), { throwIfNoEntry: false })?.isFile() ?? true;
|
|
return `${REPO_URL}/${isFile ? "blob" : "tree"}/${BRANCH}/${repoPath}${anchor}`;
|
|
}
|
|
|
|
/** Rewrites Markdown links/images and inline-HTML href/src, leaving fenced code blocks alone. */
|
|
function rewriteLinks(markdown, source) {
|
|
const dir = path.posix.dirname(source);
|
|
return markdown
|
|
.split(/(^```[\s\S]*?^```)/m)
|
|
.map((chunk, i) =>
|
|
i % 2
|
|
? chunk
|
|
: chunk
|
|
.replace(
|
|
/(!?)\[([^\]]*)\]\(([^)\s]+)\)/g,
|
|
(_, bang, text, url) => `${bang}[${text}](${rewrite(bang ? "src" : "href", url, dir)})`,
|
|
)
|
|
.replace(/\b(href|src)="([^"]*)"/g, (_, attr, url) => `${attr}="${rewrite(attr, url, dir)}"`),
|
|
)
|
|
.join("");
|
|
}
|
|
|
|
fs.rmSync(outDir, { recursive: true, force: true });
|
|
fs.mkdirSync(outDir, { recursive: true });
|
|
|
|
for (const page of pages) {
|
|
const note = `<!-- Generated from ${page.source} by .github/wiki/build.mjs. Edit that file, not the wiki. -->\n\n`;
|
|
fs.writeFileSync(path.join(outDir, `${page.name}.md`), note + rewriteLinks(page.body, page.source));
|
|
}
|
|
|
|
const groups = [...new Set(pages.filter((p) => p.group).map((p) => p.group))];
|
|
const sidebar = [
|
|
"**[Home](Home)**",
|
|
...groups.map(
|
|
(g) =>
|
|
`\n**${g}**\n\n` +
|
|
pages
|
|
.filter((p) => p.group === g)
|
|
.map((p) => `- [${p.nav ?? p.name}](${p.name})`)
|
|
.join("\n"),
|
|
),
|
|
`\n**Links**\n\n- [Website](https://thingport.net/)\n- [Releases](${REPO_URL}/releases)\n- [Issues](${REPO_URL}/issues)`,
|
|
].join("\n");
|
|
fs.writeFileSync(path.join(outDir, "_Sidebar.md"), sidebar + "\n");
|
|
fs.writeFileSync(
|
|
path.join(outDir, "_Footer.md"),
|
|
`This wiki is generated from the [repository](${REPO_URL}) docs. To change a page, edit its source file there.\n`,
|
|
);
|
|
|
|
console.log(`Wrote ${pages.length} pages to ${outDir}`);
|