// Ad-hoc probe for one document: prints structure around a given block // index, before and after a round-trip, plus the raw vMerge / numId picture // from both packages. Structure only — no document text beyond short labels. // // node test/probe.mjs [blockIndex] import { readFileSync, writeFileSync } from "node:fs"; import { loadAddonLibs, summarise } from "./harness.mjs"; const DocxEditor = loadAddonLibs(); const schema = DocxEditor.schema.build(); const file = process.argv[2]; const focus = process.argv[3] ? parseInt(process.argv[3], 10) : null; const bytes = new Uint8Array(readFileSync(file)); const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"; async function numberingPicture(b, label) { const zip = await DocxEditor.pkg.loadZip(b); const doc = DocxEditor.pkg.parseXml(await zip.file("word/document.xml").async("string")); const ps = doc.getElementsByTagNameNS(W, "p"); const seq = []; for (let i = 0; i < ps.length; i++) { const numPr = ps[i].getElementsByTagNameNS(W, "numPr")[0]; if (!numPr) { seq.push("."); continue; } const numId = numPr.getElementsByTagNameNS(W, "numId")[0]; const ilvl = numPr.getElementsByTagNameNS(W, "ilvl")[0]; seq.push(`${numId ? numId.getAttributeNS(W, "val") : "?"}/${ilvl ? ilvl.getAttributeNS(W, "val") : "0"}`); } console.log(`${label} numbering (numId/level per paragraph, "." = not a list item):`); console.log(" " + seq.join(" ")); const merges = []; const rows = doc.getElementsByTagNameNS(W, "tr"); for (let r = 0; r < rows.length; r++) { const cells = rows[r].getElementsByTagNameNS(W, "tc"); const marks = []; for (let c = 0; c < cells.length; c++) { const vm = cells[c].getElementsByTagNameNS(W, "vMerge")[0]; if (!vm) { marks.push("-"); continue; } marks.push(vm.getAttributeNS(W, "val") === "restart" ? "R" : "c"); } if (marks.includes("R") || marks.includes("c")) merges.push(`r${r}:${marks.join("")}`); } if (merges.length) console.log(`${label} vMerge: ${merges.slice(0, 20).join(" ")}`); } const first = await DocxEditor.read.docxToDoc(bytes, schema); const saved = await DocxEditor.write.docToDocx(first.doc, { originalBytes: bytes, setup: first.setup, meta: first.meta, }); const second = await DocxEditor.read.docxToDoc(saved.bytes, schema); console.log(`blocks: ${first.doc.childCount} -> ${second.doc.childCount}`); if (saved.warnings.length) console.log(`warnings: ${saved.warnings.join(" | ")}`); console.log(); await numberingPicture(bytes, "original"); console.log(); await numberingPicture(saved.bytes, "saved "); if (focus !== null) { const outline = (doc, from) => { const lines = []; for (let i = from; i < Math.min(doc.childCount, from + 8); i++) { const n = doc.child(i); lines.push(` [${i}] ${n.type.name}${n.childCount ? ` (${n.childCount} kids)` : ""} ` + JSON.stringify(n.textContent.slice(0, 40))); } return lines.join("\n"); }; console.log(`\nbefore, from [${focus}]:\n` + outline(first.doc, focus)); console.log(`\nafter, from [${focus}]:\n` + outline(second.doc, focus)); }