feat(docx): give a paragraph the heading role the document declared - #708
Merged
Merged
Conversation
…lared A twenty-page export opened as one flat run of paragraphs: nothing in the Navigation Pane, nothing in the outline view, and a generated table of contents that came back empty. Word builds all three from heading styles, and the export wrote none. The outline level a document states when it declares a bookmark now becomes Word's own HeadingN style. The style carries the outline level and nothing else — the paragraph already has the look its author gave it, and a heading style that also set a font and a size would restyle every heading on the way out. Word knows its built-in headings by the pair HeadingN and "heading N", so both are written; with one of them it is a custom style that happens to be called Heading and the Navigation Pane stays empty. Only the levels a document uses are defined, and a level past Word's nine is clamped. The role is read from what the document declared and never inferred from type size: a heading guessed from a large first line turns a subtitle into a chapter and leaves a small real heading as body text.
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.
Why
A twenty-page export opened as one flat run of paragraphs. Nothing in the Navigation Pane,
nothing in the outline view, and a table of contents generated in Word that came back
empty. Word builds all three from heading styles, and the export wrote none — so a
document handed over to be worked on had no structure to move around in, only text.
The document already says where its headings are:
bookmark(...)carries aDocumentBookmarkOptionswith an outline level, which the PDF backend turns into itsoutline tree. On the way to Word that level was read and dropped.
What changed
A stated outline level becomes Word's own
HeadingNstyle.applyHeadingRolesetsw:pStylefromDocumentBookmarkOptions.level(), andwriteHeadingStyledefines the styleit names. Word recognises its built-in headings by a pair — the id
Heading1and the nameheading 1— so both are written; with only one of them the file has a custom style thathappens to be called Heading and the Navigation Pane stays empty.
The style carries the outline level and nothing else. No run properties, no spacing,
basedOnNormal. The paragraph already has the look its author gave it, and a heading stylethat also set a font and a size would restyle every heading on the way out — the export
describes the page rather than redesigning it.
Only the levels the document uses are defined. Nine heading styles in a document with
one heading is eight entries in Word's gallery that nothing refers to, so
headingLevelsInwalks the graph first. A level past Word's nine is clamped rather than written as a style
that does not exist, which would leave the paragraph with no role at all.
The role is never inferred from type size. A heading guessed from a large first line
turns a subtitle into a chapter and leaves a small real heading as body text — both wrong in
a document someone then edits. It comes from what the document declared or not at all.
The capability matrix and the DOCX recipe said the outline is not written. Both now say what
it is.
Verification
./mvnw -B -ntp clean verifyover the seven-module gate → BUILD SUCCESS, 1784 tests../mvnw -B -ntp test -f examples/pom.xml→ 93 tests, BUILD SUCCESS; no committed previewdrifted.
render-docx goes from 193 to 199 tests.
DocxHeadingRoleTestcovers a level becoming thematching style, the id/name pair and outline level Word needs, a heading style with no
formatting of its own, only the used levels being defined, a level past nine being clamped,
and a 28pt paragraph beside a 9pt one producing no heading at all.
Checked through Word 16.0 rather than by reading the XML back: the exported document reports
style=Heading 1 outlineLevel=1for the chapter,Heading 2 / 2for the section andNormal / 10for body text, and Word's ownGetCrossReferenceItems(wdRefTypeHeading)returns the heading list with its nesting — which is the list the Navigation Pane and a
generated table of contents are built from.
Lane: canonical —
document.backend.semantic.docxonly; no engine, layout or paginationinternals are touched.