Skip to content

refactor(engine): extract TokenBreaking from TextFlowSupport#313

Merged
DemchaAV merged 2 commits into
developfrom
refactor/token-breaking-helper
Jul 6, 2026
Merged

refactor(engine): extract TokenBreaking from TextFlowSupport#313
DemchaAV merged 2 commits into
developfrom
refactor/token-breaking-helper

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Why

TextFlowSupport had grown to ~1.9k LOC, and the token-breaking family —
breakLongToken, softBreakSegments, splitLongToken, fitCharacters — is
pure string logic reachable only through breakLongToken from the three wrap
loops, yet was exercised only end-to-end via the paragraph render tests, never
directly.

What changed

  • Lift the four methods and the SOFT_BREAK_AFTER_CHARS constant verbatim into a
    new package-private TokenBreaking; TextFlowSupport now calls
    TokenBreaking.breakLongToken(...) at its three wrap sites. The methods are
    moved as-is, so behaviour is unchanged and the wrap file drops ~125 LOC.
  • TokenBreakingTest — direct coverage of soft-seam segmentation, greedy
    packing, 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 20
InlineHighlightRenderTest cases stay green unchanged — proof the move is
behaviour-identical — plus 11 new TokenBreakingTest cases.

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.

DemchaAV added 2 commits July 6, 2026 08:39
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 DemchaAV merged commit 65d97ad into develop Jul 6, 2026
11 checks passed
@DemchaAV DemchaAV deleted the refactor/token-breaking-helper branch July 6, 2026 08:18
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>
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