Skip to content

fix(docx): end a panel hung out of its cell where the page ends it - #947

Merged
DemchaAV merged 2 commits into
2.5-devfrom
fix/docx-hung-panel-right-end
Oct 23, 2026
Merged

DemchaAV merged 2 commits into
2.5-devfrom
fix/docx-hung-panel-right-end

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Why

In a table cell, the page centres a panel's left border on the cell's text edge, half of it outside. The export writes that panel with a negative w:tblInd (−half the border), and its table is half that border wider than the panel. LibreOffice and Word start a nested table half that border in from the cell's text, its border's outer edge on the text, so the table stood its whole left border right of where it is written. Its right end stood the whole border right of the page's.

whatTheHangGivesUp gave up width only where the table then ran past its cell. The report named the left edge (left edge), but nothing named the right end.

Measured on Windows:

Panel Word LibreOffice
synthetic rail with a 3pt accent, in a row's column (fill's right end) +3.07pt +2.99pt
the same rail in a filled panel's cell +1.1pt +1.02pt
Compact Mono's rail +0.9pt +0.86pt
Compact Mono's and Engineering Resume's bordered cards, Nordic Clean's rail +0.43 to +0.64pt +0.35 to +0.54pt

What changed

  • whatTheHangGivesUp always gives up what the panel's left side gave its text (hangGiven): the half border the table is wider by, plus what its left margin gave back of the other half. Its right end then stands where the page's does.
    • The give-up is no more than the editors move the table (halfLeft − indent). A panel set in less than half its border from the cell's text is moved less than the whole border.
    • A panel bled left by a margin below zero gives up its border and keeps its bleed. The editors move it, text and all, so giving up the bleed too would narrow its text.
  • What holding its right border in from the cell's edge has already taken (pullOf) counts towards it (max(what runs past the cell, given − pulled)).
    • That narrowing is reckoned with the table where the editors start it. Added to it, the give-up set cards beside a gap up to 0.96pt further left: Panel's and Obsidian's right-hand cards, Workspace's due panel and Editorial's glance panel.
    • With it counted, those cards stay where they were. pageWide, which caps the right end note, is reckoned the same way.
  • What the cell does not take goes back to the table, not the margin (whatTheHangSpares, hangBack), for a line set past its text further than its margin holds.
    • This is the same lines-past logic that gives the slack back (measureAtWordsSize, noteTheLinesPast). Without it, Engineering Resume's role card lost the stop ending a line in both editors.
    • What the cell takes (whatTheHangMustGiveUp) never goes back.
  • The report:
    • Engineering Resume's report now names its Profile and its second role card wider (right end), and its third role card at 3pt where it said 1pt. Its fill stands 3.22pt right of the page's in Word.
    • The left edge note is unchanged.
  • Docs:
    • the recipe's panel passage;
    • the capability matrix's rectangle row;
    • the javadoc of whatTheHangGivesUp and of the slack give-back;
    • the CHANGELOG (Public API);
    • the ledger's RIGHT_END.

Verification

  • DocxPanelSlackTest (+4 new, 3 updated):
    • New: a card bled 4pt left of its filled panel's text keeps its bleed in its indent (−5pt) and gives up its border, 2pt.
    • New: a card set half a point in, with a 2pt accent, gives up the 1.5pt the editors move it.
    • New: a hung card whose 7.25pt lines run past its 1pt margin takes back the slack and the 2pt its accent gave up, to the table alone. Its margin stays its padding, and it is named 3pt wider. At 7.5pt it ends where the page ends it, unnamed.
    • New: a hung card filling its column keeps the 2pt its cell takes, and ends at the cell's text, though its lines run past.
    • Updated: a rail 161pt wide in a 163pt column ends where the page ends it, 161pt from its cell's text, its slack out of its margin. This test is renamed from "the cell's edge already holds it in".
    • Updated: a card beside a gap is as wide as the page draws it. Its text is the page's and its two borders, less the point the hang gives up, but for the half point its border would take held in at the cell's text.
  • Fail-closed: 8 sabotages, each run alone, all caught:
    • only what runs past given up;
    • the border's narrowing not counted;
    • nothing taken back;
    • pageWide without the border's narrowing;
    • the hang taken back into the margin too;
    • what the cell takes taken back too;
    • the give-up not held to what the editors move the table;
    • the bleed given up too.
  • Word and LibreOffice on Windows, the 11 changed documents against the export before:
    • Compact Mono's rail: +0.90 → +0.06 in Word, +0.86 → −0.04 in LibreOffice.
    • Bordered cards and Nordic Clean's rail: from +0.43 to +0.64 to +0.24 to +0.35 in Word, and from +0.35 to +0.54 to +0.09 to +0.22 in LibreOffice, as a bordered panel's right border stands in a cell.
    • Synthetic rails, in four nestings: +0.02 to +0.14 in Word and −0.01 to +0.02 in LibreOffice.
    • No word moves in either editor, Engineering Resume's stop included.
  • Corpus: 11 of 62 DOCX change. Notes go from 1363 to 1365.
  • Gate:
    • ./mvnw -B -ntp clean verify -pl <core, render-pdf, render-docx, render-pptx, templates, testing, qa, coverage> -am → BUILD SUCCESS: core 821, render-pdf 339, render-docx 2072, testing 5, render-pptx 142, templates 127, qa 1828.
    • The JDK 17 knowledge checks pass, and core javadoc has 0 warnings.
    • ./mvnw -f examples/pom.xml test → BUILD SUCCESS, 93 tests.

