typstgen 0.3.0

Compile existing .typ files to PDF with an embedded Typst engine — no external typst binary, config-driven template resolution. Usable as CLI, Rust lib, and Wasm.
Documentation
# typstgen

Compile an existing `.typ` file to PDF. No external `typst` binary, no
subprocess — Typst runs embedded as a Rust library. Template resolution is
config-driven instead of hardcoded.

**Website and documentation:** [casoon.github.io/typstgen](https://casoon.github.io/typstgen/)

```
your-document.typ  +  typstgen.toml (template_paths)  →  your-document.pdf
```

Usable three ways from one crate:

- **CLI** (`cli` feature, default): `typstgen compile input.typ`
- **Rust library** (always available): `typstgen::compile(path, &config)`
- **Wasm** (`wasm` feature): source and imports supplied as a JSON virtual filesystem

## Why

[`docgen`](https://github.com/casoon/typst-business-templates) already does
PDF generation from Typst, but grew into a client/project-management tool
along the way and only ever hardcoded its template lookup paths. typstgen is
the minimal version of the same idea: one job (`.typ` in, PDF out), with the
template directory resolved from config instead of baked in.

The architecture follows
[`renderreport`](https://github.com/casoon/renderreport): embedded Typst,
feature-gated CLI/Wasm, embedded fonts only on Wasm.

## Quick start

```bash
cargo install typstgen
typstgen compile letter.typ          # writes letter.pdf next to it
typstgen compile invoice.typ --input customer=ACME --pdf-standard a-2b \
  --creation-timestamp "$(date +%s)"  # sys.inputs, PDF/A, fixed date
```

Imports are looked up next to the document, then in the template directories
from `typstgen.toml` (optional; without a config, `./templates` and
`./.typstgen/templates` are used if they exist):

```toml
# typstgen.toml — paths are relative to the working directory.
# Every existing directory is searched per import, in order.
template_paths = ["templates"]
```

```rust
use typstgen::{compile, Config};

let config = Config::load(None)?;
let pdf_bytes = compile("example.typ".as_ref(), &config)?;
std::fs::write("example.pdf", pdf_bytes)?;
```

## Wasm

Build with `cargo build --target wasm32-unknown-unknown --no-default-features --features wasm`.
Generate JS bindings with `wasm-bindgen`, then pass the source and importable
text files as JSON; the returned bytes are a PDF:

```js
import init, { compile } from './pkg/typstgen.js';

await init();
const pdf = compile(JSON.stringify({
  source: '#import "templates/shared.typ": title\n#title',
  files: { 'templates/shared.typ': '#let title = [Hello]' },
}))
```

## License

MIT