Skip to content

Commit bbc7b49

Browse files
authored
docs: add first-document, capabilities, diagrams, and business-templates guides (#263)
Add four developer-facing pages and wire them into the docs index. - first-document.md — a five-minute path from an empty project to a rendered PDF: the smallest document, a multi-section custom flow, the built-in template shortcut, and server streaming. - capabilities.md — a feature-to-API map giving the main call, the stability tier, and a guide link for each capability; the API stability policy stays authoritative for the contract. - diagrams.md — Mermaid decision diagrams for the authoring path, content placement, output destination, and document lifecycle. - templates/business-templates.md — the built-in InvoiceTemplateV2 and ProposalTemplateV2 compose-first contract, end to end, including the server-stream variant. getting-started.md gains a one-line pointer to first-document.md, and the docs README persona table and category index link the new pages.
1 parent ed63d60 commit bbc7b49

6 files changed

Lines changed: 486 additions & 1 deletion

File tree

docs/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ back here.
1313

1414
| You are… | Read |
1515
|---|---|
16-
| **New to GraphCompose** — what is it, how do I render my first PDF | [Getting started](getting-started.md)[Hello world in root README](../README.md#hello-world) |
16+
| **New to GraphCompose** — what is it, how do I render my first PDF | [Your first document](first-document.md)[Getting started](getting-started.md) |
17+
| **Author rendering an invoice or proposal** | [Built-in business templates](templates/business-templates.md) |
1718
| **Author rendering a CV** with your own data | [Templates v2 (layered) — quickstart](templates/v2-layered/quickstart.md) |
1819
| **Designer / author** wanting a custom visual style for CVs | [Templates v2 (layered) — authoring presets](templates/v2-layered/authoring-presets.md) |
1920
| **Author using legacy v1.6 templates** (CV / cover-letter / invoice / proposal still using `*Spec` + builders) | [Templates v1-classic — landing](templates/v1-classic/README.md) |
@@ -26,10 +27,14 @@ back here.
2627
## 📁 By category
2728

2829
### Getting started
30+
- **[first-document.md](first-document.md)** — the five-minute path from an empty project to a rendered PDF.
2931
- **[getting-started.md](getting-started.md)** — DSL vs templates, first-render walk-through, decision tree.
32+
- **[capabilities.md](capabilities.md)** — one-glance map of every feature with its stability tier and guide link.
33+
- **[diagrams.md](diagrams.md)** — visual decision diagrams (authoring path, layout, output, lifecycle).
3034
- **[troubleshooting.md](troubleshooting.md)** — symptom-first fixes for common gotchas: stray `?` glyphs, silent DOCX drops, optional-dependency `NoClassDefFoundError`, running the bundled examples.
3135

3236
### Templates
37+
- **[templates/business-templates.md](templates/business-templates.md)** — built-in invoice & proposal templates: the compose-first contract, end to end.
3338
- **[templates/v2-layered/](templates/v2-layered/)** — 🆕 canonical going-forward pattern (CV is the reference implementation): `data` / `theme` / `components` / `widgets` / `presets`.
3439
- **[templates/v1-classic/](templates/v1-classic/)** — the spec/builder/presets surface used by v1.6 CV, cover-letter, invoice, proposal templates. Still ships, still supported.
3540

docs/capabilities.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Capabilities
2+
3+
A one-glance map of what GraphCompose can do, the main API for each,
4+
and its stability tier. "Stability" rows use the tiers defined in the
5+
[API stability policy](api-stability.md); "Guide" links to the page that
6+
shows it in context.
7+
8+
This is a feature catalogue, not the contract — the
9+
[API stability policy](api-stability.md) is authoritative for what each
10+
tier promises, and [canonical ⇄ legacy parity](architecture/canonical-legacy-parity.md)
11+
tracks what is `Partial` or `Planned`.
12+
13+
---
14+
15+
## Authoring
16+
17+
| Capability | Main API | Stability | Guide |
18+
|---|---|---|---|
19+
| Open a document session | `GraphCompose.document(...)``DocumentSession` | Stable | [Your first document](first-document.md) |
20+
| Describe content in reading order | `pageFlow(...)`, `module(...)`, `addSection(...)` | Stable | [Getting started](getting-started.md) |
21+
| Maintained document templates | `InvoiceTemplateV2`, `ProposalTemplateV2`, `cv.v2.*`, `coverletter.v2.*` | Stable | [Templates](templates/which-template-system.md) |
22+
| Reusable building blocks (helpers) | helper methods / widgets over the DSL | Stable | [Diagrams](diagrams.md#choose-your-authoring-path) |
23+
| Custom node / backend | `NodeDefinition`, render-handler SPI, `FixedLayoutBackend` | Extension SPI (`@Beta`) | [Extending](recipes/extending.md) |
24+
25+
## Content
26+
27+
| Capability | Main API | Stability | Guide |
28+
|---|---|---|---|
29+
| Paragraphs & rich inline text | `addParagraph(...)`, `addRich(...)`, `RichText` | Stable | [Recipes — rich text](recipes.md) |
30+
| Lists (flat & nested) | `addList(...)`, `ListBuilder` | Stable | [Recipes](recipes.md) |
31+
| Tables (spans, zebra, totals, repeat header) | `addTable(...)`, `DocumentTableCell` | Stable | [Advanced tables](recipes/tables.md) |
32+
| Raster images | `addImage(...)`, fit modes | Stable | [Shapes & images](recipes/shapes.md) |
33+
| Vector shapes, dividers, lines | `addShape(...)`, `addLine(...)`, `addEllipse(...)` | Stable | [Shapes](recipes/shapes.md) |
34+
| Charts (bar / line / pie) | `chart(ChartSpec...)`, `ChartData` | Stable | [Charts](recipes/charts.md) |
35+
| Barcodes & QR | `addBarcode(...)` | Stable | [Recipes](recipes.md) |
36+
37+
## Layout
38+
39+
| Capability | Main API | Stability | Guide |
40+
|---|---|---|---|
41+
| Columns that still flow | `addRow(row -> row.weights(...))` | Stable | [Layered page design](recipes/layered-page-design.md) |
42+
| Page-wide fills / bands | `pageBackground(...)`, `pageBackgrounds(...)` | Stable | [Page backgrounds](recipes/page-backgrounds.md) |
43+
| Overlap & alignment | `addLayerStack(...)` | Stable | [Layered page design](recipes/layered-page-design.md) |
44+
| Shape-as-container | `addContainer(...)`, `addCircle(...)`, `addEllipse(...)` | Stable | [Shape as container](recipes/shape-as-container.md) |
45+
| Fixed (x, y) placement | `addCanvas(w, h, canvas -> canvas.position(...))` | Stable | [Absolute placement](recipes/absolute-placement.md) |
46+
| Bleed to page edge | `bleedToEdge(...)` | Stable | [Page backgrounds](recipes/page-backgrounds.md) |
47+
| Transforms (rotate / scale) | `DocumentTransform` | Stable | [Transforms](recipes/transforms.md) |
48+
49+
## Output & testing
50+
51+
| Capability | Main API | Stability | Guide |
52+
|---|---|---|---|
53+
| Write a PDF file | `buildPdf()`, `buildPdf(Path)` | Stable | [Getting started](getting-started.md) |
54+
| Stream to a caller-owned stream | `writePdf(OutputStream)` | Stable | [Streaming](recipes/streaming.md) |
55+
| In-memory bytes | `toPdfBytes()` | Stable | [Getting started](getting-started.md) |
56+
| Editable Word (semantic) | `export(new DocxSemanticBackend())` | Stable (semantic, not PDF parity) | [Troubleshooting](troubleshooting.md) |
57+
| PDF chrome (metadata / watermark / header / footer / protection) | `metadata(...)`, `watermark(...)`, `header(...)`, `footer(...)`, `protect(...)` | Stable | [Getting started](getting-started.md) |
58+
| Layout snapshot regression | `LayoutSnapshotAssertions.assertMatches(...)` | Stable | [Layout snapshot testing](operations/layout-snapshot-testing.md) |
59+
| Visual (pixel) regression | `PdfVisualRegression` | Stable | [Layout snapshot testing](operations/layout-snapshot-testing.md) |
60+
| Render-only debug overlays | `guideLines(...)`, `debug(...)` | Stable | [Getting started](getting-started.md#debug-guide-lines) |
61+
62+
## Navigation
63+
64+
| Capability | Main API | Stability | Guide |
65+
|---|---|---|---|
66+
| External links | `addLink(...)`, `inlineLink(...)` | Stable | [Getting started](getting-started.md) |
67+
| Internal jumps | `anchor("x")` + `linkTo("x")` | Stable | [Getting started](getting-started.md) |
68+
| PDF outline bookmarks | `bookmark(new DocumentBookmarkOptions(...))` | Stable | [Getting started](getting-started.md) |
69+
70+
---
71+
72+
## New in 1.9.0
73+
74+
These ship from 1.9.0 onward — confirm your dependency version before relying on them:
75+
76+
| Capability | Main API |
77+
|---|---|
78+
| Printed page references | `addPageReference("anchor")` |
79+
| Generated Table of Contents | `addTableOfContents(toc -> toc.entry(...))` |
80+
| Page preview images | `toImage(pageIndex, dpi)`, `toImages(dpi)` |
81+
82+
---
83+
84+
## See also
85+
86+
- [API stability policy](api-stability.md) — what each tier promises.
87+
- [Decision diagrams](diagrams.md) — visual "which API do I use?".
88+
- [Recipes](recipes.md) — the full cookbook.
89+
- [Which template system should I use?](templates/which-template-system.md) — template-surface decision.

docs/diagrams.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Decision Diagrams
2+
3+
Visual versions of the "which API do I reach for?" decisions. Each
4+
diagram renders on GitHub (Mermaid). The prose walkthroughs live in
5+
[Getting started](getting-started.md) and
6+
[Your first document](first-document.md).
7+
8+
---
9+
10+
## Choose your authoring path
11+
12+
Start from intent. Most documents are either a maintained template or a
13+
custom page flow; helpers, layout primitives, and extensions come later.
14+
15+
```mermaid
16+
flowchart TD
17+
A[I want to generate a document] --> B{Known family?<br/>CV / invoice / proposal / cover letter}
18+
B -- Yes --> T[Use a maintained template]
19+
B -- No --> C{Mostly reads top to bottom?}
20+
C -- Yes --> F["GraphCompose.document(...) + pageFlow(...)"]
21+
C -- Needs specific placement --> L["A layout primitive<br/>(row / canvas / shape container)"]
22+
F --> D{Same shape repeats across your app?}
23+
D -- Yes --> H[Extract a helper / widget over the DSL]
24+
D -- No --> Done1[Author the page flow]
25+
H --> Done1
26+
L --> Done2[See the layout diagram below]
27+
T --> Done3[Supply the data spec, then render]
28+
```
29+
30+
---
31+
32+
## Where does content go on the page?
33+
34+
Flow is the default. Reach for a stronger primitive only when the
35+
content has a specific placement relationship.
36+
37+
```mermaid
38+
flowchart TD
39+
A[Place content on the page] --> B{Top-to-bottom reading order?}
40+
B -- Yes --> Flow[pageFlow / sections / modules]
41+
B -- No --> C{Side by side, still part of the flow?}
42+
C -- Yes --> Row["addRow(row -> row.weights(...))"]
43+
C -- No --> D{A fill behind every page?}
44+
D -- Yes --> BG["pageBackground(s)(...)"]
45+
D -- No --> E{Overlap or a framed block?}
46+
E -- Yes --> Layer[Layer stack / shape container]
47+
E -- No --> Canvas["addCanvas(w, h, ...) — exact x/y"]
48+
```
49+
50+
---
51+
52+
## Where does the output go?
53+
54+
Choose the output method by destination. Create one `DocumentSession`
55+
per render request.
56+
57+
```mermaid
58+
flowchart TD
59+
A[The document is built] --> B{Where does it go?}
60+
B -- A file --> F["buildPdf() / buildPdf(path)"]
61+
B -- HTTP / cloud stream --> S["writePdf(OutputStream)"]
62+
B -- A byte array --> Y["toPdfBytes()"]
63+
B -- A preview image --> I["toImage(...) / toImages(...)"]
64+
B -- Editable Word --> D["export(new DocxSemanticBackend())"]
65+
```
66+
67+
---
68+
69+
## Document lifecycle
70+
71+
What happens between your code and the PDF.
72+
73+
```mermaid
74+
flowchart LR
75+
A["GraphCompose.document(...)"] --> B[DocumentSession]
76+
B --> C["pageFlow(...) → semantic nodes"]
77+
C --> D[Layout + pagination]
78+
D --> E[PDF output]
79+
D -. inspect .-> S["layoutSnapshot() (testing)"]
80+
```
81+
82+
---
83+
84+
## See also
85+
86+
- [Getting started](getting-started.md) — the prose decision tree and first render.
87+
- [Your first document](first-document.md) — a five-minute walk-through.
88+
- [Which template system should I use?](templates/which-template-system.md) — the template-surface decision.
89+
- [Capabilities](capabilities.md) — what GraphCompose can do, with stability tiers.

docs/first-document.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Your First Document
2+
3+
A five-minute path from an empty project to a real PDF. GraphCompose is
4+
session-first: you open a `DocumentSession`, describe content in reading order
5+
with a page flow, and render. No coordinates, no manual page breaks.
6+
7+
> **Prerequisites:** Java 17+ and the `io.github.demchaav:graph-compose`
8+
> dependency — see the [README install snippet](../README.md#installation).
9+
10+
## The smallest document
11+
12+
Open a session for a file path, add one page flow, render. The engine handles
13+
placement and pagination.
14+
15+
```java
16+
import com.demcha.compose.GraphCompose;
17+
import com.demcha.compose.document.api.DocumentPageSize;
18+
import com.demcha.compose.document.api.DocumentSession;
19+
20+
import java.nio.file.Path;
21+
22+
try (DocumentSession document = GraphCompose.document(Path.of("hello.pdf"))
23+
.pageSize(DocumentPageSize.A4)
24+
.margin(24, 24, 24, 24)
25+
.create()) {
26+
27+
document.pageFlow(page -> page
28+
.module("Summary", module -> module.paragraph("Hello GraphCompose")));
29+
30+
document.buildPdf();
31+
}
32+
```
33+
34+
`GraphCompose.document(path)` configures the output; `create()` returns the
35+
`DocumentSession`. Use try-with-resources so the session is always released, even
36+
if rendering fails. Inside the session, `pageFlow(...)` is the document body:
37+
modules, sections, paragraphs, lists, tables, and rows are added top to bottom.
38+
39+
## A real custom document
40+
41+
The same Flow model scales to a multi-section document. There are still no
42+
coordinates and no manual page breaks — just structure in reading order.
43+
44+
```java
45+
import com.demcha.compose.GraphCompose;
46+
import com.demcha.compose.document.api.DocumentPageSize;
47+
import com.demcha.compose.document.api.DocumentSession;
48+
49+
import java.nio.file.Path;
50+
51+
try (DocumentSession document = GraphCompose.document(Path.of("profile.pdf"))
52+
.pageSize(DocumentPageSize.A4)
53+
.margin(24, 24, 24, 24)
54+
.create()) {
55+
56+
document.pageFlow()
57+
.name("CandidateProfile")
58+
.spacing(12)
59+
.module("Professional Summary", module -> module.paragraph(
60+
"Backend engineer focused on clean Java APIs, stable document "
61+
+ "output, and reusable template architecture."))
62+
.module("Technical Skills", module -> module.bullets(
63+
"Java 21 and Spring Boot",
64+
"PDF document generation with GraphCompose",
65+
"Layout snapshot testing and render regression checks"))
66+
.module("Projects", module -> module.rows(
67+
"GraphCompose - declarative document layout engine.",
68+
"CVRewriter - profile-aware CV tailoring platform."))
69+
.build();
70+
71+
document.buildPdf();
72+
}
73+
```
74+
75+
The callback form (`pageFlow(page -> ...)`) builds and attaches the root for you.
76+
The builder form (`pageFlow().…build()`) gives you the fluent chain but you must
77+
call `.build()` yourself.
78+
79+
## Already a known document? Use a template
80+
81+
If your document is a known family — invoice, proposal, CV, cover letter — do not
82+
hand-build it. A maintained template maps a typed data object into the same
83+
session, then you render as usual:
84+
85+
```java
86+
import com.demcha.compose.document.templates.builtins.InvoiceTemplateV2;
87+
import com.demcha.compose.document.theme.BusinessTheme;
88+
89+
InvoiceTemplateV2 template = new InvoiceTemplateV2(BusinessTheme.modern());
90+
91+
try (DocumentSession document = GraphCompose.document(Path.of("invoice.pdf")).create()) {
92+
template.compose(document, invoice); // invoice = your InvoiceDocumentSpec
93+
document.buildPdf();
94+
}
95+
```
96+
97+
Templates and hand-written Flow compose into the *same* `DocumentSession`, so you
98+
can mix them. To choose a template surface, see
99+
[Which template system should I use?](templates/which-template-system.md).
100+
101+
## Rendering on a server
102+
103+
When the caller already owns the output stream — an HTTP response, a cloud
104+
upload — create the session *without* a default path and stream the PDF with
105+
`writePdf(OutputStream)` instead of `buildPdf()`. GraphCompose writes the
106+
stream but does not close it. For the full server snippet, see
107+
[Getting started — Streaming output](getting-started.md#streaming-output).
108+
109+
Create one `DocumentSession` per render request; it is mutable and not
110+
thread-safe. Use `toPdfBytes()` only when the caller truly needs a byte array.
111+
112+
## Where to go next
113+
114+
- [Getting Started](getting-started.md) — themes, hero blocks, layer stacks,
115+
shape-as-container, and built-in templates.
116+
- [Recipes](recipes.md) — themes, shapes, transforms, tables, and layout
117+
snapshots.
118+
- [Which template system should I use?](templates/which-template-system.md)
119+
the decision tree for CV / invoice / proposal surfaces.
120+
- [Production Rendering](operations/production-rendering.md) — server-side
121+
lifecycle, streaming, and load guidance.

docs/getting-started.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ with `writePdf(...)`, `buildPdf()`, or `toPdfBytes()`.
77

88
> **Prerequisites:** Java 17+ and the `io.github.demchaav:graph-compose` dependency — see the [README install snippet](../README.md#installation).
99
10+
> **New to GraphCompose?** Start with [Your First Document](first-document.md) — a five-minute, copy-paste path from an empty project to a rendered PDF, then come back here for themes, layer stacks, and built-in templates.
11+
1012
## Templates vs DSL — pick the right starting point
1113

1214
GraphCompose has two layers a caller can target. Use this decision

0 commit comments

Comments
 (0)