diff options
Diffstat (limited to 'info/digests/texhax/txh/schrod.txh')
-rw-r--r-- | info/digests/texhax/txh/schrod.txh | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/info/digests/texhax/txh/schrod.txh b/info/digests/texhax/txh/schrod.txh new file mode 100644 index 0000000000..d9ec586199 --- /dev/null +++ b/info/digests/texhax/txh/schrod.txh @@ -0,0 +1,367 @@ + 4-Aug-87 23:16:27-PDT,14596;000000000000 +Return-Path: <XITIJSCH%DDATHD21.BITNET@forsythe.stanford.edu> +Date: 04. August 1987, 17:04:55 (CET) +From: XITIJSCH%DDATHD21.BITNET@forsythe.stanford.edu +Subject: Re: footnote numbering +To: TEXHAX@score.stanford.edu + + +In the TeXhax issue #60 Malcolm Brown asked for a possibility +to number footnotes subsequently on each page. He didn't state +if he needs this possibility, i.e. these macros, in a special +environment. In my eyes this is a nice small exercise to show +the development of TeX macros and therefore I send you this +contribution. + +First I introduce a macro set to number footnotes subsequently +on each page. This macro set is written with the concept of +literate programming in mind and is portable in the manner that few +changes have to be made to the macros to get them running with +every macro package that uses the PLAIN definitions (LaTeX does). +The macro set has been tested with PLAIN TeX, LaTeX and an other +macro package of my own, always with correct results. +But I have only spent a few hours to write and test the macros, +so don't blame me if errors occur. + +After introducing the macro set I close with some remarks on +TeX macro development, i.e. in TeX programming and I also +describe possible improvements to the macros and an other +solution strategy using LaTeX. + + +---------------------------------------------- +macro set for numbering footnotes on each page +---------- 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@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@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@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@file +\gdef\foot@file@name{\jobname.fot \relax} +\gdef\init@footnote{% + \openin\foot@file=\foot@file@name + \ifeof\foot@file \closein\foot@file + \else \closein\foot@file + \read@foot@file + \fi + \immediate\openout\foot@file=\foot@file@name + \immediate\write\foot@file{\relax}% + \let\init@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@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@footnote + \global\advance\footno by \@ne + \edef\@dowrite{% + \write\foot@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@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@restore@penalty +% <original output> +% \else +% \global\@utputpenalty = \outputpenalty +% \write\foot@file{ \@footno = 0 } +% \unvbox 255 +% \penalty -\foot@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@penalty=20001 % penalty not used in macro package + +\output=\expandafter{% + \expandafter\ifnum + \expandafter\outputpenalty \expandafter<% + \expandafter-\expandafter\@maxpenalty + \expandafter\perhaps@restore@penalty + \the\output + \else \global\@utputpenalty=\outputpenalty + \write\foot@file{\@footno\z@}% + \nobreak + \unvbox\@cclv + \penalty -\foot@penalty + \fi + } +\gdef\perhaps@restore@penalty{% + \ifnum \outputpenalty=-\foot@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@foot@file{% + \begingroup + \catcode`\@=11 \catcode`\~~M=9 \relax + \input \foot@file@name + \endgroup + } + + +\catcode`\@=12 +\endgroup + + + + + +---------- cut here ------------------------------------------------------ + + +For the use of the above macro set the following fact must be +obeyed: + + IT IS STATED EXPLICITLY THAT THE COMMENTS ARE AN INTEGRAL + PART OF THIS MACRO SET. IF THE MACRO SET IS ALTERED THE + COMMENTS HAVE TO BE ALTERED, TOO. THEY MUST NOT BE DELETED. + +The writing of TeX macros is a task of programming. The computer +science community has struggled for years to encourage structured +program development. The idea of literate programming is promoted +more and more (e.g. in the CACM). + + WHY DO WE THROW ALL THIS AWAY WHEN TeX MACROS ARE WRITTEN?? + +It is my opinion that the only satisfactory way to write TeX +macros which can be maintained is to use the principles of +literate programming: describing the macros for a human reader, +not for TeX. (Perhaps the time will come, when we get a TeX-WEB.) + +It could be said very much about this topic, but back to the +macros. They are not fully developed, some features are still +missing, e.g. warnings when new footnotes are inserted or +when footnote numbers have been changed. Other improvements +can be made on the construction of the footnote names. By +involving section numbers or analogous numbers the ``running +away'' of the footnote numbers (caused by the insertion of a +new footnote) can be limited. + +Scanning through the LaTeX source it seems to me that the +same realization idea can be implemented by writing appropriate +\newlabel commands to the auxiliary file and referencing +them. But I'm not sure---perhaps L.Lamport can state a comment. + + +Well, this has become a rather long piece. I hope, it helps you. + + + Joachim Schrod + +---------------------------------------------------------------- + + TH Darmstadt + Institut fuer Theoretische Informatik + Joachim Schrod + Alexanderstr. 24 + + D-6100 Darmstadt + West Germany + +------- |