Repository navigation
fix(docx): bookmark a block of drawings alone where its first drawing is anchored - #968
Merged
Merged
Conversation
… is anchored A section, a container or a layer stack's column holding nothing but drawings writes no paragraph for its anchor's bookmark to go round, so a link to the anchor named a bookmark the file did not hold and a page reference to it was written as a fixed number. DocxDrawingAnchors now keeps the paragraph each shape is anchored in, by the shape's number, and the shapes nothing carries. At each section's end, once its drawings are anchored and before a table is split for its pages' margins, the export bookmarks such a block at the start of the paragraph holding its first drawing - the one on the earliest page, highest on it. Word keeps a drawing on its paragraph's page and moves it with that paragraph, so the reference reads the block's page and follows it through edits. A block that draws nothing, whose first drawing nothing carries, or that is composed in a table's cell keeps its report note. Measured in Word 16 (fields updated) and LibreOffice 24.2 on such a block on page 2 and on the same file with a page put in ahead of it: before, both read 2 in each and carried no link; now both read 2 and then 3, and the link goes to the block's page. The template corpus declares no anchors and is unchanged.
…t makes A table is split for its pages' margins, or a panel cut at a page, under a copy of its header rows. The split is refused where a header row holds a bookmark when it is decided, but a block of drawings alone is now marked after that, in the paragraph holding its first drawing, before the split is made. A bookmark copied with its name and id would leave two of one id, and keeping the last bookmark of each name would take both out, leaving a page reference on a bookmark the file lacks. DocxTableSplit.split and splitInItsPanel now copy the header rows without their bookmark starts and ends, as a panel's cut already copied them without their drawings; the first part keeps the bookmark, on the table's first page. Also: an end-to-end test of a block whose first drawing fills a page nothing is written on, which is named rather than marked on a later page, and of a block above a table split for its pages' margins, marked once.
…e marked A block that writes no paragraph and draws nothing is named only where no other node marks its anchor, which is known once every section's blocks of drawings alone are marked. The test pinning it held one section; a second holds the empty block in the first section and the block of drawings in the second. The Javadoc, the test class's and the recipe now say which block is named: one whose first drawing no paragraph carries as its own. A block whose first drawing stands on a page nothing is written on may have a later drawing carried, and is named all the same.
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 section, a container or a layer stack's column that holds nothing but drawings writes no paragraph: its drawings are anchored in the paragraphs beside them, or in one written on their page, when the section ends.
bookmarkAroundhad nothing to go round, so its anchor got no bookmark:linkTo, a table of contents' entry) named a bookmark the file did not hold;Measured in Word 16 (fields updated, as F9 on the whole text) and LibreOffice 24.2, on such a block on page 2 and on the same file with a page put in at its start, so a live field must move to 3: both editors read 2 in both files and carried no link, for every shape of block tried.
What changed
DocxDrawingAnchorskeeps the paragraph each shape is anchored in, by the shape's number (Ordered#drawn), whichever way it is anchored: beside a paragraph's text, in a paragraph on its page, or in a table cell. It also keeps the shapes a section's end finds nothing to carry.drawnSoFar()reads how many shapes the document has numbered;carrierOfTheFirst(from, to)returns the paragraph of the first of a range — the shape on the earliest page, highest on it — ornullwhere none of them is anchored, or the first stands on a page nothing carries: a later page's paragraph is not where the block starts.writePlacedNodeand the column writer note how many shapes were numbered before a block was written. A block that wrote no paragraph is kept with that range (UnmarkedBlock), as it was kept to be named.markTheBlocksOfDrawingsAloneruns at each section's end, once its drawings are anchored and before its pages are given their margins. It puts each such block's bookmark at the start of the paragraph holding its first drawing, opened and closed there: a place, not a range, the paragraph's text not being the block's. Word keeps a drawing on the page of the paragraph it is anchored in and moves it with that paragraph, so a page reference reads the page the block starts on and goes on reading it after edits above; a link lands beside the drawing. Before the margins: a table split for its pages' margins (DocxTableSplit.split) copies the table and takes the moved rows out of the first part, and a row's paragraph read before that is out of the file.nameTheBlocksNoBookmarkMarksruns at the document's end, as before, on the blocks left: one that draws nothing, one whose first drawing stands on a page nothing is written on, and one composed in a table's cell, whose drawings its table draws as its own. Their note now says "writes no paragraph, and no paragraph carries the first drawing of its own". It runs after every section's blocks of drawings are marked, so a block that draws nothing is not named where one of drawings marks the same anchor.settleThePageReferencesand the links need nothing new: a field is named after the bookmark its anchor was written under, and a link already names the bookmark by its anchor.startBookmarkopens a bookmark and records it (name,bookmarksWritten,bookmarksOfAnchors):bookmarkAroundandopenAnchoreach wrote those lines, and the newbookmarkAtTheStartOfuses it too.DocxTableSplit: a body table's split and a panel's cut copy the header rows without their bookmarks, as a panel's cut already copied them without their drawings. A split is refused where a header row holds a bookmark when it is decided (rowStarting), but a block's bookmark is written after that, before the split is made: copied with its name and id, a table's split would have both copies go when the export keeps the last bookmark of each name, leaving the field on none, and a panel's cut made after that would leave two bookmarks of one name and id. The first part keeps it, on the table's first page.Measured
Each case on a 400×500pt page (the last, 400×300), then the same DOCX with a page put in at its start (the stored field still reads the old number). Each cell: what the reference reads in the file as written / in the shifted one, and where the link goes.
Terms_and_conditions_of_the_agreement_be, Word's 40 characters; the bookmark, the link andPAGEREFname it alike. On a section of text the same reference read 2 / 3 before this change already: the name is made once per anchor (DocxBookmarkNames), so it is the same when the bookmark is written and when the field is settled.Verification
DocxDrawnBlockBookmarkTest(14 tests):PAGEREF <anchor> \hreading 2, the link names it, and no note mentions a bookmark;IntrokeepsIntro, the block anchoredintrotakesintro_2;DocxDrawingAnchorsTest(+4): the carrier of a range is the shape's on the earliest page, highest on it; a shape anchored in a cell is carried by the cell's paragraph; shapes whose first nothing carries have none, though a later one is carried; carriers are kept across sections and forgotten byreset.DocxTableSplitTest(+2): a body table's split and a panel's cut leave a header row's bookmark, start and end, in the first part and out of the copy.DocxAnchorWithoutABookmarkTestholds the blocks that still have no bookmark — one that draws nothing, one whose first drawing fills a page nothing is written on (+1), one composed in a table's cell — with the new note;DocxLayerColumnBookmarkTest(a column of drawings is marked; an empty column is named);DocxPanelOverPagesTestrefers to a drawn shape's own anchor to get a reference settled as its number; the node and value ledgers.2.5-dev: all 67 byte-identical; report notes 1491 → 1491.clean verifyof the reactor as CI runs it → BUILD SUCCESS (render-docx 2293, qa 1835); the four knowledge checks and core javadoc (0 warnings) pass; examples 93.Lane: shared-engine (render-docx semantic DOCX backend), no public API change.