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