docpack 0.2.1

Freeze structured data into document-native modules
Documentation

docpack

crates.io homebrew CI Release License: AGPL v3 Typst LaTeX

Freeze structured data into document-native modules.

docpack turns external data sources into checked-in document assets.

Feed it CSV, JSON, YAML, TOML, or XLSX. Get back generated Typst or LaTeX code that you can commit, diff, review, and ship with the rest of your document sources.

It is built for the cases where runtime data loading is the wrong tradeoff:

  • reproducible reports
  • compliance or approval workflows
  • offline or single-file document bundles
  • generated artifacts that need stable diffs

Why docpack

  • Manifest-first: use docpack build for repeatable project outputs.
  • CLI-friendly: use docpack emit for one-shot pipes and previews.
  • Backend-aware: Typst and LaTeX outputs share one normalized data model.
  • Explicit failures: format, inference, sheet, and shape errors are surfaced with concrete diagnostics.
  • Reviewable output: generated artifacts are plain text modules, not opaque caches.

Capability Matrix

Area Support
Inputs csv, json, yaml, toml, xlsx
Backends typst, latex
Artifacts data-module, table-fragment
Typst styles typst-official, typst-table
LaTeX styles latex-expl3, latex-classic-macro, latex-booktabs-longtable, latex-plain-tabular
Workflow modes build, emit, inspect, init

Quickstart

Install

cargo install docpack

Or via Homebrew:

brew tap acture/tools
brew install docpack

Emit to stdout

emit is the fast path. If you do not pass --output, generated code is written to stdout.

docpack emit data/profile.json --backend typst

Example output:

#let profile = ("name": "Alice", "role": "Engineer")

Emit to a file

docpack emit data/table.csv \
  --output build/table.tex \
  --artifact table-fragment

Pipe from stdin

Stdin requires an explicit format, and stdout requires an explicit backend.

cat data/input.yaml | docpack emit - --format yaml --backend typst

Bootstrap a manifest

docpack init

Build all declared outputs

docpack build

Manifest-First Workflow

Minimal docpack.toml:

[project]
name = "quarterly-report"
output_dir = "generated"

[[sources]]
id = "sales"
path = "data/sales.csv"
format = "csv"

[[outputs]]
id = "sales_typst"
source = "sales"
path = "sales.typ"
backend = "typst"
artifact = "data-module"
style = "typst-official"
root_name = "sales"

[[outputs]]
id = "sales_tex"
source = "sales"
path = "sales.tex"
backend = "latex"
artifact = "table-fragment"
style = "latex-booktabs-longtable"

Then:

docpack build

Command Surface

docpack build [manifest-path]
docpack emit <input> [--output <path>] [--format <format>] [--backend <backend>]
docpack inspect <input-or-manifest> [--as <source|manifest>] [...]
docpack init [path] [--force]

What each command is for

  • build: resolve a manifest and write all outputs in order.
  • emit: convert one source into one artifact.
  • inspect: show normalized shape, metadata, and resolved render defaults.
  • init: generate a starter manifest.

Output Styles

Backend Artifact Default Alternatives
Typst data-module typst-official none
Typst table-fragment typst-table none
LaTeX data-module latex-expl3 latex-classic-macro
LaTeX table-fragment latex-booktabs-longtable latex-plain-tabular

How It Works

docpack is intentionally small at the center:

source bytes
  -> input normalization
  -> Value + SourceMeta
  -> backend render request
  -> Typst / LaTeX artifact

Current library layers:

  • core: normalized value tree and source metadata
  • input: format adapters and normalization
  • backend: Typst and LaTeX rendering
  • manifest: project resolution, inference, and build planning
  • error: structured failure model

Examples

Inspect before generating

docpack inspect data/sales.csv --output build/sales.typ

This prints:

  • source format
  • normalized top-level shape
  • tabular metadata
  • inferred backend / artifact / style / root name

Force a specific sheet

docpack emit workbook.xlsx \
  --sheet Sales \
  --backend typst \
  --artifact table-fragment

Generate classic LaTeX macros

docpack emit data/profile.json \
  --backend latex \
  --style latex-classic-macro

Status

What is already in place:

  • manifest-driven build flow
  • one-shot emit and inspect flow
  • Typst data modules and table fragments
  • LaTeX expl3, classic macro, longtable, and plain tabular outputs
  • reference fixture coverage across json, yaml, toml, csv, and xlsx
  • real pdflatex smoke coverage for classic macro output
  • structured diagnostics for format inference, tabular shape mismatches, and missing sheets

What is still open:

  • benchmark fixtures for large csv / xlsx sources
  • memory profiling for larger manifest builds

Development

cargo fmt
cargo clippy --all-targets --all-features -- -D warnings
cargo test

Maintainers

Release automation is tag-driven. See docs/releasing.md.

Design Notes

docpack is not trying to become a general-purpose ETL framework or a plugin platform.

The core idea is narrower and more useful:

  • normalize external structured data once
  • render it into document-native code
  • keep the generated artifact reviewable and reproducible

License

docpack is licensed under AGPL-3.0-only.