3

Is it possible to declare a footnote in a way that it will attach to the first occurrence of a given word or phrase?

Doing this in a fully automated way might not be possible (see link below), but if (for example) one uses footnote labels with a macro \uniquefn[text]{id} (marking phrases that should be considered identical), this should be possible. With such a macro, one would be able to write things like this:

\documentclass{article}

\begin{document}

This is a sentence\uniquefn{an-identifier}.
Let's write\uniquefn[Every footnote identifier must have specified text
  (inside an optional argument) exactly once for all invocations of this
  macro with that identifier; if this is violated, there should be an
  error.]{another-identifier}
  two more sentences\uniquefn[If an optional argument is given, the text
  within that optional argument is what is to be displayed]{an-identifier}.
This is the penultimate sentence\uniquefn{an-identifier}.
And one final sentence\uniquefn{an-identifier}
  concludes\uniquefn[One more footnote.]{yet-another-identifier} this document.

\end{document}

Other equivalent ways of achieving the same effect would work too.

Related and potentially useful:

  • \usepackage{glossaries} \gls{label} \glslink{label}{alternate text}. It is not a \footnote, but I dont understand how you can apply what you say to document spanning many pages. Link to library. Forgot to mention: there is a field first appear in the glossaries package if you need special text on first occurence – aiao Feb 25 '13 at 03:03
  • I must confess I haven't really understood what you want but maybe the packages sepfootnotes and fixfoot are of interest. – cgnieder Feb 25 '13 at 18:10
  • @cgnieder Both existing solutions ("A.Ellett" and "David Carlisle") do what I was looking for; fixfoot does a very similar thing (I have just tried). Two remarks about fixfoot: 1. In order to use the starred version of its command, the user needs to load it with xspace; this isn't documented clearly. 2. It displays the footnote mark multiply instead of only once (which I consider a sensible design decision). – Lover of Structure Feb 25 '13 at 21:43

2 Answers2

3

I'm not entirely clear on your implementation. Here's a first stab at what you want.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\msg_new:nnnn { undefined_footnote }{ undefined_footnote }{ You've ~ attempted ~ to ~ use ~ an ~ undefined ~ footnote: ~ "#1" }{}
%% --------------------------------------------------------------------------------
%% arg #1 -> key value
%% arg #2 -> content of the footnote
\cs_new:Npn \__los_add_footnote_id:nn #1#2 {
    \tl_if_exist:cF { #1 _footnote }
                    {
                        \tl_new:c { #1 _footnote }
                        \tl_gset:cn { #1 _footnote}{#2}
                    }
}
%% --------------------------------------------------------------------------------
%% arg #1 -> key value
\cs_new:Npn \__los_uniquefn:n #1 
            {
                \int_incr:c { #1 _counter }
                \int_compare:nT { \int_use:c { #1 _counter } = 1 }
                                { 
                                    \footnote
                                    {
                                        \tl_use:c { #1 _footnote }
                                    }
                               }
            }
%% --------------------------------------------------------------------------------
%% USER INTERFACE                                                                  
%% --------------------------------------------------------------------------------
%% Define what should appear in the footnote
%% arg #1 -> key value
%% arg #2 -> content of the footnote
\NewDocumentCommand{\definefootnote}{ mm }
    {
        \__los_add_footnote_id:nn { #1 } { #2 }
        \int_if_exist:cF { #1 _counter }
                         { 
                            \int_gzero_new:c { #1 _counter }
                         }
    }
%% Possibly create footnote
\NewDocumentCommand{\uniquefn}{ m }
    {
        \tl_if_exist:cTF { #1 _footnote }
                         {    
                            \__los_uniquefn:n { #1 }
                         }
                         {
                            \msg_error:nnn { undefined_footnote } { undefined_footnote } { #1 }
                         }
    }
\ExplSyntaxOff
\definefootnote{a-thistle-ftnt}{A thistle is a kind of weed which grows on the side of roads.}
\definefootnote{a-rose-garden}{A place to go and read books.}
\usepackage{lipsum}
\pagestyle{empty}
\begin{document}

\lipsum[1]

thistle\uniquefn{a-thistle-ftnt}    
\lipsum[1]

rose garden\uniquefn{a-rose-garden}
\lipsum[1]

\lipsum[1]

\lipsum[1]

thistle\uniquefn{a-thistle-ftnt}    
\lipsum[1]

\lipsum[1]

\end{document}

What I'm unclear about is why the content of the footnote is to be put in an optional argument. Your implementation would seem to create a headache to check whether the body of the footnote has been defined anywhere. It seems better to define a library for the unique id that can be used to call up the definition of the footnote: This is what \definefootnote is supposed to provide: so in one location you can write a list of all possible footnotes.

A.Ellett
  • 50,533
  • I've clarified my question statement; any way of achieving the effect works for me :-) The "optional argument" way of doing things seems to keep the footnote content closer to the text, but given that there might be many invocation of a footnote with a particular identifier/label, your way may be cleaner. – Lover of Structure Feb 25 '13 at 04:27
  • To others: Please also see the answer by David Carlisle. This answer made a different design choice; both answers work equally well. I picked this one partly because it uses the modern package xparse, but this choice was almost arbitrary. David Carlisle's answer is closer to what I had in mind in my original question statement and deserves credit for that. – Lover of Structure Mar 04 '13 at 00:34
3

enter image description here

This saves the text in the aux file, so this will takes some runs to settle down.

\documentclass{article}

\makeatletter
\newcommand\uniquefn[2][]{%
\ifx\relax#1\relax\else
 \immediate\write\@auxout{\global\noexpand\@namedef{FTN-text-#2}{\detokenize{#1}}}%
  \expandafter\ifx\csname FTN-text-#2\endcsname\relax
    \expandafter\gdef\csname FTN-text-#2\endcsname{#1}%
  \else
    \def\tmp{#1}%
    \expandafter\ifx\csname FTN-text-#2\endcsname\tmp\else
      \PackageError{uniqueftn}{text for #2 is not unique}{make it so}%
    \fi
  \fi
\fi
\expandafter\ifx\csname FTN-seen-#2\endcsname\@empty\else
  \footnote{\csname FTN-text-#2\endcsname}%
\fi
\global\expandafter\let\csname FTN-seen-#2\endcsname\@empty
}
\makeatother

\begin{document}

This is a sentence\uniquefn{an-identifier}.
Let's write\uniquefn[Every footnote identifier must have specified text
  (inside an optional argument) exactly once for all invocations of this
  macro with that identifier; if this is violated, there should be an
  error.]{another-identifier}
  two more sentences\uniquefn[If an optional argument is given, the text
  within that optional argument is what is to be displayed]{an-identifier}.
This is the penultimate sentence\uniquefn{an-identifier}.
And one final sentence\uniquefn{an-identifier}
  concludes\uniquefn[One more footnote.]{yet-another-identifier} this document.

\end{document}
David Carlisle
  • 757,742