Repository navigation
fix(docx): report the losses the export left silent or misnamed, and hold every node field to a decision - #855
Merged
Merged
Conversation
…ode field to a decision A row's fill, outline and side borders, anything in a page zone but text and page fields, a watermark, a protection, viewer preferences and a node kind of the caller's own all reached the Word file with at most a log line, so a caller reading DocxExportReport was told the document lost nothing. Each is now a report note: row paint (DROPPED; APPROXIMATED for a row composed in a table cell, whose paint the cell drawing may draw), page zone content (once per node, by identity, though a zone is written into each kind of header it is given), watermark per section, protection and viewer preferences once for the file, and an unknown node kind named as unknown, with what it holds, instead of as dropped geometry. A page field in the body says why it is dropped. Built-in kinds are those of the node and layout packages exactly. DocxNodeFieldLedgerTest records, for every field of every public node class and every output option, whether the export writes it, reports it, has nothing to carry, or leaves a gap naming what is lost, and fails on a kind, field or non-record node class nobody decided. The DOCX bytes do not change.
…rd a zone's losses A row composed in a table cell was always reported APPROXIMATED, though the cell drawing draws a cell's paint only where it frames no text: a filled label-and-value row lost its fill and the report called it approximated. It is now DROPPED where the table drew none of its cells' paint, and APPROXIMATED, saying which way, where it drew shapes. A row of no columns and no height, which the page does not paint, is no longer reported; the note names a rounded paint and lists its parts as a sentence. Page zone notes name their section in a file of several. The once-a-kind log line no longer carries the first node's count. The ledger scans every concrete node class in the node and layout packages, nested and non-public ones included, and records page zones' own gap - a paragraph's alignment, spacing and direction and a row's columns are not written there - under the zones option.
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
DocxExportReportpromises a caller that what the Word file does not carry is said, not approximated in silence. The promise is in theDocxSemanticBackend(Consumer)constructor Javadoc. Three kinds of loss reached the file with at most aLOG.warn, so a service reading the report was told the document lost nothing:writeRowwrites the row as a table with no shading or borders, andpaintOfreads only sections and containers;docx.zone.unsupportedNode, log only);DocumentOutputOptions.watermark,protectionandviewerPreferences, which have zero references in the module. A file asked to be password-protected came back open, and nothing said so.A fourth was reported for the wrong reason. A node kind of the caller's own was "dropped geometry with no semantic Word analogue", while what was lost was its text, its pictures and its children.
Nothing stopped this list from growing. A field added to a node is drawn by the PDF backend at once, and the DOCX export never has to decide what to do with it.
What changed
reportUnwrittenRowPaintnames what the row loses (row paint): fill, outline, borders, and whether they were rounded.DROPPED, a row with no columns included, but only where the layout gives the row some height. The page paints a row only then.DROPPED; it is written as one line.drawCellDrawingdraws a cell's paint as a shape only where it frames no text, and the layout does not say which box is the row's. So:DROPPEDwhere the table drew none, which is what happens to a fill round a label and a value;APPROXIMATED, saying which way, where the table drew shapes.Page zone content (
DROPPED,page zone content) is reported once per node.IdentityHashMap): two unnamed logos are two notes, and one logo written into a first-page header and the ordinary one is one note.reportUnwrittenOutputOptionsruns once per export, on bothexportandexportSections.watermarkis reported per section that sets one.protectionandviewer preferencesare reported once for the file. They are document-wide, as the PDF backend's multi-section render takes the first a section sets (PdfFixedLayoutBackend, "the first section that declares each wins").Unknown node kinds are named as unknown, with what is lost (
droppedBecause,heldNodes).isBuiltInis an exact package match (node package, layout package). A prefix match took the test's own node, incom.demcha.compose.document.backend…, for a built-in.APPROXIMATEDnote and says what else is lost.DocxNodeFieldLedgerTestrecords a fate for:The fates are
WRITTENin the body,REPORTED,INERT(29), orGAPwith what is lost (55 node fields, plus page zones, where a paragraph's alignment, spacing and direction and a row's columns are not written). A kind or field with no entry fails, and so does a node class that is not a record. Closing a gap moves its entry in the same change.The recipe, the capability matrix (watermark, protection, viewer preferences and page-zone rows),
render-docx/README.mdand the CHANGELOG say which losses are reported.Verification
./mvnw -B -ntp install -pl :graph-compose-render-docx→ BUILD SUCCESS: 972 tests, 0 failures, 1 skipped (the property-gated fidelity probe).DocxReportedLossesTestand 5 inDocxNodeFieldLedgerTest.RowNode.gap) or a whole kind (PageBreakNode) fails the ledger.DROPPEDtest fails on the first commit's always-APPROXIMATEDbranch.DocxFidelityCorpusTest -Dgraphcompose.docxFidelity=export, SHA-256 per file, 0 of 62 differ.-pl :graph-compose-core -Dtest='com.demcha.documentation.**'→ 166 tests. The qa documentation guards plusDocxPageZoneTest,DocxTransparentWrapperTestandCrossModuleBoundaryArchTest→ 45 tests. All green.Lane: render-docx backend (report only, no change to what is written) plus tests and docs.