summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/fixfoot/fixfoot.sty
blob: 1b66b7ff8349ec62a56b534122b6fc4d1f042190 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
\ProvidesPackage{fixfoot}[2007/12/12 v0.3a fixed-text footnotes]
%
% Author: Robin Fairbairns <rf10@cam.ac.uk>
%
% This program may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.1
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.1 or later is part of all distributions of LaTeX 
% version 1999/06/01 or later.
%
% This program consists of a package file fixfoot.sty and a test file
% testfix.tex
%
% this is an experimental package that provides fixed footnotes
% only one instance of a fixed footnote will appear on any one page
%
% the package defines a single command, \DeclareFixedFootnote, which
% takes an optional *, and two `ordinary' arguments.
%
% if the optional * is present, the command declared has an \xspace
% imbedded in it, so that spaces following it in running text tend not
% to be lost.
%
% the first ordinary argument is a cs name
% the second ordinary argument is the fixed text of the footnote
%
% e.g., \DeclareFixedFootnote*{\sic}{\emph{sic}}
%       \DeclareFixedFootnote{\prooflater}{This theorem will be proved
%                                          later}
%
% the package works by exchanging information with itself via the .aux
% file.  just as with labels (and per-page footnote numbers in
% footmisc), the user ordinarily needs to run latex at least twice.
% this package does not (yet) have the ability to warn the user that
% another run of latex is still necessary (changing labels or footnote
% numbers in footmisc \emph{do} thus warn).
\newif\if@fftn@debug
\DeclareOption{debug}{\@fftn@debugtrue}
\ProcessOptions\relax
%
\newcommand\DeclareFixedFootnote{%
  \@ifstar{\@declare@fftn\xspace}%
          {\@declare@fftn\relax }%
}
%
% relay after detecting optional `|*|':
\newcommand\@declare@fftn[3]{%
% #1 \cs{xspace} (if `|*|' found) or \cs{relax}
% #2 footnote name, #3 footnote body
%
% extract the \csname bit of it...
  \edef\reserved@a{\expandafter\@gobble\string#2}%
  \@ifundefined\reserved@a
    {\@declare@@fftn{#1}{#2}{#3}}%
    {\@notdefinable}%
}
%
% finally, relayed command to do the actual job (same parameters as
% \cs{@declare@fftn}, which has simply checked that we're allowed to
% do this declaration)
\newcommand\@declare@@fftn[3]{%
  \edef\reserved@a{\expandafter\@gobble\string#2}%
%
% the actual command
  \protected@edef#2{\protect\@fixed@footnote{\reserved@a}%
                                            {#1}{#3}}%
%
% define the fixed foot serial number and page counters
  \@definecounter{@\reserved@a @fftn@serial}%                            
  \@namedef{@\reserved@a @fftn@curpage}{moocow}%
  \@namedef{@\reserved@a @fftn@scanpage}{baalamb}%
  \@namedef{@\reserved@a @fftn@pagelim}{-1}%
%
% now the things we want executed at end document:
  \protected@edef\@tempa{%
    \expandafter\protect\csname @\reserved@a @fftn@aux\endcsname}%
  \protected@edef\@tempb{%
    \expandafter\protect\csname @\reserved@a @fftn@scanpage\endcsname}%
%
% Note that \cs{AtEndDocument} has global effect\dots
  \begingroup
    \let\protect\noexpand
    \edef\@tempc{\noexpand\AtEndDocument{%
      \fftn@clearpage
      \noexpand\def\@tempa{%
        \noexpand\@reprocess@fftn@mark{\reserved@a}}%
      \noexpand\def\@tempb{oinkpig}}}%
    \@tempc
  \endgroup
  \let\fftn@clearpage\@empty
}%
\def\fftn@clearpage{\noexpand\clearpage}
%
% Stick a dummy \cs{@process@fftn@mark} into the |.aux| file, in
% accordance with good practice for such things...
\AtBeginDocument{\immediate\write\@auxout{\noexpand\providecommand
    \noexpand\@process@fftn@mark[3]{}}}
%
% \@reprocess@fftn@mark#1#2#3 will deal (when we've written it) with a
% fixed footnote mark in the .aux file at end document #1 footnote tag
% #2 serial number #3 actual page...  (What should it do???)
%
% the fundamental fixed footnote command:
% the command \cs{}\meta{tag} which is supposed to generate a footnote
% containing \meta{body}, generates a call
% \@fixed@footnote\marg{tag}\marg{end-execution}\marg{body}
\def\@fixed@footnote#1#2#3{%
% #1 footnote tag
% #2 \xspace or \relax
% #3 footnote body
% 
% count this footnote
  \stepcounter{@#1@fftn@serial}%
%
% Is this serial beyond the limit of serial numbers destined for this
% page?
  \if@fftn@debug
    \message{footnote #1 serial \csname the@#1@fftn@serial\endcsname\space
      existing limit \csname @#1@fftn@pagelim\endcsname;}%
  \fi
  \ifnum\csname @#1@fftn@pagelim\endcsname <
        \csname c@@#1@fftn@serial\endcsname
%
% so here we're going to have to create a new footnote, but let's
% first find whether the |.aux| file scan at the start gave us a
% range of serial numbers to share it with us:
    \expandafter\let\expandafter\@tempa
      \csname @#1@fftn-\the\csname c@@#1@fftn@serial\endcsname\endcsname
    \ifx\@tempa\relax
      \if@fftn@debug
        \message{footnote #1 no limit to inherit from .aux file;}%
      \fi
    \else
      \if@fftn@debug
        \message{footnote #1 limit \@tempa;}%
      \fi
%
% record the information from the file
      \global\expandafter\let\csname @#1@fftn@pagelim\endcsname\@tempa
    \fi
%
% create the footnote and record its number (whether we're going to
% use it or not)
    \footnote{#3}%
    \expandafter\xdef\csname @#1@fftn@footnote\endcsname
                      {\the\c@footnote}%
    \if@fftn@debug
      \message{written new #1 footnote, number \the\c@footnote.}%
    \fi
%
% if we're still on the same page as the previous footnote, create a
% mark only; note we can't use \cs{footnotemark} here, as it won't do
% the right thing if we're in a minipage (or anywhere where
% \cs{thempfn} isn't the same as \cs{thefootnote}).
  \else
    \protected@xdef\@thefnmark{\csname @#1@fftn@footnote\endcsname}%
    \@footnotemark
    \if@fftn@debug
      \message{reusing #1 footnote \csname @#1@fftn@footnote\endcsname.}%
    \fi
  \fi
%
% record which page `this' footnote appeared in the |.aux|
  \protected@writeaux\relax{\protect\@process@fftn@mark{#1}%
    {\the\csname c@@#1@fftn@serial\endcsname}{\noexpand\thepage}}%
%
% and finally insert the `end-command' stuff (this can be \cs{xspace}
% or \cs{relax} if we're being called from a conventionally-defined
% fixed footnote command, but could be anything, really, one
% supposes!)
  #2%
  }
%
% \@process@fftn@mark#1#2#3 deals with a fixed footnote mark in
% the .aux file at begin document;
% arguments #1 footnote tag
%           #2 serial number
%           #3 actual page
\newcommand\@process@fftn@mark[3]{%
  \if@fftn@debug
    \message{fftn #1 #2 #3;}%
  \fi
  \def\@tempa{#3}%
  \expandafter\ifx\csname @#1@fftn@scanpage\endcsname\@tempa
  \if@fftn@debug
    \message{on same page as previous;}%
  \fi
  \else
%
% well, we're no longer on whatever was last recorded as the page of a
% fixed footnote of this name -- record the serial
    \expandafter\def\csname @#1@fftn@lastserial\endcsname{#2}%
    \expandafter\let\csname @#1@fftn@scanpage\endcsname\@tempa
  \fi
%
% 
  \if@fftn@debug
    \message{setting limit for serial \csname @#1@fftn@lastserial\endcsname.}%
  \fi
  \expandafter\gdef\csname @#1@fftn-%
                     \csname @#1@fftn@lastserial\endcsname
                       \endcsname{#2}%
}
%
% \@reprocess@fftn@mark#1#2#3 deals with a fixed footnote mark in
% the .aux file at end document; arguments #1 footnote tag
% #2 serial number #3 actual page
\newcommand\@reprocess@fftn@mark[3]{}% pro tem
%
% use that when processing the .aux file at the end of the document
\AtEndDocument{\let\@process@fftn@mark\@reprocess@fftn@mark}
%
% this command originates in Matt Swift's inclusion stuff; I use it
% all over the place...
\providecommand\protected@writeaux{%
  \protected@write\@auxout
}