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//! PDF is enabled by default. To use only SVG: `default-features = false, features = ["svg"]`.
16//!
17//! ## Features
18//!
19//! - **Simple API** - Set `template-dir` and `fonts-dir` in `Cargo.toml`, then generate documents with just `document!("main.typ").to_pdf()`
20//! - **Multi-Format Output** - Generate PDF, SVG, or PNG with optional [page selection](`Document::select_pages`)
21//! - **Self-Contained Binary** - Templates, fonts, and packages are all embedded into the binary at compile time. No external files or internet connection needed at runtime
22//! - **Automatic Package Resolution** - Just use `#import "@preview/..."` as in Typst. Packages are resolved automatically using Typst's own cache and data directories
23//! - **Runtime Inputs** - Pass dynamic data from Rust structs to Typst via [`IntoValue`] / [`IntoDict`] derive macros
24//! - **Runtime Files** - Inject files at runtime with [`Document::add_file`] for dynamically generated content or downloaded resources
25//! - **Optimized Binary Size** - Embedded resources are deduplicated and compressed automatically
26//!
27//! ## Quick Start
28//!
29//! Add to your `Cargo.toml`:
30//! ```toml
31//! [dependencies]
32//! typst-bake = "0.1"
33//!
34//! [package.metadata.typst-bake]
35//! template-dir = "./templates"
36//! fonts-dir = "./fonts"
37//! ```
38//!
39//! Then use the [`document!`] macro:
40//! ```rust,ignore
41//! let doc = typst_bake::document!("main.typ");
42//!
43//! let pdf = doc.to_pdf()?;
44//! std::fs::write("output.pdf", &pdf)?;
45//!
46//! let svgs = doc.to_svg()?;
47//! std::fs::write("page1.svg", &svgs[0])?;
48//!
49//! let pngs = doc.to_png(144.0)?; // 144 DPI
50//! std::fs::write("page1.png", &pngs[0])?;
51//! ```
52
53mod build;
54mod document;
55mod error;
56#[cfg(feature = "pdf")]
57mod pdf_config;
58mod resolver;
59mod stats;
60mod util;
61
62pub use build::rebuild_if_changed;
63pub use document::{Document, Pages};
64pub use error::{Error, Result};
65#[cfg(feature = "pdf")]
66#[cfg_attr(docsrs, doc(cfg(feature = "pdf")))]
67pub use pdf_config::{PdfConfig, PdfStandard, PdfTimestamp};
68pub use stats::{
69 CategoryStats, DedupStats, EmbedStats, HasCompressionRatio, PackageInfo, PackageStats,
70};
71/// Creates a [`Document`] with embedded templates, fonts, and packages.
72///
73/// # Usage
74///
75/// ```rust,ignore
76/// let doc = typst_bake::document!("main.typ");
77///
78/// // Output formats
79/// let pdf = doc.to_pdf()?;
80/// let svgs = doc.to_svg()?;
81/// let pngs = doc.to_png(144.0)?; // 144 DPI
82///
83/// // Page selection (0-indexed)
84/// let cover_pdf = doc.select_pages([0]).to_pdf()?;
85/// let body_pdf = doc.select_pages(1..5).to_pdf()?;
86///
87/// // Page count
88/// let total = doc.page_count()?;
89/// let last_page = doc.select_pages([total - 1]).to_png(72.0)?;
90/// ```
91///
92/// # Configuration
93///
94/// Add to your `Cargo.toml`:
95/// ```toml
96/// [package.metadata.typst-bake]
97/// template-dir = "./templates"
98/// fonts-dir = "./fonts"
99/// ```
100///
101/// # What Gets Embedded
102///
103/// - **Templates**: All files in `template-dir` are embedded and accessible from `.typ` files.
104/// Paths resolve relative to the referring `.typ` file.
105/// - **Fonts**: Only supported font formats (TTF, OTF, TTC) are embedded. At least one font
106/// is required; without fonts, Typst produces invisible text.
107/// - **Packages**: Using packages requires no manual setup. Just use `#import "@preview/..."`
108/// or `#import "@local/..."` as you normally would in Typst. The macro scans for package
109/// imports and recursively resolves all dependencies at compile time. Shares Typst's own
110/// package directories, so locally installed packages are picked up automatically.
111pub use typst_bake_macros::document;
112
113/// Derive macro for converting a struct to a Typst value.
114///
115/// All structs that will be passed to Typst templates (directly or nested) must derive this.
116///
117/// - **Top-level struct**: Use both [`IntoValue`] and [`IntoDict`]
118/// - **Nested structs**: Use [`IntoValue`] only
119///
120/// # Example
121///
122/// ```rust,ignore
123/// use typst_bake::{IntoValue, IntoDict};
124///
125/// #[derive(IntoValue, IntoDict)] // Top-level: both macros
126/// struct Inputs {
127/// title: String,
128/// products: Vec<Product>,
129/// }
130///
131/// #[derive(IntoValue)] // Nested: IntoValue only
132/// struct Product {
133/// name: String,
134/// price: f64,
135/// }
136/// ```
137///
138/// In `.typ` files, nested structs are accessed as dictionaries:
139/// ```typ
140/// #for product in inputs.products [
141/// - #product.name: $#product.price
142/// ]
143/// ```
144pub use typst_bake_macros::IntoValue;
145
146/// Derive macro for converting a struct to a Typst dictionary.
147///
148/// Only the top-level struct passed to [`Document::with_inputs`] needs this.
149/// Nested structs should only derive [`IntoValue`].
150///
151/// # Example
152///
153/// ```rust,ignore
154/// use typst_bake::{IntoValue, IntoDict};
155///
156/// #[derive(IntoValue, IntoDict)] // Top-level: both macros
157/// struct Inputs {
158/// title: String,
159/// items: Vec<Item>,
160/// }
161///
162/// #[derive(IntoValue)] // Nested: IntoValue only
163/// struct Item {
164/// name: String,
165/// price: f64,
166/// }
167///
168/// let pdf = typst_bake::document!("main.typ")
169/// .with_inputs(Inputs { /* ... */ })
170/// .to_pdf()?;
171/// ```
172pub use typst_bake_macros::IntoDict;
173
174/// Re-export include_dir for macro-generated code.
175#[doc(hidden)]
176pub use include_dir;
177
178/// Internal module for macro-generated code.
179/// Do not use directly.
180#[doc(hidden)]
181pub mod __internal {
182 pub use super::document::Document;
183 pub use include_dir::Dir;
184 // Re-export include_dir crate for direct struct construction
185 pub use include_dir;
186 // Re-export typst crate for derive macros
187 pub use typst;
188}