GraphCompose recipes are split into focused pages so each page covers
one topic end-to-end. All recipes use only the canonical session-first
authoring API; public application code should not import
com.demcha.compose.engine.*.
Most document features are blocks in the same pageFlow. A section, module, or card
is a container that groups those blocks with the same calls. A row places blocks
side by side and takes a narrower set — paragraphs, images, shapes, barcodes, and
sections — so a chart or a table goes into a section inside the row.
DocumentSession
├── pageBackground(...) / pageBackgrounds(...) behind every page
├── chrome() / header(...) / footer(...) repeating page chrome
└── pageFlow(...)
├── addParagraph / addRich / addList text
├── addImage / addSvgIcon / addBarcode media
├── addTable / chart / addTimeline data and stories
├── addSection / module grouped content
├── addRow side-by-side content
├── addContainer / addLayerStack clipped or overlapping content
└── addCanvas absolute placement, only when needed
Calls such as chart(...), addTable(...), and addImage(...) are shared by
the flow containers. Put them directly on the page, or call the same method inside
a section/module when the element needs a title, panel, padding, or accent.
Start with the entry point in the middle column. The linked recipe answers the next questions: where the element can live, which controls matter most, and how pagination or backend limits behave when they apply.
| I want to add… | Smallest entry point | Recipe answers next |
|---|---|---|
| A paragraph with links, styles, icons, or emoji | addRich(rich -> ...) |
runs, links, SVG icons, emoji, inline shapes |
| A list | addList(list -> ...) |
markers, nesting, spacing, styled items |
| A table | addTable(table -> ...) |
columns, cells, zebra rows, totals, repeated headers |
| A chart | chart(ChartSpec...) |
labels, value formats, colours, bar/line shape, background, legend |
| A timeline | addTimeline(timeline -> ...) |
markers, rail geometry, dated entries, text styles, pagination |
| An image | addImage(image -> ...) |
path/bytes, size, contain/cover, links |
| A QR code or barcode | addBarcode(barcode -> ...) |
format, colour, quiet zone, card alignment |
| I want to build… | Smallest entry point | Recipe answers next |
|---|---|---|
| A section, panel, divider, or visual shape | addSection(...) / softPanel(...) |
fill, border, radius, accent, spacing, primitive shapes |
| Side-by-side columns | addRow(row -> ...) |
column weights, flow layout, and when a row is the right primitive |
| Overlapping content | addLayerStack(stack -> ...) |
alignment, offsets, z-index, and when to use a container or canvas |
| A clipped circle, ellipse, or custom container | addContainer(...) |
outline, child alignment, CLIP_PATH, bounds, visible overflow |
| A repeating page tint, sidebar, or band | pageBackgrounds(...) |
full fills, partial fills, bleed, and layering |
| Rotation, scale, or layer ordering | rotate(...) / scale(...) / position(node, x, y, align, zIndex) |
transform origin, clipped transforms, deterministic overlap |
| Pixel-precise placement | addCanvas(...) |
fixed box size, (x, y) positions, clipping, appropriate use cases |
| A block that should not split badly | keepTogether() / keepWithNext() |
sections, lines, timeline entries, relocation at page breaks |
| A theme shared across documents | BrandTheme |
palette, typography, spacing, decoration, preset-level reuse |
| I want to… | Smallest entry point | Recipe answers next |
|---|---|---|
| Add metadata, watermark, header, footer, or page numbers | metadata(...) / header(...) / footer(...) |
text chrome, node-based page zones, protection, viewer behaviour |
| Add links, bookmarks, or a clickable table of contents | anchor(...) / linkTo(...) |
internal destinations, page references, TOC entries, PDF actions |
| Preview, stream, or choose an output form | buildPdf() / writePdf(...) / toImage(...) |
files, streams, bytes, preview images, backend selection |
| See layout boxes and node names while developing | guideLines(true) / debug(...) |
margin guides, resolved boxes, stable node labels |
| Protect a document from regressions | LayoutSnapshotAssertions |
smoke tests, geometry snapshots, pixel-level PDF diffs, CI flow |
| Export semantic DOCX | export(new DocxSemanticBackend()) |
semantic mapping and fixed-layout feature fallbacks |
| Add a new node or backend capability | NodeDefinition / render handler |
extension path, fluent builder, rendering, snapshot coverage |
| Page | Covers |
|---|---|
| Charts | Native vector bar / line / area / pie-donut charts: data–spec–style layers, axis & grid toggles, point markers, value-label halos, legend placement, translucent area fills |
| Keep-together pagination | keepTogether() / keepEntriesTogether() — blocks that relocate whole instead of orphaning a heading at a page break |
| Fixed-width flows | fixedWidth(points) — a section, module or page flow pinned to a narrow width, with the height left content-driven |
| Themes | BrandTheme token bundle (palette / typography / spacing / decoration), theme factories per family, page background, direct DSL styling |
| Shapes and visual primitives | Filled cards, dividers, spacers, lines, ellipses, image fit modes, soft panels |
| Shape-as-container | addCircle / addEllipse / addContainer with ClipPolicy (clipped layered children) |
| Transforms and z-index | rotate / scale mixin, per-layer zIndex for overlays |
| Page backgrounds | pageBackground / pageBackgrounds, PageBackgroundFill columns, bands, point-based fills, layering |
| Layered page design | Page background vs. row vs. layer stack vs. canvas — choosing the layer; how a row splits its width, icon beside text, a rule that reaches the column edge |
| Absolute placement | addCanvas + position(x, y) for pixel-precise certificates and badges |
| Tables | Row span, zebra rows, totals row, repeated header on page break |
| Text direction | TextDirection — right-to-left paragraphs and table cells, AUTO resolved from the text, mixed lines, and the bundled Hebrew / Arabic families |
| Rich text | RichText mixed-style runs in one paragraph: bold/accent/styled segments, inline links, inline images, inline SVG icons, emoji shortcodes, inline shapes and checkboxes |
| Letter spacing | DocumentLetterSpacing — real typographic tracking for spaced caps, declared natively in PDF / PPTX / DOCX so the text layer still holds the word |
| Lists | addList: quick bulleted lists, marker customisation, nested lists with per-depth markers, spacing and styled items |
| Timelines | addTimeline: the leading / axis / content model, markers (dot / circle / numbered / square / custom), leading column, axis sizing, markerOnRail(), rail extent, pagination, backends |
| Barcodes | QR / Code 128 / Code 39 / EAN / UPC / PDF417 / DataMatrix, tinting, quiet zone, card centring |
| Images | Sources (bytes/path), sizing precedence, STRETCH/CONTAIN/COVER fit modes, images in rows and cards |
| PDF chrome | Metadata, watermarks, running header/footer with {page}/{pages}/{date}, protection, links and outline bookmarks |
| In-PDF navigation | Named anchor(...) destinations + internal linkTo(...) links: clickable tables of contents, #heading-style jumps, bidirectional footnotes, inline-graphic links — native PDF GoTo actions |
| Translucency | DocumentColor.rgba / withOpacity: which primitives honour alpha, byte-identity for opaque colours, layered tints |
| DOCX export | Semantic DOCX export: 1:1 node mapping, chart/shape-container fallbacks, skipped kinds |
| Snapshot testing | Layout-snapshot regression testing in consumer projects, baseline update flow |
| Streaming and output | buildPdf / writePdf / toPdfBytes, DOCX export, layout snapshots, header / footer chrome, guide lines |
| Extending GraphCompose | New semantic node, fluent setter, render backend, snapshot-based regression tests |
For longer-form material:
- Extension guide — walkthrough of the four
extension paths, with
ShapeContainerNodeas the worked example. - Font coverage and glyph fallback — WinAnsi limits,
●vs•, and the inline-shape / bundled-font alternatives. ADR 0001 — Shape as containerandADR 0002 — Theme unificationfor the design reasoning behind shape containers and the unified theme model.
The following snippets cover the three smallest "I just want to put text on a page" patterns. Use them as starting points before reaching for a focused recipe page.
document.pageFlow(page -> page
.module("Professional Summary", module -> module.paragraph(
"Backend engineer focused on secure Java systems and reliable document generation.")));document.pageFlow(page -> page
.module("Technical Skills", module -> module.bullets(
"Java 21",
"Spring Boot",
"PostgreSQL",
"Docker")));document.pageFlow(page -> page
.module("Projects", module -> module.rows(
"GraphCompose - Declarative PDF/document layout engine.",
"CVRewriter - Profile-aware CV tailoring platform.")));import com.demcha.compose.testing.layout.LayoutSnapshotAssertions;
try (DocumentSession document = GraphCompose.document().create()) {
document.pageFlow(page -> page
.module("Snapshot Example", module -> module.paragraph("Hello GraphCompose")));
LayoutSnapshotAssertions.assertMatches(document, "my-feature/hello");
}See recipes/extending.md § 4 for the full snapshot workflow including baseline approval.