refactor(engine): extract TokenBreaking from TextFlowSupport#313
Merged
Conversation
The token-breaking family — breakLongToken, softBreakSegments, splitLongToken and fitCharacters — was pure string logic reachable only through breakLongToken from the three wrap loops, yet covered only end-to-end via the paragraph render tests. Move it verbatim into a package-private TokenBreaking; TextFlowSupport now calls TokenBreaking.breakLongToken(...) at its three wrap sites. Behaviour is unchanged (methods lifted as-is) and the wrap file drops ~125 lines. Add TokenBreakingTest: direct coverage of seam segmentation, greedy packing, the char-level fallback and the min-one-char guarantee, driven by a deterministic fixed-width measurement double so the assertions do not depend on font metrics.
Guard softBreakSegments against null/empty (splitLongToken already did, and both are now package-visible directly-callable entry points), add the @author tag to match the sibling layout helpers, and cover the null/empty and fits-whole edges directly in TokenBreakingTest.
DemchaAV
added a commit
that referenced
this pull request
Jul 6, 2026
* fix(engine): contain long inline-code within its column (#307) * fix(engine): break over-wide inline-code tokens within their column 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). * feat(engine): size AUTO table columns to composed cell content 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". * docs(examples): add inline-code column-wrap example + CHANGELOG entry 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. * deps(deps-dev): bump net.bytebuddy:byte-buddy (#310) Bumps the maven-minor-patch group with 1 update in the / directory: [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy). Updates `net.bytebuddy:byte-buddy` from 1.18.10 to 1.18.11 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](raphw/byte-buddy@byte-buddy-1.18.10...byte-buddy-1.18.11) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.18.11 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: maven-minor-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Artem Demchyshyn <132658418+DemchaAV@users.noreply.github.com> * refactor(engine): extract TokenBreaking from TextFlowSupport (#313) * refactor(engine): extract TokenBreaking from TextFlowSupport The token-breaking family — breakLongToken, softBreakSegments, splitLongToken and fitCharacters — was pure string logic reachable only through breakLongToken from the three wrap loops, yet covered only end-to-end via the paragraph render tests. Move it verbatim into a package-private TokenBreaking; TextFlowSupport now calls TokenBreaking.breakLongToken(...) at its three wrap sites. Behaviour is unchanged (methods lifted as-is) and the wrap file drops ~125 lines. Add TokenBreakingTest: direct coverage of seam segmentation, greedy packing, the char-level fallback and the min-one-char guarantee, driven by a deterministic fixed-width measurement double so the assertions do not depend on font metrics. * refactor(engine): harden the TokenBreaking helper surface Guard softBreakSegments against null/empty (splitLongToken already did, and both are now package-visible directly-callable entry points), add the @author tag to match the sibling layout helpers, and cover the null/empty and fits-whole edges directly in TokenBreakingTest. * fix(web): keep showcase modal action buttons on one line In the lightbox header the action buttons could shrink to their min-content (the longest word) and wrap ("Open"/"PDF" on two lines) whenever the card title was long enough to squeeze them — so the buttons looked inconsistent between cards. Give .example-action white-space: nowrap + flex-shrink: 0 and .lightbox- actions flex-shrink: 0 so the buttons keep a stable single-line size, and give .lightbox-title min-width: 0 so a long title wraps instead of compressing them. * fix(examples): keep the deck version pill on one line for qualified versions The banner pill renders "v" + the stamped project version inside a fixed 96pt rounded rect. A dev/pre-release qualifier ("2.0.0-SNAPSHOT", "2.0.0-beta.1") is wider than the pill, and the engine now wraps long tokens at their "." / "-" seams, so the pill broke onto two lines and shifted the title-page layout. Show the base version only ("v2.0.0") — the footer keeps the full qualified version — so the pill geometry stays stable across dev and release stamps. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
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
TextFlowSupporthad grown to ~1.9k LOC, and the token-breaking family —breakLongToken,softBreakSegments,splitLongToken,fitCharacters— ispure string logic reachable only through
breakLongTokenfrom the three wraploops, yet was exercised only end-to-end via the paragraph render tests, never
directly.
What changed
SOFT_BREAK_AFTER_CHARSconstant verbatim into anew package-private
TokenBreaking;TextFlowSupportnow callsTokenBreaking.breakLongToken(...)at its three wrap sites. The methods aremoved as-is, so behaviour is unchanged and the wrap file drops ~125 LOC.
TokenBreakingTest— direct coverage of soft-seam segmentation, greedypacking, the character-level fallback and the min-one-char guarantee, driven by
a deterministic fixed-width measurement double so the assertions do not depend
on real font metrics.
Verification
./mvnw -B -ntp verify -pl .→ BUILD SUCCESS, 1632 tests. The 20InlineHighlightRenderTestcases stay green unchanged — proof the move isbehaviour-identical — plus 11 new
TokenBreakingTestcases.Lane: shared-engine — pure internal refactor, no public API or behaviour
change (package-private helper).
Follows #307 (merged): a straight extraction of the token-breaking logic that PR
introduced, with no behaviour change.