typst icon indicating copy to clipboard operation
typst copied to clipboard

Plain-text reference to footnote

Open msiniscalchi opened this issue 2 years ago • 9 comments

Description

Typst allows attaching labels to footnotes, as in #footnote[This is a test]<myfn>, and then referencing: See footnote @myfn. However, this results in the footnote being typeset as a superscript. It would be useful to have the option to show the reference as regular text. This is the default behavior in LaTeX, and may be a stumbling block for people moving over (it is for me).

Use Case

While footnotes should be used sparingly, they are useful to, for instance, elaborate on possible extensions of a result. In this case, sequences of footnotes arise quite naturally. Example:

Main text says: if X, then Y. Footnote 1 says: if X' instead of X, then we still get Y, provided we also assume Z.

Later, main text says: if X and W, then Q. Footnote 2 says: as in Footnote 1, if X' and W instead of X and W, we can still get Q provided we also assume Z.

The point is that it is useful to refer back to an earlier footnote, and it does not make sense for the label to appear as a superscript.

msiniscalchi avatar Sep 01 '23 18:09 msiniscalchi

You can use a custom function with a show rule for footnotes:

#let big-footnote(reference) = {
  show footnote: it => [
    footnote #numbering(it.numbering, ..counter(footnote).at(it.location()))
  ]
  reference
}

Hello World #footnote[This is a test]<myfn>

See #big-footnote[@myfn].

freundTech avatar Sep 01 '23 20:09 freundTech

Thanks @freundTech. This works, though there is a space right after the footnote number.

In any event, for someone coming from LaTeX, the default typst behavior will come as a surprise. Perhaps a path-of-least-resistance solution is to explicitly mention this difference in the documentation, and offer this workaround for those who need it.

msiniscalchi avatar Sep 01 '23 22:09 msiniscalchi

Oh. I didn't notice that space. You can get rid of it by removing the newline after the number:

#let big-footnote(reference) = {
  show footnote: it => [footnote #numbering(it.numbering, ..counter(footnote).at(it.location()))]
  reference
}

freundTech avatar Sep 02 '23 07:09 freundTech

In any event, for someone coming from LaTeX, the default typst behavior will come as a surprise.

The motivation behind the behavior isn't so much references to footnotes, but reusing footnotes. This is the same thing you can do in LaTeX by using \footnotemark.

(As an aside, I feel that you may be misusing footnotes if you feel the need to reference them.)

Enivex avatar Sep 02 '23 10:09 Enivex

The motivation behind the behavior isn't so much references to footnotes, but reusing footnotes. This is the same thing you can do in LaTeX by using \footnotemark.

Yes, I followed the convos on this on Discord. It's a design decision and I respect it -- just pointing out that LaTeX made a different design decision. And in any case, LaTeX provides both options out of the box, whereas typst requires you to roll your own if you want plain-text references.

(As an aside, I feel that you may be misusing footnotes if you feel the need to reference them.)

My example was admittedly contrived, but different fields, different conventions.

Overall, I think it may be enough to highlight this difference in the documentation, with @freundTech's workaround (which now works beautifully -- and it's wonderful to change code and see its effects on the fly!)

msiniscalchi avatar Sep 02 '23 19:09 msiniscalchi

Here's another solution with a show rule, making you able to reference footnotes like anything else.

#show ref: it => {
  let el = it.element
  if el != none and el.func() == footnote [
    Footnote~#numbering(el.numbering,..counter(footnote).at(el.location()))
  ] else {it}
}

Hello#footnote[world]<first>, and another#footnote[footnote]<second>

See @first or @second

image

Enivex avatar Sep 02 '23 22:09 Enivex

Here's a variation of @Enivex's solution that displays:

  • "Footnote X" if the footnote is on the same page as the reference; and
  • "Footnote X on page Y" if the footnote is on a different page.

It also turns the references into links.

#show ref: it => {
  let el = it.element
  if el != none and el.func() == footnote {
    let loc = el.location()
    let f_number = numbering(el.numbering, ..counter(footnote).at(loc))
    let p_counter = counter(page).at(loc)
    if p_counter == counter(page).at(it.location()) {
      link(loc, [Footnote~#f_number])
    } else {
      let p_number = numbering(loc.page-numbering(), ..p_counter)
      link(loc, [Footnote~#f_number on page~#p_number])
    }
  } else {
    it
  }
}

(It capitalizes "Footnote" but not "page", which seems like the right thing to me but I can't tell why.)

robamler avatar Nov 11 '24 14:11 robamler

I think it would be good to be able to reference footnote numbers as regular text as LaTeX allows.

curioustolearn avatar Mar 10 '25 12:03 curioustolearn

I agree with this, especially because there still seems to be a difference between the two versions:

My text#footnote[yay]<a> is awesome.

This one@a too.

And this one#footnote(<a>)

This produces the same result with default styling, but when styling refs, it looks different:

#show ref: underline
#show ref: set text(fill: blue)
Image

Even though a comment on the original PR suggests something different: https://github.com/typst/typst/pull/1546#issuecomment-1603318719

TheBlckbird avatar Nov 14 '25 22:11 TheBlckbird