From 43903319d9eeaddd3263ba47d2e1057e96445e75 Mon Sep 17 00:00:00 2001 From: Steffen Becker Date: Fri, 28 Aug 2026 21:03:43 +0000 Subject: [PATCH] fix: only one w:displayBackgroundShape in settings.xml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The docx package always writes the element; the page-background pass prepended a second one, breaking the CT_Settings sequence so Word repairs the file on open — and the repair drops every header and footer reference. The schema test's DOCX leg now builds with the page decor, line numbering and fold marks, which covers the pass. --- src/lib/export/docx.ts | 12 ++++++++---- tests/schema-validation.test.ts | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/lib/export/docx.ts b/src/lib/export/docx.ts index 9a46fc5..aaf04bc 100644 --- a/src/lib/export/docx.ts +++ b/src/lib/export/docx.ts @@ -1660,11 +1660,15 @@ function applyPageDecorDocx(bytes: Uint8Array, decor: PageDecor, widthPt: number const color = decor.background.replace('#', '').toUpperCase(); doc = doc.replace(/(]*>)/, `$1`); const setBytes = files['word/settings.xml']; - // Without this Word stores the colour but paints nothing. + // Without this Word stores the colour but paints nothing. The docx package already + // writes one; a duplicate breaks the CT_Settings sequence and Word repairs the file. if (setBytes) { - files['word/settings.xml'] = strToU8( - strFromU8(setBytes).replace(/(]*>)/, '$1'), - ); + const settings = strFromU8(setBytes); + if (!settings.includes(']*>)/, '$1'), + ); + } } } diff --git a/tests/schema-validation.test.ts b/tests/schema-validation.test.ts index 7758bb2..043e141 100644 --- a/tests/schema-validation.test.ts +++ b/tests/schema-validation.test.ts @@ -116,7 +116,8 @@ describe.skipIf(!hasXmllint)('exported XML validates against the format schemas' sheet, undefined, 'add', false, opts.notesSettings, opts.props, true, opts.pageNumbering, opts.decor, opts.lineNumbering, true, true)); docx = unzipSync(await buildDocx(doc, undefined, 'portrait', opts.hf, opts.language, 'A4', - sheet, undefined, 'add', false, opts.notesSettings, opts.props, true, opts.pageNumbering)); + sheet, undefined, 'add', false, opts.notesSettings, opts.props, true, + opts.pageNumbering, opts.decor, opts.lineNumbering, true, true)); }); it('every ODF part is schema-valid (foreign namespaces stripped, as extended conformance allows)', () => {