fix(docx): hold a container's content inside its sides - #733
Merged
Merged
Conversation
The DOCX export never wrote a container's left and right margin or padding, so a card's text ran flush with the page margin and its accent bar sat against the text. Paragraphs are now indented by every enclosing container's margin and padding, and a panel's side borders are spaced by its padding, so the bar and the band sit at the card's edge; a filled side with no border gets a fill-coloured hairline to carry the band there. A numbered item inside keeps its hanging indent, its border spaced from its first line. Cells start from their own edge.
…s lines With paragraphs indented by their containers, three things no longer lined up. A padded section inside a panel spaced the panel's border by the panel's own padding, so the bar stepped in; the panel now records where its edge is and spaces by the distance to it. Rows and tables stayed at the page margin; they are moved in by w:tblInd, measured to the first cell's text as the editor measures it. Pictures were sized to the page's full width and ran past the right margin; they are sized to the width left between the insets. A nested numbered item's border is spaced from its first line with or without an inset. Stale docs that called the sides unrepresentable are updated.
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 container's
marginandpaddinghold its content in from its edges, and on the page a card's text sits inside the card. The DOCX export carried a container's top and bottom edge as paragraph spacing, but never its sides.In LibreOffice, a filled card with 14pt padding and a left accent had:
What changed
writeContainerBodyaccumulates each container's left and right margin plus padding (insetLeft/insetRight), restoring them afterwards.newBodyParagraphwrites the total asw:ind(applyInset), so nested containers add up. A paragraph outside any container gets now:ind, as before.w:spaceoutside the text and shades the paragraph out to that border. InapplyContainerPaint:w:sz="2") in the fill's own colour, spaced the same way, so the band reaches that edge too.w:spacestops at 31pt, so a wider padding brings the band's edge in by the difference.w:indreplaces its numbering level's, which would drop the hanging indent.indentListItemInsidewrites the inset plus the level's indent, and keeps the hanging.ContainerPaint.at), and a side border is spaced by the distance from the text to that edge. A padded section nested in a card therefore keeps the card's bar at the card's edge. Spacing by the panel's own padding stepped the bar in by the inner padding.indentTablewritesw:tblIndfor body tables and rows once they are written. The value is the inset plus the first cell's written margin: LibreOffice measuresw:tblIndto the first cell's text, so the inset alone left the border 4pt short. Measured, the table's border lands on the card's text line, as on the page.availableWidth). Before, a full-width picture in a padded card ran past the right margin.writeCellNoderesets the inset and restores it, because a table's cells are not inset by the containers around the table.Not in this change: the panel is still paragraph-by-paragraph. Word has no element that wraps a run of paragraphs, so a filled card is shading and borders on each paragraph. In LibreOffice this leaves several gaps:
Spaced top and bottom borders were tried and broke the card into pieces around a list. Writing a painted card as a one-cell table would carry all of it; that is proposed as a follow-up. The inset logic here stays useful either way, for unpainted containers and for aligning rows, tables and pictures.
Verification
In an editor. A filled card with 14pt padding and a 3pt left accent, holding two paragraphs and a bullet list, converted with LibreOffice and compared with the engine's PNG:
Gate. Full reactor gate (
clean verifyover core, render-pdf/docx/pptx, templates, testing, qa, coverage) → BUILD SUCCESS. Examples after install: 93 green. The committedword-export-companion.docxdid not move.New
DocxPanelInsetTest(12):w:ind14pt on both sides, the accent spaced 14, a fill-coloured right hairline spaced 14;w:indis inset + 180 twips, hanging 180, and its border is spaced 14;w:ind;w:tblInd= inset + first-cell margin;w:tblInd;Sabotage checks:
indentTable, or sizing pictures to the page's width, fails the matching tests.Lane: shared-engine (render-docx). No public API change.