From 47e9597aec15a562549f6e53667fece028b35754 Mon Sep 17 00:00:00 2001 From: Johannes Neyer Date: Tue, 18 Feb 2025 14:41:27 +0100 Subject: [PATCH] cli: Allow setting an output directory This allows setting an output directory with a new `--output-path` argument. The following command writes the output file to `build/test.pdf`. If the `build` directory does not exist yet, it is created. ```sh typst compile -fpdf --output-path build test.typ ``` The following also writes the output file to `build/test.pdf`. ```sh typst compile -fpdf --output-path build src/test.typ ``` When an absolute path to an output file is specified the `--output-path` argument is ignored: ```sh typst compile -fpdf --output-path build test.typ /tmp/test.pdf ``` --- crates/typst-cli/src/args.rs | 4 ++++ crates/typst-cli/src/compile.rs | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/crates/typst-cli/src/args.rs b/crates/typst-cli/src/args.rs index d6855d100..92d24e98d 100644 --- a/crates/typst-cli/src/args.rs +++ b/crates/typst-cli/src/args.rs @@ -224,6 +224,10 @@ pub struct CompileArgs { #[arg(long = "format", short = 'f')] pub format: Option, + /// Directory to write output to. + #[clap(long = "output-path", env = "TYPST_OUTPUT_PATH", value_name = "DIR")] + pub output_path: Option, + /// World arguments. #[clap(flatten)] pub world: WorldArgs, diff --git a/crates/typst-cli/src/compile.rs b/crates/typst-cli/src/compile.rs index 2b6a7d820..19902ea0a 100644 --- a/crates/typst-cli/src/compile.rs +++ b/crates/typst-cli/src/compile.rs @@ -112,7 +112,7 @@ impl CompileConfig { OutputFormat::Pdf }; - let output = args.output.clone().unwrap_or_else(|| { + let mut output = args.output.clone().unwrap_or_else(|| { let Input::Path(path) = &input else { panic!("output must be specified when input is from stdin, as guarded by the CLI"); }; @@ -126,6 +126,19 @@ impl CompileConfig { )) }); + if let (Some(output_path), Output::Path(output_file_name)) = + (args.output_path.as_ref(), &mut output) + { + if !output_file_name.is_absolute() { + if !output_path.exists() { + fs::create_dir_all(output_path) + .expect("could not create output path: {err}"); + } + *output_file_name = + output_path.join(&output_file_name.file_name().unwrap()); + } + } + let pages = args.pages.as_ref().map(|export_ranges| { PageRanges::new(export_ranges.iter().map(|r| r.0.clone()).collect()) });