feat(cli): allow specifying output directory

This commit is contained in:
Jon Heinritz 2025-06-20 08:00:29 +02:00
parent f1c761e88b
commit a41f821fa6

View File

@ -111,19 +111,43 @@ impl CompileConfig {
OutputFormat::Pdf OutputFormat::Pdf
}; };
let output = args.output.clone().unwrap_or_else(|| { let output = match args.output.clone() {
None => {
let Input::Path(path) = &input else { let Input::Path(path) = &input else {
panic!("output must be specified when input is from stdin, as guarded by the CLI"); panic!("output must be specified when input is from stdin, as guarded by the CLI");
}; };
Output::Path(path.with_extension( Output::Path(path.with_extension(match output_format {
match output_format { OutputFormat::Pdf => "pdf",
OutputFormat::Png => "png",
OutputFormat::Svg => "svg",
OutputFormat::Html => "html",
}))
}
// 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}`
Some(Output::Path(mut path)) if has_trailing_path_separator(&path) => {
let Input::Path(input) = &input else {
bail!(
"can't infer output file when input is from stdin\n\
consider providing a full path to write to, or get input from file",
);
};
let Some(file_name) = input.file_name() else {
panic!("input path must be non-empty, as guarded by the CLI");
};
path.push(file_name);
path.set_extension(match output_format {
OutputFormat::Pdf => "pdf", OutputFormat::Pdf => "pdf",
OutputFormat::Png => "png", OutputFormat::Png => "png",
OutputFormat::Svg => "svg", OutputFormat::Svg => "svg",
OutputFormat::Html => "html", OutputFormat::Html => "html",
},
))
}); });
Output::Path(path)
}
Some(output) => output,
};
let pages = args.pages.as_ref().map(|export_ranges| { let pages = args.pages.as_ref().map(|export_ranges| {
PageRanges::new(export_ranges.iter().map(|r| r.0.clone()).collect()) PageRanges::new(export_ranges.iter().map(|r| r.0.clone()).collect())
@ -162,6 +186,16 @@ impl CompileConfig {
} }
} }
fn has_trailing_path_separator(path: &Path) -> bool {
path.as_os_str()
.as_encoded_bytes()
.last()
.copied()
.map(Into::<char>::into)
.map(std::path::is_separator)
.unwrap_or(false)
}
/// Compile a single time. /// Compile a single time.
/// ///
/// Returns whether it compiled without errors. /// Returns whether it compiled without errors.