mirror of
https://github.com/typst/typst
synced 2025-08-04 02:07:56 +08:00
refactor: add convenience methods to access settable properties
This commit is contained in:
parent
7ca8468b16
commit
95e0e76e9d
@ -13,10 +13,7 @@ use krilla::tagging::{
|
|||||||
TagGroup, TagKind, TagTree,
|
TagGroup, TagKind, TagTree,
|
||||||
};
|
};
|
||||||
use typst_library::diag::{SourceResult, bail};
|
use typst_library::diag::{SourceResult, bail};
|
||||||
use typst_library::foundations::{
|
use typst_library::foundations::{Content, LinkMarker, Packed};
|
||||||
Content, LinkMarker, NativeElement, Packed, RefableProperty, Settable,
|
|
||||||
SettableProperty, StyleChain,
|
|
||||||
};
|
|
||||||
use typst_library::introspection::Location;
|
use typst_library::introspection::Location;
|
||||||
use typst_library::layout::{Abs, Point, Rect, RepeatElem};
|
use typst_library::layout::{Abs, Point, Rect, RepeatElem};
|
||||||
use typst_library::math::EquationElem;
|
use typst_library::math::EquationElem;
|
||||||
@ -34,11 +31,13 @@ use crate::link::LinkAnnotation;
|
|||||||
use crate::tags::list::ListCtx;
|
use crate::tags::list::ListCtx;
|
||||||
use crate::tags::outline::OutlineCtx;
|
use crate::tags::outline::OutlineCtx;
|
||||||
use crate::tags::table::TableCtx;
|
use crate::tags::table::TableCtx;
|
||||||
|
use crate::tags::util::{PropertyOptRef, PropertyValCopied};
|
||||||
use crate::util::AbsExt;
|
use crate::util::AbsExt;
|
||||||
|
|
||||||
mod list;
|
mod list;
|
||||||
mod outline;
|
mod outline;
|
||||||
mod table;
|
mod table;
|
||||||
|
mod util;
|
||||||
|
|
||||||
pub(crate) fn handle_start(
|
pub(crate) fn handle_start(
|
||||||
gc: &mut GlobalContext,
|
gc: &mut GlobalContext,
|
||||||
@ -55,7 +54,7 @@ pub(crate) fn handle_start(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(artifact) = elem.to_packed::<ArtifactElem>() {
|
if let Some(artifact) = elem.to_packed::<ArtifactElem>() {
|
||||||
let kind = artifact.kind.get(StyleChain::default());
|
let kind = artifact.kind.val();
|
||||||
push_artifact(gc, surface, elem, kind);
|
push_artifact(gc, surface, elem, kind);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if let Some(_) = elem.to_packed::<RepeatElem>() {
|
} else if let Some(_) = elem.to_packed::<RepeatElem>() {
|
||||||
@ -121,7 +120,7 @@ pub(crate) fn handle_start(
|
|||||||
} else if let Some(_) = elem.to_packed::<FigureCaption>() {
|
} else if let Some(_) = elem.to_packed::<FigureCaption>() {
|
||||||
Tag::Caption.into()
|
Tag::Caption.into()
|
||||||
} else if let Some(image) = elem.to_packed::<ImageElem>() {
|
} else if let Some(image) = elem.to_packed::<ImageElem>() {
|
||||||
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() {
|
if let Some(figure_ctx) = gc.tags.stack.parent_figure() {
|
||||||
// Set alt text of outer figure tag, if not present.
|
// Set alt text of outer figure tag, if not present.
|
||||||
@ -134,12 +133,12 @@ pub(crate) fn handle_start(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
} else if let Some(equation) = elem.to_packed::<EquationElem>() {
|
} else if let Some(equation) = elem.to_packed::<EquationElem>() {
|
||||||
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)))?;
|
push_stack(gc, elem, StackEntryKind::Formula(FigureCtx::new(alt)))?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if let Some(table) = elem.to_packed::<TableElem>() {
|
} else if let Some(table) = elem.to_packed::<TableElem>() {
|
||||||
let table_id = gc.tags.next_table_id();
|
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);
|
let ctx = TableCtx::new(table_id, summary);
|
||||||
push_stack(gc, elem, StackEntryKind::Table(ctx))?;
|
push_stack(gc, elem, StackEntryKind::Table(ctx))?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -177,11 +176,7 @@ pub(crate) fn handle_start(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
} else if let Some(quote) = elem.to_packed::<QuoteElem>() {
|
} else if let Some(quote) = elem.to_packed::<QuoteElem>() {
|
||||||
// TODO: should the attribution be handled somehow?
|
// TODO: should the attribution be handled somehow?
|
||||||
if quote.block.get(StyleChain::default()) {
|
if quote.block.val() { Tag::BlockQuote.into() } else { Tag::InlineQuote.into() }
|
||||||
Tag::BlockQuote.into()
|
|
||||||
} else {
|
|
||||||
Tag::InlineQuote.into()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
@ -1047,18 +1042,3 @@ fn artifact_type(kind: ArtifactKind) -> ArtifactType {
|
|||||||
ArtifactKind::Other => ArtifactType::Other,
|
ArtifactKind::Other => ArtifactType::Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PropertyGetAsRef<E, T, const I: u8> {
|
|
||||||
fn get_as_ref(&self) -> Option<&T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E, T, const I: u8> PropertyGetAsRef<E, T, I> for Settable<E, I>
|
|
||||||
where
|
|
||||||
E: NativeElement,
|
|
||||||
E: SettableProperty<I, Type = Option<T>>,
|
|
||||||
E: RefableProperty<I>,
|
|
||||||
{
|
|
||||||
fn get_as_ref(&self) -> Option<&T> {
|
|
||||||
self.get_ref(StyleChain::default()).as_ref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -4,11 +4,12 @@ use std::num::NonZeroU32;
|
|||||||
use az::SaturatingAs;
|
use az::SaturatingAs;
|
||||||
use krilla::tagging::{Tag, TagId, TagKind};
|
use krilla::tagging::{Tag, TagId, TagKind};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use typst_library::foundations::{Packed, Smart, StyleChain};
|
use typst_library::foundations::{Packed, Smart};
|
||||||
use typst_library::model::TableCell;
|
use typst_library::model::TableCell;
|
||||||
use typst_library::pdf::{TableCellKind, TableHeaderScope};
|
use typst_library::pdf::{TableCellKind, TableHeaderScope};
|
||||||
use typst_syntax::Span;
|
use typst_syntax::Span;
|
||||||
|
|
||||||
|
use crate::tags::util::PropertyValCopied;
|
||||||
use crate::tags::{BBoxCtx, TableId, TagNode};
|
use crate::tags::{BBoxCtx, TableId, TagNode};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -50,8 +51,8 @@ impl TableCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn contains(&self, cell: &Packed<TableCell>) -> bool {
|
pub(crate) fn contains(&self, cell: &Packed<TableCell>) -> bool {
|
||||||
let x = cell.x.get(StyleChain::default()).unwrap_or_else(|| unreachable!());
|
let x = cell.x.val().unwrap_or_else(|| unreachable!());
|
||||||
let y = cell.y.get(StyleChain::default()).unwrap_or_else(|| unreachable!());
|
let y = cell.y.val().unwrap_or_else(|| unreachable!());
|
||||||
self.get(x, y).is_some()
|
self.get(x, y).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,11 +65,11 @@ impl TableCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn insert(&mut self, cell: &Packed<TableCell>, nodes: Vec<TagNode>) {
|
pub(crate) fn insert(&mut self, cell: &Packed<TableCell>, nodes: Vec<TagNode>) {
|
||||||
let x = cell.x.get(StyleChain::default()).unwrap_or_else(|| unreachable!());
|
let x = cell.x.val().unwrap_or_else(|| unreachable!());
|
||||||
let y = cell.y.get(StyleChain::default()).unwrap_or_else(|| unreachable!());
|
let y = cell.y.val().unwrap_or_else(|| unreachable!());
|
||||||
let rowspan = cell.rowspan.get(StyleChain::default());
|
let rowspan = cell.rowspan.val();
|
||||||
let colspan = cell.colspan.get(StyleChain::default());
|
let colspan = cell.colspan.val();
|
||||||
let kind = cell.kind.get(StyleChain::default());
|
let kind = cell.kind.val();
|
||||||
|
|
||||||
// Extend the table grid to fit this cell.
|
// Extend the table grid to fit this cell.
|
||||||
let required_height = y + rowspan.get();
|
let required_height = y + rowspan.get();
|
||||||
|
71
crates/typst-pdf/src/tags/util.rs
Normal file
71
crates/typst-pdf/src/tags/util.rs
Normal file
@ -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<E, T, const I: u8> {
|
||||||
|
/// Get the copied value.
|
||||||
|
fn val(&self) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, T: Copy, const I: u8> PropertyValCopied<E, T, I> for Settable<E, I>
|
||||||
|
where
|
||||||
|
E: NativeElement,
|
||||||
|
E: SettableProperty<I, Type = T>,
|
||||||
|
{
|
||||||
|
fn val(&self) -> T {
|
||||||
|
self.get(StyleChain::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PropertyValCloned<E, T, const I: u8> {
|
||||||
|
/// Get the cloned value.
|
||||||
|
fn val_cloned(&self) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, T: Clone, const I: u8> PropertyValCloned<E, T, I> for Settable<E, I>
|
||||||
|
where
|
||||||
|
E: NativeElement,
|
||||||
|
E: SettableProperty<I, Type = T>,
|
||||||
|
{
|
||||||
|
fn val_cloned(&self) -> T {
|
||||||
|
self.get_cloned(StyleChain::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PropertyValRef<E, T, const I: u8> {
|
||||||
|
/// Get a reference to the value.
|
||||||
|
fn val_ref(&self) -> &T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, T, const I: u8> PropertyValRef<E, T, I> for Settable<E, I>
|
||||||
|
where
|
||||||
|
E: NativeElement,
|
||||||
|
E: SettableProperty<I, Type = T>,
|
||||||
|
E: RefableProperty<I>,
|
||||||
|
{
|
||||||
|
fn val_ref(&self) -> &T {
|
||||||
|
self.get_ref(StyleChain::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PropertyOptRef<E, T, const I: u8> {
|
||||||
|
fn opt_ref(&self) -> Option<&T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, T, const I: u8> PropertyOptRef<E, T, I> for Settable<E, I>
|
||||||
|
where
|
||||||
|
E: NativeElement,
|
||||||
|
E: SettableProperty<I, Type = Option<T>>,
|
||||||
|
E: RefableProperty<I>,
|
||||||
|
{
|
||||||
|
/// Get an `Option` with a reference to the contained value.
|
||||||
|
fn opt_ref(&self) -> Option<&T> {
|
||||||
|
self.get_ref(StyleChain::default()).as_ref()
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user