How to prevent recursion on `show`?

i have a Word¹, and every time i write this Word¹ i want a footnote attached to it, displaying its definition


¹word a wording word worded in the wording world.

so what happened is that i gravitated towards using the show keyword like so:

#show "word": [*word* #footnote[/ word: a wording word worded in the wording world.]

the problem is that the resulting footnote contains word, which seems to be caught by show, because every time i attempt to write it in, my local compiler hangs, and i also have to reboot my lsp Tinymist. my current workaround is to avoid using the word¹ altogether in the footnote, but that then also means i can’t place a Definition in the footnote.

any solutions?

thank you for reading

Hello @wilker,

I do not recommend show rules like that. Instead, use a variable.

#let word = [*word* #footnote[/ word: a wording word worded in the wording world]]

This is a #word.
2 Likes

Here’s a hacky way to get closer to your original idea. The problem of too many footnotes could be solved with the use of a state variable, but I’ll leave that as an exercise for the reader.

#show regex("\b[wW]ord\b"): it => {
  let newWord = [#it.text.slice(0,2)#[#sym.zwj]#it.text.slice(2)]
  newWord
  footnote([/ wo#[#sym.zwj]rd: a wording wo#[#sym.zwj]rd wor#[#sym.zwj]ded in the wording world.])
}

This word is important.  Whenever you write this word (or Word, but not WORD), a footnote gets added.
But doing it this way results in too many footnotes for the word word.
Results

1 Like

To spoil the fun a bit for gezepi (I usually dislike having not the solution spoon fed to me), I’ll spoon feed you the solution, which might not be the best, nor might it actually work correctly.

So here’s the code. It uses fancy regex (which I assume can turn into a huge resource hog at some point).

The show rule is contructed by combining all the listed regex’es together, so only one show rule exists. Then the it is used to acquire the term information from the descriptions dictionary. The state member is used to detect if it is the first occurence of the term (true = not yet detected, false = previously detected).

#let descriptions = (
  word: (
    regex: "\b[wW]ord\b",
    state: state("word", true),
    description: "a wording word worded in the wording world."
  ),
  footnote: (
    regex: "\b[fF]ootnote\b",
    state: state("footnote", true),
    description: "footnote is not noting foots on a note."
  ),
)

#show regex(descriptions.values().map(x => x.regex).join("|")): it => context {   
  let term = descriptions.at(lower(it.text))
  if term.state.get() == true {
    term.state.update(false)
    underline(it)
    let tex = (strong(lower(it.text)) + ": " + term.description)
    footnote("Hello")// footnote(tex) breaks the online compiler
  } else {
    it
  }
}

This word is important.  Whenever you write this word (or Word, but not WORD), a footnote gets added. But doing it this way results in too many footnotes for the word 'word'.
Result

The biggest issue this solution has, is my instance of the web app just breaks when I insert footnote(tex) and I don’t know why exactly. The description texts are correctly concated.

My conclussion would be: use a glossary package, which does this job for you.

3 Likes