Skip to content

v2(Phase 1): slot mapping — CvDocument supports multi-column placement#47

Merged
DemchaAV merged 1 commit into
developfrom
feature/cv-v2-slots
May 24, 2026
Merged

v2(Phase 1): slot mapping — CvDocument supports multi-column placement#47
DemchaAV merged 1 commit into
developfrom
feature/cv-v2-slots

Conversation

@DemchaAV
Copy link
Copy Markdown
Owner

Summary

Closes the single-column-only regression v2 had vs. the legacy
CvBuilder.place(slot, name) API. Multi-column presets can now place
sections into named slots without forking the data model.

What's new

  • data/Slot.java — enum {MAIN, SIDEBAR, FOOTER}. MAIN is the
    default when a section is built without an explicit slot.
  • CvDocument refactor — canonical record is now
    (CvIdentity, List<Placement>) where Placement(Slot, CvSection).
    Custom sections() still returns the flat list (source-order) so
    debug/inspect code keeps working. New sectionsIn(Slot) and
    slotOf(CvSection) accessors.
  • Builder gains slot overloads:
    .section(Slot.SIDEBAR, languagesSpoken)
    .sections(Slot.SIDEBAR, certs, refs)
    Zero-slot calls (.section(s), .sections(s1, s2)) default to
    MAIN. Every existing call site keeps compiling unchanged.
  • @Deprecated migration helper CvDocument.ofMainSections(identity, list)
    for any caller that used a direct two-arg constructor pattern.

What's updated

  • BoxedSections + MinimalUnderlined now iterate
    doc.sectionsIn(Slot.MAIN) instead of doc.sections(). Sidebar /
    footer content is silently dropped by single-column presets —
    documented in AUTHORS.md.
  • AUTHORS.md gains Recipe 6 ("place sections in slots") with
    both builder-side and preset-side patterns. Old Recipe 6
    (conditional sections) renumbered to 7.
  • package-info.java (both root v2 and data/) gains a Slots
    section.

What's NOT changed

  • Engine — zero edits.
  • v1 CV surface — zero edits.
  • Visual output — both v2 PDFs render pixel-identical to the
    baseline (sample data is all MAIN today).
  • Public v2 API call sites — every existing .section(...) /
    .sections(...) call works unchanged. New Slot-parameterised
    overloads are additive.

Test plan

  • CvDocumentSlotTest — 10 new tests (default MAIN, explicit
    slot, sectionsIn filter, slotOf, source-order across slots,
    varargs into a slot, deprecated ofMainSections, null guards)
  • Existing v2 tests stay green: BoxedSectionsSmokeTest,
    MinimalUnderlinedSmokeTest, CvDecorationTest, CvNameTest,
    CvContactTest
  • mvn test881/881 pass
  • cv-boxed-sections-v2.pdf rendered, pixel-identical to baseline
  • cv-minimal-underlined.pdf rendered, pixel-identical to baseline
  • CI green

Next phase

Phase 2 — port TimelineMinimal (single-column v1 preset) onto v2.
Will exercise the data/theme/components/presets shape on a non-trivial
visual style. Phase 3 then uses slots for real with a
TwoColumnSidebar port.

void deprecated_ofMainSections_wraps_everything_in_main() {
ParagraphSection a = new ParagraphSection("A", "x");
ParagraphSection b = new ParagraphSection("B", "y");
CvDocument doc = CvDocument.ofMainSections(identity(), List.of(a, b));
Closes the single-column-only regression that v2 had vs. the legacy
CvBuilder.place(slot, name) API. Single PR, no engine changes, no v1
edits, no behavioural change for existing single-column callers.

What's new
----------

- data/Slot.java — enum {MAIN, SIDEBAR, FOOTER}. MAIN is the default
  when a section is built without an explicit slot.
- data/CvDocument refactor: canonical record is now
  (CvIdentity, List<Placement>) where Placement(Slot, CvSection).
  Custom sections() method still returns the flat list (source-order)
  so debug/inspect call sites keep working. New sectionsIn(Slot) and
  slotOf(CvSection) accessors.
- CvDocument.Builder gains:
    .section(Slot slot, CvSection section)
    .sections(Slot slot, CvSection... values)
  The pre-existing zero-slot calls (.section(s), .sections(s1, s2))
  default to MAIN — every existing call site keeps compiling and
  rendering identically.
- @deprecated CvDocument.ofMainSections(identity, list) — migration
  helper for any caller that used a direct two-arg constructor. The
  Builder is the recommended path forward.

What's updated
--------------

- presets/BoxedSections + presets/MinimalUnderlined now iterate
  doc.sectionsIn(Slot.MAIN) instead of doc.sections(). Sidebar /
  footer placements are silently dropped by single-column presets —
  documented in AUTHORS.md.
- AUTHORS.md gains Recipe 6 ("place sections in slots") with both the
  builder-side and the preset-side patterns. Old Recipe 6 (conditional
  sections) renumbered to 7.
- package-info.java gains a "Slots — placing sections in columns"
  section in the root v2 package.
- data/package-info.java mentions Placement and Slot.

Tests
-----

- New CvDocumentSlotTest with 10 cases (default MAIN, explicit slot,
  source-order across slots, sectionsIn filter, slotOf, deprecated
  ofMainSections, null guards).
- All existing v2 tests stay green (BoxedSectionsSmokeTest,
  MinimalUnderlinedSmokeTest, CvDecorationTest, CvNameTest,
  CvContactTest).
- Full mvn test: 881/881 pass.
- cv-boxed-sections-v2.pdf and cv-minimal-underlined.pdf render
  pixel-identical to baseline (sample data is all MAIN today).
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.

2 participants