feat(docx): write horizontal lines and dividers as Word rules - #737
Merged
Merged
Conversation
The export dropped every LineNode and standalone ShapeNode, so the rules a template draws under a heading or between entries were missing from the Word file. A horizontal line with no transform, and a filled bar no taller than Word's thickest border with no stroke, radius, gradient or transform (what addDivider draws), are now Word's own rule: an empty paragraph whose bottom border is the stroke, in its colour and thickness, with its ends as the paragraph's indents and the space above and below the stroke in its box kept. A dash becomes Word's dashed or dotted border and is reported APPROXIMATED. Vertical and slanted lines and other shapes are still dropped and reported. The committed word-export-companion.docx gains its divider and nothing else. Two report tests that used a horizontal line as their example of a dropped node now use a vertical one.
…page A line laid over another in a layer stack, canvas or shape container was written as a rule in the flow: a skill meter's track and the fill over it came out as two bars one under the other, unreported. Only a rule in the flow is written now; one in an overlay is dropped and reported as before, and registers no bookmark a page reference could point at. A translucent rule is flattened against what lies under it, and one not drawn at all keeps its place and draws nothing. A stroke thicker than its box spills out of it on the page and takes no room, so the room it takes in Word comes off the space owed below. In a cell of unwritten width the right end is not placed against the page. A bar filled with a solid paint is a rule too, a link on a rule is reported as not carried, and a start past the end is held at the end. The recipe, matrix and CHANGELOG state the limits: overlaid lines and rules in page zones are dropped, Word draws identical adjacent rules as one, and the placement was measured in LibreOffice only.
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 dropped every
LineNodeand every standaloneShapeNode. So the rules a template draws under a heading or between entries were missing from the Word file. Across templates and examples there are 147addLine(calls, 96 of them horizontal, plus 12addDivider(, and together they are among the most common drawing in the templates.Word has a horizontal rule of its own: the bottom border of a paragraph. It is what Word itself makes when a reader types three hyphens and presses Enter. As a paragraph it flows with the text, and a reader moves or deletes it as a line of the document.
What changed
DocxRules.of(node)decides what is a rule. It returns the rule, ornullfor anything else. Two kinds qualify:LineNodewhose ends sit at one height, with a visible stroke and no transform;ShapeNodethat is only a fill (no stroke, radius, gradient or transform) and no taller than Word's thickest border, 12pt. That is whataddDividerdraws.writeRulewrites it as an empty paragraph whose bottom border is the stroke.w:szin eighths of a point, clamped to Word's 2..96.fill()line runs to the right edge; the width comes from the layout when it placed the node.height − startY. The space above the stroke is the paragraph's exact height, and never less than the 0.1pt the table separator uses. The space below it is owed to whatever follows.dotted, any other becomesdashed. Word's dash lengths are its own, so the report notes adash patternasAPPROXIMATED. The line cap is not carried.anchoron a rule is a bookmark on its paragraph (blockAnchorOf). A dropped drawing registers none, so no page reference can point at a missing bookmark.LayerStackNode, aCanvasLayerNodeor aShapeContainerNodeis not written as a rule (overlayDepth). A skill meter's track and the fill over it would otherwise come out as two bars, one under the other. Such a line is dropped and reported, and registers no bookmark, so no page reference can point at a missing one.horizontal()sizes the box from the stroke set before it, so a 2pt stroke set afterwards sits in a 1pt box. The extra room it takes in Word comes off the space owed below it.DocumentPaintis a rule too.word-export-companion.docxgains its gold divider: one paragraph,w:bottom single sz=16 C4994C, right indent 1580 twips. Nothing else in itsdocument.xmlchanges, and the package has the same parts.DocxExportReportTestused a horizontal line as its example of a dropped node; it now uses a vertical one.troubleshooting.mdand the CHANGELOG are updated.Verification
In an editor. Five rules around text:
Each was rendered by the engine and converted with LibreOffice, then measured by pixel runs:
Every rule is 1–3px lower in LibreOffice, and for these rules the offset does not grow down the page. Each rule's length is within 2px of the engine's. Word has not been measured.
Tests.
./mvnw -B -ntp test -pl :graph-compose-render-docx→ 382 run, 0 failures. NewDocxRuleTest(17):single, sz 16, its colour, indents 0/0;dashed, and short dashes →dotted, each reported;DROPPED, three notes;startY;DROPPED, and noPAGEREFto the dropped line's anchor;7F7F7F;Each of these was sabotaged and fails its test:
w:szclamp;Gate. Full reactor gate (
clean verifyover core, render-pdf/docx/pptx, templates, testing, qa, coverage) → BUILD SUCCESS (qa 1788 green). Examples after install: 93 green, withword-export-companion.docxregenerated byWordExportExample: itsdocument.xmlgains the divider paragraph and nothing else.Notes
Lane: shared-engine (render-docx). No public API change.