[texhax] macro for numbering footnotes on each page
Adam Fenn
acwfenn at hotmail.com
Sat May 29 10:10:47 CEST 2010
I found the file below (schrod.txh) in the texhax archives which resets the footnote number to 1 on each new page.
However, I cannot get it to work. I assume that ~ ought to be ^ but other than that I am at a loss. Can anyone here
get it to work or have a more up to date plain TeX solution?
TIA
Adam.
---------- cut here ------------------------------------------------------
%
% 1. (@*) Introduction.
%
% This macro set numbers footnotes subsequently on each page.
% It was written by J. Schrod on August 1, 1987.
% A footnote is typeset by the command \footnote. This command
% has one parameter, the text of the footnote. The macro
% package assumes that the conventions set up by PLAIN are in
% effect and is written primarily for use with PLAIN. With two minor
% changes it runs with LaTeX, but in LaTeX better approaches
% are available. Every place in the macro set where the used
% macro package is important has the line
%
% @~ system dependencies @>
%
% added (WEB lives!). We use the private macros of PLAIN
% and for that reason we catcode the character `@' to letter.
\begingroup % to get the catcode change local
\catcode`\@=11
% 2. But let's regard first the implementation strategy. Because
% the contents of one page is determined at (nearly) random places
% with an asynchronous invogation of the output routine, we can not
% give numbers to every footnote subsequently between output and
% output: a footnote at the top of a page will perhaps get a number
% before the output is triggered and there is no way to change
% this number. The problem is like forward references to text
% places and it is solved in a similar fashion. We need two TeX runs
% to get the numbering right but this is acceptable (who's got a
% finished text after one run?!). In the first run we gather up in
% a file the information where the footnotes are standing and in
% the second run we use this information.
% 3. This leads to our first code, the initialization of the
% macro set. We need a file descriptor, \foot at file, which we
% use for the file interaction. The name of the file is built
% from the jobname and the suffix `.fot' (I hope that no macro
% package uses this suffix).
% @~ system dependencies @>
%
% The \init at footnote macro reads the contents of the footnote
% file if it exists (\ifeof returns true if the file doesn't
% exist). The description of the reading of this file
% (\read at foot@file) is deferred until we know the structure
% of the contents. After reading, the file is closed and we
% can open it for writing. For security, i.e. to have a defined
% minimal contents, we immediately write \relax to the file.
% In the end the macro defines itself to \relax to allow calling
% it again.
%
% Please note here the placement of `%' chars. Because we don't
% know if this macro is used only in vertical mode,
% (italics on)
% every line not ending with a macro name is ended by a %.
% (italics off)
\newwrite\foot at file
\gdef\foot at file@name{\jobname.fot \relax}
\gdef\init at footnote{%
\openin\foot at file=\foot at file@name
\ifeof\foot at file \closein\foot at file
\else \closein\foot at file
\read at foot@file
\fi
\immediate\openout\foot at file=\foot at file@name
\immediate\write\foot at file{\relax}%
\let\init at footnote=\relax
}
% 4. Now comes the first real macro package dependent part.
% We want to set the footnote with a number in the superscript
% position (or with a corresponding symbol for that number). This
% is done with the macro \@footnote, which gets the number as its
% parameter. Below are the definitions for PLAIN TeX and LaTeX,
% the LaTeX part is commented out. To activate it, simply comment
% the PLAIN part out and remove the other `%'-signs.
%
% I think here is the place to state that I'm no LaTeX wizard.
% I don't know if there are any other (better) ways to get the
% footnote.
\let\@@footnote=\footnote % original meaning of \footnote
\gdef\@footnote#1{% % set footnote with mark #1 (PLAIN)
\@@footnote{\hbox{$~{#1}$}}%
}
%\gdef\@footnote#1{% % set footnote with mark #1 (LaTeX)
% \xdef\@thefnmark{#1}\@footnotemark\@footnotetext
% }
%
% 5. (@*) Realisation.
%
% We must identify all footnotes if we write their numbers to
% the footnote file, so each footnote gets an unary name
% built with the counter \footno. The name is `f@<footno>',
% where <footno> is the footnote name number. This name
% building scheme has several disadvantages, e.g. the insertion
% of a new footnote destroys the knowledge of the former run
% about the following footnotes. In the beginning of every
% footnote \init at footnote is called to guarantee that the
% handling is initialized (this especially means that the
% footnote numbers are read in by the first footnote).
\newcount\footno % for generating footnote mark names
\newcount\@footno % numbers of footnotes
% 6. It remains an open problem how to get the numbers there.
% The footnote numbering must be initialized to zero in the
% output routine and every footnote must increment this footnote
% number. The only thing that is expanded during the output
% process is the output routine itself and the \write's, but
% the expanded tokens of \write are written out, not interpreted.
% Well, the idea is simple: We defer the counting to the second
% run and write the instructions that do this to the file. The
% counting is then done while reading the footnote file.
%
% That means that the output routine adds entries like
% \@footno = 0
% and every footnote adds an entry that looks like
% \advance\@footno by 1 \xdef\csname f@<footno> \endcsname{\number\@footno}
% where <footno> is replaced by the current footnote name number.
% The expansion of \footno must be made in \footnote, therefore
% we first define the macro \@dowrite which contains the \write
% and the expanded tokens which are to be put out. Every token
% that should not be expanded is prefixed by \string (resulting
% in character tokens that represent the token name) and a \space
% must be inserted to separate \csname from f.
%
% After writing the entry to the footnote file the \footnote
% macro defines the footnote mark to `?' if it is not already
% defined (from a previous run). To build the token name first
% and test afterwards an \expandafter is needed. At the end the
% \@footnote command is issued.
\gdef\footnote{%
\init at footnote
\global\advance\footno by \@ne
\edef\@dowrite{%
\write\foot at file{%
\string\advance\@footno\@ne
\string\expandafter\xdef
\string\csname\space f@\number\footno \endcsname{%
\string\number\@footno
}%
}%
}%
\@dowrite
\expandafter\ifx \csname f@\number\footno \endcsname \relax
\expandafter\gdef \csname f@\number\footno \endcsname {?}%
\fi
\@footnote{\csname f@\number\footno \endcsname}%
}
% 7. Now let's look at the intervention in the output routine. The
% goal is to be (almost) independent from the used output routine.
% This is done by forming a layer around the originial output routine,
% but relies on the fact that the output routine is not altered
% by itself. For macro packages doing so an expansion of the
% output routine has to be made.
% @~ system dependencies @>
%
% Output routines serve for two purposes: they put out text
% to the file and they collect information. Usually macro packages
% communicate with the output routine by inserting special
% penalties. This macro set assumes that penalties above
% -\@maxpenalty are used to output text and penalties below
% -\@maxpenalty do other things (look at LATEX.TEX if you
% wonder what one can do in the output routine...). For every
% macro package \@maxpenalty has to be adjusted. If the precondition
% of one range of penalties for text output doesn't hold the
% following algorithm has to be altered. As with the definition
% of \@footnote, both the values for PLAIN TeX and for LaTeX are
% given, the LaTeX value is commented out.
% @~ system dependencies @>
\mathchardef\@maxpenalty=20000 % maximal used penalty for text pages (PLAIN)
%\mathchardef\@maxpenalty=10000 % maximal used penalty for text pages (LaTeX)
% 8. We must insert a \write in front of the output. There are two
% ways to do this. (1) We can shipout a box copy with the \write
% in it before the rest of the box (but this must be done in one
% shipout or an empty page will result). This approach needs deep
% intervention in the original output routine and is therefore not
% used. (2) We can trigger the output routine two times for each
% page. The first time we insert the \write, put the page back to
% the page builder and insert a special penalty, -\foot at penalty,
% which must be less than -\@maxpenalty and which must not be used
% by the macro package. The value 20001 is suitable for PLAIN TeX
% and LaTeX.
% @~ system dependencies @>
% The next time the \outputpenalty of the first time is restored
% and the original output routine is called. This handling is only
% done if text output appears, otherwise the original output routine
% is called directly. The following output routine evolves:
%
% \output={
% \ifnum \outputpenalty < -\@maxpenalty
% \perhaps at restore@penalty
% <original output>
% \else
% \global\@utputpenalty = \outputpenalty
% \write\foot at file{ \@footno = 0 }
% \unvbox 255
% \penalty -\foot at penalty
% \fi
% }
%
% <original output> is the contents of the output token register
% before executing the statement below. To insert it in the new
% contents of the output register, the old output register must
% be evaluated before the assignment is done. We use \expandafter
% to skip over all preceding tokens.
\newcount\@utputpenalty % save register for \outputpenalty
\mathchardef\foot at penalty=20001 % penalty not used in macro package
\output=\expandafter{%
\expandafter\ifnum
\expandafter\outputpenalty \expandafter<%
\expandafter-\expandafter\@maxpenalty
\expandafter\perhaps at restore@penalty
\the\output
\else \global\@utputpenalty=\outputpenalty
\write\foot at file{\@footno\z@}%
\nobreak
\unvbox\@cclv
\penalty -\foot at penalty
\fi
}
\gdef\perhaps at restore@penalty{%
\ifnum \outputpenalty=-\foot at penalty
\global\outputpenalty=\@utputpenalty
\fi
}
% 9. The last section is the reading of the footnote file. We have
% to read in macros with names containing `@' characters. This
% will be done in horizontal mode, so we have to ignore lineends
% to discard undesired spaces.
\gdef\read at foot@file{%
\begingroup
\catcode`\@=11 \catcode`\~~M=9 \relax
\input \foot at file@name
\endgroup
}
\catcode`\@=12
\endgroup
---------- cut here ------------------------------------------------------
_________________________________________________________________
http://clk.atdmt.com/UKM/go/197222280/direct/01/
We want to hear all your funny, exciting and crazy Hotmail stories. Tell us now
More information about the texhax
mailing list