mirror of
https://github.com/typst/typst
synced 2025-06-08 13:16:24 +08:00
Add support for exporting to specific version
This commit is contained in:
parent
9a4bd9be25
commit
880aa4b8a1
@ -241,10 +241,14 @@ pub struct CompileArgs {
|
|||||||
#[arg(long = "pages", value_delimiter = ',')]
|
#[arg(long = "pages", value_delimiter = ',')]
|
||||||
pub pages: Option<Vec<Pages>>,
|
pub pages: Option<Vec<Pages>>,
|
||||||
|
|
||||||
/// One (or multiple comma-separated) PDF standards that Typst will enforce
|
/// The version of the produced PDF.
|
||||||
|
#[arg(long = "pdf-version")]
|
||||||
|
pub pdf_version: Option<PdfVersion>,
|
||||||
|
|
||||||
|
/// A PDF standard that Typst will enforce
|
||||||
/// conformance with.
|
/// conformance with.
|
||||||
#[arg(long = "pdf-standard", value_delimiter = ',')]
|
#[arg(long = "pdf-standard")]
|
||||||
pub pdf_standard: Vec<PdfStandard>,
|
pub pdf_standard: Option<PdfStandard>,
|
||||||
|
|
||||||
/// The PPI (pixels per inch) to use for PNG export.
|
/// The PPI (pixels per inch) to use for PNG export.
|
||||||
#[arg(long = "ppi", default_value_t = 144.0)]
|
#[arg(long = "ppi", default_value_t = 144.0)]
|
||||||
@ -463,16 +467,45 @@ pub enum Feature {
|
|||||||
|
|
||||||
display_possible_values!(Feature);
|
display_possible_values!(Feature);
|
||||||
|
|
||||||
|
/// A PDF version.
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, ValueEnum)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub enum PdfVersion {
|
||||||
|
/// PDF 1.4.
|
||||||
|
#[value(name = "1.4")]
|
||||||
|
V_1_4,
|
||||||
|
/// PDF 1.5.
|
||||||
|
#[value(name = "1.5")]
|
||||||
|
V_1_5,
|
||||||
|
/// PDF 1.5.
|
||||||
|
#[value(name = "1.6")]
|
||||||
|
V_1_6,
|
||||||
|
/// PDF 1.7.
|
||||||
|
#[value(name = "1.7")]
|
||||||
|
V_1_7,
|
||||||
|
}
|
||||||
|
|
||||||
|
display_possible_values!(PdfVersion);
|
||||||
|
|
||||||
/// A PDF standard that Typst can enforce conformance with.
|
/// A PDF standard that Typst can enforce conformance with.
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, ValueEnum)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, ValueEnum)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub enum PdfStandard {
|
pub enum PdfStandard {
|
||||||
/// PDF 1.7.
|
/// PDF/A-2u.
|
||||||
#[value(name = "1.7")]
|
#[value(name = "a-1b")]
|
||||||
V_1_7,
|
A_1b,
|
||||||
/// PDF/A-2b.
|
/// PDF/A-2b.
|
||||||
#[value(name = "a-2b")]
|
#[value(name = "a-2b")]
|
||||||
A_2b,
|
A_2b,
|
||||||
|
/// PDF/A-2u.
|
||||||
|
#[value(name = "a-2u")]
|
||||||
|
A_2u,
|
||||||
|
/// PDF/A-3u.
|
||||||
|
#[value(name = "a-3b")]
|
||||||
|
A_3b,
|
||||||
|
/// PDF/A-2b.
|
||||||
|
#[value(name = "a-3u")]
|
||||||
|
A_3u,
|
||||||
}
|
}
|
||||||
|
|
||||||
display_possible_values!(PdfStandard);
|
display_possible_values!(PdfStandard);
|
||||||
|
@ -17,11 +17,11 @@ use typst::html::HtmlDocument;
|
|||||||
use typst::layout::{Frame, Page, PageRanges, PagedDocument};
|
use typst::layout::{Frame, Page, PageRanges, PagedDocument};
|
||||||
use typst::syntax::{FileId, Source, Span};
|
use typst::syntax::{FileId, Source, Span};
|
||||||
use typst::WorldExt;
|
use typst::WorldExt;
|
||||||
use typst_pdf::{PdfOptions, PdfStandards};
|
use typst_pdf::{PdfOptions, PdfStandards, Validator};
|
||||||
|
|
||||||
use crate::args::{
|
use crate::args::{
|
||||||
CompileArgs, CompileCommand, DiagnosticFormat, Input, Output, OutputFormat,
|
CompileArgs, CompileCommand, DiagnosticFormat, Input, Output, OutputFormat,
|
||||||
PdfStandard, WatchCommand,
|
PdfStandard, PdfVersion, WatchCommand,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "http-server")]
|
#[cfg(feature = "http-server")]
|
||||||
use crate::server::HtmlServer;
|
use crate::server::HtmlServer;
|
||||||
@ -62,9 +62,10 @@ pub struct CompileConfig {
|
|||||||
/// Opens the output file with the default viewer or a specific program after
|
/// Opens the output file with the default viewer or a specific program after
|
||||||
/// compilation.
|
/// compilation.
|
||||||
pub open: Option<Option<String>>,
|
pub open: Option<Option<String>>,
|
||||||
/// One (or multiple comma-separated) PDF standards that Typst will enforce
|
/// The version that should be used to export the PDF.
|
||||||
/// conformance with.
|
pub pdf_version: Option<PdfVersion>,
|
||||||
pub pdf_standards: PdfStandards,
|
/// A standard the PDF should conform to.
|
||||||
|
pub pdf_standard: Option<PdfStandard>,
|
||||||
/// A path to write a Makefile rule describing the current compilation.
|
/// A path to write a Makefile rule describing the current compilation.
|
||||||
pub make_deps: Option<PathBuf>,
|
pub make_deps: Option<PathBuf>,
|
||||||
/// The PPI (pixels per inch) to use for PNG export.
|
/// The PPI (pixels per inch) to use for PNG export.
|
||||||
@ -129,18 +130,6 @@ impl CompileConfig {
|
|||||||
PageRanges::new(export_ranges.iter().map(|r| r.0.clone()).collect())
|
PageRanges::new(export_ranges.iter().map(|r| r.0.clone()).collect())
|
||||||
});
|
});
|
||||||
|
|
||||||
let pdf_standards = {
|
|
||||||
let list = args
|
|
||||||
.pdf_standard
|
|
||||||
.iter()
|
|
||||||
.map(|standard| match standard {
|
|
||||||
PdfStandard::V_1_7 => typst_pdf::PdfStandard::V_1_7,
|
|
||||||
PdfStandard::A_2b => typst_pdf::PdfStandard::A_2b,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
PdfStandards::new(&list)?
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "http-server")]
|
#[cfg(feature = "http-server")]
|
||||||
let server = match watch {
|
let server = match watch {
|
||||||
Some(command)
|
Some(command)
|
||||||
@ -157,15 +146,16 @@ impl CompileConfig {
|
|||||||
output,
|
output,
|
||||||
output_format,
|
output_format,
|
||||||
pages,
|
pages,
|
||||||
pdf_standards,
|
|
||||||
creation_timestamp: args.world.creation_timestamp,
|
creation_timestamp: args.world.creation_timestamp,
|
||||||
make_deps: args.make_deps.clone(),
|
make_deps: args.make_deps.clone(),
|
||||||
ppi: args.ppi,
|
ppi: args.ppi,
|
||||||
diagnostic_format: args.process.diagnostic_format,
|
diagnostic_format: args.process.diagnostic_format,
|
||||||
open: args.open.clone(),
|
open: args.open.clone(),
|
||||||
|
pdf_version: args.pdf_version,
|
||||||
export_cache: ExportCache::new(),
|
export_cache: ExportCache::new(),
|
||||||
#[cfg(feature = "http-server")]
|
#[cfg(feature = "http-server")]
|
||||||
server,
|
server,
|
||||||
|
pdf_standard: args.pdf_standard,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,7 +267,22 @@ fn export_pdf(document: &PagedDocument, config: &CompileConfig) -> SourceResult<
|
|||||||
config.creation_timestamp.unwrap_or_else(chrono::Utc::now),
|
config.creation_timestamp.unwrap_or_else(chrono::Utc::now),
|
||||||
),
|
),
|
||||||
page_ranges: config.pages.clone(),
|
page_ranges: config.pages.clone(),
|
||||||
standards: config.pdf_standards.clone(),
|
pdf_version: config.pdf_version.map(|v| match v {
|
||||||
|
PdfVersion::V_1_4 => typst_pdf::PdfVersion::Pdf14,
|
||||||
|
PdfVersion::V_1_5 => typst_pdf::PdfVersion::Pdf15,
|
||||||
|
PdfVersion::V_1_6 => typst_pdf::PdfVersion::Pdf16,
|
||||||
|
PdfVersion::V_1_7 => typst_pdf::PdfVersion::Pdf17,
|
||||||
|
}),
|
||||||
|
validator: config
|
||||||
|
.pdf_standard
|
||||||
|
.map(|s| match s {
|
||||||
|
PdfStandard::A_1b => Validator::A1_B,
|
||||||
|
PdfStandard::A_2b => Validator::A2_B,
|
||||||
|
PdfStandard::A_2u => Validator::A2_U,
|
||||||
|
PdfStandard::A_3b => Validator::A3_B,
|
||||||
|
PdfStandard::A_3u => Validator::A3_U,
|
||||||
|
})
|
||||||
|
.unwrap_or(Validator::None),
|
||||||
};
|
};
|
||||||
let buffer = typst_pdf::pdf(document, &options)?;
|
let buffer = typst_pdf::pdf(document, &options)?;
|
||||||
config
|
config
|
||||||
|
@ -4,11 +4,10 @@ use ecow::eco_format;
|
|||||||
use pdf_writer::types::Direction;
|
use pdf_writer::types::Direction;
|
||||||
use pdf_writer::writers::PageLabel;
|
use pdf_writer::writers::PageLabel;
|
||||||
use pdf_writer::{Finish, Name, Pdf, Ref, Str, TextStr};
|
use pdf_writer::{Finish, Name, Pdf, Ref, Str, TextStr};
|
||||||
use typst_library::diag::{bail, SourceResult};
|
use typst_library::diag::SourceResult;
|
||||||
use typst_library::foundations::{Datetime, Smart};
|
use typst_library::foundations::{Datetime, Smart};
|
||||||
use typst_library::layout::Dir;
|
use typst_library::layout::Dir;
|
||||||
use typst_library::text::Lang;
|
use typst_library::text::Lang;
|
||||||
use typst_syntax::Span;
|
|
||||||
use xmp_writer::{DateTime, LangId, RenditionClass, Timezone, XmpWriter};
|
use xmp_writer::{DateTime, LangId, RenditionClass, Timezone, XmpWriter};
|
||||||
|
|
||||||
use crate::page_old::PdfPageLabel;
|
use crate::page_old::PdfPageLabel;
|
||||||
@ -128,34 +127,34 @@ pub fn write_catalog(
|
|||||||
xmp.create_date(xmp_date);
|
xmp.create_date(xmp_date);
|
||||||
xmp.modify_date(xmp_date);
|
xmp.modify_date(xmp_date);
|
||||||
|
|
||||||
if ctx.options.standards.pdfa {
|
// if ctx.options.standards.pdfa {
|
||||||
let mut history = xmp.history();
|
// let mut history = xmp.history();
|
||||||
history
|
// history
|
||||||
.add_event()
|
// .add_event()
|
||||||
.action(xmp_writer::ResourceEventAction::Saved)
|
// .action(xmp_writer::ResourceEventAction::Saved)
|
||||||
.when(xmp_date)
|
// .when(xmp_date)
|
||||||
.instance_id(&eco_format!("{instance_id}_source"));
|
// .instance_id(&eco_format!("{instance_id}_source"));
|
||||||
history
|
// history
|
||||||
.add_event()
|
// .add_event()
|
||||||
.action(xmp_writer::ResourceEventAction::Converted)
|
// .action(xmp_writer::ResourceEventAction::Converted)
|
||||||
.when(xmp_date)
|
// .when(xmp_date)
|
||||||
.instance_id(&instance_id)
|
// .instance_id(&instance_id)
|
||||||
.software_agent(&creator);
|
// .software_agent(&creator);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert dominance.
|
// // Assert dominance.
|
||||||
if ctx.options.standards.pdfa {
|
// if ctx.options.standards.pdfa {
|
||||||
let mut extension_schemas = xmp.extension_schemas();
|
// let mut extension_schemas = xmp.extension_schemas();
|
||||||
extension_schemas
|
// extension_schemas
|
||||||
.xmp_media_management()
|
// .xmp_media_management()
|
||||||
.properties()
|
// .properties()
|
||||||
.describe_instance_id();
|
// .describe_instance_id();
|
||||||
extension_schemas.pdf().properties().describe_all();
|
// extension_schemas.pdf().properties().describe_all();
|
||||||
extension_schemas.finish();
|
// extension_schemas.finish();
|
||||||
xmp.pdfa_part(2);
|
// xmp.pdfa_part(2);
|
||||||
xmp.pdfa_conformance("B");
|
// xmp.pdfa_conformance("B");
|
||||||
}
|
// }
|
||||||
|
|
||||||
let xmp_buf = xmp.finish(None);
|
let xmp_buf = xmp.finish(None);
|
||||||
let meta_ref = alloc.bump();
|
let meta_ref = alloc.bump();
|
||||||
@ -200,22 +199,22 @@ pub fn write_catalog(
|
|||||||
catalog.lang(TextStr(lang.as_str()));
|
catalog.lang(TextStr(lang.as_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.options.standards.pdfa {
|
// if ctx.options.standards.pdfa {
|
||||||
catalog
|
// catalog
|
||||||
.output_intents()
|
// .output_intents()
|
||||||
.push()
|
// .push()
|
||||||
.subtype(pdf_writer::types::OutputIntentSubtype::PDFA)
|
// .subtype(pdf_writer::types::OutputIntentSubtype::PDFA)
|
||||||
.output_condition(TextStr("sRGB"))
|
// .output_condition(TextStr("sRGB"))
|
||||||
.output_condition_identifier(TextStr("Custom"))
|
// .output_condition_identifier(TextStr("Custom"))
|
||||||
.info(TextStr("sRGB IEC61966-2.1"))
|
// .info(TextStr("sRGB IEC61966-2.1"))
|
||||||
.dest_output_profile(ctx.globals.color_functions.srgb.unwrap());
|
// .dest_output_profile(ctx.globals.color_functions.srgb.unwrap());
|
||||||
}
|
// }
|
||||||
|
|
||||||
catalog.finish();
|
catalog.finish();
|
||||||
|
|
||||||
if ctx.options.standards.pdfa && pdf.refs().count() > 8388607 {
|
// if ctx.options.standards.pdfa && pdf.refs().count() > 8388607 {
|
||||||
bail!(Span::detached(), "too many PDF objects");
|
// bail!(Span::detached(), "too many PDF objects");
|
||||||
}
|
// }
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -244,9 +244,9 @@ impl ColorFontMap<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (frame, tofu) = glyph_frame(font, glyph.id);
|
let (frame, tofu) = glyph_frame(font, glyph.id);
|
||||||
if options.standards.pdfa && tofu {
|
// if options.standards.pdfa && tofu {
|
||||||
bail!(failed_to_convert(text, glyph));
|
// bail!(failed_to_convert(text, glyph));
|
||||||
}
|
// }
|
||||||
|
|
||||||
let width = font.advance(glyph.id).unwrap_or(Em::new(0.0)).get()
|
let width = font.advance(glyph.id).unwrap_or(Em::new(0.0)).get()
|
||||||
* font.units_per_em();
|
* font.units_per_em();
|
||||||
|
@ -149,9 +149,9 @@ pub fn alloc_color_functions_refs(
|
|||||||
let mut chunk = PdfChunk::new();
|
let mut chunk = PdfChunk::new();
|
||||||
let mut used_color_spaces = ColorSpaces::default();
|
let mut used_color_spaces = ColorSpaces::default();
|
||||||
|
|
||||||
if context.options.standards.pdfa {
|
// if context.options.standards.pdfa {
|
||||||
used_color_spaces.mark_as_used(ColorSpace::Srgb);
|
// used_color_spaces.mark_as_used(ColorSpace::Srgb);
|
||||||
}
|
// }
|
||||||
|
|
||||||
context.resources.traverse(&mut |r| {
|
context.resources.traverse(&mut |r| {
|
||||||
used_color_spaces.merge(&r.colors);
|
used_color_spaces.merge(&r.colors);
|
||||||
@ -384,11 +384,11 @@ impl QuantizedColor for f32 {
|
|||||||
|
|
||||||
/// Fails with an error if PDF/A processing is enabled.
|
/// Fails with an error if PDF/A processing is enabled.
|
||||||
pub(super) fn check_cmyk_allowed(options: &PdfOptions) -> SourceResult<()> {
|
pub(super) fn check_cmyk_allowed(options: &PdfOptions) -> SourceResult<()> {
|
||||||
if options.standards.pdfa {
|
// if options.standards.pdfa {
|
||||||
bail!(
|
// bail!(
|
||||||
Span::detached(),
|
// Span::detached(),
|
||||||
"cmyk colors are not currently supported by PDF/A export"
|
// "cmyk colors are not currently supported by PDF/A export"
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -418,13 +418,13 @@ fn write_group(ctx: &mut Builder, pos: Point, group: &GroupItem) -> SourceResult
|
|||||||
|
|
||||||
/// Encode a text run into the content stream.
|
/// Encode a text run into the content stream.
|
||||||
fn write_text(ctx: &mut Builder, pos: Point, text: &TextItem) -> SourceResult<()> {
|
fn write_text(ctx: &mut Builder, pos: Point, text: &TextItem) -> SourceResult<()> {
|
||||||
if ctx.options.standards.pdfa && text.font.info().is_last_resort() {
|
// if ctx.options.standards.pdfa && text.font.info().is_last_resort() {
|
||||||
bail!(
|
// bail!(
|
||||||
Span::find(text.glyphs.iter().map(|g| g.span.0)),
|
// Span::find(text.glyphs.iter().map(|g| g.span.0)),
|
||||||
"the text {} could not be displayed with any font",
|
// "the text {} could not be displayed with any font",
|
||||||
&text.text,
|
// &text.text,
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
let outline_glyphs =
|
let outline_glyphs =
|
||||||
text.glyphs.iter().filter(|g| should_outline(&text.font, g)).count();
|
text.glyphs.iter().filter(|g| should_outline(&text.font, g)).count();
|
||||||
@ -516,9 +516,9 @@ fn write_normal_text(
|
|||||||
|
|
||||||
// Write the glyphs with kerning adjustments.
|
// Write the glyphs with kerning adjustments.
|
||||||
for glyph in text.glyphs() {
|
for glyph in text.glyphs() {
|
||||||
if ctx.options.standards.pdfa && glyph.id == 0 {
|
// if ctx.options.standards.pdfa && glyph.id == 0 {
|
||||||
bail!(tofu(&text, glyph));
|
// bail!(tofu(&text, glyph));
|
||||||
}
|
// }
|
||||||
|
|
||||||
adjustment += glyph.x_offset;
|
adjustment += glyph.x_offset;
|
||||||
|
|
||||||
@ -607,9 +607,9 @@ fn write_complex_glyphs(
|
|||||||
.or_default();
|
.or_default();
|
||||||
|
|
||||||
for glyph in text.glyphs() {
|
for glyph in text.glyphs() {
|
||||||
if ctx.options.standards.pdfa && glyph.id == 0 {
|
// if ctx.options.standards.pdfa && glyph.id == 0 {
|
||||||
bail!(tofu(&text, glyph));
|
// bail!(tofu(&text, glyph));
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Retrieve the Type3 font reference and the glyph index in the font.
|
// Retrieve the Type3 font reference and the glyph index in the font.
|
||||||
let color_fonts = ctx
|
let color_fonts = ctx
|
||||||
@ -732,8 +732,7 @@ fn write_image(
|
|||||||
) -> SourceResult<()> {
|
) -> SourceResult<()> {
|
||||||
let index = ctx.resources.images.insert(image.clone());
|
let index = ctx.resources.images.insert(image.clone());
|
||||||
ctx.resources.deferred_images.entry(index).or_insert_with(|| {
|
ctx.resources.deferred_images.entry(index).or_insert_with(|| {
|
||||||
let (image, color_space) =
|
let (image, color_space) = deferred_image(image.clone(), false);
|
||||||
deferred_image(image.clone(), ctx.options.standards.pdfa);
|
|
||||||
if let Some(color_space) = color_space {
|
if let Some(color_space) = color_space {
|
||||||
ctx.resources.colors.mark_as_used(color_space);
|
ctx.resources.colors.mark_as_used(color_space);
|
||||||
}
|
}
|
||||||
@ -749,9 +748,9 @@ fn write_image(
|
|||||||
ctx.content.transform([w, 0.0, 0.0, -h, x, y + h]);
|
ctx.content.transform([w, 0.0, 0.0, -h, x, y + h]);
|
||||||
|
|
||||||
if let Some(alt) = image.alt() {
|
if let Some(alt) = image.alt() {
|
||||||
if ctx.options.standards.pdfa && alt.len() > Str::PDFA_LIMIT {
|
// if ctx.options.standards.pdfa && alt.len() > Str::PDFA_LIMIT {
|
||||||
bail!(span, "the image's alt text is too long");
|
// bail!(span, "the image's alt text is too long");
|
||||||
}
|
// }
|
||||||
|
|
||||||
let mut image_span =
|
let mut image_span =
|
||||||
ctx.content.begin_marked_content_with_properties(Name(b"Span"));
|
ctx.content.begin_marked_content_with_properties(Name(b"Span"));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::primitive::{PointExt, SizeExt, TransformExt};
|
use crate::primitive::{PointExt, SizeExt, TransformExt};
|
||||||
use crate::{paint, AbsExt, PdfOptions};
|
use crate::{paint, AbsExt, PdfOptions};
|
||||||
use bytemuck::TransparentWrapper;
|
use bytemuck::TransparentWrapper;
|
||||||
use ecow::EcoString;
|
use ecow::{eco_format, EcoString};
|
||||||
use krilla::action::{Action, LinkAction};
|
use krilla::action::{Action, LinkAction};
|
||||||
use krilla::annotation::{LinkAnnotation, Target};
|
use krilla::annotation::{LinkAnnotation, Target};
|
||||||
use krilla::destination::XyzDestination;
|
use krilla::destination::XyzDestination;
|
||||||
@ -178,15 +178,32 @@ pub fn pdf(
|
|||||||
typst_document: &PagedDocument,
|
typst_document: &PagedDocument,
|
||||||
options: &PdfOptions,
|
options: &PdfOptions,
|
||||||
) -> SourceResult<Vec<u8>> {
|
) -> SourceResult<Vec<u8>> {
|
||||||
|
let version = match options.pdf_version {
|
||||||
|
None => options.validator.recommended_version(),
|
||||||
|
Some(v) => {
|
||||||
|
if !options.validator.compatible_with_version(v) {
|
||||||
|
let v_string = v.as_str();
|
||||||
|
let s_string = options.validator.as_str();
|
||||||
|
let h_message = format!(
|
||||||
|
"export using {} instead",
|
||||||
|
options.validator.recommended_version().as_str()
|
||||||
|
);
|
||||||
|
bail!(Span::detached(), "{v_string} is not compatible with standard {s_string}"; hint: "{h_message}");
|
||||||
|
} else {
|
||||||
|
v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let settings = SerializeSettings {
|
let settings = SerializeSettings {
|
||||||
compress_content_streams: true,
|
compress_content_streams: true,
|
||||||
no_device_cs: true,
|
no_device_cs: true,
|
||||||
ascii_compatible: false,
|
ascii_compatible: false,
|
||||||
xmp_metadata: true,
|
xmp_metadata: true,
|
||||||
cmyk_profile: None,
|
cmyk_profile: None,
|
||||||
validator: Validator::None,
|
validator: options.validator,
|
||||||
enable_tagging: false,
|
enable_tagging: false,
|
||||||
pdf_version: PdfVersion::Pdf17,
|
pdf_version: version,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut document = krilla::Document::new_with(settings);
|
let mut document = krilla::Document::new_with(settings);
|
||||||
|
@ -18,14 +18,13 @@ mod pattern_old;
|
|||||||
mod primitive;
|
mod primitive;
|
||||||
mod resources_old;
|
mod resources_old;
|
||||||
|
|
||||||
|
use base64::Engine;
|
||||||
|
use pdf_writer::{Chunk, Name, Pdf, Ref, Str, TextStr};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::{self, Debug, Formatter};
|
use std::fmt::{self, Debug, Formatter};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use base64::Engine;
|
|
||||||
use pdf_writer::{Chunk, Name, Pdf, Ref, Str, TextStr};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use typst_library::diag::{bail, SourceResult, StrResult};
|
use typst_library::diag::{bail, SourceResult, StrResult};
|
||||||
use typst_library::foundations::{Datetime, Smart};
|
use typst_library::foundations::{Datetime, Smart};
|
||||||
use typst_library::layout::{Abs, Em, PageRanges, PagedDocument, Transform};
|
use typst_library::layout::{Abs, Em, PageRanges, PagedDocument, Transform};
|
||||||
@ -79,6 +78,9 @@ pub fn pdf(document: &PagedDocument, options: &PdfOptions) -> SourceResult<Vec<u
|
|||||||
// .export_with(write_catalog)
|
// .export_with(write_catalog)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use ::krilla::validation::Validator;
|
||||||
|
pub use ::krilla::version::PdfVersion;
|
||||||
|
|
||||||
/// Settings for PDF export.
|
/// Settings for PDF export.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct PdfOptions<'a> {
|
pub struct PdfOptions<'a> {
|
||||||
@ -100,8 +102,10 @@ pub struct PdfOptions<'a> {
|
|||||||
/// Specifies which ranges of pages should be exported in the PDF. When
|
/// Specifies which ranges of pages should be exported in the PDF. When
|
||||||
/// `None`, all pages should be exported.
|
/// `None`, all pages should be exported.
|
||||||
pub page_ranges: Option<PageRanges>,
|
pub page_ranges: Option<PageRanges>,
|
||||||
/// A list of PDF standards that Typst will enforce conformance with.
|
/// The version that should be used to export the PDF.
|
||||||
pub standards: PdfStandards,
|
pub pdf_version: Option<PdfVersion>,
|
||||||
|
/// A standard the PDF should conform to.
|
||||||
|
pub validator: Validator,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encapsulates a list of compatible PDF standards.
|
/// Encapsulates a list of compatible PDF standards.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user