Notes for review:

  • A hung panel's text keeps more than where nothing holds its right border in, no more than what the hang gives, in three cases. The javadoc of whatTheHangGivesUp names them:
    • Holding the right border in takes less than the hang gives. The margin still gives what it took. This is an approximation, and no corpus document meets it.
    • The cell's margin holds the right border. The right margin gives what the hang gives up more there than held in at the cell's text (hungMore). The cards beside a gap in Panel, Metered, Obsidian and Workspace meet it, and keep the width they had before. None of their documents changes.
    • A line set past its text takes the hang back, to the table alone. Given back to the margin too, it cut off Engineering Resume's stop in both editors.
  • The give-up is measured with the border on the cell's text. For a panel set in less than half its border, or bled, it is reckoned from that case.
  • A hung panel is never split over pages. A panel is written a table a page only in the body, and a row's panels whole, so its right end is reckoned once.

Lane: shared-engine (render-docx): no public API change.

- A panel whose left border the page centres on its cell's text edge is
  written with a negative indent, its table half that border wider.
  LibreOffice and Word start a nested table half that border in from
  the cell's text, so its right end stood the whole border right of the
  page's. It gave up width only where it then ran past its cell.
- It now always gives up what its left side gave its text, no more than
  the editors move it, counting what holding its right border in has
  taken. A bled panel keeps its bleed.
- What the cell does not take goes back to the table, not the margin,
  for a line set past its text further than the margin holds, and the
  panel is named wider (right end).
- Measured on Windows: Compact Mono's rail +0.90/+0.86 to +0.06/-0.04;
  bordered cards +0.35..0.64 to +0.09..0.35; synthetic rails +3.0 to
  within 0.14; no word moves in either editor.
- Tests: a hung card taking the hang back for its lines, one filling its
  column keeping what the cell takes, a bled card, a card set in half a
  point; three updated to the new widths.
@DemchaAV
DemchaAV marked this pull request as draft October 23, 2026 08:03
- The javadoc of whatTheHangGivesUp names the three cases where a hung
  panel's text keeps more than where nothing holds its right border in.
  The first is holding the border in taking less than the hang gives,
  which no corpus document meets. The second is the cell's margin
  holding the border, as for the cards beside a gap of Panel, Metered,
  Obsidian and Workspace, none of which changes. The third is a line
  taking the hang back.
- It says the give-up is measured with the border on the cell's text,
  and reckoned from that for a panel set in or bled. It also says the
  left edge note counts from the border's outer edge.
- The CHANGELOG and the recipe give the bordered cards' range apart:
  0.24 to 0.35pt in Word, and 0.09 to 0.22pt in LibreOffice.
- A gap card test names its text width for what it is.
@DemchaAV
DemchaAV marked this pull request as ready for review October 23, 2026 08:25
@DemchaAV
DemchaAV merged commit fe90f85 into 2.5-dev Oct 23, 2026
13 checks passed
@DemchaAV
DemchaAV deleted the fix/docx-hung-panel-right-end branch October 23, 2026 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant