From 33803b16148ec064ccabc9bffd4a9383b969e23e Mon Sep 17 00:00:00 2001 From: MALO <57839069+MDLC01@users.noreply.github.com> Date: Mon, 26 Jun 2023 13:40:52 +0200 Subject: [PATCH] Make footnotes referenceable (#1546) --- library/src/layout/flow.rs | 5 ++ library/src/meta/bibliography.rs | 2 +- library/src/meta/footnote.rs | 107 ++++++++++++++++++++++++++----- library/src/meta/reference.rs | 16 +++-- tests/ref/meta/footnote-refs.png | Bin 0 -> 28467 bytes tests/typ/meta/footnote-refs.typ | 40 ++++++++++++ 6 files changed, 149 insertions(+), 21 deletions(-) create mode 100644 tests/ref/meta/footnote-refs.png create mode 100644 tests/typ/meta/footnote-refs.typ diff --git a/library/src/layout/flow.rs b/library/src/layout/flow.rs index c173ef1a1..accd092a6 100644 --- a/library/src/layout/flow.rs +++ b/library/src/layout/flow.rs @@ -488,6 +488,11 @@ impl FlowLayouter<'_> { // Process footnotes one at a time. let mut k = 0; while k < notes.len() { + if notes[k].is_ref() { + k += 1; + continue; + } + if !self.has_footnotes { self.layout_footnote_separator(vt)?; } diff --git a/library/src/meta/bibliography.rs b/library/src/meta/bibliography.rs index 9bc88f280..0abcf5bb0 100644 --- a/library/src/meta/bibliography.rs +++ b/library/src/meta/bibliography.rs @@ -545,7 +545,7 @@ fn create( } if style == CitationStyle::ChicagoNotes { - content = FootnoteElem::new(content).pack(); + content = FootnoteElem::with_content(content).pack(); } (location, Some(content)) diff --git a/library/src/meta/footnote.rs b/library/src/meta/footnote.rs index 950057baf..31ec9fe91 100644 --- a/library/src/meta/footnote.rs +++ b/library/src/meta/footnote.rs @@ -1,15 +1,35 @@ +use comemo::Prehashed; use std::str::FromStr; use super::{Counter, Numbering, NumberingPattern}; use crate::layout::{HElem, ParElem}; +use crate::meta::{Count, CounterUpdate}; use crate::prelude::*; use crate::text::{SuperElem, TextElem, TextSize}; use crate::visualize::LineElem; +/// The body of a footnote can be either some content or a label referencing +/// another footnote. +#[derive(Debug)] +pub enum FootnoteBody { + Content(Content), + Reference(Label), +} + +cast! { + FootnoteBody, + self => match self { + Self::Content(v) => v.into_value(), + Self::Reference(v) => v.into_value(), + }, + v: Content => Self::Content(v), + v: Label => Self::Reference(v), +} + /// A footnote. /// -/// Include additional remarks and references on the same page with footnotes. A -/// footnote will insert a superscript number that links to the note at the +/// Includes additional remarks and references on the same page with footnotes. +/// A footnote will insert a superscript number that links to the note at the /// bottom of the page. Notes are numbered sequentially throughout your document /// and can break across multiple pages. /// @@ -28,6 +48,15 @@ use crate::visualize::LineElem; /// there is a space before it in the markup. To force space, you can use the /// string `[#" "]` or explicit [horizontal spacing]($func/h). /// +/// By giving a label to a footnote, you can have multiple references to it. +/// +/// ```example +/// You can edit Typst documents online. +/// #footnote[https://typst.app/app] +/// Checkout Typst's website. @fn +/// And the online app. #footnote() +/// ``` +/// /// _Note:_ Set and show rules in the scope where `footnote` is called may not /// apply to the footnote's content. See [here][issue] more information. /// @@ -35,7 +64,7 @@ use crate::visualize::LineElem; /// /// Display: Footnote /// Category: meta -#[element(Locatable, Synthesize, Show)] +#[element(Locatable, Synthesize, Show, Count)] #[scope( scope.define("entry", FootnoteEntry::func()); scope @@ -58,9 +87,49 @@ pub struct FootnoteElem { #[default(Numbering::Pattern(NumberingPattern::from_str("1").unwrap()))] pub numbering: Numbering, - /// The content to put into the footnote. + /// The content to put into the footnote. Can also be the label of another + /// footnote this one should point to. #[required] - pub body: Content, + pub body: FootnoteBody, +} + +impl FootnoteElem { + /// Creates a new footnote that the passed content as its body. + pub fn with_content(content: Content) -> Self { + Self::new(FootnoteBody::Content(content)) + } + + /// Creates a new footnote referencing the footnote with the specified label. + pub fn with_label(label: Label) -> Self { + Self::new(FootnoteBody::Reference(label)) + } + + /// Tests if this footnote is a reference to another footnote. + pub fn is_ref(&self) -> bool { + matches!(self.body(), FootnoteBody::Reference(_)) + } + + /// Returns the content of the body of this footnote if it is not a ref. + pub fn body_content(&self) -> Option { + match self.body() { + FootnoteBody::Content(content) => Some(content), + _ => None, + } + } + + /// Returns the location of the definition of this footnote. + pub fn declaration_location(&self, vt: &Vt) -> StrResult { + match self.body() { + FootnoteBody::Reference(label) => { + let element: Prehashed = vt.introspector.query_label(&label)?; + let footnote = element + .to::() + .ok_or("referenced element should be a footnote")?; + footnote.declaration_location(vt) + } + _ => Ok(self.0.location().unwrap()), + } + } } impl Synthesize for FootnoteElem { @@ -73,14 +142,22 @@ impl Synthesize for FootnoteElem { impl Show for FootnoteElem { #[tracing::instrument(name = "FootnoteElem::show", skip_all)] fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult { - let loc = self.0.location().unwrap(); - let numbering = self.numbering(styles); - let counter = Counter::of(Self::func()); - let num = counter.at(vt, loc)?.display(vt, &numbering)?; - let sup = SuperElem::new(num).pack(); - let hole = HElem::new(Abs::zero().into()).with_weak(true).pack(); - let loc = self.0.location().unwrap().variant(1); - Ok(hole + sup.linked(Destination::Location(loc))) + Ok(vt.delayed(|vt| { + let loc = self.declaration_location(vt).at(self.span())?; + let numbering = self.numbering(styles); + let counter = Counter::of(Self::func()); + let num = counter.at(vt, loc)?.display(vt, &numbering)?; + let sup = SuperElem::new(num).pack(); + let hole = HElem::new(Abs::zero().into()).with_weak(true).pack(); + let loc = loc.variant(1); + Ok(hole + sup.linked(Destination::Location(loc))) + })) + } +} + +impl Count for FootnoteElem { + fn update(&self) -> Option { + (!self.is_ref()).then(|| CounterUpdate::Step(NonZeroUsize::ONE)) } } @@ -201,7 +278,7 @@ impl Show for FootnoteEntry { HElem::new(self.indent(styles).into()).pack(), sup, HElem::new(number_gap.into()).with_weak(true).pack(), - note.body(), + note.body_content().unwrap(), ])) } } @@ -218,5 +295,5 @@ impl Finalize for FootnoteEntry { cast! { FootnoteElem, - v: Content => v.to::().cloned().unwrap_or_else(|| Self::new(v.clone())), + v: Content => v.to::().cloned().unwrap_or_else(|| Self::with_content(v.clone())), } diff --git a/library/src/meta/reference.rs b/library/src/meta/reference.rs index 26961ec56..908238711 100644 --- a/library/src/meta/reference.rs +++ b/library/src/meta/reference.rs @@ -1,4 +1,5 @@ use super::{BibliographyElem, CiteElem, Counter, Figurable, Numbering}; +use crate::meta::FootnoteElem; use crate::prelude::*; use crate::text::TextElem; @@ -11,11 +12,11 @@ use crate::text::TextElem; /// bibliography. /// /// Referenceable elements include [headings]($func/heading), -/// [figures]($func/figure), and [equations]($func/math.equation). To create a -/// custom referenceable element like a theorem, you can create a figure of a -/// custom [`kind`]($func/figure.kind) and write a show rule for it. In the -/// future, there might be a more direct way to define a custom referenceable -/// element. +/// [figures]($func/figure), [equations]($func/math.equation), and +/// [footnotes]($func/footnote). To create a custom referenceable element like a +/// theorem, you can create a figure of a custom [`kind`]($func/figure.kind) and +/// write a show rule for it. In the future, there might be a more direct way to +/// define a custom referenceable element. /// /// If you just want to link to a labelled element and not get an automatic /// textual reference, consider using the [`link`]($func/link) function instead. @@ -160,6 +161,11 @@ impl Show for RefElem { } let elem = elem.at(span)?; + + if elem.func() == FootnoteElem::func() { + return Ok(FootnoteElem::with_label(target).pack().spanned(span)); + } + let refable = elem .with::() .ok_or_else(|| { diff --git a/tests/ref/meta/footnote-refs.png b/tests/ref/meta/footnote-refs.png new file mode 100644 index 0000000000000000000000000000000000000000..3fab7bd5d6feb56df3f3b6bcc576f6370813ff7e GIT binary patch literal 28467 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

u_m>%Y4ZQlFXniINO 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 \ +A reference to it @fn + +--- +// Multiple footnotes are refs +First #footnote[A] \ +Second #footnote[B] \ +First ref @fn1 \ +Third #footnote[C] \ +Fourth #footnote[D] \ +Fourth ref @fn4 \ +Second ref @fn2 \ +Second ref again @fn2 + +--- +// Forward reference +Usage @fn \ +Definition #footnote[Hi] + +--- +// Footnote ref in footnote +#footnote[Reference to next @fn] +#footnote[Reference to myself @fn] +#footnote[Reference to previous @fn] + +--- +// Styling +#show footnote: text.with(fill: red) +Real #footnote[...] \ +Ref @fn + +--- +// Footnote call with label +#footnote() +#footnote[Hi] +#ref() +#footnote()