From e0122a5b509d151b7e0197d37a120fd965a055d5 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Mon, 2 Dec 2024 14:19:52 +0100 Subject: Add HTML export format --- crates/typst-cli/Cargo.toml | 1 + crates/typst-cli/src/args.rs | 1 + crates/typst-cli/src/compile.rs | 46 ++++++++++++++++++++++++++++++++++------- 3 files changed, 40 insertions(+), 8 deletions(-) (limited to 'crates/typst-cli') diff --git a/crates/typst-cli/Cargo.toml b/crates/typst-cli/Cargo.toml index 4b4abc55..12cf94a7 100644 --- a/crates/typst-cli/Cargo.toml +++ b/crates/typst-cli/Cargo.toml @@ -20,6 +20,7 @@ doc = false [dependencies] typst = { workspace = true } typst-eval = { workspace = true } +typst-html = { workspace = true } typst-kit = { workspace = true } typst-macros = { workspace = true } typst-pdf = { workspace = true } diff --git a/crates/typst-cli/src/args.rs b/crates/typst-cli/src/args.rs index bc3d1225..d9ecc921 100644 --- a/crates/typst-cli/src/args.rs +++ b/crates/typst-cli/src/args.rs @@ -512,6 +512,7 @@ pub enum OutputFormat { Pdf, Png, Svg, + Html, } impl Display for OutputFormat { diff --git a/crates/typst-cli/src/compile.rs b/crates/typst-cli/src/compile.rs index c6d37ffe..2a319424 100644 --- a/crates/typst-cli/src/compile.rs +++ b/crates/typst-cli/src/compile.rs @@ -12,6 +12,7 @@ use typst::diag::{ bail, At, Severity, SourceDiagnostic, SourceResult, StrResult, Warned, }; use typst::foundations::{Datetime, Smart}; +use typst::html::HtmlDocument; use typst::layout::{Frame, Page, PageRanges, PagedDocument}; use typst::syntax::{FileId, Source, Span}; use typst::WorldExt; @@ -41,6 +42,7 @@ impl CompileCommand { OutputFormat::Pdf => "pdf", OutputFormat::Png => "png", OutputFormat::Svg => "svg", + OutputFormat::Html => "html", }, )) }) @@ -57,6 +59,7 @@ impl CompileCommand { Some(ext) if ext.eq_ignore_ascii_case("pdf") => OutputFormat::Pdf, Some(ext) if ext.eq_ignore_ascii_case("png") => OutputFormat::Png, Some(ext) if ext.eq_ignore_ascii_case("svg") => OutputFormat::Svg, + Some(ext) if ext.eq_ignore_ascii_case("html") => OutputFormat::Html, _ => bail!( "could not infer output format for path {}.\n\ consider providing the format manually with `--format/-f`", @@ -95,9 +98,6 @@ impl CompileCommand { /// Execute a compilation command. pub fn compile(mut timer: Timer, mut command: CompileCommand) -> StrResult<()> { - // Only meant for input validation - _ = command.output_format()?; - let mut world = SystemWorld::new(&command.common).map_err(|err| eco_format!("{err}"))?; timer.record(&mut world, |world| compile_once(world, &mut command, false))??; @@ -113,15 +113,16 @@ pub fn compile_once( command: &mut CompileCommand, watching: bool, ) -> StrResult<()> { + _ = command.output_format()?; + let start = std::time::Instant::now(); if watching { Status::Compiling.print(command).unwrap(); } - let Warned { output, warnings } = typst::compile(world); - let result = output.and_then(|document| export(world, &document, command, watching)); + let Warned { output, warnings } = compile_and_export(world, command, watching); - match result { + match output { // Export the PDF / PNG. Ok(()) => { let duration = start.elapsed(); @@ -167,14 +168,43 @@ pub fn compile_once( Ok(()) } +fn compile_and_export( + world: &mut SystemWorld, + command: &mut CompileCommand, + watching: bool, +) -> Warned> { + let format = command.output_format().unwrap(); + + match format { + OutputFormat::Html => { + let Warned { output, warnings } = typst::compile::(world); + let result = output.and_then(|document| { + command + .output() + .write(typst_html::html(&document)?.as_bytes()) + .map_err(|err| eco_format!("failed to write HTML file ({err})")) + .at(Span::detached()) + }); + Warned { output: result, warnings } + } + _ => { + let Warned { output, warnings } = typst::compile::(world); + let result = output + .and_then(|document| export_paged(world, &document, command, watching)); + Warned { output: result, warnings } + } + } +} + /// Export into the target format. -fn export( +fn export_paged( world: &mut SystemWorld, document: &PagedDocument, command: &CompileCommand, watching: bool, ) -> SourceResult<()> { match command.output_format().at(Span::detached())? { + OutputFormat::Pdf => export_pdf(document, command), OutputFormat::Png => { export_image(world, document, command, watching, ImageExportFormat::Png) .at(Span::detached()) @@ -183,7 +213,7 @@ fn export( export_image(world, document, command, watching, ImageExportFormat::Svg) .at(Span::detached()) } - OutputFormat::Pdf => export_pdf(document, command), + OutputFormat::Html => unreachable!(), } } -- cgit v1.2.3