feat(docx): carry whatever a composed table cell is built from - #706
Merged
Merged
Conversation
DocumentTableCell.node(...) lets a cell hold anything the document can hold, and the export wrote paragraphs out of it and nothing else: a cell built from an image, a list or a table came out empty. Not wrong -- empty, with content the page draws simply missing from the file and one line in a log to say so. A table is where a document keeps the things a reader counts, which makes it the worst place to lose something quietly. The fix is not a second writer that knows about cells. The cell is a destination now: newBodyParagraph points at it and writeNode does the rest, so everything that can be written anywhere is written here too. A nested table is a real w:tbl followed by the paragraph Word requires a cell to end with, registered through insertTable so the model and the XML agree -- getTables() is unmodifiable, and adding to it throws rather than letting them drift apart. This uncovered a defect in reading columns back from the layout. A table whose cell is built from another table emits that inner table's rows under the OWNER's path, so the fragments at one path are not all one table's: a two-column table came out with a three-column grid, 45.3 / 32.7 / 76.9 where 78.0 / 76.9 belonged, and Word placed every edge exactly where it was told. Only rows that span the table are read now, and the derived count must match the one the table resolves -- a wrong grid is worse than none. A nested table is given the width of the column it sits in, less the margins Word keeps inside a cell. That is not the width the page gives it: the layout reports a composed cell's content under the owner's path, so which measured row belongs to which nested table cannot be told apart there. The choice was not between exact and approximate but between approximate and unreadable -- with no width at all, Word squeezes a nested table to about one character a line, confirmed by opening the export in Word 16.0 before and after. Tests: seven over the exported package -- an image, a list, a nested table, the paragraph that has to follow it, a transparent wrapper, the width, and the destination returning to the body afterwards. Verification: ./mvnw -B -ntp clean verify over the seven-module gate, 1784 tests, BUILD SUCCESS; render-docx 175 to 182; the examples module separately, 93 tests, BUILD SUCCESS, no committed preview drifted.
The capability matrix said a composed cell writes paragraphs only and one built from an image or a list lands empty, which is no longer what happens. The recipe listed tables and said nothing about what a cell can be built from.
| double twips = 0; | ||
| int last = Math.min(placement.column() + placement.colSpan(), grid.sizeOfGridColArray()); | ||
| for (int index = placement.column(); index < last; index++) { | ||
| twips += Long.parseLong(String.valueOf(grid.getGridColArray(index).getW())); |
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
DocumentTableCell.node(...)lets a cell hold anything the document can hold, and theexport wrote paragraphs out of it and nothing else. A cell built from an image, a list or a
table came out empty — not wrong, empty: content the page draws simply missing from the
file, with one line in a log to say so. A table is where a document keeps the things a
reader counts, which makes it the worst place to lose something quietly.
What changed
The cell is a destination, not a place with its own writer. It had a dispatcher that had
learned about paragraphs and the wrappers a paragraph sits in, and that is exactly the set
it could carry.
newBodyParagraphnow points at the cell being filled andwriteNodedoesthe rest, so everything writable anywhere is writable there. Nested tables work without
anything in the cell path knowing how a table is written.
w:tbl, registered throughXWPFTableCell.insertTableso themodel and the XML agree —
getTables()is unmodifiable and throws rather than lettingthem drift apart — and followed by the paragraph Word requires a cell to end with. A cell
ending in a table is malformed and Word refuses the file rather than showing it.
table whose cells hold content of their own.
A defect in reading columns back from the layout, uncovered by the above. A table whose
cell is built from another table emits that inner table's rows under the owner's path,
so the fragments at one path are not all one table's.
DocxLayoutMetrics.tableColumnsmerged their boundaries: a two-column table came out with a three-column grid — 45.3 / 32.7
/ 76.9 where 78.0 / 76.9 belonged — and Word placed every edge exactly where it was told.
Only rows that span the table's own placed width are read now, and the derived count must
equal the one
TableGridresolves; a wrong grid is worse than none.A nested table is given the width of the column it sits in, less the 5.4pt margins Word
keeps inside each cell edge. That is not the width the page gives it — the layout reports a
composed cell's content under the owner's path, so which measured row belongs to which
nested table cannot be told apart there. The choice was not between exact and approximate
but between approximate and unreadable: with no width at all Word squeezes a nested table to
about one character a line, confirmed by opening the export in Word 16.0 before and after.
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, which matters here because the column-reading fix applies to every table, not only
to the ones with composed cells.
render-docx goes from 175 to 182 tests.
DocxComposedCellTestcovers an image, a list, anested table, the paragraph that has to follow it, a transparent wrapper inside the cell, the
nested table's width, and the destination returning to the body afterwards.
Checked by opening the export in Word 16.0: the nested table renders as a table with its rows
and the list as bullets, where the same document previously had two empty cells.
Lane: canonical —
document.backend.semantic.docxonly; no engine, layout or paginationinternals are touched.