diff --git a/docs/templates/v2-layered/quickstart.md b/docs/templates/v2-layered/quickstart.md index a448f7e5e..03c6f2349 100644 --- a/docs/templates/v2-layered/quickstart.md +++ b/docs/templates/v2-layered/quickstart.md @@ -14,14 +14,15 @@ GraphCompose's templates v2 (layered) gives you: - **Themes describing visuals** — `BrandTheme` (palette + typography + spacing + decoration). Swap a theme to change colours, fonts, bullet glyphs without touching renderers. -- **Widgets as visual LEGO bricks** — `Headline`, `Subheadline`, - `ContactLine`, `SectionHeader`. Each one is a named visual decision - you can drop into a preset. +- **Widgets as visual LEGO bricks** — the neutral header bricks + (`Headline`, `Subheadline`, `ContactLine`) live in the shared + `templates.core.identity`; CV-specific ones (`SectionHeader` and + friends) in `cv.v2.widgets`. Each is a named visual decision you + drop into a preset. - **Presets as compositions** — a preset orchestrates widgets in a - page flow. `BoxedSections`, `MinimalUnderlined`, - `ModernProfessional`, `CenteredHeadline`, `BlueBanner`, - `EditorialBlue`, `ClassicSerif`, `NordicClean`, and `CompactMono` - ship today; writing your own is ~150 lines. + page flow. Sixteen ship today (`BoxedSections`, `ModernProfessional`, + `NordicClean`, `EditorialBlue`, `Executive`, `EngineeringResume`, + `TimelineMinimal`, …); writing your own is ~150 lines. You hand a `CvDocument` to a preset, you get a PDF. The preset internally composes widgets that read theme tokens that ultimately @@ -84,42 +85,42 @@ Same data, different visual. That's the layering. --- -## The 5 layers +## The layers ``` -┌─────────────────────────────────────────────────────────────┐ -│ presets/ BoxedSections, MinimalUnderlined, │ -│ ModernProfessional, CenteredHeadline, │ -│ BlueBanner, EditorialBlue, ClassicSerif, │ -│ NordicClean, CompactMono │ -│ — composition of widgets in a page flow │ -└─────────────────────────────────────────────────────────────┘ +┌────────────────────────────────────────────────────────────────────────────┐ +│ presets/ 16 CV compositions │ +│ BoxedSections, ModernProfessional, NordicClean, ... │ +│ -- widgets composed in a page flow │ +└────────────────────────────────────────────────────────────────────────────┘ │ compose from widgets ▼ -┌─────────────────────────────────────────────────────────────┐ -│ widgets/ Headline, Subheadline, ContactLine, │ -│ SectionHeader │ -│ — named visual LEGO bricks │ -└─────────────────────────────────────────────────────────────┘ - │ delegate to ↓ │ read tokens from ↓ - ▼ ▼ -┌─────────────────────┐ ┌──────────────────────────────────┐ -│ components/ │ │ theme/ │ -│ SectionDispatcher │ │ Palette (colours) │ -│ EntryRenderer │ │ Typography (fonts + sizes) │ -│ RowRenderer │ │ Spacing (margins + gaps) │ -│ ParagraphRenderer │ │ Decoration (bullet, sep) │ -│ + primitives │ │ BrandTheme (bundle + factories) │ -└─────────────────────┘ └──────────────────────────────────┘ - │ renders into DSL +┌────────────────────────────────────────────────────────────────────────────┐ +│ widgets/ CV-specific visual bricks │ +│ SectionHeader, FlowSectionHeader, SkillBar, SectionModule, ... │ +│ (neutral header bricks -- Headline, Subheadline, ContactLine, │ +│ Masthead, SvgGlyph -- live in core.identity) │ +└────────────────────────────────────────────────────────────────────────────┘ + │ delegate to ▼ -┌─────────────────────────────────────────────────────────────┐ -│ data/ CvDocument, CvIdentity, CvSection (sealed), │ -│ ParagraphSection / SkillsSection / RowsSection │ -│ / EntriesSection, │ -│ CvRow, CvEntry, Slot │ -│ — pure records, zero rendering deps │ -└─────────────────────────────────────────────────────────────┘ +┌────────────────────────────────────────────────────────────────────────────┐ +│ components/ CV section renderers │ +│ SectionDispatcher, EntryRenderer, RowRenderer, ParagraphRenderer │ +└────────────────────────────────────────────────────────────────────────────┘ + │ render into + ▼ +┌────────────────────────────────────────────────────────────────────────────┐ +│ data/ CvDocument, CvIdentity, CvSection (sealed), │ +│ ParagraphSection / SkillsSection / RowsSection / EntriesSection, │ +│ CvRow, CvEntry, Slot -- pure records, zero rendering deps │ +└────────────────────────────────────────────────────────────────────────────┘ + + ...all built on the shared, family-neutral core (templates.core.*): +┌────────────────────────────────────────────────────────────────────────────┐ +│ core.theme BrandTheme = Palette / Typography / Spacing / Decoration │ +│ core.identity Headline, Subheadline, ContactLine, Masthead, SvgGlyph │ +│ core.text MarkdownText, RichParagraphRenderer, TextStyles │ +└────────────────────────────────────────────────────────────────────────────┘ ``` **What each layer is for** (in plain English): @@ -127,7 +128,7 @@ Same data, different visual. That's the layering. | Layer | "Answers the question…" | |---|---| | `data/` | "What goes on the page?" — content, no styling. | -| `theme/` | "How does it look?" — colours, fonts, glyphs. | +| `core.theme` | "How does it look?" — colours, fonts, glyphs (shared `BrandTheme`). | | `components/` | "How is one element drawn?" — paragraph, row, entry primitives. | | `widgets/` | "Which visual building block do I want here?" — named LEGO bricks. | | `presets/` | "In what order, with which widgets, on which page flow?" — composition. | diff --git a/src/main/java/com/demcha/compose/document/templates/api/DocumentTemplate.java b/src/main/java/com/demcha/compose/document/templates/api/DocumentTemplate.java index ccaea6c3d..11d872d5b 100644 --- a/src/main/java/com/demcha/compose/document/templates/api/DocumentTemplate.java +++ b/src/main/java/com/demcha/compose/document/templates/api/DocumentTemplate.java @@ -10,12 +10,14 @@ * {@link DocumentSession}. The interface is intentionally minimal — just * identity (for registry lookup) and one composition seam.

