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 templates
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::{CategoryStats, EmbedStats, PackageInfo, PackageStats};
59/// Creates a [`Document`] with embedded templates, fonts, and packages.
60///
61/// # Usage
62///
63/// ```rust,ignore
64/// // Generate PDF
65/// let pdf = typst_bake::document!("main.typ").to_pdf()?;
66///
67/// // Generate SVG (one per page)
68/// let svgs = typst_bake::document!("main.typ").to_svg()?;
69///
70/// // Generate PNG at 144 DPI (Retina)
71/// let pngs = typst_bake::document!("main.typ").to_png(144.0)?;
72/// ```
73///
74/// # Configuration
75///
76/// Add to your `Cargo.toml`:
77/// ```toml
78/// [package.metadata.typst-bake]
79/// template-dir = "./templates"
80/// fonts-dir = "./fonts"
81/// ```
82///
83/// # What Gets Embedded
84///
85/// - **Templates**: All files in `template-dir` are embedded and accessible from `.typ` files
86/// - **Fonts**: Only supported font formats (TTF, OTF, TTC) are embedded. At least one font
87/// is required; without fonts, Typst produces invisible text
88/// - **Packages**: Using packages requires no manual setup. Just use `#import "@preview/..."`
89/// as you normally would in Typst. The macro scans for package imports and
90/// recursively resolves all dependencies at compile time
91pub use typst_bake_macros::document;
92
93/// Derive macro for converting a struct to a Typst value.
94///
95/// All structs that will be passed to Typst templates (directly or nested) must derive this.
96///
97/// - **Top-level struct**: Use both [`IntoValue`] and [`IntoDict`]
98/// - **Nested structs**: Use [`IntoValue`] only
99///
100/// # Example
101///
102/// ```rust,ignore
103/// use typst_bake::{IntoValue, IntoDict};
104///
105/// #[derive(IntoValue, IntoDict)] // Top-level: both macros
106/// struct Inputs {
107/// title: String,
108/// products: Vec<Product>,
109/// }
110///
111/// #[derive(IntoValue)] // Nested: IntoValue only
112/// struct Product {
113/// name: String,
114/// price: f64,
115/// }
116/// ```
117///
118/// In Typst templates, nested structs are accessed as dictionaries:
119/// ```typ
120/// #for product in inputs.products [
121/// - #product.name: $#product.price
122/// ]
123/// ```
124pub use typst_bake_macros::IntoValue;
125
126/// Derive macro for converting a struct to a Typst dictionary.
127///
128/// Only the top-level struct passed to [`Document::with_inputs`] needs this.
129/// Nested structs should only derive [`IntoValue`].
130///
131/// # Example
132///
133/// ```rust,ignore
134/// use typst_bake::{IntoValue, IntoDict};
135///
136/// #[derive(IntoValue, IntoDict)] // Top-level: both macros
137/// struct Inputs {
138/// title: String,
139/// items: Vec<Item>,
140/// }
141///
142/// #[derive(IntoValue)] // Nested: IntoValue only
143/// struct Item {
144/// name: String,
145/// price: f64,
146/// }
147///
148/// let pdf = typst_bake::document!("main.typ")
149/// .with_inputs(Inputs { /* ... */ })
150/// .to_pdf()?;
151/// ```
152pub use typst_bake_macros::IntoDict;
153
154/// Re-export include_dir for macro-generated code.
155#[doc(hidden)]
156pub use include_dir;
157
158/// Internal module for macro-generated code.
159/// Do not use directly.
160#[doc(hidden)]
161pub mod __internal {
162 pub use super::document::Document;
163 pub use include_dir::Dir;
164 // Re-export include_dir crate for direct struct construction
165 pub use include_dir;
166 // Re-export typst crate for derive macros
167 pub use typst;
168}