Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
26b677f
Initial plan
Copilot May 28, 2026
ad5a279
refactor: compose haru backend capabilities
Copilot May 28, 2026
b95e349
refactor: finalize backend capability composition
Copilot May 28, 2026
bbd0d51
refactor(backend): unify rendering backend interface and improve docu…
Cadons May 30, 2026
6ae5d36
chore(gitignore): add local documentation and analysis directory
Cadons May 30, 2026
30c4928
refactor(backend): introduce shared state for Haru backend capabilities
Cadons May 30, 2026
44ce1c1
refactor(backend): update rendering context access across components
Cadons Jun 1, 2026
35df88b
refactor(backend): simplify backend component dependencies and improv…
Cadons Jun 4, 2026
50452c3
refactor(backend): centralize page and graphics state management in s…
Cadons Jun 4, 2026
dc2eb04
refactor(backend): update backend context initialization and provider…
Cadons Jun 4, 2026
378e1f0
refactor(backend): rename backend providers to capability providers f…
Cadons Jun 4, 2026
7c337c9
refactor(backend): enhance backend architecture with capability provi…
Cadons Jun 4, 2026
ce43086
refactor(exceptions): introduce domain-specific exception hierarchy f…
Cadons Jun 4, 2026
70ccb0a
refactor(exceptions): introduce domain-specific exception hierarchy f…
Cadons Jun 4, 2026
ab7d2e0
refactor(document): streamline document configuration access and enha…
Cadons Jun 4, 2026
91eb932
refactor(parser): update TBody child access to use string constructor
Cadons Jun 4, 2026
9dc77b6
refactor(parser): update TBody child access to use data method
Cadons Jun 4, 2026
92b9ed8
refactor(layout): introduce horizontal and vertical table layout hand…
Cadons Jun 6, 2026
5ab3708
refactor(layout): improve title and cell height calculations for cons…
Cadons Jun 7, 2026
7101b01
refactor(layout): enhance table layout handling and title node access.
Cadons Jun 7, 2026
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
15 changes: 15 additions & 0 deletions .github/agents/docraft.agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
description: >-
Docraft - C++ declarative PDF generation library. Context for working with the
codebase.
tools: ['insert_edit_into_file', 'replace_string_in_file', 'create_file', 'apply_patch', 'get_terminal_output', 'open_file', 'run_in_terminal', 'get_errors', 'list_dir', 'read_file', 'file_search', 'grep_search', 'validate_cves', 'run_subagent', 'semantic_search']
---

# Docraft Agent Context

**Docraft** is a C++ library for generating PDF documents declaratively using the **Craft Language** (XML markup).
Use this document to understand the architecture, structure, and workflow for contributing or working with the codebase.

---

See `doc/contributors/components/` for deep dives.
274 changes: 274 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
## Quick Facts

- **Type**: C++ Library (header-only or compiled)
- **Main API**: `DocraftDocument`, `DocraftCraftLanguageParser`
- **Backend**: libharu (PDF generation)
- **Language**: XML-based markup (Craft Language)
- **Templating**: Variable substitution + Foreach loops via JSON
- **Output**: Single-file PDF with metadata support

---

## Architecture Overview

```
XML (Craft Language)
Parser (pugixml)
DOM AST (DocraftNode tree)
Template Engine (substitute ${var}, expand Foreach)
Layout Engine (compute positions, pagination)
Renderer (visitor pattern → painter calls)
Capability Provider Interfaces
PDF Implementation (Haru)
PDF Output
```

**Key insight**: Each layer is loosely coupled via interfaces. Only Parser and Document are tightly bound.

---

## Folder Structure

```
docraft/
├── include/docraft/
│ ├── docraft_document.h ← Main API
│ ├── docraft_document_context.h ← Shared render state
│ ├── backend/
│ │ ├── docraft_rendering_backend.h ← Capability provider interfaces
│ │ ├── docraft_*_rendering_backend.h ← Capability interfaces
│ │ └── pdf/
│ │ ├── docraft_haru_backend.h ← PDF impl
│ │ └── docraft_haru_*.h ← Inner classes
│ ├── layout/
│ │ ├── docraft_layout_engine.h
│ │ └── handler/ ← Chain of Responsibility
│ ├── renderer/ ← Visitor pattern
│ ├── craft/ ← Parser
│ ├── model/ ← Node types
│ ├── templating/ ← Variable + Foreach
│ └── utils/ ← Font, keyword, logger
├── src/docraft/ ← Implementations
└── test/docraft/ ← Unit tests
```

