diff --git a/crates/typst-cli/src/args.rs b/crates/typst-cli/src/args.rs index fd0eb5f05..d5544e997 100644 --- a/crates/typst-cli/src/args.rs +++ b/crates/typst-cli/src/args.rs @@ -1,3 +1,4 @@ +use std::ffi::OsStr; use std::fmt::{self, Display, Formatter}; use std::num::NonZeroUsize; use std::ops::RangeInclusive; @@ -443,6 +444,27 @@ pub enum OutputFormat { Html, } +impl OutputFormat { + pub fn from_file_ext(ext: &OsStr) -> Option { + match ext { + ext if ext.eq_ignore_ascii_case("pdf") => Some(OutputFormat::Pdf), + ext if ext.eq_ignore_ascii_case("png") => Some(OutputFormat::Png), + ext if ext.eq_ignore_ascii_case("svg") => Some(OutputFormat::Svg), + ext if ext.eq_ignore_ascii_case("html") => Some(OutputFormat::Html), + _ => None, + } + } + + pub fn as_file_ext(&self) -> &'static str { + match self { + Self::Pdf => "pdf", + Self::Png => "png", + Self::Svg => "svg", + Self::Html => "html", + } + } +} + display_possible_values!(OutputFormat); /// Which format to use for diagnostics. diff --git a/crates/typst-cli/src/compile.rs b/crates/typst-cli/src/compile.rs index afc6863d0..d8a189191 100644 --- a/crates/typst-cli/src/compile.rs +++ b/crates/typst-cli/src/compile.rs @@ -96,12 +96,9 @@ impl CompileConfig { let output_format = if let Some(specified) = args.format { specified } else if let Some(Output::Path(output)) = &args.output { - match output.extension() { - 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!( + match output.extension().and_then(OutputFormat::from_file_ext) { + Some(format) => format, + None => bail!( "could not infer output format for path {}.\n\ consider providing the format manually with `--format/-f`", output.display() @@ -116,12 +113,7 @@ impl CompileConfig { let Input::Path(path) = &input else { panic!("output must be specified when input is from stdin, as guarded by the CLI"); }; - Output::Path(path.with_extension(match output_format { - OutputFormat::Pdf => "pdf", - OutputFormat::Png => "png", - OutputFormat::Svg => "svg", - OutputFormat::Html => "html", - })) + Output::Path(path.with_extension(output_format.as_file_ext())) } // Check if a [`Path`] has a trailing `/` (or on `windows` a `\`) character, // indicating that the output should be written to `{output}/{input_file_name}.{ext}` @@ -146,12 +138,7 @@ impl CompileConfig { })?; path.push(file_name); - path.set_extension(match output_format { - OutputFormat::Pdf => "pdf", - OutputFormat::Png => "png", - OutputFormat::Svg => "svg", - OutputFormat::Html => "html", - }); + path.set_extension(output_format.as_file_ext()); Output::Path(path) } Some(output) => output,