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