Skip to main content

office2pdf/
lib.rs

1//! Pure-Rust conversion of Office documents (DOCX, PPTX, XLSX) to PDF.
2//!
3//! # Quick start (native only)
4//!
5//! ```no_run
6//! # #[cfg(not(target_arch = "wasm32"))]
7//! # {
8//! let result = office2pdf::convert("report.docx").unwrap();
9//! std::fs::write("report.pdf", &result.pdf).unwrap();
10//! # }
11//! ```
12//!
13//! # With options (native only)
14//!
15//! ```no_run
16//! # #[cfg(not(target_arch = "wasm32"))]
17//! # {
18//! use office2pdf::config::{ConvertOptions, PaperSize, SlideRange};
19//!
20//! let options = ConvertOptions {
21//!     paper_size: Some(PaperSize::A4),
22//!     slide_range: Some(SlideRange::new(1, 5)),
23//!     ..Default::default()
24//! };
25//! let result = office2pdf::convert_with_options("slides.pptx", &options).unwrap();
26//! std::fs::write("slides.pdf", &result.pdf).unwrap();
27//! # }
28//! ```
29//!
30//! # In-memory conversion (works on all targets including WASM)
31//!
32//! ```no_run
33//! use office2pdf::config::{ConvertOptions, Format};
34//!
35//! let docx_bytes = std::fs::read("report.docx").unwrap();
36//! let result = office2pdf::convert_bytes(&docx_bytes, Format::Docx, &ConvertOptions::default()).unwrap();
37//! std::fs::write("report.pdf", &result.pdf).unwrap();
38//! ```
39
40pub mod config;
41pub mod defaults;
42pub mod error;
43pub mod ir;
44pub mod parser;
45#[cfg(feature = "pdf-ops")]
46pub mod pdf_ops;
47pub mod render;
48#[cfg(feature = "wasm")]
49pub mod wasm;
50
51use config::{ConvertOptions, Format};
52use error::{ConvertError, ConvertResult};
53#[path = "lib_pipeline.rs"]
54mod pipeline;
55#[cfg(test)]
56#[path = "lib_test_support.rs"]
57mod test_support;
58
59#[cfg(test)]
60fn is_ole2(data: &[u8]) -> bool {
61    pipeline::is_ole2(data)
62}
63
64#[cfg(not(target_arch = "wasm32"))]
65#[cfg(test)]
66fn should_resolve_font_context(doc: &ir::Document, options: &ConvertOptions) -> bool {
67    pipeline::should_resolve_font_context(doc, options, false)
68}
69
70/// Convert a file at the given path to PDF bytes with warnings.
71///
72/// Detects the format from the file extension (`.docx`, `.pptx`, `.xlsx`).
73///
74/// This function is not available on `wasm32` targets because it reads from the
75/// filesystem. Use [`convert_bytes`] for in-memory conversion on WASM.
76///
77/// # Errors
78///
79/// Returns [`ConvertError::UnsupportedFormat`] if the extension is unrecognized,
80/// [`ConvertError::Io`] if the file cannot be read, or other variants for
81/// parse/render failures.
82#[cfg(not(target_arch = "wasm32"))]
83pub fn convert(path: impl AsRef<std::path::Path>) -> Result<ConvertResult, ConvertError> {
84    pipeline::convert(path)
85}
86
87/// Convert a file at the given path to PDF bytes with options.
88///
89/// See [`ConvertOptions`] for available settings (paper size, sheet filter, etc.).
90///
91/// This function is not available on `wasm32` targets because it reads from the
92/// filesystem. Use [`convert_bytes`] for in-memory conversion on WASM.
93///
94/// # Errors
95///
96/// Returns [`ConvertError`] on unsupported format, I/O, parse, or render failure.
97#[cfg(not(target_arch = "wasm32"))]
98pub fn convert_with_options(
99    path: impl AsRef<std::path::Path>,
100    options: &ConvertOptions,
101) -> Result<ConvertResult, ConvertError> {
102    pipeline::convert_with_options(path, options)
103}
104
105/// Convert raw bytes of a known format to PDF bytes with warnings.
106///
107/// Use this when you already have the file contents in memory and know the
108/// [`Format`].
109///
110/// When `options.streaming` is `true` and the format is XLSX, the conversion
111/// processes rows in chunks to bound peak memory during Typst compilation.
112/// This requires the `pdf-ops` feature for PDF merging.
113///
114/// # Errors
115///
116/// Returns [`ConvertError`] on parse or render failure.
117pub fn convert_bytes(
118    data: &[u8],
119    format: Format,
120    options: &ConvertOptions,
121) -> Result<ConvertResult, ConvertError> {
122    pipeline::convert_bytes(data, format, options)
123}
124
125/// Render an IR Document to PDF bytes.
126///
127///// Render an IR [`Document`](ir::Document) directly to PDF bytes.
128///
129/// Takes a fully constructed [`ir::Document`] and runs it through
130/// the Typst codegen → PDF compilation pipeline.
131///
132/// # Errors
133///
134/// Returns [`ConvertError::Render`] if Typst compilation or PDF export fails.
135pub fn render_document(doc: &ir::Document) -> Result<Vec<u8>, ConvertError> {
136    pipeline::render_document(doc)
137}
138
139#[cfg(test)]
140#[path = "lib_pipeline_tests.rs"]
141mod pipeline_tests;
142
143#[cfg(test)]
144#[path = "lib_render_tests.rs"]
145mod render_tests;
146
147#[cfg(test)]
148#[path = "lib_conversion_tests.rs"]
149mod conversion_tests;
150
151#[cfg(test)]
152#[path = "lib_robustness_tests.rs"]
153mod robustness_tests;
154
155#[cfg(all(test, feature = "typescript"))]
156#[path = "lib_ts_integration_tests.rs"]
157mod ts_integration_tests;
158
159#[cfg(all(test, feature = "pdf-ops"))]
160#[path = "lib_streaming_tests.rs"]
161mod streaming_tests;