Extract LinkTarget::resolve

This commit is contained in:
Laurenz 2025-07-15 10:44:58 +02:00
parent 12c66e36b5
commit 733a2cda15
2 changed files with 19 additions and 11 deletions

View File

@ -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<TermsElem> = |elem, _, styles| {
const LINK_RULE: ShowFn<LinkElem> = |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<HeadingElem> = |elem, engine, styles| {

View File

@ -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<Introspector>) -> StrResult<Destination> {
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 {