Community

Architecture

Follow one typed document model from authoring and validation through DOCX, PDF, parity, and every adapter.

View Markdown source

RusDox has one typed document model and several deliberately thin entry points. The CLI, Rust API, Word-template workflow, GitHub Action, stdin protocol, and loopback service converge before packaging; they do not maintain separate DOCX or PDF renderers.

End-to-end flow

YAML / JSON / TOML / Word template / Rust caller
                    │
                    ▼
        parse + bounded composition expansion
                    │
                    ▼
       semantic validation + source locations
                    │
                    ▼
          typed Document + Stylesheet model
                  ┌─┴───────────────┐
                  ▼                 ▼
       OOXML package writer    native PDF layout
       XML + rels + ZIP        fonts + pages + links
                  └─┬───────────────┘
                    ▼
       structural + semantic + visual parity
                    │
                    ▼
       CLI / Rust bytes / local protocol response

Authoring and parsing

src/spec.rs owns the versioned high-level DocumentSpec. It parses YAML, JSON, and TOML under InputLimits. src/spec_expand.rs performs bounded variables, includes, repeaters, conditions, and deterministic filters before deserialization. It rejects cycles, excess includes, future spec versions, and general-purpose expression syntax.

src/source.rs maps semantic paths back to one-based line/column spans. The generated schema in src/schema.rs is the contract consumed by the CLI, checked JSON Schema, and VS Code tooling. Migration belongs in the CLI because it is a filesystem transaction; version interpretation belongs in the library.

Validation gate

src/validate.rs checks the spec and active config before any durable render. It catches invalid references, colors, table shapes, blank or missing values, assets, and geometry. Render commands call the same gate used by validate; adapters must not invent a weaker validation path.

The Renderer boundary in src/renderer.rs accepts file-backed or inline sources, exposes validation diagnostics, composes through Studio, and returns DOCX/PDF bytes. src/protocol.rs adds correlation IDs, output confinement, hashes, and JSON response semantics without duplicating rendering behavior.

Composition model

src/studio.rs maps DocumentSpec blocks and configured styles into the typed Document model. Document retains ordered paragraphs, tables, metadata, sections, headers/footers, page numbering, visuals, relationships, and styles. Lower-level types live in focused modules such as paragraph.rs, run.rs, table.rs, visual.rs, layout.rs, and metadata.rs.

Word-native templates enter through src/template.rs. Template expansion changes only supported placeholders and structural blocks, then reuses the same Document/PDF/parity path. Untouched ZIP parts and relationships are preserved.

DOCX packaging

src/document.rs coordinates save/open behavior and atomic replacement. src/xml_utils.rs serializes and parses WordprocessingML. Media, numbering, styles, metadata, headers, footers, relationships, content types, and custom parts are assembled into the OOXML ZIP package. src/package_validate.rs checks XML well-formedness, declared content types, and internal relationship targets under resource ceilings.

The DOCX writer is not a generic ZIP passthrough: open/modify/save preserves parts the model does not own, while generated parts remain deterministic.

Native PDF layout

The PDF path in src/studio.rs lays out the same Document, not a DOCX conversion. It resolves page geometry, shapes text with configured/system font fallback, paginates paragraphs and tables, draws images and vector-derived rasters, emits bookmarks and links, and can write deterministic page snapshots. Unsupported equivalence is documented in the compatibility matrix rather than hidden by an HTML or office-runtime conversion.

Parity and regression evidence

src/parity.rs compares the expected typed projection with the reopened DOCX and PDF evidence. Reports include semantic checks, package/PDF checks, artifact hashes, and optional rendered-page comparisons. Golden pages live under tests/golden/pages/<platform>/; compatibility fixtures and dated viewer results live under compatibility/.

The CLI verify command is the public orchestration layer. The GitHub Action, template evidence scripts, gallery generator, and contributor visual-diff lab all call it instead of reimplementing comparisons.

Boundaries and invariants

  • Author data stays local unless a caller explicitly uploads its own artifacts.
  • Every parser and transport has a declared size or count limit.
  • Durable file replacement is atomic; a failed build preserves the previous successful destination where the command promises recovery.
  • DOCX and PDF claims require executable parity evidence.
  • Browser previews and external viewer observations are labeled separately from native render proof.
  • Protocol and schema versions reject unknown futures instead of guessing.
  • Core rendering remains independent of GitHub, Pages, Node, Python, or Go.

Where to make a change

ChangeStart hereRequired evidence
New spec field or blocksrc/spec.rs, src/schema.rsparse round-trip, migration decision, validation, DOCX/PDF parity
OOXML behaviorsrc/xml_utils.rs, src/document.rspackage validation, open/save preservation, viewer fixture when relevant
PDF layoutsrc/studio.rssemantic parity plus platform page baseline
Validation rulesrc/validate.rs, src/source.rsvalid/invalid fixtures and exact source location
Word template syntaxsrc/template.rsstrict/lenient diagnostics, package preservation, template evidence
CLI or protocolsrc/bin/rusdox.rs, src/protocol.rstext/JSON contract test, bounded failure, cross-platform path behavior
Documentation sitescripts/build_site.mjsgenerated-site check, local links, mobile/browser QA

Read Contributing for commands and Governance for decision and maintainer policy.