// Builds docs/index.html from docs/pithos-docs.md (the Markdown stays the
// source of truth and is published beside it for AI assistants).
// node docs/build-docs.mjs
// Handles the Markdown this page uses: headings, paragraphs, lists (one
// nested level), fenced code, tables, inline code, bold, italics and links.
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const dir = path.dirname(fileURLToPath(import.meta.url));
const md = fs.readFileSync(path.join(dir, 'pithos-docs.md'), 'utf8').replace(/\r\n/g, '\n');
const esc = (s) => s.replace(/&/g, '&').replace(//g, '>');
const slug = (s) => s.toLowerCase().replace(/<[^>]+>/g, '').replace(/[`*]/g, '').replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
function inline(s) {
const codes = [];
s = s.replace(/`([^`]+)`/g, (_, c) => { codes.push(`${esc(c)}`); return `\u0000${codes.length - 1}\u0000`; });
s = esc(s)
.replace(/\*\*([^*]+)\*\*/g, '$1')
.replace(/(^|[\s(])\*([^*\s][^*]*)\*/g, '$1$2')
.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, '$1');
return s.replace(/\u0000(\d+)\u0000/g, (_, i) => codes[+i]);
}
const lines = md.split('\n');
const out = [];
const toc = [];
let i = 0;
let title = 'Pithos documentation';
while (i < lines.length) {
const line = lines[i];
if (!line.trim()) { i++; continue; }
const fence = /^```(\w*)/.exec(line);
if (fence) {
const buf = [];
i++;
while (i < lines.length && !lines[i].startsWith('```')) buf.push(lines[i++]);
i++;
out.push(`
${esc(buf.join('\n'))}`);
continue;
}
const hd = /^(#{1,3}) (.+)$/.exec(line);
if (hd) {
const level = hd[1].length;
const text = hd[2];
if (level === 1) { title = text; i++; continue; }
const id = slug(text);
toc.push({ level, id, text: inline(text) });
out.push(`| ${inline(c)} | `).join('')}
|---|
| ${inline(c)} | `).join('')}
${inline(para.join(' '))}
`); } const tocHtml = toc.filter((t) => t.level === 2).map((t) => `${t.text}`).join(''); const html = `