chiark / gitweb /
.mdw-build.conf: Don't try `vpath' builds with this package.
[mdwtools] / footnote.dtx
1 % \begin{meta-comment}
2 %
3 % $Id: footnote.dtx,v 1.2 2002/03/13 21:50:04 mdw Exp $
4 %
5 % Save footnotes around boxing environments and things
6 %
7 % (c) 1996 Mark Wooding
8 %
9 % \end{meta-comment}
10 %
11 % \begin{meta-comment} <general public licence>
12 %%
13 %% footnote package -- Save footnotes around boxing environments
14 %% Copyright (c) 1996 Mark Wooding
15 %<*package>
16 %%
17 %% This program is free software; you can redistribute it and/or modify
18 %% it under the terms of the GNU General Public License as published by
19 %% the Free Software Foundation; either version 2 of the License, or
20 %% (at your option) any later version.
21 %%
22 %% This program is distributed in the hope that it will be useful,
23 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
24 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 %% GNU General Public License for more details.
26 %%
27 %% You should have received a copy of the GNU General Public License
28 %% along with this program; if not, write to the Free Software
29 %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 %</package>
31 %%
32 % \end{meta-comment}
33 %
34 % \begin{meta-comment} <Package preamble>
35 %<+package>\NeedsTeXFormat{LaTeX2e}
36 %<+package>\ProvidesPackage{footnote}
37 %<+package>                [1997/01/28 1.13 Save footnotes around boxes]
38 % \end{meta-comment}
39 %
40 % \CheckSum{328}
41 %\iffalse
42 %<*package>
43 %\fi
44 %% \CharacterTable
45 %%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
46 %%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
47 %%   Digits        \0\1\2\3\4\5\6\7\8\9
48 %%   Exclamation   \!     Double quote  \"     Hash (number) \#
49 %%   Dollar        \$     Percent       \%     Ampersand     \&
50 %%   Acute accent  \'     Left paren    \(     Right paren   \)
51 %%   Asterisk      \*     Plus          \+     Comma         \,
52 %%   Minus         \-     Point         \.     Solidus       \/
53 %%   Colon         \:     Semicolon     \;     Less than     \<
54 %%   Equals        \=     Greater than  \>     Question mark \?
55 %%   Commercial at \@     Left bracket  \[     Backslash     \\
56 %%   Right bracket \]     Circumflex    \^     Underscore    \_
57 %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
58 %%   Right brace   \}     Tilde         \~}
59 %%
60 %\iffalse
61 %</package>
62 %\fi
63 %
64 % \begin{meta-comment} <driver>
65 %
66 %<*driver>
67 \input{mdwtools}
68 \describespackage{footnote}
69 \mdwdoc
70 %</driver>
71 %
72 % \end{meta-comment}
73 %
74 % \section{User guide}
75 %
76 % This package provides some commands for handling footnotes slightly
77 % better than \LaTeX\ usually does; there are several commands and
78 % environments (notably |\parbox|, \env{minipage} and \env{tabular}
79 % \begin{footnote}
80 %   The \package{mdwtab} package, provided in this distribution, handles
81 %   footnotes correctly anyway; it uses an internal version of this package
82 %   to do so.
83 % \end{footnote})
84 % which `trap' footnotes so that they can't escape and appear at the bottom
85 % of the page.
86 %
87 % \DescribeEnv{savenotes}
88 % The \env{savenotes} environment saves up any footnotes encountered within
89 % it, and performs them all at the end.
90 %
91 % \DescribeMacro{\savenotes}
92 % \DescribeMacro{\spewnotes}
93 % If you're defining a command or environment, you can use the |\savenotes|
94 % command to start saving up footnotes, and the |\spewnotes| command to
95 % execute them all at the end.  Note that |\savenotes| and |\spewnotes|
96 % enclose a group, so watch out.  You can safely nest the commands and
97 % environments -- they work out if they're already working and behave
98 % appropriately.
99 %
100 % \DescribeEnv{minipage*}
101 % To help things along a bit, the package provides a $*$-version of the
102 % \env{minipage} environment, which doesn't trap footnotes for itself (and
103 % in fact sends any footnotes it contains to the bottom of the page, where
104 % they belong).
105 %
106 % \DescribeMacro{\makesavenoteenv}
107 % The new \env{minipage$*$} environment was created with a magic command
108 % called |\makesavenoteenv|.  It has a fairly simple syntax:
109 %
110 % \begin{grammar}
111 % <make-save-note-env-cmd> ::= \[[
112 %   "\\makesavenoteenv"
113 %   \begin{stack} \\ "[" <new-env-name> "]" \end{stack}
114 %   "{" <env-name> "}"
115 % \]]
116 % \end{grammar}
117 %
118 % Without the optional argument, it redefines the named environment so that
119 % it handles footnotes correctly.  With the optional argument, it makes
120 % the new environment named by \<new-env-name> into a footnote-friendly
121 % version of the \<env-name> environment.
122 %
123 % \DescribeMacro{\parbox}
124 % The package also redefines the |\parbox| command so that it works properly
125 % with footnotes.
126 %
127 % \DescribeEnv{footnote}
128 % The other problem which people tend to experience with footnotes is that
129 % you can't put verbatim text (with the |\verb| comamnd or the \env{verbatim}
130 % environment) into the |\footnote| command's argument.  This package
131 % provides a \env{footnote} \emph{environment}, which \emph{does} allow
132 % verbatim things.  You use the environment just like you do the command.
133 % It's really easy.  It even has an optional argument, which works the same
134 % way.
135 %
136 % \DescribeEnv{footnotetext}
137 % To go with the \env{footnote} environment, there's a \env{footnotetext}
138 % environment, which just puts the text in the bottom of the page, like
139 % |\footnotetext| does.
140 %
141 % There's a snag with these environments, though.  Some other nonstandard
142 % environments, like \env{tabularx}, try to handle footnotes their own
143 % way, because they won't work otherwise.  The way they do this is not
144 % compatible with the way that the \env{footnote} and \env{footnotetext}
145 % environments work, and you will get strange results if you try (there'll
146 % be odd vertical spacing, and the footnote text may well be incorrect).
147 % \begin{footnote}
148 %   The solution to this problem is to send mail to David Carlisle persuading
149 %   him to use this package to handle footnotes, rather than doing it his
150 %   way.
151 % \end{footnote}
152 %
153 % \implementation
154 %
155 % \section{Implementation}
156 %
157 % Most implementations of footnote-saving (in particular, that used in
158 % the \package{tabularx} and \package{longtable} packages) use a token
159 % list register to store the footnote text, and then expand it when whatever
160 % was preventing footnotes (usually a vbox) stops.  This is no good at all
161 % if the footnotes contain things which might not be there by the time the
162 % expansion occurs.  For example, references to things in temporary boxes
163 % won't work.
164 %
165 % This implementation therefore stores the footnotes up in a box register.
166 % This must be just as valid as using tokens, because all I'm going to do
167 % at the end is unbox the box).
168 %
169 %    \begin{macrocode}
170 %<*macro|package>
171 \ifx\fn@notes\@@undefined%
172   \newbox\fn@notes%
173 \fi
174 %    \end{macrocode}
175 %
176 % I'll need a length to tell me how wide the footnotes should be at the
177 % moment.
178 %
179 %    \begin{macrocode}
180 \newdimen\fn@width
181 %    \end{macrocode}
182 %
183 % Of course, I can't set this up until I actually start saving footnotes.
184 % Until then I'll use |\columnwidth| (which works in \package{multicol}
185 % even though it doesn't have any right to).
186 %
187 %    \begin{macrocode}
188 \let\fn@colwidth\columnwidth
189 %    \end{macrocode}
190 %
191 % And now a switch to remember if we're already handling footnotes,
192 %
193 %    \begin{macrocode}
194 \newif\if@savingnotes
195 %    \end{macrocode}
196 %
197 %
198 % \subsection{Building footnote text}
199 %
200 % I need to emulate \LaTeX's footnote handling when I'm putting the notes
201 % into my box; this is also useful in the verbatim-in-footnotes stuff.
202 %
203 % \begin{macro}{\fn@startnote}
204 %
205 % Here's how a footnote gets started.  Most of the code here is stolen
206 % from |\@footnotetext|.
207 %
208 %    \begin{macrocode}
209 \def\fn@startnote{%
210   \hsize\fn@colwidth%
211   \interlinepenalty\interfootnotelinepenalty%
212   \reset@font\footnotesize%
213   \floatingpenalty\@MM% Is this right???
214   \@parboxrestore%
215   \protected@edef\@currentlabel{\csname p@\@mpfn\endcsname\@thefnmark}%
216   \color@begingroup%
217 }
218 %    \end{macrocode}
219 %
220 % \end{macro}
221 %
222 % \begin{macro}{\fn@endnote}
223 %
224 % Footnotes are finished off by this macro.  This is the easy bit.
225 %
226 %    \begin{macrocode}
227 \let\fn@endnote\color@endgroup
228 %    \end{macrocode}
229 %
230 % \end{macro}
231 %
232 %
233 % \subsection{Footnote saving}
234 %
235 % \begin{macro}{\fn@fntext}
236 %
237 % Now to define how to actually do footnotes.  I'll just add the notes to
238 % the bottom of the footnote box I'm building.
239 %
240 % There's some hacking added here to handle the case that a footnote is
241 % in an |\intertext| command within a broken \package{amsmath} alignment
242 % environment -- otherwise the footnotes get duplicated due to the way that
243 % that package measures equations.
244 % \begin{footnote}
245 %   The correct solution of course is to
246 %   implement aligning environments in a sensible way, by building the table
247 %   and leaving penalties describing the intended format, and then pick that
248 %   apart in a postprocessing phase.  If I get the time, I'll start working
249 %   on this again.  I have a design worked out and the beginnings of an
250 %   implementation, but it's going to be a long time coming.
251 % \end{footnote}
252 %
253 %    \begin{macrocode}
254 \long\def\fn@fntext#1{%
255   \ifx\ifmeasuring@\@@undefined%
256     \expandafter\@secondoftwo\else\expandafter\@iden%
257   \fi%
258   {\ifmeasuring@\expandafter\@gobble\else\expandafter\@iden\fi}%
259   {%
260     \global\setbox\fn@notes\vbox{%
261       \unvbox\fn@notes%
262       \fn@startnote%
263       \@makefntext{%
264         \rule\z@\footnotesep%
265         \ignorespaces%
266         #1%
267         \@finalstrut\strutbox%
268       }%
269       \fn@endnote%
270     }%
271   }%
272 }
273 %    \end{macrocode}
274 %
275 % \end{macro}
276 %
277 % \begin{macro}{\savenotes}
278 %
279 % The |\savenotes| declaration starts saving footnotes, to be spewed at a
280 % later date.  We'll also remember which counter we're meant to use, and
281 % redefine the footnotes used by minipages.
282 %
283 % The idea here is that we'll gather up footnotes within the environment,
284 % and output them in whatever format they were being typeset outside the
285 % environment.
286 %
287 % I'll take this a bit at a time.  The start is easy: we need a group in
288 % which to keep our local definitions.
289 %
290 %    \begin{macrocode}
291 \def\savenotes{%
292   \begingroup%
293 %    \end{macrocode}
294 %
295 % Now, if I'm already saving footnotes away, I won't bother doing anything
296 % here.  Otherwise I need to start hacking, and set the switch.
297 %
298 %    \begin{macrocode}
299   \if@savingnotes\else%
300     \@savingnotestrue%
301 %    \end{macrocode}
302 %
303 % I redefine the |\@footnotetext| command, which is responsible for adding
304 % a footnote to the appropriate insert.  I'll redefine both the current
305 % version, and \env{minipage}'s specific version, in case there's a nested
306 % minipage.
307 %
308 %    \begin{macrocode}
309     \let\@footnotetext\fn@fntext%
310     \let\@mpfootnotetext\fn@fntext%
311 %    \end{macrocode}
312 %
313 % I'd better make sure my box is empty before I start, and I must set up
314 % the column width so that later changes (e.g., in \env{minipage}) don't
315 % upset things too much.
316 %
317 %    \begin{macrocode}
318     \fn@width\columnwidth%
319     \let\fn@colwidth\fn@width%
320     \global\setbox\fn@notes\box\voidb@x%
321 %    \end{macrocode}
322 %
323 % Now for some yuckiness.  I want to ensure that \env{minipage} doesn't
324 % change how footnotes are handled once I've taken charge.  I'll store the
325 % current values of |\thempfn| (which typesets a footnote marker) and
326 % |\@mpfn| (which contains the name of the current footnote counter).
327 %
328 %    \begin{macrocode}
329     \let\fn@thempfn\thempfn%
330     \let\fn@mpfn\@mpfn%
331 %    \end{macrocode}
332 %
333 % The \env{minipage} environment provides a hook, called |\@minipagerestore|.
334 % Initially it's set to |\relax|, which is unfortunately unexpandable, so if
335 % I want to add code to it, I must check this possibility.  I'll make it
336 % |\@empty| (which expands to nothing) if it's still |\relax|.  Then I'll
337 % add my code to the hook, to override |\thempfn| and |\@mpfn| set up by
338 % \env{minipage}.
339 %
340 % Note that I can't just force the |mpfootnote| counter to be equal to
341 % the |footnote| one, because \env{minipage} clears |\c@mpfootnote| to zero
342 % when it starts.  This method will ensure that even so, the current counter
343 % works OK.
344 %
345 %    \begin{macrocode}
346     \ifx\@minipagerestore\relax\let\@minipagerestore\@empty\fi%
347     \expandafter\def\expandafter\@minipagerestore\expandafter{%
348       \@minipagerestore%
349       \let\thempfn\fn@thempfn%
350       \let\@mpfn\fn@mpfn%
351     }%
352   \fi%
353 }
354 %    \end{macrocode}
355 %
356 % \end{macro}
357 %
358 % \begin{macro}{\spewnotes}
359 %
360 % Now I can spew out the notes we saved.  This is a bit messy, actually.
361 % Since the standard |\@footnotetext| implementation tries to insert funny
362 % struts and things, I must be a bit careful.  I'll disable all this bits
363 % which start paragraphs prematurely.
364 %
365 %    \begin{macrocode}
366 \def\spewnotes{%
367   \endgroup%
368   \if@savingnotes\else\ifvoid\fn@notes\else\begingroup%
369     \let\@makefntext\@empty%
370     \let\@finalstrut\@gobble%
371     \let\rule\@gobbletwo%
372     \@footnotetext{\unvbox\fn@notes}%
373   \endgroup\fi\fi%
374 }
375 %    \end{macrocode}
376 %
377 % \end{macro}
378 %
379 % Now make an environment, for users.
380 %
381 %    \begin{macrocode}
382 \let\endsavenotes\spewnotes
383 %    \end{macrocode}
384 %
385 % That's all that needs to be in the shared code section.
386 %
387 %    \begin{macrocode}
388 %</macro|package>
389 %<*package>
390 %    \end{macrocode}
391 %
392 %
393 % \subsection{The \env{footnote} environment}
394 %
395 % Since |\footnote| is a command with an argument, things like \env{verbatim}
396 % are unwelcome in it.  Every so often someone on |comp.text.tex| moans
397 % about it and I post a nasty hack to make it work.  However, as a more
398 % permanent and `official' solution, here's an environment which does the
399 % job rather better.  Lots of this is based on code from my latest attempt
400 % on the newsgroup.
401 %
402 % I'll work on this in a funny order, although I think it's easier to
403 % understand.  First, I'll do some macros for reading the optional argument
404 % of footnote-related commands.
405 %
406 % \begin{macro}{\fn@getmark}
407 %
408 % Saying \syntax{"\\fn@getmark{"<default-code>"}{"<cont-code>"}"} will read
409 % an optional argument giving a value for the footnote counter; if the
410 % argument isn't there, the \<default-code> is executed, and it's expected
411 % to set up the appropriate counter to the current value.  The footnote
412 % marker text is stored in the macro |\@thefnmark|, as is conventional for
413 % \LaTeX's footnote handling macros.  Once this is done properly, the
414 % \<cont-code> is called to continue handling things.
415 %
416 % Since the handling of the optional argument plays with the footnote
417 % counter locally, I'll start a group right now to save some code.  Then I'll
418 % decide what to do based on the presence of the argument.
419 %
420 %    \begin{macrocode}
421 \def\fn@getmark#1#2{%
422   \begingroup%
423   \@ifnextchar[%
424     {\fn@getmark@i{#1}}%
425     {#1\fn@getmark@ii{#2}}%
426 }
427 %    \end{macrocode}
428 %
429 % There's an optional argument, so I need to read it and assign it to the
430 % footnote counter.
431 %
432 %    \begin{macrocode}
433 \def\fn@getmark@i#1[#2]{%
434   \csname c@\@mpfn\endcsname#2%
435   \fn@getmark@ii%
436 }
437 %    \end{macrocode}
438 %
439 % Finally, set up the macro properly, and end the group.
440 %
441 %    \begin{macrocode}
442 \def\fn@getmark@ii#1{%
443   \unrestored@protected@xdef\@thefnmark{\thempfn}%
444   \endgroup%
445   #1%
446 }
447 %    \end{macrocode}
448 %
449 % \end{macro}
450 %
451 % From argument reading, I'll move on to footnote typesetting.
452 %
453 % \begin{macro}{\fn@startfntext}
454 %
455 % The |\fn@startfntext| macro sets everything up for building the footnote
456 % in a box register, ready for unboxing into the footnotes insert.  The
457 % |\fn@prefntext| macro is a style hook I'll set up later.
458 %
459 %    \begin{macrocode}
460 \def\fn@startfntext{%
461   \setbox\z@\vbox\bgroup%
462     \fn@startnote%
463     \fn@prefntext%
464     \rule\z@\footnotesep%
465     \ignorespaces%
466 }
467 %    \end{macrocode}
468 %
469 % \end{macro}
470 %
471 % \begin{macro}{\fn@endfntext}
472 %
473 % Now I'll end the vbox, and add it to the footnote insertion.  Again, I
474 % must be careful to prevent |\@footnotetext| from adding horizontal mode
475 % things in bad places.
476 %
477 %    \begin{macrocode}
478 \def\fn@endfntext{%
479     \@finalstrut\strutbox%
480     \fn@postfntext%
481   \egroup%
482   \begingroup%
483     \let\@makefntext\@empty%
484     \let\@finalstrut\@gobble%
485     \let\rule\@gobbletwo%
486     \@footnotetext{\unvbox\z@}%
487   \endgroup%
488 }
489 %    \end{macrocode}
490 %
491 % \end{macro}
492 %
493 % \begin{environment}{footnote}
494 %
495 % I can now start on the environment proper.  First I'll look for an
496 % optional argument.
497 %
498 %    \begin{listing}
499 %\def\footnote{%
500 %    \end{listing}
501 %
502 % Oh.  I've already come up against the first problem: that name's already
503 % used.  I'd better save the original version.
504 %
505 %    \begin{macrocode}
506 \let\fn@latex@@footnote\footnote
507 %    \end{macrocode}
508 %
509 % The best way I can think of for seeing if I'm in an environment is to
510 % look at |\@currenvir|.  I'll need something to compare with, then.
511 %
512 %    \begin{macrocode}
513 \def\fn@footnote{footnote}
514 %    \end{macrocode}
515 %
516 % Now to start properly.  |;-)|
517 %
518 %    \begin{macrocode}
519 \def\footnote{%
520   \ifx\@currenvir\fn@footnote%
521     \expandafter\@firstoftwo%
522   \else%
523     \expandafter\@secondoftwo%
524   \fi%
525   {\fn@getmark{\stepcounter\@mpfn}%
526               {\leavevmode\unskip\@footnotemark\fn@startfntext}}%
527   {\fn@latex@@footnote}%
528 }
529 %    \end{macrocode}
530 %
531 % Ending the environment is simple.
532 %
533 %    \begin{macrocode}
534 \let\endfootnote\fn@endfntext
535 %    \end{macrocode}
536 %
537 % \end{environment}
538 %
539 % \begin{environment}{footnotetext}
540 %
541 % I'll do the same magic as before for |\footnotetext|.
542 %
543 %    \begin{macrocode}
544 \def\fn@footnotetext{footnotetext}
545 \let\fn@latex@@footnotetext\footnotetext
546 \def\footnotetext{%
547   \ifx\@currenvir\fn@footnotetext%
548     \expandafter\@firstoftwo%
549   \else%
550     \expandafter\@secondoftwo%
551   \fi%
552   {\fn@getmark{}\fn@startfntext}%
553   {\fn@latex@@footnotetext}%
554 }
555 \let\endfootnotetext\endfootnote
556 %    \end{macrocode}
557 %
558 % \end{environment}
559 %
560 % \begin{macro}{\fn@prefntext}
561 % \begin{macro}{\fn@postfntext}
562 %
563 % Now for one final problem.  The style hook for footnotes is the command
564 % |\@makefntext|, which takes the footnote text as its argument.  Clearly
565 % this is utterly unsuitable, so I need to split it into two bits, where
566 % the argument is.  This is very tricky, and doesn't deserve to work,
567 % although it appears to be a good deal more effective than it has any right
568 % to be.
569 %
570 %    \begin{macrocode}
571 \long\def\@tempa#1\@@#2\@@@{\def\fn@prefntext{#1}\def\fn@postfntext{#2}}
572 \expandafter\@tempa\@makefntext\@@\@@@
573 %    \end{macrocode}
574 %
575 % \end{macro}
576 % \end{macro}
577 %
578 %
579 % \subsection{Hacking existing environments}
580 %
581 % Some existing \LaTeX\ environments ought to have footnote handling but
582 % don't.  Now's our chance.
583 %
584 % \begin{macro}{\makesavenoteenv}
585 %
586 % The |\makesavenoteenv| command makes an environment save footnotes around
587 % itself.
588 %
589 % It would also be nice to make |\parbox| work with footnotes.  I'll do this
590 % later.
591 %
592 %    \begin{macrocode}
593 \def\makesavenoteenv{\@ifnextchar[\fn@msne@ii\fn@msne@i}
594 %    \end{macrocode}
595 %
596 % We're meant to redefine the environment.  We'll copy it (using |\let|) to
597 % a magic name, and then pass it on to stage~2.
598 %
599 %    \begin{macrocode}
600 \def\fn@msne@i#1{%
601   \expandafter\let\csname msne$#1\expandafter\endcsname%
602                   \csname #1\endcsname%
603   \expandafter\let\csname endmsne$#1\expandafter\endcsname%
604                   \csname end#1\endcsname%
605   \fn@msne@ii[#1]{msne$#1}%
606 }
607 %    \end{macrocode}
608 %
609 % Now we'll define the new environment.  The start is really easy, since we
610 % just need to insert a |\savenotes|.  The end is more complex, since we
611 % need to preserve the |\if@endpe| flag so that |\end| can pick it up.  I
612 % reckon that proper hooks should be added to |\begin| and |\end| so that
613 % environments can define things to be done outside the main group as
614 % well as within it; still, we can't all have what we want, can we?
615 %
616 %    \begin{macrocode}
617 \def\fn@msne@ii[#1]#2{%
618   \expandafter\edef\csname#1\endcsname{%
619     \noexpand\savenotes%
620     \expandafter\noexpand\csname#2\endcsname%
621   }%
622   \expandafter\edef\csname end#1\endcsname{%
623     \expandafter\noexpand\csname end#2\endcsname%
624     \noexpand\expandafter%
625     \noexpand\spewnotes%
626     \noexpand\if@endpe\noexpand\@endpetrue\noexpand\fi%
627   }%
628 }
629 %    \end{macrocode}
630 %
631 % \end{macro}
632 %
633 % \begin{environment}{minipage*}
634 %
635 % Let's define a \env{minipage$*$} environment which handles footnotes
636 % nicely.  Really easy:
637 %
638 %    \begin{macrocode}
639 \makesavenoteenv[minipage*]{minipage}
640 %    \end{macrocode}
641 %
642 % \end{environment}
643 %
644 % \begin{macro}{\parbox}
645 %
646 % Now to alter |\parbox| slightly, so that it handles footnotes properly.
647 % I'm going to do this fairly inefficiently, because I'm going to try and
648 % change it as little as possible.
649 %
650 % First, I'll save the old |\parbox| command.  If I don't find a \lit{*},
651 % I'll just call this command.
652 %
653 %    \begin{macrocode}
654 \let\fn@parbox\parbox
655 %    \end{macrocode}
656 %
657 % This is the clever bit: I don't know how many optional arguments
658 % Mr~Mittelbach and his chums will add to |\parbox|, so I'll handle any
659 % number.  I'll store them all up in my first argument and call myself
660 % every time I find a new one.  If I run out of optional arguments,
661 % I'll call the original |\parbox| command, surrounding it with |\savenotes|
662 % and |\spewnotes|.
663 %
664 %    \begin{macrocode}
665 \def\parbox{\@ifnextchar[{\fn@parbox@i{}}{\fn@parbox@ii{}}}
666 \def\fn@parbox@i#1[#2]{%
667   \@ifnextchar[{\fn@parbox@i{#1[#2]}}{\fn@parbox@ii{#1[#2]}}%
668 }
669 \long\def\fn@parbox@ii#1#2#3{\savenotes\fn@parbox#1{#2}{#3}\spewnotes}
670 %    \end{macrocode}
671 %
672 % \end{macro}
673 %
674 % Done!
675 %
676 %    \begin{macrocode}
677 %</package>
678 %    \end{macrocode}
679 %
680 % \hfill Mark Wooding, \today
681 %
682 % \Finale
683 %
684 \endinput