From d6f1bf5cc21753c08fb880cd4245ff778696ac71 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Sat, 28 Mar 2026 15:30:47 +0100 Subject: [PATCH 1/6] Adds export_typst_bundle() helper to core --- Cargo.lock | 1 + crates/core/Cargo.toml | 1 + crates/core/src/bundle_compile.rs | 36 +++++++++++++++++++++++++++++++ crates/core/src/lib.rs | 4 ++++ 4 files changed, 42 insertions(+) create mode 100644 crates/core/src/bundle_compile.rs diff --git a/Cargo.lock b/Cargo.lock index 4cd4ad8..473ce10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2915,6 +2915,7 @@ dependencies = [ "tracing", "tracing-subscriber", "typst", + "typst-bundle", "typst-html", "typst-kit", "typst-layout", diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index bb5392d..dffcb14 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -16,6 +16,7 @@ typst-library = { workspace = true } typst-kit = { workspace = true } typst-syntax = { workspace = true } typst-layout = { workspace = true } +typst-bundle = { workspace = true } comemo = { workspace = true } # Error handling and diagnostics diff --git a/crates/core/src/bundle_compile.rs b/crates/core/src/bundle_compile.rs new file mode 100644 index 0000000..402ac93 --- /dev/null +++ b/crates/core/src/bundle_compile.rs @@ -0,0 +1,36 @@ +use crate::diagnostics::print_diagnostics; +use crate::RheoError; +use crate::RheoWorld; +use crate::Result; +use typst::diag::Warned; + +/// Compile and export a Typst bundle to file bytes. +/// +/// This helper function consolidates the common bundle compilation and export +/// logic used by both HTML and PDF plugins. It compiles the bundle using the +/// world, prints diagnostics, and returns the exported file bytes. +/// +/// # Arguments +/// * `world` - The RheoWorld for compilation context +/// +/// # Returns +/// A vector of (filename, bytes) pairs representing the exported bundle files +/// +/// # Errors +/// Returns `RheoError::project_config` if compilation or export fails +pub fn export_typst_bundle(world: &RheoWorld) -> Result)>> { + let Warned { output, warnings } = typst::compile::(world); + let _ = print_diagnostics(world, &[], &warnings); + let bundle = output.map_err(|errors| { + let _ = print_diagnostics(world, &errors[..], &[]); + let msgs: Vec = errors.iter().map(|e| e.message.to_string()).collect(); + RheoError::project_config(format!("bundle compilation had errors: {}", msgs.join(", "))) + })?; + let bundle_options = typst_bundle::BundleOptions { + pixel_per_pt: 144.0, + pdf: typst_pdf::PdfOptions::default(), + }; + let fs = typst_bundle::export(&bundle, &bundle_options) + .map_err(|e| RheoError::project_config(format!("bundle export failed: {:?}", e)))?; + Ok(fs.into_iter().map(|(p, b)| (p.get_without_slash().to_string(), b.to_vec())).collect()) +} diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index cbb1e69..1157590 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -1,3 +1,4 @@ +pub mod bundle_compile; pub mod compile; pub mod config; pub mod constants; @@ -71,6 +72,9 @@ pub use reticulate::spine::generate_bundle_entry; // PDF utilities pub use pdf_utils::DocumentTitle; +// Bundle compilation helper +pub use bundle_compile::export_typst_bundle; + // Typst types (commonly used by plugins) pub use typst_types::{ EcoString, HeadingElem, HtmlDocument, NativeElement, OutlineNode, StyleChain, eco_format, From 93cd1777a8c8b7db9dcefbe0226a70d347658880 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Sat, 28 Mar 2026 15:38:28 +0100 Subject: [PATCH 2/6] Updates HTML plugin to use export_typst_bundle --- crates/html/src/lib.rs | 36 +++++------------------------------- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/crates/html/src/lib.rs b/crates/html/src/lib.rs index c12db4f..03006fd 100644 --- a/crates/html/src/lib.rs +++ b/crates/html/src/lib.rs @@ -7,13 +7,11 @@ mod server; pub const DEFAULT_STYLESHEET: &str = include_str!("templates/style.css"); use rheo_core::{ - FormatPlugin, OpenHandle, PluginContext, PluginSection, Result, RheoCompileOptions, RheoError, - ServerHandle, diagnostics::print_diagnostics, + export_typst_bundle, FormatPlugin, OpenHandle, PluginContext, PluginSection, Result, + RheoCompileOptions, RheoError, ServerHandle, }; use std::path::Path; use tracing::{debug, info, warn}; -use typst::diag::Warned; -use typst_pdf::PdfOptions; /// Reload callback type - called by watch loop after successful compilation. /// Defined here because it's only needed by the HTML plugin's development server. @@ -125,38 +123,14 @@ fn compile_html_bundle(options: RheoCompileOptions, config: &PluginSection) -> R info!("compiling HTML bundle"); - // Compile the bundle using the world (which has the synthetic bundle entry as main) - let Warned { output, warnings } = typst::compile::(options.world); - - // Print warnings (ignore errors from diagnostic printing) - let _ = print_diagnostics(options.world, &[], &warnings); - - let bundle = output.map_err(|errors| { - // Print errors to stderr with proper formatting - let _ = print_diagnostics(options.world, &errors, &[]); - // Return error for error handling - let error_messages: Vec = errors.iter().map(|e| e.message.to_string()).collect(); - RheoError::project_config(format!( - "bundle compilation had errors: {}", - error_messages.join(", ") - )) - })?; - - // Export the bundle to get HTML files - let bundle_options = typst_bundle::BundleOptions { - pixel_per_pt: 144.0, - pdf: PdfOptions::default(), - }; - - let fs = typst_bundle::export(&bundle, &bundle_options) - .map_err(|e| RheoError::project_config(format!("bundle export failed: {:?}", e)))?; + // Compile and export the bundle using the core helper + let fs = export_typst_bundle(options.world)?; debug!(file_count = fs.len(), "exported HTML bundle"); // Write each HTML file and web asset to the output directory. // Skip .pdf files: those belong to the PDF plugin's output directory. - for (vpath, bytes) in &fs { - let filename = vpath.get_without_slash(); + for (filename, bytes) in &fs { if filename.ends_with(".pdf") { continue; } From 45ddc88129fdf2d69341e96f07248f6ae0708f6e Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Sat, 28 Mar 2026 15:44:06 +0100 Subject: [PATCH 3/6] Updates PDF plugin to use export_typst_bundle --- crates/pdf/src/lib.rs | 66 +++++-------------------------------------- 1 file changed, 7 insertions(+), 59 deletions(-) diff --git a/crates/pdf/src/lib.rs b/crates/pdf/src/lib.rs index 81657c7..107aecd 100644 --- a/crates/pdf/src/lib.rs +++ b/crates/pdf/src/lib.rs @@ -1,13 +1,8 @@ use rheo_core::{ - FormatPlugin, PluginContext, Result, RheoError, RheoWorld, diagnostics::print_diagnostics, + export_typst_bundle, FormatPlugin, PluginContext, Result, RheoError, RheoWorld, }; use std::path::Path; use tracing::{debug, info}; -use typst::diag::Warned; -use typst_pdf::PdfOptions; - -/// PDF pixel-per-point ratio: 2x the standard 72 DPI for quality printing. -const PDF_PIXEL_PER_PT: f32 = 144.0; pub struct PdfPlugin; @@ -57,37 +52,14 @@ fn compile_pdf_bundle_impl(world: &RheoWorld, output_path: &Path, merge: bool) - fn compile_pdf_merged_bundle(world: &RheoWorld, output_path: &Path) -> Result<()> { info!("compiling merged PDF bundle"); - // Compile the bundle using the world (which has the synthetic bundle entry as main) - let Warned { output, warnings } = typst::compile::(world); - - // Print warnings (ignore errors from diagnostic printing) - let _ = print_diagnostics(world, &[], &warnings); - - let bundle = output.map_err(|errors| { - // Print errors to stderr with proper formatting - let _ = print_diagnostics(world, &errors, &[]); - // Return error for error handling - let error_messages: Vec = errors.iter().map(|e| e.message.to_string()).collect(); - RheoError::project_config(format!( - "bundle compilation had errors: {}", - error_messages.join(", ") - )) - })?; - - // Export the bundle to get PDF files - let bundle_options = typst_bundle::BundleOptions { - pixel_per_pt: PDF_PIXEL_PER_PT, - pdf: PdfOptions::default(), - }; - - let fs = typst_bundle::export(&bundle, &bundle_options) - .map_err(|e| RheoError::project_config(format!("bundle export failed: {:?}", e)))?; + // Compile and export the bundle using the core helper + let fs = export_typst_bundle(world)?; debug!(file_count = fs.len(), "exported PDF bundle"); // For merged PDF, the bundle produces a single PDF file // Export it and write to the output path - let (_vpath, pdf_bytes) = fs + let (_filename, pdf_bytes) = fs .into_iter() .next() .ok_or_else(|| RheoError::invalid_data("bundle produced no output"))?; @@ -106,31 +78,8 @@ fn compile_pdf_merged_bundle(world: &RheoWorld, output_path: &Path) -> Result<() fn compile_pdf_per_file_bundle(world: &RheoWorld, output_dir: &Path) -> Result<()> { info!("compiling per-file PDF bundle"); - // Compile the bundle using the world - let Warned { output, warnings } = typst::compile::(world); - - // Print warnings (ignore errors from diagnostic printing) - let _ = print_diagnostics(world, &[], &warnings); - - let bundle = output.map_err(|errors| { - // Print errors to stderr with proper formatting - let _ = print_diagnostics(world, &errors, &[]); - // Return error for error handling - let error_messages: Vec = errors.iter().map(|e| e.message.to_string()).collect(); - RheoError::project_config(format!( - "bundle compilation had errors: {}", - error_messages.join(", ") - )) - })?; - - // Export the bundle to get PDF files - let bundle_options = typst_bundle::BundleOptions { - pixel_per_pt: PDF_PIXEL_PER_PT, - pdf: PdfOptions::default(), - }; - - let fs = typst_bundle::export(&bundle, &bundle_options) - .map_err(|e| RheoError::project_config(format!("bundle export failed: {:?}", e)))?; + // Compile and export the bundle using the core helper + let fs = export_typst_bundle(world)?; debug!(file_count = fs.len(), "exported PDF bundle"); @@ -138,8 +87,7 @@ fn compile_pdf_per_file_bundle(world: &RheoWorld, output_dir: &Path) -> Result<( // Filter to .pdf files only: bundles that also target HTML will include HTML files // and assets in the export; writing those to the PDF output dir would corrupt it. let mut file_count = 0; - for (vpath, bytes) in fs { - let filename = vpath.get_without_slash(); + for (filename, bytes) in fs { if !filename.ends_with(".pdf") { continue; } From 69fd1091295ae3164c976b3fee2a83d8db6a3c4b Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Sat, 28 Mar 2026 15:52:51 +0100 Subject: [PATCH 4/6] Removes uses_bundle_api() from FormatPlugin trait --- crates/cli/src/lib.rs | 2 +- crates/core/src/plugins/mod.rs | 15 --------------- crates/html/src/lib.rs | 4 ---- crates/pdf/src/lib.rs | 4 ---- 4 files changed, 1 insertion(+), 24 deletions(-) diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 9163eb4..811f0ef 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -620,7 +620,7 @@ fn perform_compilation( let plugin_section = project.config.plugin_section(plugin.name()); // Dispatch to appropriate compilation path - if !spine.merge && plugin.uses_bundle_api() { + if !spine.merge { compile_bundle( plugin.as_ref(), &plugin_output_dir, diff --git a/crates/core/src/plugins/mod.rs b/crates/core/src/plugins/mod.rs index 212e495..a1f6fc7 100644 --- a/crates/core/src/plugins/mod.rs +++ b/crates/core/src/plugins/mod.rs @@ -153,21 +153,6 @@ pub trait FormatPlugin: Send + Sync { /// Whether this plugin uses the Typst bundle API for compilation. /// - /// Override to return `true` for formats that use `typst::compile::()`. - /// When `true`, the CLI generates a bundle entry and injects it into the world - /// before compilation. When `false`, the plugin uses per-file compilation. - /// - /// # Examples - /// - /// ```ignore - /// fn uses_bundle_api(&self) -> bool { - /// true // HTML and PDF use bundle compilation - /// } - /// ``` - fn uses_bundle_api(&self) -> bool { - false - } - /// Set plugin-specific smart defaults when no rheo.toml section exists. /// /// Called by the CLI after loading a project when the plugin's section is not diff --git a/crates/html/src/lib.rs b/crates/html/src/lib.rs index 03006fd..9aed8f8 100644 --- a/crates/html/src/lib.rs +++ b/crates/html/src/lib.rs @@ -71,10 +71,6 @@ impl FormatPlugin for HtmlPlugin { "html" } - fn uses_bundle_api(&self) -> bool { - true - } - fn init_templates(&self) -> Vec<(&'static str, &'static str)> { vec![("style.css", include_str!("templates/style.css"))] } diff --git a/crates/pdf/src/lib.rs b/crates/pdf/src/lib.rs index 107aecd..cb0bca0 100644 --- a/crates/pdf/src/lib.rs +++ b/crates/pdf/src/lib.rs @@ -11,10 +11,6 @@ impl FormatPlugin for PdfPlugin { "pdf" } - fn uses_bundle_api(&self) -> bool { - true - } - fn typst_library(&self) -> Option<&'static str> { // PDF-specific lemma function for numbered lemmas in academic documents Some( From 3f75d480f9d51dc0bed8fd8c862f0a95c44a2944 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Sat, 28 Mar 2026 16:01:44 +0100 Subject: [PATCH 5/6] Merges CLI dispatch functions; deletes dead per-file path --- crates/cli/src/lib.rs | 243 +++++------------------------------------- 1 file changed, 27 insertions(+), 216 deletions(-) diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 811f0ef..195b602 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -247,66 +247,12 @@ fn resolve_build_dir( } } -fn get_output_filename(typ_file: &std::path::Path) -> Result { - typ_file - .file_stem() - .and_then(|s| s.to_str()) - .map(|s| s.to_string()) - .ok_or_else(|| RheoError::project_config(format!("invalid .typ filename: {:?}", typ_file))) -} - -/// Per-plugin invariants shared across all files in a single-plugin compilation pass. -struct PerFileCtx<'a> { - plugin: &'a dyn FormatPlugin, - plugin_output_dir: &'a Path, - project: &'a ProjectConfig, - output_config: &'a OutputConfig, - spine: &'a TracedSpine, - plugin_section: &'a PluginSection, - resolved_inputs: &'a HashMap<&'static str, PathBuf>, - content_dir: &'a Path, -} - -/// Compile one file with the given world, recording success/failure in `results`. -/// -/// `get_output_filename` errors propagate; `plugin.compile()` errors are recorded -/// as failures rather than propagated (so other files in the batch still compile). -fn compile_one_file( - world: &mut RheoWorld, - typ_file: &Path, - pfc: &PerFileCtx<'_>, - results: &mut CompilationResults, -) -> Result<()> { - let filename = get_output_filename(typ_file)?; - let output_path = pfc - .plugin_output_dir - .join(&filename) - .with_extension(pfc.plugin.output_extension()); - let options = RheoCompileOptions::new(&output_path, pfc.content_dir, world); - let ctx = PluginContext { - project: pfc.project, - output_config: pfc.output_config, - options, - spine: pfc.spine.clone(), - config: pfc.plugin_section.clone(), - inputs: pfc.resolved_inputs.clone(), - }; - match pfc.plugin.compile(ctx) { - Ok(_) => results.record_success(pfc.plugin.name()), - Err(e) => { - error!(file = %typ_file.display(), error = %e, "{} compilation failed", pfc.plugin.name()); - results.record_failure(pfc.plugin.name()); - } - } - Ok(()) -} - /// Bundle compilation: generate bundle entry, inject into world, compile once. -/// Used by plugins that use the bundle API (HTML, PDF non-merge). +/// Used by all plugins (HTML, PDF, EPUB) with the bundle API. #[allow(clippy::too_many_arguments)] -fn compile_bundle( +fn compile_with_bundle( plugin: &dyn FormatPlugin, - plugin_output_dir: &Path, + output: &Path, project: &ProjectConfig, output_config: &OutputConfig, spine: &TracedSpine, @@ -334,7 +280,7 @@ fn compile_bundle( ); bundle_world.inject_bundle_entry(bundle_entry_source); - let options = RheoCompileOptions::new(plugin_output_dir, &project.root, &mut bundle_world); + let options = RheoCompileOptions::new(output, compilation_root, &mut bundle_world); let ctx = PluginContext { project, @@ -357,115 +303,10 @@ fn compile_bundle( Ok(()) } -/// Merged compilation: single output from all spine documents. -/// Used by PDF merge mode and EPUB. -#[allow(clippy::too_many_arguments)] -fn compile_merged( - plugin: &dyn FormatPlugin, - plugin_output_dir: &Path, - project: &ProjectConfig, - output_config: &OutputConfig, - spine: &TracedSpine, - plugin_section: &PluginSection, - resolved_inputs: HashMap<&'static str, PathBuf>, - results: &mut CompilationResults, - compilation_root: &Path, -) -> Result<()> { - let output_path = plugin_output_dir - .join(&project.name) - .with_extension(plugin.output_extension()); - - let plugin_library = plugin.typst_library().map(|s| s.to_string()); - let mut bundle_world = RheoWorld::new( - compilation_root, - spine - .documents - .first() - .map(|d| d.path.as_path()) - .unwrap_or(compilation_root), - plugin_library, - )?; - - let bundle_entry_source = generate_bundle_entry( - spine, - compilation_root, - plugin.name(), - plugin.typst_library().unwrap_or_default(), - ); - bundle_world.inject_bundle_entry(bundle_entry_source); - - let options = RheoCompileOptions::new(&output_path, compilation_root, &mut bundle_world); - - let ctx = PluginContext { - project, - output_config, - options, - spine: spine.clone(), - config: plugin_section.clone(), - inputs: resolved_inputs, - }; - - match plugin.compile(ctx) { - Ok(_) => { - results.record_success(plugin.name()); - } - Err(e) => { - error!(error = %e, "{} generation failed", plugin.name()); - results.record_failure(plugin.name()); - } - } - Ok(()) -} - -/// Per-file compilation: loop through spine documents, compile each individually. -/// Used by PDF non-merge mode. -#[allow(clippy::too_many_arguments)] -fn compile_per_file( - plugin: &dyn FormatPlugin, - plugin_output_dir: &Path, - project: &ProjectConfig, - output_config: &OutputConfig, - spine: &TracedSpine, - plugin_section: &PluginSection, - resolved_inputs: &HashMap<&'static str, PathBuf>, - content_dir: &Path, - world: &mut Option<&mut RheoWorld>, - results: &mut CompilationResults, -) -> Result<()> { - let files: Vec = spine.documents.iter().map(|d| d.path.clone()).collect(); - - let pfc = PerFileCtx { - plugin, - plugin_output_dir, - project, - output_config, - spine, - plugin_section, - resolved_inputs, - content_dir, - }; - - if let Some(ref mut existing_world) = *world { - for typ_file in &files { - existing_world.set_main(typ_file)?; - existing_world.reset(); - compile_one_file(existing_world, typ_file, &pfc, results)?; - } - } else { - let plugin_library = plugin.typst_library().map(|s| s.to_string()); - for typ_file in &files { - let mut fresh_world = RheoWorld::new(content_dir, typ_file, plugin_library.clone())?; - compile_one_file(&mut fresh_world, typ_file, &pfc, results)?; - } - } - Ok(()) -} - fn perform_compilation( project: &ProjectConfig, output_config: &OutputConfig, plugins: &[Box], - mut world: Option<&mut RheoWorld>, ) -> Result<()> { if project.typ_files.is_empty() { return Err(RheoError::project_config("no .typ files found in project")); @@ -605,59 +446,29 @@ fn perform_compilation( )? }; - // For non-single-file mode, use compilation_root; for single file mode, use file's parent - let content_dir = if project.mode == ProjectMode::SingleFile { - // For single file mode, use the file's parent directory - project.typ_files[0] - .parent() - .unwrap_or(&project.root) - .to_path_buf() - } else { - compilation_root.clone() - }; - // Get full plugin section let plugin_section = project.config.plugin_section(plugin.name()); - // Dispatch to appropriate compilation path - if !spine.merge { - compile_bundle( - plugin.as_ref(), - &plugin_output_dir, - project, - output_config, - &spine, - &plugin_section, - resolved_inputs, - &mut results, - &compilation_root, - )?; - } else if spine.merge { - compile_merged( - plugin.as_ref(), - &plugin_output_dir, - project, - output_config, - &spine, - &plugin_section, - resolved_inputs, - &mut results, - &compilation_root, - )?; + // Determine output path based on merge mode + let output = if spine.merge { + plugin_output_dir + .join(&project.name) + .with_extension(plugin.output_extension()) } else { - compile_per_file( - plugin.as_ref(), - &plugin_output_dir, - project, - output_config, - &spine, - &plugin_section, - &resolved_inputs, - &content_dir, - &mut world, - &mut results, - )?; - } + plugin_output_dir.clone() + }; + + compile_with_bundle( + plugin.as_ref(), + &output, + project, + output_config, + &spine, + &plugin_section, + resolved_inputs, + &mut results, + &compilation_root, + )?; } let names: Vec<&str> = plugins.iter().map(|p| p.name()).collect(); @@ -846,7 +657,7 @@ fn run_watch(sub: &ArgMatches) -> Result<()> { )?; // Initial compilation (best-effort; watch continues on failure) - if let Err(e) = perform_compilation(&ctx.project, &ctx.output_config, &ctx.plugins, None) { + if let Err(e) = perform_compilation(&ctx.project, &ctx.output_config, &ctx.plugins) { warn!(error = %e, "initial compilation failed"); } @@ -873,7 +684,7 @@ fn run_watch(sub: &ArgMatches) -> Result<()> { match event { WatchEvent::FilesChanged => { info!("files changed, recompiling"); - if perform_compilation(&ctx.project, &ctx.output_config, &ctx.plugins, None).is_ok() + if perform_compilation(&ctx.project, &ctx.output_config, &ctx.plugins).is_ok() { for handle in &open_handles { if let OpenHandle::Server(server) = handle { @@ -892,7 +703,7 @@ fn run_watch(sub: &ArgMatches) -> Result<()> { ) { Ok(new_ctx) => { ctx = new_ctx; - if perform_compilation(&ctx.project, &ctx.output_config, &ctx.plugins, None) + if perform_compilation(&ctx.project, &ctx.output_config, &ctx.plugins) .is_ok() { for handle in &open_handles { @@ -920,7 +731,7 @@ fn run_compile(sub: &ArgMatches) -> Result<()> { let ctx = setup_compilation_context(&path, config.as_deref(), build_dir, enabled)?; - perform_compilation(&ctx.project, &ctx.output_config, &ctx.plugins, None) + perform_compilation(&ctx.project, &ctx.output_config, &ctx.plugins) } fn run_clean(sub: &ArgMatches) -> Result<()> { From 5b9923ded8c20a3105026fcf74735007e9eaf959 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Sat, 28 Mar 2026 19:20:35 +0100 Subject: [PATCH 6/6] Formats --- crates/cli/src/lib.rs | 3 +-- crates/core/src/bundle_compile.rs | 14 ++++++++++---- crates/html/src/lib.rs | 4 ++-- crates/pdf/src/lib.rs | 4 +--- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 195b602..5a61ebc 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -684,8 +684,7 @@ fn run_watch(sub: &ArgMatches) -> Result<()> { match event { WatchEvent::FilesChanged => { info!("files changed, recompiling"); - if perform_compilation(&ctx.project, &ctx.output_config, &ctx.plugins).is_ok() - { + if perform_compilation(&ctx.project, &ctx.output_config, &ctx.plugins).is_ok() { for handle in &open_handles { if let OpenHandle::Server(server) = handle { server.reload(); diff --git a/crates/core/src/bundle_compile.rs b/crates/core/src/bundle_compile.rs index 402ac93..9cad9ca 100644 --- a/crates/core/src/bundle_compile.rs +++ b/crates/core/src/bundle_compile.rs @@ -1,7 +1,7 @@ -use crate::diagnostics::print_diagnostics; +use crate::Result; use crate::RheoError; use crate::RheoWorld; -use crate::Result; +use crate::diagnostics::print_diagnostics; use typst::diag::Warned; /// Compile and export a Typst bundle to file bytes. @@ -24,7 +24,10 @@ pub fn export_typst_bundle(world: &RheoWorld) -> Result)>> let bundle = output.map_err(|errors| { let _ = print_diagnostics(world, &errors[..], &[]); let msgs: Vec = errors.iter().map(|e| e.message.to_string()).collect(); - RheoError::project_config(format!("bundle compilation had errors: {}", msgs.join(", "))) + RheoError::project_config(format!( + "bundle compilation had errors: {}", + msgs.join(", ") + )) })?; let bundle_options = typst_bundle::BundleOptions { pixel_per_pt: 144.0, @@ -32,5 +35,8 @@ pub fn export_typst_bundle(world: &RheoWorld) -> Result)>> }; let fs = typst_bundle::export(&bundle, &bundle_options) .map_err(|e| RheoError::project_config(format!("bundle export failed: {:?}", e)))?; - Ok(fs.into_iter().map(|(p, b)| (p.get_without_slash().to_string(), b.to_vec())).collect()) + Ok(fs + .into_iter() + .map(|(p, b)| (p.get_without_slash().to_string(), b.to_vec())) + .collect()) } diff --git a/crates/html/src/lib.rs b/crates/html/src/lib.rs index 9aed8f8..b4a2189 100644 --- a/crates/html/src/lib.rs +++ b/crates/html/src/lib.rs @@ -7,8 +7,8 @@ mod server; pub const DEFAULT_STYLESHEET: &str = include_str!("templates/style.css"); use rheo_core::{ - export_typst_bundle, FormatPlugin, OpenHandle, PluginContext, PluginSection, Result, - RheoCompileOptions, RheoError, ServerHandle, + FormatPlugin, OpenHandle, PluginContext, PluginSection, Result, RheoCompileOptions, RheoError, + ServerHandle, export_typst_bundle, }; use std::path::Path; use tracing::{debug, info, warn}; diff --git a/crates/pdf/src/lib.rs b/crates/pdf/src/lib.rs index cb0bca0..295ae9d 100644 --- a/crates/pdf/src/lib.rs +++ b/crates/pdf/src/lib.rs @@ -1,6 +1,4 @@ -use rheo_core::{ - export_typst_bundle, FormatPlugin, PluginContext, Result, RheoError, RheoWorld, -}; +use rheo_core::{FormatPlugin, PluginContext, Result, RheoError, RheoWorld, export_typst_bundle}; use std::path::Path; use tracing::{debug, info};