mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Add format arg to CLI (#1985)
This commit is contained in:
parent
3fcb5ea73c
commit
ff5dc9191e
@ -46,6 +46,10 @@ pub struct CompileCommand {
|
|||||||
/// Path to output file (PDF, PNG, or SVG)
|
/// Path to output file (PDF, PNG, or SVG)
|
||||||
pub output: Option<PathBuf>,
|
pub output: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// The format of the output file, inferred from the extension by default
|
||||||
|
#[arg(long = "format", short = 'f')]
|
||||||
|
pub format: Option<OutputFormat>,
|
||||||
|
|
||||||
/// Opens the output file using the default viewer after compilation
|
/// Opens the output file using the default viewer after compilation
|
||||||
#[arg(long = "open")]
|
#[arg(long = "open")]
|
||||||
pub open: Option<Option<String>>,
|
pub open: Option<Option<String>>,
|
||||||
@ -59,15 +63,6 @@ pub struct CompileCommand {
|
|||||||
pub flamegraph: Option<Option<PathBuf>>,
|
pub flamegraph: Option<Option<PathBuf>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompileCommand {
|
|
||||||
/// The output path.
|
|
||||||
pub fn output(&self) -> PathBuf {
|
|
||||||
self.output
|
|
||||||
.clone()
|
|
||||||
.unwrap_or_else(|| self.common.input.with_extension("pdf"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Processes an input file to extract provided metadata
|
/// Processes an input file to extract provided metadata
|
||||||
#[derive(Debug, Clone, Parser)]
|
#[derive(Debug, Clone, Parser)]
|
||||||
pub struct QueryCommand {
|
pub struct QueryCommand {
|
||||||
@ -158,3 +153,20 @@ impl Display for DiagnosticFormat {
|
|||||||
.fmt(f)
|
.fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Which format to use for the generated output file.
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, ValueEnum)]
|
||||||
|
pub enum OutputFormat {
|
||||||
|
Pdf,
|
||||||
|
Png,
|
||||||
|
Svg,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for OutputFormat {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
self.to_possible_value()
|
||||||
|
.expect("no values are skipped")
|
||||||
|
.get_name()
|
||||||
|
.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||||
use codespan_reporting::term::{self, termcolor};
|
use codespan_reporting::term::{self, termcolor};
|
||||||
@ -11,7 +11,7 @@ use typst::geom::Color;
|
|||||||
use typst::syntax::{FileId, Source};
|
use typst::syntax::{FileId, Source};
|
||||||
use typst::World;
|
use typst::World;
|
||||||
|
|
||||||
use crate::args::{CompileCommand, DiagnosticFormat};
|
use crate::args::{CompileCommand, DiagnosticFormat, OutputFormat};
|
||||||
use crate::watch::Status;
|
use crate::watch::Status;
|
||||||
use crate::world::SystemWorld;
|
use crate::world::SystemWorld;
|
||||||
use crate::{color_stream, set_failed};
|
use crate::{color_stream, set_failed};
|
||||||
@ -19,6 +19,33 @@ use crate::{color_stream, set_failed};
|
|||||||
type CodespanResult<T> = Result<T, CodespanError>;
|
type CodespanResult<T> = Result<T, CodespanError>;
|
||||||
type CodespanError = codespan_reporting::files::Error;
|
type CodespanError = codespan_reporting::files::Error;
|
||||||
|
|
||||||
|
impl CompileCommand {
|
||||||
|
/// The output path.
|
||||||
|
pub fn output(&self) -> PathBuf {
|
||||||
|
self.output
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| self.common.input.with_extension("pdf"))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The format to use for generated output, either specified by the user or inferred from the extension.
|
||||||
|
///
|
||||||
|
/// Will return `Err` if the format was not specified and could not be inferred.
|
||||||
|
pub fn output_format(&self) -> StrResult<OutputFormat> {
|
||||||
|
Ok(if let Some(specified) = self.format {
|
||||||
|
specified
|
||||||
|
} else if let Some(output) = &self.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,
|
||||||
|
_ => bail!("could not infer output format for path {}.\nconsider providing the format manually with `--format/-f`", output.display()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
OutputFormat::Pdf
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Execute a compilation command.
|
/// Execute a compilation command.
|
||||||
pub fn compile(mut command: CompileCommand) -> StrResult<()> {
|
pub fn compile(mut command: CompileCommand) -> StrResult<()> {
|
||||||
let mut world = SystemWorld::new(&command.common)?;
|
let mut world = SystemWorld::new(&command.common)?;
|
||||||
@ -97,14 +124,10 @@ pub fn compile_once(
|
|||||||
|
|
||||||
/// Export into the target format.
|
/// Export into the target format.
|
||||||
fn export(document: &Document, command: &CompileCommand) -> StrResult<()> {
|
fn export(document: &Document, command: &CompileCommand) -> StrResult<()> {
|
||||||
match command.output().extension() {
|
match command.output_format()? {
|
||||||
Some(ext) if ext.eq_ignore_ascii_case("png") => {
|
OutputFormat::Png => export_image(document, command, ImageExportFormat::Png),
|
||||||
export_image(document, command, ImageExportFormat::Png)
|
OutputFormat::Svg => export_image(document, command, ImageExportFormat::Svg),
|
||||||
}
|
OutputFormat::Pdf => export_pdf(document, command),
|
||||||
Some(ext) if ext.eq_ignore_ascii_case("svg") => {
|
|
||||||
export_image(document, command, ImageExportFormat::Svg)
|
|
||||||
}
|
|
||||||
_ => export_pdf(document, command),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user