fix(engine): contain long inline-code within its column#307
Merged
Conversation
Long code tokens with no whitespace — package coordinates, FQCNs, URLs like org.junit.jupiter:junit-jupiter:5.10.2 — overflowed a paragraph or table cell instead of wrapping, drawing over the neighbouring content. All three paragraph wrap paths placed a lone over-wide token as-is, and highlight-chip words were never broken at all. Route an over-wide token through a new breakLongToken helper on the plain, inline, and markdown wrap paths. It breaks at soft seams (. : / -) so coordinates and URLs split at readable boundaries, and char-splits any segment still too wide as a last resort. Highlight-chip words break the same way while keeping one rounded fill per visual fragment: the split pieces retain the run's highlight group and background, with the outer padding on the first and last fragment only and the break seams open. Tokens that already fit follow the unchanged fast path, so existing prose and layouts are byte-identical (full suite green, no snapshot drift).
A composed table cell (DocumentTableCell.node(...)) contributed no natural width, so an AUTO column holding only composed content collapsed toward zero and its child — an inline-code chip, say — was laid out at a near-zero width. Measure a composed cell's intrinsic content width in resolveNaturalColumnWidths and feed it into the AUTO column's natural width, reusing the same prepare-to-measure pattern as RowSlots.intrinsicColumnWidths. The child is measured against the table's inner width, so one cell can never demand more than the table can give. Only single-column composed cells in AUTO columns are measured; plain-text cells, FIXED columns and spanning cells are unchanged, so a chip in a FIXED column keeps its declared width and breaks inside it. As with plain-text AUTO columns, a table too narrow for the summed intrinsic width of its AUTO columns still reports "exceeds available width".
InlineCodeColumnWrapExample renders a long inlineCode(...) coordinate breaking at its . : / - seams inside a narrow fixed column and fitting on one line in an auto column, registered in GenerateAllExamples with a committed preview PDF and a README quick-reference row. CHANGELOG v1.9.1 documents the chip-overflow fix and the auto-column sizing.
Owner
Author
|
Perf smoke A/B — Normal scenarios are within laptop noise (±5–10%, mixed direction), so no general hot-path regression — consistent with the fit fast-path being byte-identical:
The |
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 long inline-code token with no whitespace — a package coordinate, FQCN or URL
like
org.junit.jupiter:junit-jupiter:5.10.2— overflowed its paragraph ortable cell and drew over the neighbouring content, silently (no exception). It
surfaced through
graph-compose-markdownrendering a Markdown table, where acoordinate lands in a narrow fixed-width column. Prose wrapped fine; only long
unbreakable code tokens spilled. Two root causes: all three paragraph wrap paths
placed a lone over-wide token as-is (the first-token / empty-line branch skipped
any break), and a composed cell contributed zero natural width, so an
auto()column collapsed toward zero instead of sizing to its content.
What changed
TextFlowSupport— break over-wide tokens on all three wrap paths.wrapParagraph,wrapInlineParagraphandwrapMarkdownParagraphnow route alone over-wide token through a new
breakLongTokenhelper instead of placingit raw. It prefers soft seams (
.:/-) so coordinates and URLs breakat readable boundaries, and char-splits any segment still too wide as the
containment guarantee. A token that already fits takes the unchanged fast
path, so existing prose and layout are byte-identical (no snapshot churn).
word is split into pieces that keep the run's
highlightGroupandbackground, with the outer padding on the first and last piece only and thebreak seams open — the existing per-line coalescer paints one rounded fill per
fragment with no change. Links stay clickable on each fragment.
TableLayoutSupport.composedAutoCellNaturalWidth—auto()columns size tocomposed content. A composed cell (
DocumentTableCell.node(...)) in anauto()column now contributes its intrinsic content width, measured againstthe table's inner width so it self-clamps, reusing the same
RowSlots.intrinsicColumnWidthsprepare-to-measure pattern.fixed(...)columns are untouched, so a chip in a fixed column keeps its declared width
and breaks inside it.
Verification
./mvnw -B -ntp clean verify -pl .→ BUILD SUCCESS, 1621 tests, no snapshotdrift. New coverage: over-wide break on plain / inline / markdown paths,
soft-seam breaking, per-fragment chip fill and one clickable rect per fragment,
narrow-cell containment (with a committed
LayoutSnapshotAssertionsbaseline anda
target/visual-testsPDF), andauto()grows-to-one-fragment vsfixed()breaks-to-many.
GenerateAllExamplesSmokeTestgreen with a runnableInlineCodeColumnWrapExample, its committed preview PDF and anexamples/READMErow.
Lane: shared-engine — paragraph wrap + table column sizing; no public API
change (all-private helpers). Behaviour documented in CHANGELOG
## v1.9.1 — Planned.Notes
auto()columns, a table too narrow for the summedintrinsic width of its
auto()columns now reportsexceeds available widthwhere it previously collapsed silently — consistent and intended.
auto()cells are prepared twice (measure + final layout), bounded tothat case only; this matches the existing
RowSlotsintrinsic-width idiom.seam); soft-seam breaking is the readability layer on top of it.