From 8075f551e269876339e6412730e7835029b70616 Mon Sep 17 00:00:00 2001 From: Tobias Schmitz Date: Mon, 23 Jun 2025 18:42:13 +0200 Subject: [PATCH] feat: use local krilla version --- Cargo.lock | 2 - Cargo.toml | 4 +- crates/typst-pdf/src/convert.rs | 10 +++++ crates/typst-pdf/src/tags.rs | 66 ++++++++++++++++----------------- 4 files changed, 44 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 550c4141a..0ad90fb38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1367,7 +1367,6 @@ dependencies = [ [[package]] name = "krilla" version = "0.4.0" -source = "git+https://github.com/LaurenzV/krilla?rev=20c14fe#20c14fefee5002566b3d6668b338bbe2168784e7" dependencies = [ "base64", "bumpalo", @@ -1395,7 +1394,6 @@ dependencies = [ [[package]] name = "krilla-svg" version = "0.1.0" -source = "git+https://github.com/LaurenzV/krilla?rev=20c14fe#20c14fefee5002566b3d6668b338bbe2168784e7" dependencies = [ "flate2", "fontdb", diff --git a/Cargo.toml b/Cargo.toml index 6cc59ee89..7029c389d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,8 +73,8 @@ image = { version = "0.25.5", default-features = false, features = ["png", "jpeg indexmap = { version = "2", features = ["serde"] } infer = { version = "0.19.0", default-features = false } kamadak-exif = "0.6" -krilla = { git = "https://github.com/LaurenzV/krilla", rev = "20c14fe", default-features = false, features = ["raster-images", "comemo", "rayon"] } -krilla-svg = { git = "https://github.com/LaurenzV/krilla", rev = "20c14fe" } +krilla = { path = "../krilla/crates/krilla", default-features = false, features = ["raster-images", "comemo", "rayon"] } +krilla-svg = { path = "../krilla/crates/krilla-svg" } kurbo = "0.11" libfuzzer-sys = "0.4" lipsum = "0.9" diff --git a/crates/typst-pdf/src/convert.rs b/crates/typst-pdf/src/convert.rs index abdb4c1dd..6f62cff58 100644 --- a/crates/typst-pdf/src/convert.rs +++ b/crates/typst-pdf/src/convert.rs @@ -588,6 +588,16 @@ fn convert_error( "{prefix} missing document date"; hint: "set the date of the document" ), + ValidationError::DuplicateTagId(_id, loc) => { + // TODO: display the id and better error message + let span = to_span(*loc); + error!(span, "{prefix} duplicate tag id") + } + ValidationError::UnknownHeaderTagId(_id, loc) => { + // TODO: display the id and better error message + let span = to_span(*loc); + error!(span, "{prefix} unknown header tag id") + } } } diff --git a/crates/typst-pdf/src/tags.rs b/crates/typst-pdf/src/tags.rs index 94219b1a1..e36c15ef0 100644 --- a/crates/typst-pdf/src/tags.rs +++ b/crates/typst-pdf/src/tags.rs @@ -4,7 +4,8 @@ use std::collections::HashMap; use krilla::page::Page; use krilla::surface::Surface; use krilla::tagging::{ - ArtifactType, ContentTag, Identifier, Node, Tag, TagGroup, TagTree, + ArtifactType, ContentTag, Identifier, Node, Tag, TagBuilder, TagGroup, TagKind, + TagTree, }; use typst_library::foundations::{Content, LinkMarker, StyleChain}; use typst_library::introspection::Location; @@ -100,25 +101,22 @@ impl Tags { } pub(crate) fn build_tree(&mut self) -> TagTree { - let mut tree = TagTree::new(); - let nodes = std::mem::take(&mut self.tree); - // PERF: collect into vec and construct TagTree directly from tag nodes. - for node in nodes.into_iter().map(|node| self.resolve_node(node)) { - tree.push(node); - } - tree + let children = std::mem::take(&mut self.tree) + .into_iter() + .map(|node| self.resolve_node(node)) + .collect::>(); + TagTree::from(children) } /// Resolves [`Placeholder`] nodes. fn resolve_node(&mut self, node: TagNode) -> Node { match node { TagNode::Group(tag, nodes) => { - let mut group = TagGroup::new(tag); - // PERF: collect into vec and construct TagTree directly from tag nodes. - for node in nodes.into_iter().map(|node| self.resolve_node(node)) { - group.push(node); - } - Node::Group(group) + let children = nodes + .into_iter() + .map(|node| self.resolve_node(node)) + .collect::>(); + Node::Group(TagGroup::with_children(tag, children)) } TagNode::Leaf(identifier) => Node::Leaf(identifier), TagNode::Placeholder(placeholder) => self.take_placeholder(placeholder), @@ -196,31 +194,31 @@ pub(crate) fn handle_start( let mut link_id = None; let mut wrappers = Vec::new(); - let tag = if let Some(pdf_tag) = elem.to_packed::() { + let tag: Tag = if let Some(pdf_tag) = elem.to_packed::() { let kind = pdf_tag.kind(StyleChain::default()); match kind { - PdfTagKind::Part => Tag::Part, + PdfTagKind::Part => TagKind::Part.into(), _ => todo!(), } } else if let Some(heading) = elem.to_packed::() { let level = heading.level(); let name = heading.body.plain_text().to_string(); match level.get() { - 1 => Tag::H1(Some(name)), - 2 => Tag::H2(Some(name)), - 3 => Tag::H3(Some(name)), - 4 => Tag::H4(Some(name)), - 5 => Tag::H5(Some(name)), + 1 => TagKind::H1(Some(name)).into(), + 2 => TagKind::H2(Some(name)).into(), + 3 => TagKind::H3(Some(name)).into(), + 4 => TagKind::H4(Some(name)).into(), + 5 => TagKind::H5(Some(name)).into(), // TODO: when targeting PDF 2.0 headings `> 6` are supported - _ => Tag::H6(Some(name)), + _ => TagKind::H6(Some(name)).into(), } } else if let Some(_) = elem.to_packed::() { - Tag::TOC + TagKind::TOC.into() } else if let Some(_) = elem.to_packed::() { - Tag::TOCI + TagKind::TOCI.into() } else if let Some(_) = elem.to_packed::() { let alt = None; // TODO - Tag::Figure(alt) + TagKind::Figure.with_alt_text(alt) } else if let Some(image) = elem.to_packed::() { let alt = image.alt(StyleChain::default()).map(|s| s.to_string()); @@ -228,26 +226,26 @@ pub(crate) fn handle_start( let id = surface.start_tagged(ContentTag::Other); let mut node = TagNode::Leaf(id); - if let Some(Tag::Figure(alt_text)) = gc.tags.parent().0 { - // HACK: set alt text of outer figure tag, if the contained image - // has alt text specified - if alt_text.is_none() { - *alt_text = alt; + if let Some(parent) = gc.tags.parent().0 { + if parent.kind == TagKind::Figure && parent.alt_text.is_none() { + // HACK: set alt text of outer figure tag, if the contained image + // has alt text specified + parent.alt_text = alt; } } else { - node = TagNode::Group(Tag::Figure(alt), vec![node]); + node = TagNode::Group(TagKind::Figure.with_alt_text(alt), vec![node]); } gc.tags.push(node); return; } else if let Some(_) = elem.to_packed::() { - Tag::Caption + TagKind::Caption.into() } else if let Some(link) = elem.to_packed::() { link_id = Some(gc.tags.next_link_id()); if let Destination::Position(_) | Destination::Location(_) = link.dest { - wrappers.push(Tag::Reference); + wrappers.push(TagKind::Reference.into()); } - Tag::Link + TagKind::Link.into() } else { return; };