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/// - **Fonts**: Only supported font formats (TTF, OTF, TTC) are embedded. At least one font
89///   is required; without fonts, Typst produces invisible text
90/// - **Packages**: Using packages requires no manual setup. Just use `#import "@preview/..."`
91///   or `#import "@local/..."` as you normally would in Typst. The macro scans for package
92///   imports and recursively resolves all dependencies at compile time. Shares Typst's own
93///   package directories, so locally installed packages are picked up automatically
94pub use typst_bake_macros::document;
95
96/// Derive macro for converting a struct to a Typst value.
97///
98/// All structs that will be passed to Typst templates (directly or nested) must derive this.
99///
100/// - **Top-level struct**: Use both [`IntoValue`] and [`IntoDict`]
101/// - **Nested structs**: Use [`IntoValue`] only
102///
103/// # Example
104///
105/// ```rust,ignore
106/// use typst_bake::{IntoValue, IntoDict};
107///
108/// #[derive(IntoValue, IntoDict)]  // Top-level: both macros
109/// struct Inputs {
110///     title: String,
111///     products: Vec<Product>,
112/// }
113///
114/// #[derive(IntoValue)]  // Nested: IntoValue only
115/// struct Product {
116///     name: String,
117///     price: f64,
118/// }
119/// ```
120///
121/// In `.typ` files, nested structs are accessed as dictionaries:
122/// ```typ
123/// #for product in inputs.products [
124///   - #product.name: $#product.price
125/// ]
126/// ```
127pub use typst_bake_macros::IntoValue;
128
129/// Derive macro for converting a struct to a Typst dictionary.
130///
131/// Only the top-level struct passed to [`Document::with_inputs`] needs this.
132/// Nested structs should only derive [`IntoValue`].
133///
134/// # Example
135///
136/// ```rust,ignore
137/// use typst_bake::{IntoValue, IntoDict};
138///
139/// #[derive(IntoValue, IntoDict)]  // Top-level: both macros
140/// struct Inputs {
141///     title: String,
142///     items: Vec<Item>,
143/// }
144///
145/// #[derive(IntoValue)]  // Nested: IntoValue only
146/// struct Item {
147///     name: String,
148///     price: f64,
149/// }
150///
151/// let pdf = typst_bake::document!("main.typ")
152///     .with_inputs(Inputs { /* ... */ })
153///     .to_pdf()?;
154/// ```
155pub use typst_bake_macros::IntoDict;
156
157/// Re-export include_dir for macro-generated code.
158#[doc(hidden)]
159pub use include_dir;
160
161/// Internal module for macro-generated code.
162/// Do not use directly.
163#[doc(hidden)]
164pub mod __internal {
165    pub use super::document::Document;
166    pub use include_dir::Dir;
167    // Re-export include_dir crate for direct struct construction
168    pub use include_dir;
169    // Re-export typst crate for derive macros
170    pub use typst;
171}