134 lines
4.1 KiB
JavaScript
134 lines
4.1 KiB
JavaScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const repoRoot = process.cwd();
|
|
const legacyHtmlRoot = path.join(repoRoot, "archive-source");
|
|
const cssRoot = path.join(repoRoot, "css");
|
|
|
|
const themeCssPath = path.join(cssRoot, "theme.css");
|
|
const siteCssPath = path.join(cssRoot, "site.css");
|
|
|
|
function read(filePath) {
|
|
return fs.readFileSync(filePath, "utf8");
|
|
}
|
|
|
|
function write(filePath, value) {
|
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
fs.writeFileSync(filePath, value);
|
|
}
|
|
|
|
function walkHtml(dir) {
|
|
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
|
const fullPath = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
return walkHtml(fullPath);
|
|
}
|
|
return entry.isFile() && entry.name.endsWith(".html") ? [fullPath] : [];
|
|
});
|
|
}
|
|
|
|
function extractStyle(html, id) {
|
|
return html.match(new RegExp(`<style\\b[^>]*id=["']${id}["'][^>]*>([\\s\\S]*?)<\\/style>`))?.[1].trim() ?? "";
|
|
}
|
|
|
|
function extractAnonymousShortcodeCss(html) {
|
|
return (
|
|
Array.from(html.matchAll(/<style\s+type=["']text\/css["']>([\s\S]*?)<\/style>/g))
|
|
.map((match) => match[1].trim())
|
|
.find((body) => body.includes(".su-column-size-1-4")) ?? ""
|
|
);
|
|
}
|
|
|
|
function buildCssFiles() {
|
|
const aboutHtml = read(path.join(legacyHtmlRoot, "about.html"));
|
|
const indexHtml = read(path.join(legacyHtmlRoot, "index.html"));
|
|
|
|
const aboutTheme = extractStyle(aboutHtml, "parabola-style-inline-css");
|
|
const indexTheme = extractStyle(indexHtml, "parabola-style-inline-css");
|
|
if (!aboutTheme || !indexTheme) {
|
|
return false;
|
|
}
|
|
const marker = "/* Parabola Custom CSS */";
|
|
const indexExtra = indexTheme.includes(marker)
|
|
? indexTheme.slice(0, indexTheme.indexOf(marker)).replace(aboutTheme.slice(0, aboutTheme.indexOf(marker)), "").trim()
|
|
: "";
|
|
|
|
const customBackground = extractStyle(aboutHtml, "custom-background-css");
|
|
const headerFix = extractStyle(aboutHtml, "site-custom-css");
|
|
const shortcodeCss = extractAnonymousShortcodeCss(aboutHtml);
|
|
|
|
write(
|
|
themeCssPath,
|
|
[
|
|
"/* Extracted from the exported Parabola inline theme settings. */",
|
|
aboutTheme,
|
|
"",
|
|
].join("\n")
|
|
);
|
|
|
|
write(
|
|
siteCssPath,
|
|
[
|
|
"/* Shared site fixes extracted from repeated inline styles. */",
|
|
customBackground,
|
|
"",
|
|
headerFix,
|
|
"",
|
|
"/* Shortcodes Ultimate column rule used by exported content. */",
|
|
shortcodeCss,
|
|
"",
|
|
"/* Homepage slider/frontpage settings from the original export. */",
|
|
indexExtra,
|
|
"",
|
|
]
|
|
.filter((section) => section !== "")
|
|
.join("\n")
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
function ensureThemeLinks(html) {
|
|
if (html.includes("href='/css/theme.css'") || html.includes('href="/css/theme.css"')) {
|
|
return html;
|
|
}
|
|
|
|
const links = [
|
|
"<link rel='stylesheet' id='familyfedie-theme-css' href='/css/theme.css' type='text/css' media='all' />",
|
|
"<link rel='stylesheet' id='familyfedie-site-css' href='/css/site.css' type='text/css' media='all' />",
|
|
].join("\n");
|
|
|
|
return html.replace(
|
|
/(<link rel=['"]stylesheet['"] id=['"]parabola-style-css['"][^>]*>\s*)/,
|
|
`$1${links}\n`
|
|
);
|
|
}
|
|
|
|
function removeExtractedInlineStyles(html) {
|
|
return html
|
|
.replace(/\n?<style\b[^>]*id=["']parabola-style-inline-css["'][^>]*>[\s\S]*?<\/style>\s*/g, "\n")
|
|
.replace(/\n?<style\b[^>]*id=["']custom-background-css["'][^>]*>[\s\S]*?<\/style>\s*/g, "\n")
|
|
.replace(/\n?<style\b[^>]*id=["']site-custom-css["'][^>]*>[\s\S]*?<\/style>\s*/g, "\n")
|
|
.replace(/\n?<style\s+type=["']text\/css["']>\s*\.su-column-size-1-4\{[\s\S]*?<\/style>\s*/g, "\n");
|
|
}
|
|
|
|
const wroteCssFiles = buildCssFiles();
|
|
|
|
let updated = 0;
|
|
|
|
for (const filePath of walkHtml(legacyHtmlRoot)) {
|
|
const original = read(filePath);
|
|
const next = removeExtractedInlineStyles(ensureThemeLinks(original));
|
|
|
|
if (next !== original) {
|
|
write(filePath, next);
|
|
updated += 1;
|
|
}
|
|
}
|
|
|
|
console.log(
|
|
wroteCssFiles
|
|
? "Extracted repeated inline CSS to css/theme.css and css/site.css."
|
|
: "Inline theme CSS was already extracted; kept existing css/theme.css and css/site.css."
|
|
);
|
|
console.log(`Updated ${updated} HTML files.`);
|