102 lines
3.3 KiB
JavaScript
102 lines
3.3 KiB
JavaScript
import fs from "node:fs";
|
|
import vm from "node:vm";
|
|
|
|
const sourcePath = "doc/index.html";
|
|
const html = fs.readFileSync(sourcePath, "utf8");
|
|
|
|
const styleMatch = html.match(/<style>([\s\S]*?)<\/style>/);
|
|
const scriptMatch = html.match(/<script>([\s\S]*?)<\/script>/);
|
|
|
|
if (!styleMatch || !scriptMatch) {
|
|
throw new Error("Could not find inline style or script in doc/index.html");
|
|
}
|
|
|
|
const css = styleMatch[1]
|
|
.replaceAll("href=\"?page=", "href=\"/")
|
|
.replace(/href="\/home"/g, "href=\"/\"");
|
|
|
|
const legacyScript = scriptMatch[1];
|
|
const renderScript = legacyScript.replace(
|
|
/const params = new URLSearchParams\(window\.location\.search\);[\s\S]*$/,
|
|
"globalThis.__pageData = pageData;"
|
|
);
|
|
|
|
const sandbox = {
|
|
console,
|
|
URLSearchParams,
|
|
window: { location: { search: "" } },
|
|
document: {
|
|
title: "",
|
|
getElementById() {
|
|
return { innerHTML: "" };
|
|
},
|
|
querySelectorAll() {
|
|
return [];
|
|
},
|
|
querySelector() {
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
vm.createContext(sandbox);
|
|
vm.runInContext(renderScript, sandbox, { filename: sourcePath });
|
|
|
|
const pageData = sandbox.__pageData;
|
|
const routeMap = {
|
|
home: "/",
|
|
press: "/press",
|
|
judging: "/judging",
|
|
scholarly: "/scholarly",
|
|
services: "/services",
|
|
why: "/why",
|
|
resources: "/resources",
|
|
faq: "/faq",
|
|
thanks: "/thanks",
|
|
terms: "/terms",
|
|
privacy: "/privacy",
|
|
disclaimer: "/disclaimer"
|
|
};
|
|
|
|
const pages = Object.fromEntries(
|
|
Object.entries(routeMap).map(([key, path]) => {
|
|
const page = pageData[key];
|
|
if (!page?.body) {
|
|
throw new Error(`Missing page body for ${key}`);
|
|
}
|
|
return [
|
|
key,
|
|
{
|
|
key,
|
|
path,
|
|
title: key === "home" ? "Paprika" : `Paprika - ${key}`,
|
|
html: normalizeLinks(page.body)
|
|
}
|
|
];
|
|
})
|
|
);
|
|
|
|
function normalizeLinks(value) {
|
|
return value
|
|
.replaceAll("href=\"?page=home\"", "href=\"/\"")
|
|
.replace(/href="\?page=([a-z-]+)"/g, (_match, page) => {
|
|
if (page === "home") return "href=\"/\"";
|
|
return `href="/${page}"`;
|
|
});
|
|
}
|
|
|
|
fs.mkdirSync("app", { recursive: true });
|
|
fs.mkdirSync("lib", { recursive: true });
|
|
|
|
fs.writeFileSync(
|
|
"app/globals.css",
|
|
`${css}\n\n.form-error { color: var(--deep-red); font-size: 14px; font-weight: 750; line-height: 1.4; }\n.form-success { color: var(--green); font-size: 14px; font-weight: 750; line-height: 1.4; }\n.field-control { width: 100%; border: 0; outline: 0; background: transparent; color: var(--ink); font: inherit; font-weight: 650; }\n.field-control::placeholder { color: var(--muted); opacity: .78; }\ntextarea.field-control { min-height: 126px; resize: vertical; line-height: 1.45; }\n.checkbox-field { align-items: flex-start; gap: 12px; text-align: left; color: var(--text); font-size: 14px; line-height: 1.45; }\n.checkbox-field input { margin-top: 3px; accent-color: var(--red); }\n.button[disabled] { cursor: not-allowed; opacity: .62; }\n`
|
|
);
|
|
|
|
fs.writeFileSync(
|
|
"lib/legacy-pages.ts",
|
|
`export type LegacyPageKey = ${Object.keys(pages).map((key) => JSON.stringify(key)).join(" | ")};\n\nexport type LegacyPage = {\n key: LegacyPageKey;\n path: string;\n title: string;\n html: string;\n};\n\nexport const legacyPages = ${JSON.stringify(pages, null, 2)} as const satisfies Record<LegacyPageKey, LegacyPage>;\n`
|
|
);
|
|
|
|
console.log(`Generated ${Object.keys(pages).length} pages from ${sourcePath}`);
|