Title: DocxReader never populates WordDocument.sectionProperties from the body-level <w:sectPr>
Summary
DocxReader reads and then discards the document-wide <w:sectPr>. WordDocument.sectionProperties is left at its SectionProperties() defaults. Because any typed re-emission of word/document.xml rebuilds <w:sectPr> from that defaulted model, a round-trip that touches the body (insert_paragraph, add_header, …) silently collapses the section to defaults — dropping header/footer references, custom margins, page size/orientation, titlePg, pgNumType, vAlign, line numbers, and docGrid.
Root cause
In DocxReader.swift the body-child switch explicitly skips sectPr:
case "sectPr":
// <w:sectPr> as a direct child of <w:body> is the document-wide
// section properties block. It's parsed separately into
// `WordDocument.sectionProperties` (not into BodyChild) — skip
// here so it doesn't get captured as a `.rawBlockElement`.
continue
The comment claims it is "parsed separately into WordDocument.sectionProperties", but there is no such parse — grep -n "sectionProperties =" Sources/OOXMLSwift/IO/DocxReader.swift returns nothing. The block is skipped and never read into the typed model.
Impact
Every source-loaded document that has meaningful section properties (essentially all real-world Word docs — footer references, non-default margins, letter/A4 page size, landscape sections) loses them the first time a typed edit re-emits document.xml. This is a silent data-loss bug.
Repro
- Open a
.docx whose body <w:sectPr> has a <w:footerReference> and custom <w:pgMar>.
insert_paragraph (or any typed body edit) and save.
- Inspect the saved
word/document.xml: <w:sectPr> now carries default margins and no footer reference.
Suggested fix
Parse the body-level <w:sectPr> into WordDocument.sectionProperties in DocxReader (header/footer references by type, pgSz, pgMar, cols, titlePg, section break type, pgNumType, vAlign, lnNumType, docGrid), matching the fields the typed model can already represent. Either that, or preserve the raw <w:sectPr> verbatim and re-emit it unchanged when the typed model hasn't modified it.
Workaround in place downstream
che-word-mcp's open_document now hydrates sectionProperties from the source <w:sectPr> itself (hydrateSectionProperties) as a server-side shim. That covers the fields the typed model represents but can't recover sectPr children the model doesn't model (footnotePr, rsid attrs, exotic children) — so a proper reader-side fix is still wanted.
Environment
ooxml-swift v1.4.0.
Title:
DocxReadernever populatesWordDocument.sectionPropertiesfrom the body-level<w:sectPr>Summary
DocxReaderreads and then discards the document-wide<w:sectPr>.WordDocument.sectionPropertiesis left at itsSectionProperties()defaults. Because any typed re-emission ofword/document.xmlrebuilds<w:sectPr>from that defaulted model, a round-trip that touches the body (insert_paragraph,add_header, …) silently collapses the section to defaults — dropping header/footer references, custom margins, page size/orientation,titlePg,pgNumType,vAlign, line numbers, anddocGrid.Root cause
In
DocxReader.swiftthe body-child switch explicitly skipssectPr:The comment claims it is "parsed separately into
WordDocument.sectionProperties", but there is no such parse —grep -n "sectionProperties =" Sources/OOXMLSwift/IO/DocxReader.swiftreturns nothing. The block is skipped and never read into the typed model.Impact
Every source-loaded document that has meaningful section properties (essentially all real-world Word docs — footer references, non-default margins, letter/A4 page size, landscape sections) loses them the first time a typed edit re-emits
document.xml. This is a silent data-loss bug.Repro
.docxwhose body<w:sectPr>has a<w:footerReference>and custom<w:pgMar>.insert_paragraph(or any typed body edit) and save.word/document.xml:<w:sectPr>now carries default margins and no footer reference.Suggested fix
Parse the body-level
<w:sectPr>intoWordDocument.sectionPropertiesinDocxReader(header/footer references by type,pgSz,pgMar,cols,titlePg, section breaktype,pgNumType,vAlign,lnNumType,docGrid), matching the fields the typed model can already represent. Either that, or preserve the raw<w:sectPr>verbatim and re-emit it unchanged when the typed model hasn't modified it.Workaround in place downstream
che-word-mcp'sopen_documentnow hydratessectionPropertiesfrom the source<w:sectPr>itself (hydrateSectionProperties) as a server-side shim. That covers the fields the typed model represents but can't recoversectPrchildren the model doesn't model (footnotePr, rsid attrs, exotic children) — so a proper reader-side fix is still wanted.Environment
ooxml-swift v1.4.0.