---

## Core Components

### 1. Document & Context

- **DocraftDocument**: Entry point, orchestrates pipeline
- **DocraftDocumentContext**: Shared render state
- ⚠️ Service Locator anti-pattern (20+ getters)

### 2. Parser

- **DocraftCraftLanguageParser**: XML → typed AST
- Uses **pugixml**
- Case-sensitive tags
- Unknown tags = parse error

### 3. Backend Interface

Capability provider contracts are split by domain:

- Line, Text, Shape, Image, Page rendering
- Output, Font, Metadata backends
- Implementation: `DocraftHaruBackend` (libharu)

### 4. Layout Engine

- Computes x, y, width, height
- Handles automatic page breaking
- **Chain of Responsibility** pattern
- Specialized handlers per node type

### 5. Renderer

- **Visitor pattern** on AST
- **Painters** call backend primitives
- Node knows WHAT, Painter knows HOW

### 6. Model / DOM

- **DocraftNode**: Base class
- **50+ node types**: Text, Table, List, Shape, etc.
- Each has: parser, layout handler, draw method

### 7. Template Engine

- `${variable}` substitution
- `<Foreach>` expansion
- Runs before layout
- No-op if not set

---

## Data Flow

```
Parser → DocraftDocument → render()
→ configure_settings()
→ template_document()
→ layout()
→ render()
→ save_to_file()
```

---

## Common Tasks

### Add a node type

1. Model: `model/docraft_my_node.h`
2. Parser: Register tag
3. Handler: Layout logic
4. Renderer: Painter calls
5. Tests: All subsystems

### Fix a bug

1. Locate node type
2. Breakpoint in layout handler
3. Breakpoint in painter
4. Breakpoint in backend

### Add backend capability

1. Interface: `backend/docraft_*.h`
2. Extend: capability provider interfaces (Rendering/Resource/Lifecycle)
3. Implement: Haru backend
4. Add to: `DocraftHaruBackend`
5. Use: In painters

---

## Critical Issues

**10 architectural issues in `.local/ARCHITETTURA_CRITICITA.md`:**

1. **SRP** - historical aggregated facade removed; capability providers are split by domain
2. **Circular deps** - PageHaruBackend ↔ DocraftHaruBackend
3. **Ownership** - State scattered (pdf_, cursor, colors)
4. **Interfaces** - Missing coordinate, color space abstractions
5. **Mock** - Doesn't reflect reality
6. **Accessors** - nullptr not compile-time safe
7. **Service Locator** - 20+ getters in Context
8. **Fallback** - No unsupported capability strategy
9. **Conceptual** - Font/Metadata/Output mixed with rendering
10. **Versioning** - No interface evolution support

Severity: 🔴 High (1,2,5,7) | 🟠 Medium (3,4,8,9) | 🟡 Low (6,10)

---

## Templating

```xml
<!-- Variable -->
<Text>Invoice ${invoice_number}</Text>

<!-- Foreach -->
<Foreach model="${items}">
<Text>${data("name")} x ${data("qty")}</Text>
</Foreach>

<!-- Table from JSON -->
<Table model='${table_data}' header='${headers}'/>
```

---

## Node Attributes

**Common**: `name`, `x`, `y`, `width`, `height`, `padding`, `weight`, `z_index`, `position`, `visible`

**Text**: `font_name`, `font_size`, `style`, `color`, `alignment`, `underline`

**Colors**: `#RRGGBB`, named colors (`red`, `blue`, etc.)

---

## File Organization

- Headers: `include/docraft/` (parallel `src/`)
- Implementations: `src/docraft/` (`.cpp`)
- Tests: `test/docraft/` (by subsystem)
- No circular includes
- Forward declarations for pointer types

---

## Testing

- Unit tests by subsystem
- Mock backend: `test/docraft/utils/`
- Parser: schema validation
- Layout: positioning
- Renderer: painter calls
- Backend: Haru-specific

