How to avoid duplicate footnotes with same content?

Hi everyone,

I need to automatically deduplicate identical footnotes that appear multiple times on the same page. Instead of showing the same footnote content repeatedly, I want subsequent instances to reference the first occurrence with the same footnote number. The manual approach using labels isn’t suitable for my use case since I need this to work automatically without manually tracking which footnotes have already been used. Is there a way to implement this automatic deduplication behavior in Typst?

Maybe this is a way to do it, or a start.

I’m using metadata and a global show rule for style. The style rule figures out which footnotes are unique on each page and shows them.

We want to avoid using state and toggling footnotes from visible to not visible. I guess some layout convergence problems might show up anyway, but maybe this can be a way to avoid the largest problems.

#set page(width: 5cm, height: 5cm)

#let dedupfootnotes(body) = context {
  let sel = selector.and(metadata, <_dedup_footnote_item>)
  // find every first unique footnote on each page
  let footnotes = query(sel).dedup(key: mt => (mt.value.footnote, mt.location().page()))

  show sel: mt => {
    if footnotes.any(elt => elt.location() == mt.location()) {
      // this is the first footnote
      footnote(mt.value.footnote)
    } else {
      // duplicate footnote, get the previous one's number.
      let previous-numbers = query(sel.before(here()))
        .filter(elt => elt.location().page() == here().page())
        .filter(elt => elt.value.footnote == mt.value.footnote)
      for prev in previous-numbers {
        super([#{counter(footnote).at(prev.location()).first() + 1}])
        break
      }
    }
    mt
  }
  body
}

#show: dedupfootnotes

#let ft(body) = {
  [#metadata((footnote: body))<_dedup_footnote_item>]
}

One#ft[one] two#ft[one] and three#ft[one] and four#ft[two]

#pagebreak()

Again#ft[one] and again#ft[two] and again#ft[one]



2 Likes

Thanks for your effort, but somehow this solution doesn’t work at all in my document. On one hand, I tried to put the code in one file and to change all the existing footnotes to #ft and on the other hand I tried to put the code in the main.typ and to change all existing footnotes in the whole document. Both solution didn’t work.
Maybe there is some interference with another workaround. I had to hide the footnote in the table and image outlines with this code:

#show footnote.entry: hide
#set footnote.entry(separator: none)
#show ref: none
#show footnote: none

Additionally, after the outlines there is a counter definitions which sets the footnote counter to zero:

#counter(footnote).update(0)

Could this be the problem?

I don’t know if that can be a problem, would be best to have a reduced example that demonstrates it, unfortunately.

When we talk about problems, even if it doesn’t “work at all” it would help to report what the expected document result was and what the actual document result was, and why that’s a problem :slightly_smiling_face: