feat: add persistent book navigation and public-only pages

This commit is contained in:
2026-10-15 17:53:48 +09:00
parent f6905074b1
commit 839eb2a6a4
22 changed files with 1191 additions and 269 deletions
+8 -3
View File
@@ -18,7 +18,12 @@ async function document(filename) {
if (!cache.has(filename)) cache.set(filename, load(await readFile(filename, 'utf8')));
return cache.get(filename);
}
const htmlFiles = (await files(root)).filter((file) => file.endsWith('.html'));
const outputFiles = await files(root);
for (const filename of outputFiles) {
const relative = path.relative(root, filename).split(path.sep).join('/');
if (/^(?:book\/)?draft(?:\/|$)/.test(relative)) failures.push(`Unpublished draft in output: ${relative}`);
}
const htmlFiles = outputFiles.filter((file) => file.endsWith('.html'));
for (const filename of htmlFiles) {
const relative = path.relative(root, filename).split(path.sep).join('/');
const pagePath = base + relative.replace(/index\.html$/, '');
@@ -57,9 +62,9 @@ for (const filename of htmlFiles) {
}
}
}
// Every source document must have its own generated page (including drafts).
// Every published source has a page; draft sources must never be emitted.
const contents = fileURLToPath(new URL('../../contents/', import.meta.url));
const markdown = (await files(contents)).filter((file) => file.endsWith('.md'));
const markdown = (await files(contents)).filter((file) => file.endsWith('.md') && path.relative(contents, file).split(path.sep)[0] !== 'draft');
for (const file of markdown) {
const slug = path.relative(contents, file).replace(/\.md$/, '');
const output = path.join(root, 'book', slug, 'index.html');