---

## Craft Language

**Tags**: Document, Settings, Metadata, Header, Body, Footer, Text, Table, List, Image, Shape, Layout, Foreach

**Rules**:

- `<Document>` and `<Body>` required
- Unknown tags = error
- Invalid enums = error
- Text can't contain Text

---

## Dependencies

| Library | Purpose | License |
|---------------|------------|---------|
| libharu | PDF gen | ZLIB |
| pugixml | XML parse | MIT |
| nlohmann-json | JSON parse | MIT |
| GoogleTest | Testing | BSD |

**Build**: CMake ≥ 3.16, C++17, macOS/Linux/Windows

---

## Commands

```bash
# Build
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j

# Test
ctest --test-dir build -C Release --output-on-failure

# Render
./build/artifacts/bin/docraft_tool input.craft output.pdf

# Docs
cd doc && make html
```

---

## Next Steps

1. **Read `.local/ARCHITETTURA_CRITICITA.md`** - Architectural analysis
2. **Read `.local/PROGETTO_CONTESTO.md`** - Deep context
3. **Pick a task** from Common Tasks above
4. **Write tests** for features
5. **Run full build + tests** before PR
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,7 @@ Thumbs.db
.dockerignore

#CMake presets
CMakeUserPresets.json
CMakeUserPresets.json

# Local documentation and analysis (for Copilot/internal use)
.local/
13 changes: 9 additions & 4 deletions doc/project-doc/contributors/components/backend-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,21 @@ Important implication:

## 2. Interface contract you must implement

A backend must implement `IDocraftRenderingBackend`, which aggregates:
A backend must implement `IDocraftRenderingBackend`, which exposes capability
accessors for:

- text primitives,
- line/shape primitives,
- line primitives,
- shape primitives,
- image primitives,
- page management,
- save/output extension,
- metadata application,
- font registration and font selection hooks.

In practice you implement one concrete class inheriting `IDocraftRenderingBackend`.
In practice you implement one concrete class inheriting
`IDocraftRenderingBackend` and return the capability objects from the root via
`<capability>() const` and `edit_<capability>()`.

## 3. External integration (recommended path)

Expand Down Expand Up @@ -64,7 +68,8 @@ void render_with_external_backend(const std::string &craft_path) {
Typical steps for a backend added directly in this repository:

1. Add backend class, for example `docraft::backend::svg::DocraftSvgBackend`.
2. Implement all methods of `IDocraftRenderingBackend`.
2. Implement all root methods of `IDocraftRenderingBackend` and wire each
capability accessor to the appropriate capability object.
3. Add new source/header files to `docraft/CMakeLists.txt`.
4. Add tests in `docraft/test/backend/` and/or rendering smoke tests.
5. Choose selection strategy:
Expand Down
14 changes: 10 additions & 4 deletions doc/project-doc/contributors/components/backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ The backend layer is the portability boundary for output targets.

## 1. Contract hierarchy

`IDocraftRenderingBackend` aggregates these contracts:
`IDocraftRenderingBackend` exposes these contracts via explicit accessors:

- `IDocraftTextRenderingBackend`
- `IDocraftLineRenderingBackend`
- `IDocraftShapeRenderingBackend`
- `IDocraftImageRenderingBackend`
- `IDocraftPageRenderingBackend`
Expand All @@ -18,17 +19,22 @@ Plus lifecycle methods:
- font registration/selection helpers
- metadata application

This design lets renderers/painters consume only the primitives they need.
Capability interfaces are standalone (no inheritance chain between them), and
the root backend provides `<capability>() const` plus `edit_<capability>()`
accessors so renderers/painters can consume only the primitives they need.

## 2. Concrete implementation: Haru backend

`DocraftHaruBackend` implements all contracts over libharu.
`DocraftHaruBackend` remains the single concrete backend entry point, but it
composes smaller libharu-backed capability objects internally.

Responsibilities include:

- managing document/page handles,
- text drawing and measurement,
- line/shape/image drawing,
- line drawing,
- shape drawing and graphics state,
- image drawing,
- page navigation and page format,
- metadata mapping to PDF info fields,
- save to `.pdf`.
Expand Down
Loading
Loading