fix(templates): Timeline Minimal renders the whole CV - #519
Open
DemchaAV wants to merge 1 commit into
Open
Conversation
The preset dropped content three ways, none of them visible in the output. Per-module caps kept the first few lines of each block and discarded the rest, so a fourth degree or a third employer was simply never drawn — on a page the fixed-height axis left looking four-fifths used. Prose was cut at a character count, ending a summary mid-sentence with an ellipsis while the column still had room. And sections were matched to modules by title keyword, first hit wins: a second prose section was shadowed by the first, a section whose title matched nothing was never looked at, and the ones that did match were relabelled, so "Projects" printed as EXPERTISE and "Additional Information" as LANGUAGES. Everything the document carries is now rendered. SectionAllocation hands each section out once and returns what no module claimed, which lands in the main column under its own heading; headings come from the section's own title, leaving the preset's labels for a module that matched nothing. Content past one page continues on the next. The body is a row and a row is atomic — only List, Paragraph and Table implement NodeDefinition.split, so the paginator cannot break inside one and a too-tall row raises AtomicNodeTooLargeException rather than flowing. ColumnPagination therefore estimates each column's height from its width and the theme's font metrics, and the preset emits one row per page, letting each finished row overflow naturally. The axis keeps its full height on the opening page and follows the content on a continuation page. What the masthead takes off the budget is measured from the identity, since the contact stack grows a row per link. The nine other slot presets still match by keyword and still discard what does not match; they are untouched here.
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
TimelineMinimaldropped CV content three ways, none of them visible in therendered PDF.
Per-module caps.
ModulePlacementcarried a line limit per block — Profile 1,Expertise 3, Languages 3, Work Experience 4, Education 5, Skills 6 — applied as
lines.stream().limit(n). Entries past the cap were not drawn and nothing said so.A fourth degree, a third employer, the eighth skill group: gone, on a page whose
fixed-height axis left it looking four-fifths used.
Character-budget clipping.
excerpt(line, 76 | 136 | 245)cut text with anellipsis by counting characters, not by what fit, so a summary ended mid-sentence
with the column still open beneath it.
Keyword-only slotting. Each module called
SectionLookup.firstMatchingindependently. A second section answering the same keywords was shadowed by the
first; a section whose title matched no list — a user's own "Awards",
"Publications" — was never looked at; and matched sections were relabelled, so a
section the author titled "Projects" printed as EXPERTISE and "Additional
Information" printed as LANGUAGES.
What
Everything the document carries is rendered.
SectionAllocation(new,cv/components) hands each section out once andreturns what no module claimed. The leftovers go into the main column under their
own headings. Module headings are the section's own title; the preset's labels are
left for a module that matched nothing — and since such a module also has nothing
to draw, they are effectively unreachable.
Pagination instead of truncation. The body is an
addRow, and a row is atomic:only
ListDefinition,ParagraphDefinitionandTableDefinitionimplementNodeDefinition.split, so the paginator cannot break inside a row and one tallerthan the page raises
AtomicNodeTooLargeExceptionrather than flowing. Droppingthe caps outright therefore trades silent loss for a crash — reproduced before
writing the fix.
ColumnPagination(new, package-private) estimates a column'sheight by turning a character count into wrapped lines from the column width and
the theme's font metrics; the preset emits one row per page and lets each finished
row overflow naturally, the same way
MintEditorialreaches its second page. Whatthe masthead takes off the budget is measured from the identity, because the
contact stack grows a row per link.
The axis keeps its full 620pt on the opening page — it is the preset's signature —
and follows the content on a continuation page, so a page carrying three lines does
not get 620pt of rule beside them.
Not in scope. Nine sibling presets still slot by keyword and still discard what
does not match (
BlueBanner,ClassicSerif,CompactMono,EngineeringResume,MintEditorial,MonogramSidebar,NordicClean,Panel,SidebarPortrait);three still cap, one still clips with an ellipsis. Untouched here.
Tests
TimelineMinimalContentFidelityTest(new, 5) renders a dense CV — four degrees,three employers, three projects, eight skill groups, a second prose section, an
"Awards" section matching no keyword list — and reads the text back out of the PDF.
Verified from both sides: with the preset reverted to
develop, four of the fivefail; with it restored, all pass. The first fixture's summary sat under the old
245-character budget, so the ellipsis test passed on the broken code until the
summary was lengthened enough to discriminate.
ColumnPaginationTest(new, 10) covers the estimator directly, includingconservation across pages, a block carried across pages keeping its heading, a
block moving whole rather than orphaning its opening lines, and — under
@Timeout(5)— a budget too small for even a heading, which must still terminateand still keep every line.
SectionAllocationTest(new, 11) covers claim-once semantics, document-orderleftovers, empty sections, null tolerance, and that a blank title cannot reach the
fallback because every
CvSectionrejects one at construction.Visual baselines for
timeline_minimalwere re-approved after inspecting therender; page 1 goes from 80% to 94% of the page used and page 2 is new. The other
eleven baselines the approve run rewrote were reverted — the flag re-records every
preset, and those are recorded on a different platform.
Gates: full reactor
clean verifyacross the eight CI modules BUILD SUCCESS,coverage checks met;
examplesverify73/73 includingCommittedAssetDriftTestagainst the refreshed preview;
javadoc:javadocgreen for:graph-compose-coreand
:graph-compose-templates.