#!/usr/bin/env node /** * Generate output HTML from template + data for asteroid-splitting documents. * * Usage: node generate.mjs * Example: node generate.mjs asteroid-splitting-1 * * Reads: docs/.template.html * Reads: docs/.data.json (optional) * Writes: docs/.output.html * * data.json format: * { * pages: [{ * page: 1, * sections: [{ index: 0, scale: 1.2, rotate: 15 }] * }] * } * * Applies transform to big asteroid img (w-[26mm] container) * and proportionally to small asteroid imgs (w-[12mm] containers) in formula rows. */ import { readFileSync, writeFileSync, existsSync } from 'fs'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; import { postGenerate } from '../../../src/scripts/post-generate.mjs'; const __dirname = dirname(fileURLToPath(import.meta.url)); const docsDir = join(__dirname, '..', 'docs'); const docId = process.argv[2]; if (!docId) { console.error('Usage: node generate.mjs '); process.exit(1); } const templatePath = join(docsDir, `${docId}.template.html`); const dataPath = join(docsDir, `${docId}.data.json`); const outputPath = join(docsDir, `${docId}.output.html`); if (!existsSync(templatePath)) { console.error(`Template not found: ${templatePath}`); process.exit(1); } let html = readFileSync(templatePath, 'utf-8'); if (existsSync(dataPath)) { const data = JSON.parse(readFileSync(dataPath, 'utf-8')); html = applyData(html, data); console.log(`Applied data from ${data.pages?.length || 0} pages`); } writeFileSync(outputPath, html); console.log(`Generated: ${outputPath}`); await postGenerate(outputPath); function applyData(html, data) { if (!data.pages) return html; // Split HTML into pages by w-[210mm] divs const pageRegex = /
)(\s*/g, `$1 style="${transform}">` ); } pageHtml = pageHtml.slice(0, secStart) + secHtml + pageHtml.slice(secEnd); } return pageHtml; }