#!/usr/bin/env node // Regenerate the import fixture corpus (issue #63, ADR 0009) from the committed // `*.src.html` sources: for each source, write `.docx`, `.odt`, and // the expected Markdown snapshot for each format. Run against a reachable pandoc // sidecar (the pinned `pandoc/core:3.6`, so snapshots match CI): // // docker run --rm -p 3030:3030 pandoc/core:3.6 server // PANDOC_URL=http://localhost:3030 node scripts/gen-import-fixtures.mjs // // The pipeline mirrors ImportService: `html → ` builds the document, then // ` → html` (embed-resources) → `html → gfm` reproduces what an import // would parse, with image data URIs normalised to a stable token. import { readFileSync, writeFileSync, readdirSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname, join } from 'node:path'; const FIXTURES = join(dirname(fileURLToPath(import.meta.url)), '..', 'fixtures', 'import'); const PANDOC_URL = process.env.PANDOC_URL ?? 'http://localhost:3030'; const MARKDOWN_FORMAT = 'gfm-implicit_figures-raw_html'; /** POST a conversion to pandoc-server. Without an `Accept` header the server * returns text for text writers and raw bytes for binary ones (docx/odt). */ async function pandoc(params, binaryOut = false) { const res = await fetch(`${PANDOC_URL}/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(params), }); if (!res.ok) throw new Error(`pandoc ${res.status}: ${await res.text()}`); return binaryOut ? Buffer.from(await res.arrayBuffer()) : res.text(); } async function buildDocument(html, ext) { return pandoc({ text: html, from: 'html', to: ext, standalone: true }, true); } async function toExpectedMarkdown(documentBytes, ext) { const embedded = await pandoc({ text: documentBytes.toString('base64'), from: ext, to: 'html', standalone: false, 'embed-resources': true, }); const md = await pandoc({ text: embedded, from: 'html', to: MARKDOWN_FORMAT, standalone: false, wrap: 'none', }); return md.replace(/data:image\/[a-zA-Z0-9.+-]+;base64,[A-Za-z0-9+/=]+/g, 'data:embedded-image'); } const sources = readdirSync(FIXTURES).filter((f) => f.endsWith('.src.html')); for (const source of sources) { const name = source.replace(/\.src\.html$/, ''); const html = readFileSync(join(FIXTURES, source), 'utf8'); for (const ext of ['docx', 'odt']) { const bytes = await buildDocument(html, ext); writeFileSync(join(FIXTURES, `${name}.${ext}`), bytes); writeFileSync( join(FIXTURES, `${name}.${ext}.expected.md`), await toExpectedMarkdown(bytes, ext), ); console.log(`wrote ${name}.${ext} (+ expected.md)`); } }