From 733a2cda1535af1f11aea1f353dfad23bc3949d5 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 15 Jul 2025 10:44:58 +0200 Subject: [PATCH] Extract `LinkTarget::resolve` --- crates/typst-layout/src/rules.rs | 14 ++++---------- crates/typst-library/src/model/link.rs | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/crates/typst-layout/src/rules.rs b/crates/typst-layout/src/rules.rs index ebccd92e8..c78f94d55 100644 --- a/crates/typst-layout/src/rules.rs +++ b/crates/typst-layout/src/rules.rs @@ -20,8 +20,8 @@ use typst_library::math::EquationElem; use typst_library::model::{ Attribution, BibliographyElem, CiteElem, CiteGroup, CslSource, Destination, EmphElem, EnumElem, FigureCaption, FigureElem, FootnoteElem, FootnoteEntry, HeadingElem, - LinkElem, LinkTarget, ListElem, Outlinable, OutlineElem, OutlineEntry, ParElem, - ParbreakElem, QuoteElem, RefElem, StrongElem, TableCell, TableElem, TermsElem, Works, + LinkElem, ListElem, Outlinable, OutlineElem, OutlineEntry, ParElem, ParbreakElem, + QuoteElem, RefElem, StrongElem, TableCell, TableElem, TermsElem, Works, }; use typst_library::pdf::EmbedElem; use typst_library::text::{ @@ -216,14 +216,8 @@ const TERMS_RULE: ShowFn = |elem, _, styles| { const LINK_RULE: ShowFn = |elem, engine, _| { let body = elem.body.clone(); - Ok(match &elem.dest { - LinkTarget::Dest(dest) => body.linked(dest.clone()), - LinkTarget::Label(label) => { - let elem = engine.introspector.query_label(*label).at(elem.span())?; - let dest = Destination::Location(elem.location().unwrap()); - body.linked(dest) - } - }) + let dest = elem.dest.resolve(engine.introspector).at(elem.span())?; + Ok(body.linked(dest)) }; const HEADING_RULE: ShowFn = |elem, engine, styles| { diff --git a/crates/typst-library/src/model/link.rs b/crates/typst-library/src/model/link.rs index c630835e0..7b8483400 100644 --- a/crates/typst-library/src/model/link.rs +++ b/crates/typst-library/src/model/link.rs @@ -1,12 +1,13 @@ use std::ops::Deref; +use comemo::Tracked; use ecow::{eco_format, EcoString}; use crate::diag::{bail, StrResult}; use crate::foundations::{ cast, elem, Content, Label, Packed, Repr, ShowSet, Smart, StyleChain, Styles, }; -use crate::introspection::Location; +use crate::introspection::{Introspector, Locatable, Location}; use crate::layout::Position; use crate::text::TextElem; @@ -124,6 +125,19 @@ pub enum LinkTarget { Label(Label), } +impl LinkTarget { + /// Resolves the destination. + pub fn resolve(&self, introspector: Tracked) -> StrResult { + Ok(match self { + LinkTarget::Dest(dest) => dest.clone(), + LinkTarget::Label(label) => { + let elem = introspector.query_label(*label)?; + Destination::Location(elem.location().unwrap()) + } + }) + } +} + cast! { LinkTarget, self => match self {