diff --git a/crates/typst-pdf/src/tags/mod.rs b/crates/typst-pdf/src/tags/mod.rs index fc98bc23d..d19307054 100644 --- a/crates/typst-pdf/src/tags/mod.rs +++ b/crates/typst-pdf/src/tags/mod.rs @@ -13,10 +13,7 @@ use krilla::tagging::{ TagGroup, TagKind, TagTree, }; use typst_library::diag::{SourceResult, bail}; -use typst_library::foundations::{ - Content, LinkMarker, NativeElement, Packed, RefableProperty, Settable, - SettableProperty, StyleChain, -}; +use typst_library::foundations::{Content, LinkMarker, Packed}; use typst_library::introspection::Location; use typst_library::layout::{Abs, Point, Rect, RepeatElem}; use typst_library::math::EquationElem; @@ -34,11 +31,13 @@ use crate::link::LinkAnnotation; use crate::tags::list::ListCtx; use crate::tags::outline::OutlineCtx; use crate::tags::table::TableCtx; +use crate::tags::util::{PropertyOptRef, PropertyValCopied}; use crate::util::AbsExt; mod list; mod outline; mod table; +mod util; pub(crate) fn handle_start( gc: &mut GlobalContext, @@ -55,7 +54,7 @@ pub(crate) fn handle_start( } if let Some(artifact) = elem.to_packed::() { - let kind = artifact.kind.get(StyleChain::default()); + let kind = artifact.kind.val(); push_artifact(gc, surface, elem, kind); return Ok(()); } else if let Some(_) = elem.to_packed::() { @@ -121,7 +120,7 @@ pub(crate) fn handle_start( } else if let Some(_) = elem.to_packed::() { Tag::Caption.into() } else if let Some(image) = elem.to_packed::() { - let alt = image.alt.get_as_ref().map(|s| s.to_string()); + let alt = image.alt.opt_ref().map(|s| s.to_string()); if let Some(figure_ctx) = gc.tags.stack.parent_figure() { // Set alt text of outer figure tag, if not present. @@ -134,12 +133,12 @@ pub(crate) fn handle_start( return Ok(()); } } else if let Some(equation) = elem.to_packed::() { - let alt = equation.alt.get_as_ref().map(|s| s.to_string()); + let alt = equation.alt.opt_ref().map(|s| s.to_string()); push_stack(gc, elem, StackEntryKind::Formula(FigureCtx::new(alt)))?; return Ok(()); } else if let Some(table) = elem.to_packed::() { let table_id = gc.tags.next_table_id(); - let summary = table.summary.get_as_ref().map(|s| s.to_string()); + let summary = table.summary.opt_ref().map(|s| s.to_string()); let ctx = TableCtx::new(table_id, summary); push_stack(gc, elem, StackEntryKind::Table(ctx))?; return Ok(()); @@ -177,11 +176,7 @@ pub(crate) fn handle_start( return Ok(()); } else if let Some(quote) = elem.to_packed::() { // TODO: should the attribution be handled somehow? - if quote.block.get(StyleChain::default()) { - Tag::BlockQuote.into() - } else { - Tag::InlineQuote.into() - } + if quote.block.val() { Tag::BlockQuote.into() } else { Tag::InlineQuote.into() } } else { return Ok(()); }; @@ -1047,18 +1042,3 @@ fn artifact_type(kind: ArtifactKind) -> ArtifactType { ArtifactKind::Other => ArtifactType::Other, } } - -trait PropertyGetAsRef { - fn get_as_ref(&self) -> Option<&T>; -} - -impl PropertyGetAsRef for Settable -where - E: NativeElement, - E: SettableProperty>, - E: RefableProperty, -{ - fn get_as_ref(&self) -> Option<&T> { - self.get_ref(StyleChain::default()).as_ref() - } -} diff --git a/crates/typst-pdf/src/tags/table.rs b/crates/typst-pdf/src/tags/table.rs index fc90eb4dc..dbc52f990 100644 --- a/crates/typst-pdf/src/tags/table.rs +++ b/crates/typst-pdf/src/tags/table.rs @@ -4,11 +4,12 @@ use std::num::NonZeroU32; use az::SaturatingAs; use krilla::tagging::{Tag, TagId, TagKind}; use smallvec::SmallVec; -use typst_library::foundations::{Packed, Smart, StyleChain}; +use typst_library::foundations::{Packed, Smart}; use typst_library::model::TableCell; use typst_library::pdf::{TableCellKind, TableHeaderScope}; use typst_syntax::Span; +use crate::tags::util::PropertyValCopied; use crate::tags::{BBoxCtx, TableId, TagNode}; #[derive(Clone, Debug)] @@ -50,8 +51,8 @@ impl TableCtx { } pub(crate) fn contains(&self, cell: &Packed) -> bool { - let x = cell.x.get(StyleChain::default()).unwrap_or_else(|| unreachable!()); - let y = cell.y.get(StyleChain::default()).unwrap_or_else(|| unreachable!()); + let x = cell.x.val().unwrap_or_else(|| unreachable!()); + let y = cell.y.val().unwrap_or_else(|| unreachable!()); self.get(x, y).is_some() } @@ -64,11 +65,11 @@ impl TableCtx { } pub(crate) fn insert(&mut self, cell: &Packed, nodes: Vec) { - let x = cell.x.get(StyleChain::default()).unwrap_or_else(|| unreachable!()); - let y = cell.y.get(StyleChain::default()).unwrap_or_else(|| unreachable!()); - let rowspan = cell.rowspan.get(StyleChain::default()); - let colspan = cell.colspan.get(StyleChain::default()); - let kind = cell.kind.get(StyleChain::default()); + let x = cell.x.val().unwrap_or_else(|| unreachable!()); + let y = cell.y.val().unwrap_or_else(|| unreachable!()); + let rowspan = cell.rowspan.val(); + let colspan = cell.colspan.val(); + let kind = cell.kind.val(); // Extend the table grid to fit this cell. let required_height = y + rowspan.get(); diff --git a/crates/typst-pdf/src/tags/util.rs b/crates/typst-pdf/src/tags/util.rs new file mode 100644 index 000000000..16489939b --- /dev/null +++ b/crates/typst-pdf/src/tags/util.rs @@ -0,0 +1,71 @@ +//! Convenience method to retrieve a property value by passind the default +//! stylechain. +//! Since in the PDF export all elements are materialized, meaning all of their +//! fields have been copied from the stylechain, there is no point in providing +//! any other stylechain. + +use typst_library::foundations::{ + NativeElement, RefableProperty, Settable, SettableProperty, StyleChain, +}; + +pub trait PropertyValCopied { + /// Get the copied value. + fn val(&self) -> T; +} + +impl PropertyValCopied for Settable +where + E: NativeElement, + E: SettableProperty, +{ + fn val(&self) -> T { + self.get(StyleChain::default()) + } +} + +pub trait PropertyValCloned { + /// Get the cloned value. + fn val_cloned(&self) -> T; +} + +impl PropertyValCloned for Settable +where + E: NativeElement, + E: SettableProperty, +{ + fn val_cloned(&self) -> T { + self.get_cloned(StyleChain::default()) + } +} + +pub trait PropertyValRef { + /// Get a reference to the value. + fn val_ref(&self) -> &T; +} + +impl PropertyValRef for Settable +where + E: NativeElement, + E: SettableProperty, + E: RefableProperty, +{ + fn val_ref(&self) -> &T { + self.get_ref(StyleChain::default()) + } +} + +pub trait PropertyOptRef { + fn opt_ref(&self) -> Option<&T>; +} + +impl PropertyOptRef for Settable +where + E: NativeElement, + E: SettableProperty>, + E: RefableProperty, +{ + /// Get an `Option` with a reference to the contained value. + fn opt_ref(&self) -> Option<&T> { + self.get_ref(StyleChain::default()).as_ref() + } +}