한국어 | English
This focused technical reference generates Web and DOCX output from one physical document/layout state, renders the DOCX with actual Microsoft Word, and records measurable Web-to-Word layout deltas as structured JSON evidence.
Equivalent-looking style inputs do not necessarily produce the same physical layout in a browser and Microsoft Word. A relative line-height value such as 1.45, for example, can acquire different physical meaning when each renderer interprets it independently.
The resolver therefore converts relative input once: 10.5 pt × 1.45 = 15.225 pt. Both adapters consume that resolved value.
relative style input
↓
shared layout resolver
↓
physical values (mm / pt)
↓
Web / DOCX
Shared Document / Layout State
│
↓
Physical Layout Resolver
│
┌───────┴────────┐
│ │
↓ ↓
Web Renderer DOCX Renderer
│ │
↓ ↓
Edge → PDF DOCX
│
↓
Microsoft Word
│
↓
PDF
│ │
└───────┬────────┘
↓
Layout Comparison
↓
Structured Evidence
PDF is derivative renderer evidence, not the source document representation.
- Common model: format-neutral millimetres and points; no public OOXML units
- Physical resolver: resolves relative line height before either adapter runs
- DOCX adapter: mm-to-twip and pt-to-half-point/twip conversion, exact line spacing, and East Asian fonts
- A4 geometry, 20 mm margins, real Word numbering, fixed table layout, and explicit page breaks
- Word automation: COM
ExportAsFixedFormat, owned-process identification, and document/COM/process cleanup - Layout comparison: PDF page geometry and fixture-configured text-anchor coordinates
- Structural tests: OOXML page size, margins, exact spacing, fonts, numbering, table geometry, and page breaks
- DOCX package reproducibility fixture: isolates variable ZIP/core timestamps and external-hyperlink relationship IDs, then verifies bounded canonicalization produces stable bytes
- Renderer-led page-flow fixture: removes explicit page breaks and records independently produced Edge/Word pagination without pretending to provide a shared pagination engine
- Inline-image line-spacing fixture: demonstrates that an image paragraph inheriting exact body line spacing is clipped in Word and verifies the explicit automatic-line-spacing correction with rendered pixels
DOCX-specific twips, half-points, and DXA values remain inside the DOCX adapter.
The committed bilingual A4 fixture was rendered with Microsoft Edge 151 and Microsoft Word 16.0. Full measurements and hashes are in evidence/comparison.json.
| Check | Result |
|---|---|
| DOCX generated | PASS |
| Microsoft Word rendered | PASS |
| Web / Word pages | 2 / 2 |
| Web / Word automatic-flow pages | 3 / 2 |
| Maximum page-width delta | 0.24 pt |
| Maximum page-height delta | 0.12 pt |
| Maximum anchor X delta | 0.48 pt |
| Maximum anchor Y delta | 0.92 pt |
| Reference renderer | NOT RUN |
| Pixel-perfect equality | Not claimed |
These measurements cover one controlled fixture. They are not a universal fidelity benchmark for arbitrary Word documents or Word versions.
The separate automatic-flow fixture contains no explicit page break. With the committed 63-row table, Edge 151 produced 3 pages while native Microsoft Word 16.0 produced 2 pages; the final marker remained present in both outputs. Renderer provenance, hashes, content checks, and measurements are in evidence/page-flow-comparison.json. This is fixture- and version-scoped evidence that shared physical inputs do not by themselves guarantee shared pagination.
The independent inline-image fixture keeps a 40 x 20 mm diagnostic PNG constant and varies only the image paragraph's line-spacing rule. In native Microsoft Word 16.0, inheriting the document default exact body line spacing left 22.51% of the diagnostic colors visible; explicitly setting the image paragraph to automatic line spacing restored 83.29%, matching the full Edge rendering for the measured color coverage. Structure, renderer identity, hashes, physical bounds, pixel samples, and non-claims are recorded in evidence/image-line-spacing.json.
| Web — Microsoft Edge | DOCX — Microsoft Word |
|---|---|
![]() |
![]() |
- Browser and Word must not interpret the same relative line-height independently; resolve it once to an absolute point value.
- A quoting bug inside an HTML
styleattribute caused Edge to use default font sizes and produced an intermediate maximum Y delta of87.91 pt. Inspecting actual PDF span sizes identified the defect, and a regression test now protects the fix. - Closing a Word document is not sufficient COM hygiene. The automation identifies its WINWORD process and checks for a residual process after cleanup.
- Automatic page flow remains renderer-owned: a no-break fixture generated from one resolved physical state produced different Edge and Word page counts while preserving required content.
- A DOCX inline image paragraph must explicitly override inherited exact body line spacing. Omitting
w:lineon the paragraph does not clear an exact rule inherited from the default paragraph style; the measured correction emitsw:line="240" w:lineRule="auto"for that paragraph.
See docs/ENGINEERING_NOTES.md for the Problem → Cause → Solution → Verification record.
These commands do not require Microsoft Word:
npm ci
npm run typecheck
npm test
npm run generateStructural CI verifies TypeScript/OOXML behavior and generation on Linux and Windows. It is not native Word verification.
python -m pip install -r requirements.txt
npm run verifyFull verification requires Windows, Microsoft Word, Microsoft Edge, Python 3, and PyMuPDF. A LibreOffice render is never reported as Microsoft Word verification.
Fixture-specific anchors belong in config/anchors.json, not in the comparison engine.
This repository is not:
- a document editor or Word replacement;
- a DOCX import engine;
- a generic document-conversion platform;
- an automatic pagination engine; or
- a universal Microsoft Word fidelity benchmark.
Its scope is reproducible physical-layout mapping and comparison across Web, DOCX, Microsoft Word, and OOXML. It measures automatic pagination divergence but does not implement a pagination engine. Matching page counts alone do not prove that an explicit page break survived; the OOXML structure is tested separately.
See docs/DECISIONS.md for technical decisions and docs/TECHNICAL_ASSET_POLICY.md for the standing policy used to separate reusable engineering assets from Product work.
MIT © 2026 monancho

