From 2dacb1f86b56a2bef0b5ec54abb22fc75a60dc0d Mon Sep 17 00:00:00 2001 From: Steffen Becker Date: Thu, 3 Sep 2026 07:13:52 +0200 Subject: [PATCH] fix: the parity reference keeps the blank pages LibreOffice inserts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Its PDF export drops auto-inserted blank pages unless IsSkipEmptyPages=false is passed, so a document whose chapters open on a right page was measured against a reference several sheets short of what LibreOffice lays out: 456 pages against 468 on the largest fixture, 28 against 32 on another. The corpus total rises on the honest reference — that is drift the old one hid, not new drift. --- tests/render-parity/README.md | 5 +++++ tests/render-parity/run.mjs | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/render-parity/README.md b/tests/render-parity/README.md index ef33fbb..a91b536 100644 --- a/tests/render-parity/README.md +++ b/tests/render-parity/README.md @@ -19,6 +19,11 @@ Exit code 1 when any document differs. `--json` also dumps both sides' lines | | reference | editor | |---|---|---| | render | `soffice --convert-to pdf` | Playwright Chromium, real app, real file input | + +The PDF is exported with `IsSkipEmptyPages=false`: LibreOffice drops its own +auto-inserted blank pages by default — a chapter forced onto a right page — and the +reference then has fewer sheets than the document LibreOffice lays out (the +458-page guide 456 against 468, one fixture 28 against 32). | read | `pdftotext -bbox-layout` (word boxes, pt) | `Range.getClientRects()` (word boxes, px) | Both sides are normalized to mm from the top-left of each page, grouped into lines, diff --git a/tests/render-parity/run.mjs b/tests/render-parity/run.mjs index 0ab9a02..68c5446 100644 --- a/tests/render-parity/run.mjs +++ b/tests/render-parity/run.mjs @@ -24,7 +24,11 @@ const POS_TOL_MM = 1.0; // reported as a position difference beyond this function loRender(file, work) { execFileSync('soffice', [ '--headless', '--norestore', `-env:UserInstallation=file://${work}/loprofile`, - '--convert-to', 'pdf', '--outdir', work, file, + // Keep the blank pages LibreOffice inserts itself (a chapter forced onto a right + // page): its PDF export drops them by default and the reference then loses a sheet + // the document really has. + '--convert-to', 'pdf:writer_pdf_Export:{"IsSkipEmptyPages":{"type":"boolean","value":"false"}}', + '--outdir', work, file, ], { stdio: 'pipe', timeout: 120_000 }); const pdf = join(work, basename(file, extname(file)) + '.pdf'); if (!existsSync(pdf)) throw new Error(`LibreOffice produced no PDF for ${file}`);