* - *

Templates v2 contract (introduced in v1.6 alongside - * the templates restructure):

+ *

Implementation contract:

* * - *

Domain-specific interfaces ({@code CvTemplate}, {@code InvoiceTemplate}, - * etc.) remain in this package during the v1.6 migration window for - * backward compatibility. New templates should implement - * {@code DocumentTemplate} directly.

- * - * @param the spec type rendered by this template (e.g. {@code CvSpec}, + * @param the spec type rendered by this template (e.g. {@code CvDocument}, * {@code InvoiceSpec}, {@code ProposalSpec}) */ public interface DocumentTemplate { diff --git a/src/main/java/com/demcha/compose/document/templates/cv/v2/AUTHORS.md b/src/main/java/com/demcha/compose/document/templates/cv/v2/AUTHORS.md index 740874530..316ad85a6 100644 --- a/src/main/java/com/demcha/compose/document/templates/cv/v2/AUTHORS.md +++ b/src/main/java/com/demcha/compose/document/templates/cv/v2/AUTHORS.md @@ -5,8 +5,9 @@ on top of the v2 surface. It complements the JavaDoc in `package-info.java` with longer, copy-pasteable recipes. If you have never used this package before, read -[the package overview](./package-info.java) first. The four layers -(`data/` · `theme/` · `components/` · `presets/`) and what each is for +[the package overview](./package-info.java) first. The four CV layers +(`data/` · `components/` · `widgets/` · `presets/`) — plus the shared +theme / text / identity in `templates.core.*` — and what each is for are explained there. This guide answers the **"how do I…"** questions. diff --git a/src/main/java/com/demcha/compose/document/templates/cv/v2/package-info.java b/src/main/java/com/demcha/compose/document/templates/cv/v2/package-info.java index 59ef9ab40..63f28f897 100644 --- a/src/main/java/com/demcha/compose/document/templates/cv/v2/package-info.java +++ b/src/main/java/com/demcha/compose/document/templates/cv/v2/package-info.java @@ -13,54 +13,42 @@ * section titles are free strings and links are optional. See * {@code AUTHORS.md} for a non-IT example.

* - *

Four layers, one responsibility each

+ *

Four CV layers, built on the shared core

* *
- *   ┌─────────────────────────────────────────────────────────────┐
- *   │  presets/                                                   │
- *   │    BoxedSections      ← composition: data + theme + render  │
- *   │    MinimalUnderlined  ← another composition, same pieces    │
- *   │    ModernProfessional ← corporate composition variant       │
- *   │    CenteredHeadline   ← classic centred headline variant    │
- *   │    BlueBanner         ← full-width banner composition       │
- *   │    EditorialBlue      ← compact editorial composition       │
- *   │    ClassicSerif       ← serif cover/detail preset           │
- *   │    NordicClean        ← teal two-column rail preset         │
- *   │    CompactMono        ← dark header + rail/card preset      │
- *   └─────────────────────────────────────────────────────────────┘
+ *
+ *   ┌───────────────────────────────────────────────────────────────────────┐
+ *   │  presets/    16 CV compositions                                       │
+ *   │    BoxedSections, ModernProfessional, NordicClean, EditorialBlue, ... │
+ *   └───────────────────────────────────────────────────────────────────────┘
  *           │ compose from
  *           ▼
- *   ┌─────────────────────────────────────────────────────────────┐
- *   │  widgets/  ← named visual building blocks (LEGO bricks)    │
- *   │    Headline       .spacedCentered | .uppercaseCentered      │
- *   │                   | .uppercaseLeftAligned | .rightAligned  │
- *   │    Subheadline    .centeredSpacedCaps                       │
- *   │    ContactLine    .centered | .centered(...styles)          │
- *   │                   .rightAligned | .leftAligned              │
- *   │                   .rightAlignedStacked                      │
- *   │                   .twoRowRightAligned                       │
- *   │    SectionHeader  .banner | .fullWidthBanner | .underlined  │
- *   │                   .flat | .flatSpacedCaps | .tickLabel      │
- *   └─────────────────────────────────────────────────────────────┘
- *           │ delegate to                       │ read tokens from
- *           ▼                                   ▼
- *   ┌──────────────────────┐         ┌──────────────────────────┐
- *   │  components/         │         │  theme/                  │
- *   │    RowRenderer       │ reads   │    Palette  (colours)  │
- *   │    EntryRenderer     │◀────────│    Typography (fonts)  │
- *   │    ParagraphRenderer │         │    Spacing  (margins)  │
- *   │    SectionDispatcher │         │    Decoration (glyphs) │
- *   │    ParagraphPrimitive│         │    BrandTheme    (bundle)   │
- *   └──────────────────────┘         └──────────────────────────┘
- *           │ renders
+ *   ┌───────────────────────────────────────────────────────────────────────┐
+ *   │  widgets/    CV-specific visual bricks                                │
+ *   │    SectionHeader, FlowSectionHeader, SkillBar,                        │
+ *   │    SectionModule, ProfileBand, IconTextRow                            │
+ *   └───────────────────────────────────────────────────────────────────────┘
+ *           │ delegate to
+ *           ▼
+ *   ┌───────────────────────────────────────────────────────────────────────┐
+ *   │  components/    CV section renderers                                  │
+ *   │    SectionDispatcher, EntryRenderer, RowRenderer,                     │
+ *   │    ParagraphRenderer, ParagraphPrimitive                              │
+ *   └───────────────────────────────────────────────────────────────────────┘
+ *           │ render into
  *           ▼
- *   ┌─────────────────────────────────────────────────────────────┐
- *   │  data/                                                      │
- *   │    CvIdentity   ← name, optional job title, contact, links  │
- *   │    CvSection    ← sealed: Paragraph | Rows | Entries | Skills│
- *   │    CvDocument   ← identity + Placement(slot, section)       │
- *   │    Slot         ← MAIN | SIDEBAR | FOOTER                   │
- *   └─────────────────────────────────────────────────────────────┘
+ *   ┌───────────────────────────────────────────────────────────────────────┐
+ *   │  data/    CvIdentity, CvSection (sealed), CvDocument, Slot            │
+ *   └───────────────────────────────────────────────────────────────────────┘
+ *
+ *     ...built on the shared, family-neutral core in templates.core.* :
+ *   ┌───────────────────────────────────────────────────────────────────────┐
+ *   │  core.theme       BrandTheme = Palette / Typography /                 │
+ *   │                   Spacing / Decoration tokens                         │
+ *   │  core.identity    Headline, Subheadline, ContactLine, Masthead,       │
+ *   │                   SvgGlyph  (neutral header bricks)                   │
+ *   │  core.text        MarkdownText, RichParagraphRenderer, TextStyles     │
+ *   └───────────────────────────────────────────────────────────────────────┘
  * 
* *

What goes where — when you write your own template

@@ -71,20 +59,23 @@ * No colours, no fonts, no sizes. Pure records. If you're * describing a person's job history, this is where you live. * - *
{@code theme/}
+ *
{@code templates.core.theme}
*
The cosmetic decisions. "How does it look?" - * Colours, fonts, sizes, margins, glyphs. Swap-able without - * touching renderers. If you want a navy theme or a different - * bullet character, this is where you live.
+ * Colours, fonts, sizes, margins, glyphs — the family-neutral + * {@code BrandTheme} bundle, shared by every template family. + * Swap-able without touching renderers. If you want a navy theme + * or a different bullet character, this is where you live. * *
{@code widgets/}
*
The LEGO bricks. "Which visual building block do I * want here — a banner, an underlined title, a right-aligned - * headline?" Each widget has a small set of named - * variants and, where useful, a lower-level entry for ad-hoc - * parameter combinations. This - * is where most preset code lives — picking widgets and - * composing them.
+ * headline?" CV-specific bricks ({@code SectionHeader} + * and friends) live here; the neutral header bricks + * ({@code Headline}, {@code Subheadline}, {@code ContactLine}, + * {@code Masthead}, {@code SvgGlyph}) live in + * {@code templates.core.identity}. Each widget has a small set + * of named variants — this is where most preset code lives, + * picking widgets and composing them. * *
{@code components/}
*
The reusable drawing primitives. "How is a section diff --git a/src/main/java/com/demcha/compose/document/templates/themes/Spacing.java b/src/main/java/com/demcha/compose/document/templates/themes/Spacing.java index 041bd897e..a2c8392da 100644 --- a/src/main/java/com/demcha/compose/document/templates/themes/Spacing.java +++ b/src/main/java/com/demcha/compose/document/templates/themes/Spacing.java @@ -7,7 +7,7 @@ /** * One source of truth for all template spacing tokens. * - *

Replaces the historical {@code BrandTheme.spacing}/{@code BrandTheme.spacingModuleName} + *

Replaces the historical per-theme {@code spacing} / {@code spacingModuleName} * fields plus the hard-coded {@code MINIMUM_TOP_LEVEL_MODULE_SPACING} * constant scattered throughout the legacy composers. Templates v2 presets * read every spacing decision from a {@code Spacing} instance and pass it diff --git a/src/main/java/com/demcha/compose/document/templates/themes/Typography.java b/src/main/java/com/demcha/compose/document/templates/themes/Typography.java index b8e2b7f24..c94eb2fd2 100644 --- a/src/main/java/com/demcha/compose/document/templates/themes/Typography.java +++ b/src/main/java/com/demcha/compose/document/templates/themes/Typography.java @@ -55,7 +55,7 @@ public record Typography( /** * Returns the default Helvetica-based typography matching the historical - * {@code BrandTheme.defaultTheme()} sizing. + * default-theme sizing. * * @return Helvetica typography preset */