Repository navigation
fix(docx): name a block that writes no paragraph for its anchor's bookmark - #936
Merged
Merged
Conversation
…kmark A bookmark goes round the paragraphs a block writes. A section or a container of drawings alone writes none, its drawings standing in the paragraph beside them, and a link to its anchor is written to a bookmark the file lacks. Measured in Word and LibreOffice, the page's link went to the section's place, and both editors' PDFs carried no link at all. The report said nothing. Such a block is now named, with its anchor, once every bookmark is written and only where no other node's bookmark carries that anchor: a link to it points at none, and a page reference to it is a fixed number. A block with a note of its own has the loss added there. A bookmark name is asked for only where a block marks something, so one given for nothing cannot push another anchor onto a suffix. The file itself is unchanged.
DemchaAV
marked this pull request as draft
October 21, 2026 13:37
A block that writes no paragraph for its anchor's bookmark has the loss added to its own note, found by subject and path from the note count before it was written. The search ran on to the report's end, and a path is its section's own. In a document of two sections, the second's first block, with a note for its outline entry, had the first's anchor added to that note, and the first went unnamed; two such blocks at one path shared one note. The search now stops at the note count after the block was written.
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
The DOCX export marks an anchored block with a bookmark round the paragraphs it writes
(
bookmarkAround). A section or a container of drawings alone writes no paragraph: its drawingsstand in the paragraph beside them. It got no bookmark, while a link to its anchor was still
written as
w:hyperlink w:anchorpointing at it.Measured in Word 16 and LibreOffice on Windows, with a paragraph linking to such a section:
A drawn shape, a stack's column and a page zone's paragraph or picture already name this loss in
their own notes, and a page reference to such an anchor already named itself.
What changed
bookmarkAroundreturns whether it marked anything. As before, it asks for a bookmark nameonly where it marks something; a test now pins that. A name is kept once given, without case: one
given for nothing would push another anchor that cleans to it onto a suffix.
writePlacedNoderecords a block that marked nothing (UnmarkedBlock), with the note countbefore and after it was written.
nameTheBlocksNoBookmarkMarksruns once every bookmark is written. It names a recorded blockonly where no other node's bookmark carries the same anchor: where one does, a link goes there,
and
keepTheLastBookmarkOfEachAnchornames the anchor two nodes declare.notes added while the block was written (
DocxExportReport.Builder.addTo). A path is itssection's own: a later section's node, or a later place the same node is written, may have the
same one, and is not looked at. Otherwise the block
gets a note of its own: "writes no paragraph, so its anchor "…" has no bookmark in the Word
file: a link to it points at none, and a page reference to it is a fixed number rather than a
field".
settleThePageReferencesputs itsnotes in by the places it counted while writing, and a note put in earlier would move them.
gets a note of its own.
DocxNodeFieldLedgerTest:SectionNode.anchorandContainerNode.anchornow say the anchoris reported where the block writes no paragraph.
The DOCX bytes do not change; only the report does.
Other block kinds that go through
bookmarkAroundalways write something:tried beside its label, it was written inline and bookmarked.
Verification
carry the note, and the drawn shape keeps its one note.
2.5-dev, and the 1246 notes unchanged. No corpusdocument has such an anchor.
DocxAnchorWithoutABookmarkTest(new, 12 tests):in the file;
its own;
two blocks at one path have a note each;
./mvnw -B -ntp clean verifyon the reactor: BUILD SUCCESS (render-docx 1955, qa 1828),plus the JDK 17 knowledge checks and core Javadoc.
Not changed here
Writing a bookmark for such a block is left for later: a collapsed one in the paragraph that holds
its first drawing, so a link lands where the page sends it. The report now says where it is missing.
It names the block and its anchor, not the linking paragraph.
Lane: shared-engine (render-docx semantic backend): DOCX report only, no public API change.