use anyhow::{bail, Context};
use clap::ValueEnum;
use oicana::Template;
use oicana_export::pdf::export_merged_pdf;
use oicana_export::png::export_merged_png;
use oicana_export::svg::export_merged_svg;
use oicana_files::native::NativeTemplate;
use oicana_template::PdfStandard;
use std::fs;
use std::path::Path;
use typst::layout::PagedDocument;
pub fn export_pdf(
document: &PagedDocument,
out: &Path,
world: &Template<NativeTemplate>,
cli_standards: Option<Vec<String>>,
) -> anyhow::Result<()> {
let standards = if let Some(cli_stds) = cli_standards {
parse_pdf_standards(&cli_stds)?
} else {
world.manifest().tool.oicana.export.pdf.standards.clone()
};
let pdf_buffer = match export_merged_pdf(document, world, &standards) {
Ok(pdf_buffer) => pdf_buffer,
Err(diagnostics) => {
bail!("Failed to compile PDF\n{diagnostics}");
}
};
fs::write(out, pdf_buffer).context("Failed to write PDF")?;
Ok(())
}
fn parse_pdf_standards(standards: &[String]) -> anyhow::Result<Vec<PdfStandard>> {
standards
.iter()
.map(|s| {
serde_json::from_value(serde_json::Value::String(s.clone()))
.with_context(|| format!("Invalid PDF standard: '{}'. Valid values: 1.4, 1.5, 1.6, 1.7, 2.0, a-1b, a-1a, a-2b, a-2u, a-2a, a-3b, a-3u, a-3a, a-4, a-4f, a-4e, ua-1", s))
})
.collect()
}
#[derive(Debug, Clone, ValueEnum)]
pub enum ExportFormat {
Pdf,
Png,
Svg,
}
impl ExportFormat {
pub(crate) fn file_ending(&self) -> &'static str {
match self {
ExportFormat::Pdf => "pdf",
ExportFormat::Png => "png",
ExportFormat::Svg => "svg",
}
}
}
pub enum ImageExportFormat {
Png,
Svg,
}
pub fn export_image(
document: &PagedDocument,
out: &Path,
fmt: ImageExportFormat,
) -> anyhow::Result<()> {
let buffer = match fmt {
ImageExportFormat::Png => export_merged_png(document, 1.)?,
ImageExportFormat::Svg => export_merged_svg(document),
};
fs::write(out, buffer).context("Failed to write image")?;
Ok(())
}