fix: real insert/remove_watermark, honest image-watermark error, sectPr hydration - #171
Open
ebolamerican wants to merge 1 commit into
Open
Conversation
ebolamerican
force-pushed
the
fix/watermark-remove-and-sectpr-hydration
branch
from
July 17, 2026 21:26
6fb4509 to
7fb031e
Compare
…Pr hydration The watermark tools were stubs that reported success without touching the document, and open_document never populated sectionProperties from the source sectPr — so any typed re-emission of word/document.xml collapsed margins, page geometry, and header/footer references to defaults. - insert_watermark now writes Word's VML WordArt watermark (PowerPlusWaterMarkObject textpath, o:spt="136") into the default page header, honoring font/color/size/semitransparent/rotation. Three paths: append to an existing default header; pure-typed for scratch-built docs; and, for source-loaded docs with no header part, surgically wire the new header (relationship + Content_Types Override + sectPr headerReference) into the preserved archive BEFORE registering the typed Header, so DocxWriter's overlay gates stay closed and source rels/[Content_Types] are preserved verbatim. A second insert errors instead of stacking shapes. - remove_watermark strips watermark paragraphs from every header (typed raw blocks and source-parsed w:pict runs) and errors when none exists. - insert_image_watermark returns an honest not-implemented error instead of the prior false success that wrote nothing. - open_document hydrates sectionProperties (header/footer refs incl. first/even, page size + orientation, margins, columns, titlePg, section break type, pgNumType, vAlign, line numbers, docGrid) from the source body-level <w:sectPr>, working around DocxReader's sectPr stub. Regression tests: WatermarkInsertRegressionTests, SectPrPreservationProbeTests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ebolamerican
force-pushed
the
fix/watermark-remove-and-sectpr-hydration
branch
from
July 17, 2026 21:27
7fb031e to
cf2e0d5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The watermark tools were stubs that reported success without touching the document, and
open_documentnever populatedsectionPropertiesfrom the sourcesectPr— so any typed re-emission ofword/document.xmlcollapsed margins, page geometry, and header/footer references to defaults.This PR makes those tools do what they claim, and works around the
DocxReadersectPrgap server-side.Changes
insert_watermarkactually inserts a watermark. Writes Word's own VML WordArt watermark (PowerPlusWaterMarkObjecttextpath shape,o:spt="136") into the default page header, honoringfont/color/size/semitransparent/rotation. Three paths:bodyChildren.archiveTempDir) — pure typed path viaaddHeader; the writer emits every part from the typed model..docxwithfooter1.xmlonly) — wire the new header surgically into the preserved archive (relationship inword/_rels/document.xml.rels, Override in[Content_Types].xml,<w:headerReference>inserted into the existing body-level<w:sectPr>) before registering the typedHeader, soDocxWriter's overlay gates stay closed and the source rels /[Content_Types].xmlare preserved verbatim. A second insert errors instead of stacking duplicate shapes.remove_watermarkactually removes. Strips watermark paragraphs from every header (typed raw blocks and source-parsedw:pictruns) and errors honestly when no watermark exists.insert_image_watermarkreturns an honest error. Image watermarks need media-part plumbing that isn't implemented; the tool now returns a not-implemented error instead of the prior false success that wrote nothing.open_documenthydratessectionProperties(header/footer refs incl. first/even, page size + orientation, margins, columns,titlePg, section break type,pgNumType,vAlign, line numbers,docGrid) from the source body-level<w:sectPr>. This works aroundDocxReaderleavingsectionPropertiesat defaults (see filed upstream issue), which otherwise caused every typed re-emission ofword/document.xmlto silently drop the source's footer reference, custom margins, and page geometry.Tests
Tests/CheWordMCPTests/WatermarkInsertRegressionTests.swift— append-to-existing-header, create-header-when-none-exists, remove actually removes, second insert errors.Tests/CheWordMCPTests/SectPrPreservationProbeTests.swift—insert_paragraphpreserves the source footer reference.swift buildclean;swift testgreen (5/5 on the new suites).Related upstream issues
These fixes work around, but do not fix, three root-cause bugs filed separately:
DocxWriter.buildTypedRelationshipshardcodes rId1–3 and drops/remaps sourcestyles.xml/numbering.xmlrelationships.DocxReadernever populatessectionPropertiesfrom<w:sectPr>.protect_documentis still a stub that reports success without writing<w:documentProtection>.🤖 Generated with Claude Code