Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 14 additions & 20 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,23 @@ When writing new code, avoid Java 21+ APIs and language constructs that don't ex

## How to propose changes

GraphCompose follows a fork → feature branch → pull request flow. **Target the branch that matches your change** — GraphCompose is mid-transition to the 2.0 module line, so pick the base branch from this table before you fork:
GraphCompose follows a fork → feature branch → pull request flow. **Target the branch that matches your change** — pick the base branch from this table before you fork:

| Change type | Base branch |
|---|---|
| **2.0 feature / fix** (almost all current work) | `2.0-dev` |
| **Critical 1.9.x fix** (bug / security backport) | `develop` |
| **Feature / fix** (almost all work) | `develop` |
| **Critical 1.9.x fix** (bug / security backport) | `1.x` |
| Stable releases (tags) | `main` |
| After 2.0 GA | `develop` |

Almost all current work is 2.0 and targets **`2.0-dev`**. `develop` and `main` carry the shipping **1.9.x** line and take only critical fixes; `main` is the public stable surface and accepts release merges only. See [Version lines](#version-lines-and-the-1x-maintenance-branch) below for the full transition.
Almost all work targets **`develop`**, the ongoing 2.x line. The `1.x` branch takes critical fixes and security backports only — no features. `main` is the public stable surface and accepts release merges only. See [Version lines](#version-lines-and-the-1x-maintenance-branch) below.

### Contribution flow

1. **Fork** the repository on GitHub and clone your fork locally.
2. **Create a feature branch** from your target base (`2.0-dev` for 2.0 work — substitute `develop` for a critical 1.9.x fix):
2. **Create a feature branch** from your target base (`develop` for feature work — substitute `1.x` for a critical 1.9.x backport):
```bash
git checkout 2.0-dev
git pull --ff-only origin 2.0-dev
git checkout develop
git pull --ff-only origin develop
git checkout -b feature/short-description
```
Use `feature/...` for new functionality, `fix/...` for bug fixes, and `docs/...` for documentation-only changes. Issue-prefixed names (`42/fix/short-description`) are also welcome — convenient when the branch closes a specific issue.
Expand All @@ -62,7 +61,7 @@ Almost all current work is 2.0 and targets **`2.0-dev`**. `develop` and `main` c
./mvnw -B -ntp clean verify
```
This runs the architecture-and-documentation guards plus the full test suite. The same gate runs in CI on every PR.
5. **Push** your feature branch to your fork and open a pull request against the base branch you started from (`2.0-dev` for 2.0 work) on `DemchaAV/GraphCompose`. Reference any related issue and describe the user-visible change in the PR body.
5. **Push** your feature branch to your fork and open a pull request against the base branch you started from (`develop` for feature work) on `DemchaAV/GraphCompose`. Reference any related issue and describe the user-visible change in the PR body.
6. **CI runs automatically.** Active jobs:
- `Architecture and Documentation Guards` — fast canonical / engine-boundary guard tests, fail-first gate (always runs)
- `Build and run tests (JDK 17)`, `(JDK 21)`, `(JDK 25)` — full `mvnw verify` in parallel matrix across the supported JVMs
Expand All @@ -71,7 +70,7 @@ Almost all current work is 2.0 and targets **`2.0-dev`**. `develop` and `main` c
- `Performance Smoke Check` — PR-only coarse benchmark to catch performance regressions
- `CI Gate` — single aggregate status check that is green when every job that ran passed

**Selective on pull requests:** a `dorny/paths-filter` step skips the heavy jobs when a PR touches nothing that affects the build — a **docs-only PR runs the guards only**; `Binary Compatibility` runs only when the core module changed, and the `Performance Smoke Check` only when core / render-pdf / templates changed. Pushes to `2.0-dev` / `main` (and manual dispatch) always run the full gate. Point branch protection at **`CI Gate`** + **`Architecture and Documentation Guards`** rather than the individual matrix legs, so a docs-only PR is not left waiting on a skipped check.
**Selective on pull requests:** a `dorny/paths-filter` step skips the heavy jobs when a PR touches nothing that affects the build — a **docs-only PR runs the guards only**; `Binary Compatibility` runs only when the core module changed, and the `Performance Smoke Check` only when core / render-pdf / templates changed. Pushes to `develop` / `main` (and manual dispatch) always run the full gate. Point branch protection at **`CI Gate`** + **`Architecture and Documentation Guards`** rather than the individual matrix legs, so a docs-only PR is not left waiting on a skipped check.

The PR cannot merge into a protected branch until all required checks are green.
7. **Address review comments**, then squash any fixup commits before merge. The maintainer merges through GitHub once review is complete.
Expand All @@ -85,7 +84,7 @@ Almost all current work is 2.0 and targets **`2.0-dev`**. `develop` and `main` c
- linear history is enforced (squash or rebase, no merge commits)
- force pushes and branch deletion are disabled

`2.0-dev` (and, for 1.9.x fixes, `develop`) accepts feature-branch PRs from contributors. The maintainer may push directly for solo-driven release-prep work; external contributions still flow through PRs.
`develop` (and, for 1.9.x backports, `1.x`) accepts feature-branch PRs from contributors. The maintainer may push directly for solo-driven release-prep work; external contributions still flow through PRs.

### Release flow

Expand All @@ -98,16 +97,11 @@ See [docs/contributing/release-process.md](./docs/contributing/release-process.m

### Version lines and the 1.x maintenance branch

GraphCompose is mid-transition to the 2.0 module line. Until 2.0 ships:
The 2.0 GA shipped, so the branches now hold their long-term roles:

- **`2.0-dev`** is the working branch for 2.0 — feature branches for 2.0 work target `2.0-dev`, not `develop`.
- **`develop`** and **`main`** carry the shipping **1.9.x** line; `main` is its stable, tagged surface (latest `v1.9.x`).

At the **2.0 GA** merge the branches take their long-term roles:

- **`main`** fast-forwards to 2.0 and becomes the stable 2.0 line.
- **`develop`** becomes the ongoing 2.x working branch (what `2.0-dev` was); `2.0-dev` retires.
- A **`1.x`** maintenance branch is cut from the final 1.9.x commit on `main` at that moment. It receives **critical fixes and security / CVE backports only — no features** — released as `1.9.x` patches from `1.x` via the same `cut-release.ps1` + tag flow. New feature work always targets the 2.x line.
- **`develop`** is the ongoing 2.x working branch — all feature branches target it.
- **`main`** is the stable 2.x line, tagged at each release (latest `v2.x`).
- **`1.x`** is the maintenance branch cut from the final 1.9.x commit. It receives **critical fixes and security / CVE backports only — no features** — released as `1.9.x` patches from `1.x` via the same `cut-release.ps1` + tag flow. New feature work always targets the 2.x line.

## Repository map

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

## One source → a PDF <i>and</i> an editable PowerPoint deck

The same `DocumentSession` emits both. The PDF backend prints the resolved layout; the PPTX backend (**beta**) rebuilds it as slides with identical geometry — text, panels, tables, and vectors arrive in PowerPoint as **native, editable shapes**, not screenshots (the page below lands as 69 native shapes; only its clip-masked logo art is a picture).
The same `DocumentSession` emits both. The PDF backend prints the resolved layout; the PPTX backend (**beta**) rebuilds it as slides. Both consume the same resolved layout graph, so page and slide frames and every positioned element share the same geometry — text, panels, tables, and vectors arrive in PowerPoint as **native, editable shapes**, not screenshots (the page below lands as 69 native shapes; only its clip-masked logo art is a picture). Glyphs are rasterised by the viewer, so the exact text rendering depends on the fonts installed on the viewing machine; see the [backend capability matrix](docs/architecture/backend-capability-matrix.md) for per-feature fidelity.

```java
Path deck = Path.of("twin-output.pptx");
Expand Down
27 changes: 14 additions & 13 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,42 @@

GraphCompose is solo-maintained. This roadmap is a direction, not a contract. Dates are intentionally omitted. Concrete work is tracked in [issues](https://github.com/DemchaAV/GraphCompose/issues) and shipped work is recorded in [CHANGELOG.md](CHANGELOG.md). For v1.6 phase-level detail, see [docs/roadmaps/v1.6-roadmap.md](docs/roadmaps/v1.6-roadmap.md).

## Now — 2.0 line
## Now — 2.1 line

In flight on `2.0-dev`, preparing the 2.0.0 GA. The 2.0 line is about **packaging and internal hygiene**, not new authoring API — binary-breaking by design, with `japicmp` report-only for the cycle.
In development on `develop`, building toward the **2.1.0** minor. The headline is the **fixed-layout PPTX render backend**: the same `DocumentSession` that prints a PDF now also emits an editable PowerPoint deck — one page per slide, identical geometry by construction, native shapes. It ships as `@Beta` (Experimental) while its API shape settles; the geometry identity with the PDF backend is a design invariant, not subject to change. See the [API stability policy](docs/api-stability.md) and the [backend capability matrix](docs/architecture/backend-capability-matrix.md).

**Scope frozen (2026-07).** 2.0.0 ships exactly the set below; no further internal engineering is pulled in before GA — that work is the post-2.0 line (next section).
Alongside it, 2.1 hardens pagination: `keepWithNext()` for headings, orphaned-heading fixes ahead of paragraphs, tables and lists, and the layered CV presets wired to the keep-with-next policy.

Full detail lands in [CHANGELOG.md](CHANGELOG.md) under `v2.1.0`.

## Current stable — 2.0

The **2.0.0** GA is the current stable line. 2.0 was about **packaging and internal hygiene**, not new authoring API — binary-breaking by design.

- **Modular split** &mdash; the single jar is split into `graph-compose-core` plus `graph-compose-render-pdf` / `graph-compose-render-docx` / `graph-compose-render-pptx` / `graph-compose-templates` / `graph-compose-testing`, with render backends discovered through a `ServiceLoader` SPI. `graph-compose` stays a drop-in wrapper (core + render-pdf) so existing PDF callers upgrade unchanged. See the [2.0 modules migration guide](docs/migration/v2.0.0-modules.md) and [ADR 0016](docs/adr/0016-multi-module-packaging.md).
- **Legacy removal** &mdash; the dead Entity-Component-System execution layer and the deprecated (`forRemoval`) public API are gone; the classic template presets are replaced by the layered `templates.*` stack on `BrandTheme`.
- **Release &amp; publishing pipeline** &mdash; multi-module Maven Central publishing, the `core/`-layout reactor (`./mvnw clean verify` at the root builds everything), and the cut / tag / GA runbook.
- **Compatibility tests** &mdash; the guard, snapshot, and visual-regression suites that prove the split left rendered output unchanged.
- **Maintenance** &mdash; the **v1.9.x** line (current stable) receives critical fixes only.

Further internal engineering — more layout-class decomposition, abstraction cleanup, streaming, optional performance work — is **deferred to post-2.0** and does not gate GA.

Full detail in [CHANGELOG.md](CHANGELOG.md) under `v2.0.0 — Planned`.
The **v1.9.x** line receives critical fixes only.

## Next — post-2.0 engineering

Committed direction for after the 2.0 GA: internal refactors, scale work, and tooling that do **not** change the public authoring API. Tracked in [docs/roadmaps/post-2.0-engineering.md](docs/roadmaps/post-2.0-engineering.md).
Committed internal direction for the post-2.0 line: refactors, scale work, and tooling that do **not** change the public authoring API. Tracked in [docs/roadmaps/post-2.0-engineering.md](docs/roadmaps/post-2.0-engineering.md).

- **Decompose the layout hot files** &mdash; split `LayoutCompiler` and `TextFlowSupport` along their natural seams into individually-tested collaborators, with layout output unchanged.
- **ArchUnit module-boundary guards** &mdash; enforce the canonical / engine / render layering structurally, replacing the path-based greps that can pass vacuously after a move.
- **Cross-module coverage aggregation** &mdash; a dedicated non-published module that compile-depends on the tested modules so JaCoCo sees the `qa` suites; report-only first, thresholds after a baseline read.
- **Per-module binary-compatibility baselines** &mdash; once the 2.0 GA artifacts are published, switch `japicmp` to per-module baselines in break-on-incompatible mode.
- **Per-module binary-compatibility baselines** &mdash; now that the 2.0 GA artifacts are published, switch `japicmp` from the single-artifact baseline to per-module baselines in break-on-incompatible mode.

## Later (directional)

Not committed. Reflects current thinking; priorities may shift based on user feedback and adoption signals.

- **PPTX beyond beta.** Graduate the fixed-layout PPTX backend from `@Beta` to stable and close the remaining fidelity gaps &mdash; true vector clipping instead of the raster fallback ([#413](https://github.com/DemchaAV/GraphCompose/issues/413)), exact numeric dash arrays, and distinct per-corner radii.
- **DOCX visibility for unsupported nodes.** Make currently-silent skips (`shape`, `line`, `ellipse`, `barcode`) loud &mdash; minimum a warn log, ideally a strict-mode flag that fails instead of dropping content silently.
- **Block-level alignment for fixed-size flow children.** Paths, images, layer stacks, shape containers and barcodes currently left-align in a flow; centring one means wrapping it in a full-width `ShapeContainer` just to use its CENTER anchor. Add a per-node horizontal align (left / centre / right &mdash; the `margin: auto` / `align(center)` analogue) so a fixed box can place itself in the flow directly. Surfaced by the v1.8 SVG icon-gallery and feature-catalog work.
- **Backend-neutral layout measurement.** Decouple measurement from PDFBox-specific resources so non-PDF backends do not pull PDFBox into the dependency graph.
- **DOCX maturity.** Either expand DOCX coverage toward PDF parity, or move DOCX behind an explicitly experimental flag.
- **Property-based testing.** Random table spans, pagination edge cases, deeply nested layouts.
- **Real PPTX export.** Current state is a manifest skeleton. Will only be built out if there is concrete user demand.
- **Property-based testing.** Expand the `@Property` layout-invariant seed to random table spans, pagination edge cases, and deeply nested layouts.
- **Public Javadoc site.** Generated and hosted, kept in sync with releases.

## Not on the roadmap
Expand Down
5 changes: 5 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ back here.
- **[templates/v2-layered/](templates/v2-layered/)** — the template surface (CV is the reference implementation): `data` / `theme` / `components` / `widgets` / `presets`.
- **[templates/v1-classic/](templates/v1-classic/)** — 🗄️ archived: the classic spec/builder/presets surface removed in 2.0; kept for pre-2.0 callers.

### Output backends
- **[architecture/backend-capability-matrix.md](architecture/backend-capability-matrix.md)** — what each render backend supports, per capability. The source of truth for PDF vs PPTX fidelity.
- **[../render-pptx/README.md](../render-pptx/README.md)** — `graph-compose-render-pptx`: editable PowerPoint decks from the same session that prints the PDF (`@Beta`, first shipped in 2.1.0).
- **[api-stability.md](api-stability.md)** — stability tier per package, and what a tier promises.

### Architecture
- **[architecture/overview.md](architecture/overview.md)** — high-level system architecture (engine + DSL + templates + backends).
- **[architecture/lifecycle.md](architecture/lifecycle.md)** — the document lifecycle from `GraphCompose.document(...)` through `buildPdf()`.
Expand Down
2 changes: 2 additions & 0 deletions docs/api-stability.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ Javadoc per element.
| `com.demcha.compose.document.templates.invoice.*` | **Stable** | `graph-compose-templates` | Layered invoice family — `ModernInvoice` on `InvoiceDocumentSpec`. |
| `com.demcha.compose.document.templates.proposal.*` | **Stable** | `graph-compose-templates` | Layered proposal family — `ModernProposal` on `ProposalDocumentSpec`. |
| `com.demcha.compose.document.templates.data.*` | **Stable** | `graph-compose-templates` | Family-neutral document data records (invoice / proposal / schedule specs). |
| `com.demcha.compose.document.backend.fixed.pptx` | **Experimental** | `graph-compose-render-pptx` | Marked `@Beta` at the package level — `PptxFixedLayoutBackend`, its builder, and `PptxFixedLayoutBackendProvider`. First shipped in 2.1.0. |
| `com.demcha.compose.document.backend.fixed.pptx.handlers` | **Experimental** | `graph-compose-render-pptx` | Marked `@Beta` at the package level — the `PptxFragmentRenderHandler` seam and its built-in handlers. |
| `com.demcha.compose.document.layout.*` | **Internal** | `graph-compose-core` | Marked `@Internal` at the package level. Engine surface. |
| `com.demcha.compose.engine.*` | **Internal** | `graph-compose-core` | Engine surface; not part of the public contract regardless of `public` keyword. `engine.render.pdf.*` ships in `graph-compose-render-pdf`. |

Expand Down
9 changes: 6 additions & 3 deletions docs/architecture/backend-capability-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ Backends:
`com.demcha.compose.document.backend.fixed.pdf`. Consumes the resolved
`LayoutGraph`; the reference implementation.
- **PPTX (fixed-layout)** — `graph-compose-render-pptx`,
`com.demcha.compose.document.backend.fixed.pptx` (in development).
Consumes the same resolved `LayoutGraph`; geometry-identical to PDF by
construction, since layout is compiled in core before any backend runs.
`com.demcha.compose.document.backend.fixed.pptx`. Consumes the same
resolved `LayoutGraph`; geometry-identical to PDF by construction, since
layout is compiled in core before any backend runs. Ships as `@Beta`
(Experimental) in its first release — usable, with the per-capability
status in the tables below; the API shape may still change in a minor
while feedback lands (see [../api-stability.md](../api-stability.md)).
- **DOCX (semantic)** — `graph-compose-render-docx`,
`DocxSemanticBackend`. Walks the semantic node tree, deliberately
ignores fixed-layout geometry; Word owns the flow. Geometry rows are
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/canonical-legacy-parity.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ compatibility concerns. New authoring features should be added through
| Guide lines | Done | `guideLines(true)` is available on document builder and session. |
| Metadata/protection/watermark/header/footer | Done | Configure on `DocumentSession` (e.g. `metadata(...)`, `watermark(...)`, `protect(...)`, `header(...)`, `footer(...)`); convenience PDF entrypoints (`buildPdf`, `writePdf`, `toPdfBytes`) honour these options without an explicit backend builder. `PdfFixedLayoutBackend.builder()` remains for advanced cases. |
| DOCX semantic export | Done | Use `session.export(new DocxSemanticBackend())` for paragraph/table/image-aware Word output. Requires `org.apache.poi:poi-ooxml` on the consumer classpath. |
| PPTX semantic export | Planned for v1.6 (stretch) | Build out `PptxSemanticBackend` from the existing manifest skeleton to a working POI-based exporter — paragraphs as text boxes, tables as PowerPoint tables, sections as slides. See [v1.6 roadmap, Phase D](../roadmaps/v1.6-roadmap.md). |
| PPTX export | Done (fixed-layout, `@Beta` since 2.1.0) | `session.buildPptx(path)` with `graph-compose-render-pptx` on the classpath emits an editable deck from the same resolved layout graph as the PDF — one page per slide, native shapes, matching geometry. See the [backend capability matrix](backend-capability-matrix.md). The older `PptxSemanticBackend` manifest remains in the module but is not what the convenience methods use. |
| PDFBox types in session API | Rejected | Keep PDFBox behind the fixed PDF backend. |

## Diagnostics
Expand Down
Loading