Skip to main content

typst_bake/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3//! # typst-bake
4//!
5//! Bake Typst templates, fonts, and packages into your Rust binary — use Typst
6//! as a self-contained, embedded library.
7//!
8//! ## Cargo Features
9//!
10//! - **`pdf`** (default) - Enable PDF generation via [`Document::to_pdf`]
11//! - **`svg`** - Enable SVG generation via [`Document::to_svg`]
12//! - **`png`** - Enable PNG rasterization via [`Document::to_png`]
13//! - **`full`** - Enable all output formats
14//!
15//! ## Features
16//!
17//! - **Multiple Output Formats** - Generate PDF, SVG, or PNG from the same template
18//! - **File Embedding** - All files in `template-dir` are embedded and accessible from `.typ` files
19//! - **Font Embedding** - Fonts (TTF, OTF, TTC) in `fonts-dir` are automatically bundled
20//! - **Package Bundling** - Scans for package imports and recursively resolves all dependencies
21//! - **Optimized Binary Size** - Resources are compressed with zstd and decompressed lazily at runtime
22//! - **Runtime Inputs** - Pass dynamic data from Rust structs to Typst via [`IntoValue`] / [`IntoDict`] derive macros
23//!
24//! ## Quick Start
25//!
26//! Add to your `Cargo.toml`:
27//! ```toml
28//! [package.metadata.typst-bake]
29//! template-dir = "./templates"
30//! fonts-dir = "./fonts"
31//!
32//! [dependencies]
33//! typst-bake = "0.1"
34//! ```
35//!
36//! Then use the [`document!`] macro:
37//! ```rust,ignore
38//! // Generate PDF
39//! let pdf = typst_bake::document!("main.typ").to_pdf()?;
40//!
41//! // Generate SVG (one per page)
42//! let svgs = typst_bake::document!("main.typ").to_svg()?;
43//!
44//! // Generate PNG at 144 DPI (Retina)
45//! let pngs = typst_bake::document!("main.typ").to_png(144.0)?;
46//! ```
47
48mod build;
49mod document;
50mod error;
51mod resolver;
52mod stats;
53mod util;
54
55pub use build::rebuild_if_changed;
56pub use document::Document;
57pub use error::{Error, Result};
58pub use stats::{
59    CategoryStats, DedupStats, EmbedStats, HasCompressionRatio, PackageInfo, PackageStats,
60};
61/// Creates a [`Document`] with embedded templates, fonts, and packages.
62///
63/// # Usage
64///
65/// ```rust,ignore
66/// // Generate PDF
67/// let pdf = typst_bake::document!("main.typ").to_pdf()?;
68///
69/// // Generate SVG (one per page)
70/// let svgs = typst_bake::document!("main.typ").to_svg()?;
71///
72/// // Generate PNG at 144 DPI (Retina)
73/// let pngs = typst_bake::document!("main.typ").to_png(144.0)?;
74/// ```
75///
76/// # Configuration
77///
78/// Add to your `Cargo.toml`:
79/// ```toml
80/// [package.metadata.typst-bake]
81/// template-dir = "./templates"
82/// fonts-dir = "./fonts"
83/// ```
84///
85/// # What Gets Embedded
86///
87/// - **Templates**: All files in `template-dir` are embedded and accessible from `.typ` files.
88///   Paths resolve relative to the referring `.typ` file.
89/// - **Fonts**: Only supported font formats (TTF, OTF, TTC) are embedded. At least one font
90///   is required; without fonts, Typst produces invisible text.
91/// - **Packages**: Using packages requires no manual setup. Just use `#import "@preview/..."`
92///   or `#import "@local/..."` as you normally would in Typst. The macro scans for package
93///   imports and recursively resolves all dependencies at compile time. Shares Typst's own
94///   package directories, so locally installed packages are picked up automatically.
95pub use typst_bake_macros::document;
96
97/// Derive macro for converting a struct to a Typst value.
98///
99/// All structs that will be passed to Typst templates (directly or nested) must derive this.
100///
101/// - **Top-level struct**: Use both [`IntoValue`] and [`IntoDict`]
102/// - **Nested structs**: Use [`IntoValue`] only
103///
104/// # Example
105///
106/// ```rust,ignore
107/// use typst_bake::{IntoValue, IntoDict};
108///
109/// #[derive(IntoValue, IntoDict)]  // Top-level: both macros
110/// struct Inputs {
111///     title: String,
112///     products: Vec<Product>,
113/// }
114///
115/// #[derive(IntoValue)]  // Nested: IntoValue only
116/// struct Product {
117///     name: String,
118///     price: f64,
119/// }
120/// ```
121///
122/// In `.typ` files, nested structs are accessed as dictionaries:
123/// ```typ
124/// #for product in inputs.products [
125///   - #product.name: $#product.price
126/// ]
127/// ```
128pub use typst_bake_macros::IntoValue;
129
130/// Derive macro for converting a struct to a Typst dictionary.
131///
132/// Only the top-level struct passed to [`Document::with_inputs`] needs this.
133/// Nested structs should only derive [`IntoValue`].
134///
135/// # Example
136///
137/// ```rust,ignore
138/// use typst_bake::{IntoValue, IntoDict};
139///
140/// #[derive(IntoValue, IntoDict)]  // Top-level: both macros
141/// struct Inputs {
142///     title: String,
143///     items: Vec<Item>,
144/// }
145///
146/// #[derive(IntoValue)]  // Nested: IntoValue only
147/// struct Item {
148///     name: String,
149///     price: f64,
150/// }
151///
152/// let pdf = typst_bake::document!("main.typ")
153///     .with_inputs(Inputs { /* ... */ })
154///     .to_pdf()?;
155/// ```
156pub use typst_bake_macros::IntoDict;
157
158/// Re-export include_dir for macro-generated code.
159#[doc(hidden)]
160pub use include_dir;
161
162/// Internal module for macro-generated code.
163/// Do not use directly.
164#[doc(hidden)]
165pub mod __internal {
166    pub use super::document::Document;
167    pub use include_dir::Dir;
168    // Re-export include_dir crate for direct struct construction
169    pub use include_dir;
170    // Re-export typst crate for derive macros
171    pub use typst;
172}