Files
jp-editor/scripts/run-m3-probe.mjs
T
2026-09-22 16:33:35 +08:00

31 lines
2.6 KiB
JavaScript

import { mkdir, readFile, writeFile } from "node:fs/promises";
import { parseJpwabc } from "../dist/domain/jpwabc.js";
import { modelFromParse } from "../dist/domain/score-model.js";
import { DeterministicFontMeasurementProvider } from "../dist/layout/font-measure.js";
import { DEFAULT_PAPER_CONFIG, layoutDocument, layoutSummary } from "../dist/layout/layout-engine.js";
import { probeSvg, renderSnapshotSvg } from "../dist/layout/svg-renderer.js";
const raw = await readFile("research/jpw7/demo/JP-Word练习曲-歌曲-康定情歌.jpwabc");
const model = modelFromParse(parseJpwabc(raw), { fileName: "康定情歌.jpwabc" });
const snapshot = await layoutDocument(model, DEFAULT_PAPER_CONFIG, new DeterministicFontMeasurementProvider());
const [svg] = renderSnapshotSvg(snapshot);
const summary = layoutSummary(snapshot);
const probe = probeSvg(svg);
const report = {
reportVersion: 1,
milestone: "M3",
input: "research/jpw7/demo/JP-Word练习曲-歌曲-康定情歌.jpwabc",
expected: { pageCount: 1, lineCount: 6, measureCount: 16, pageWidthMm: 210, pageHeightMm: 297, viewBox: "0 0 21000 29700" },
actual: { ...summary, pageWidthMm: snapshot.pages[0]?.widthMm ?? null, pageHeightMm: snapshot.pages[0]?.heightMm ?? null, viewBox: probe.viewBox, deterministicKey: snapshot.deterministicKey },
fontGate: { provider: "DeterministicFontMeasurementProvider", measurements: snapshot.fontMeasurements.length, allLoaded: snapshot.fontMeasurements.every((measurement) => measurement.loaded), fallbackCount: snapshot.fontMeasurements.filter((measurement) => measurement.fallback).length },
warningsByCode: Object.fromEntries([...new Set(snapshot.warnings.map((warning) => warning.code))].sort().map((code) => [code, snapshot.warnings.filter((warning) => warning.code === code).length])),
svgProbe: probe,
referenceBoundary: "16 measures/1 page/6 lines are the structural baseline; Web symbol count and unknown JPW object geometry are not claimed pixel-equivalent.",
evidencePaths: ["src/layout/layout-engine.ts", "src/layout/font-measure.ts", "src/layout/svg-renderer.ts", "acceptance/m3/kangding-page-1.svg"]
};
if (summary.pageCount !== 1 || summary.lineCount !== 6 || summary.measureCount !== 16 || probe.viewBox !== "0 0 21000 29700") throw new Error(`M3 baseline mismatch: ${JSON.stringify({ summary, probe })}`);
await mkdir("acceptance/m3", { recursive: true });
await writeFile("acceptance/m3/kangding-layout-summary.json", `${JSON.stringify(report, null, 2)}\n`, "utf8");
await writeFile("acceptance/m3/kangding-page-1.svg", svg, "utf8");
console.log(JSON.stringify({ ok: true, summary, deterministicKey: snapshot.deterministicKey, svg: probe }, null, 2));