Remove the redundant file headers.
[mdwtools] / doafter.dtx
CommitLineData
86f6a31e 1% \begin{meta-comment} <general public licence>
2%%
3%% doafter package -- insert a token really after a group
4%% Copyright (c) 1996 Peter Schmitt and Mark Wooding
5%<*package>
6%%
7%% This program is free software; you can redistribute it and/or modify
8%% it under the terms of the GNU General Public License as published by
9%% the Free Software Foundation; either version 2 of the License, or
10%% (at your option) any later version.
11%%
12%% This program is distributed in the hope that it will be useful,
13%% but WITHOUT ANY WARRANTY; without even the implied warranty of
14%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15%% GNU General Public License for more details.
16%%
17%% You should have received a copy of the GNU General Public License
18%% along with this program; if not, write to the Free Software
19%% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20%</package>
21%%
22% \end{meta-comment}
23%
24% \begin{meta-comment} <Package preamble>
25%<+latex2e>\NeedsTeXFormat{LaTeX2e}
26%<+latex2e>\ProvidesPackage{doafter}
8995c091 27%<+latex2e> [1996/05/08 1.2 Aftergroup hacking]
86f6a31e 28% \end{meta-comment}
29%
30% \CheckSum{259}
31%\iffalse
32%<*package>
33%\fi
34%% \CharacterTable
35%% {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
36%% 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
37%% Digits \0\1\2\3\4\5\6\7\8\9
38%% Exclamation \! Double quote \" Hash (number) \#
39%% Dollar \$ Percent \% Ampersand \&
40%% Acute accent \' Left paren \( Right paren \)
41%% Asterisk \* Plus \+ Comma \,
42%% Minus \- Point \. Solidus \/
43%% Colon \: Semicolon \; Less than \<
44%% Equals \= Greater than \> Question mark \?
45%% Commercial at \@ Left bracket \[ Backslash \\
46%% Right bracket \] Circumflex \^ Underscore \_
47%% Grave accent \` Left brace \{ Vertical bar \|
48%% Right brace \} Tilde \~}
49%%
50%\iffalse
51%</package>
52%\fi
53%
54% \begin{meta-comment} <driver>
55%
56%<*driver>
57\input{mdwtools}
58\describespackage{doafter}
59\author{Peter Schmitt\thanks{%
60 Peter came up with the basic implementation after I posed the problem
61 in the \texttt{comp.text.tex} newsgroup. I fixed some really piddly little
62 things, to improve it a bit, wrote the documentation, and turned the code
63 into a nice \package{doc}ced package. Then Peter gave me an updated
64 version, and I upgraded this from memory. Then he gave me some more tweaks
65 which I haven't incorporated.}
66 \and Mark Wooding}
67\def\author#1{}
68\mdwdoc
69%</driver>
70%
71% \end{meta-comment}
72%
73% \section{Description}
74%
75% \subsection{What it's all about}
76%
77% \DescribeMacro{\doafter}
78% It's common for the \TeX\ primitive |\aftergroup| to be used to `tidy up'
79% after a group. For example, \LaTeX's colour handling uses this to insert
80% appropriate |\special|s when the scope of a colour change ends. This
81% causes several problems, though; for example, extra grouping must be added
82% within boxes to ensure that the |\special|s don't `leak' out of their box
83% and appear in odd places in the document. \LaTeX\ usually solves this
84% problem by reading the box contents as an argument, although this isn't
85% particularly desirable. The |\doafter| macro provided here will solve the
86% problem in a different way, by allowing a macro to regain control after
87% all the |\aftergroup| things have been processed.
88%
89% The macro works like this:
90% \begin{grammar}
91% <doafter-cmd> ::= \[[
92% "\\doafter" <token> <group>
93% \]]
94% \end{grammar}
95% The \<token> can be any token you like, except an explicit braces, since
96% it's read as an undelimited macro argument. The \<group> is a normal
97% \TeX\ group, surrounded by either implicit or explicit braces, or by
98% |\begingroup| and |\endgroup| tokens. Once the final closing token of the
99% \<group> is read, and any tokens saved up by |\aftergroup| have been
100% processed, the \<token> is inserted and processed. Under normal
101% circumstances, this will be a macro.
102%
103% There are some subtle problems with the current implementation, which you
104% may need to be aware of:
105%
106% \begin{itemize}
107%
108% \item Since we're inserting things after all the |\aftergroup| tokens,
109% those tokens might read something they're not expecting if they try
110% to look ahead at the text after the group (e.g., with |\futurelet|).
111% This is obviously totally unavoidable.
112%
113% \item Implicit braces (like |\bgroup| and |\egroup|) inserted using
114% |\aftergroup| may be turned into \emph{explicit} $|{|_1$ and $|}|_2$
115% characters within a |\doafter| group. This can cause probems under
116% very specialised circumstances. The names |\bgroup| and |\egroup|
117% are treated specially, and they will work normally (remaining as
118% implicit braces). This should minimise problems caused by this
119% slight difference. (This only applies to the last |\aftergroup|
120% token in a group.)
121%
122% \item To handle the |\aftergroup| tokens properly, |\doafter| has to insert
123% some |\aftergroup| tokens of its own. It will then process the
124% other tokens some more, and set them up to be read again. This does
125% mean that after the group ends, some assignments and other `stomach
126% operations' will be performed, which may cause problems in
127% alignments and similar places.
128%
129% \end{itemize}
130%
131%
132% \subsection{Package options}
133%
134% There are a fair few \textsf{docstrip} options provided by this packge:
135%
136% \begin{description}
137% \item [driver] extracts the documentation driver. This isn't usually
138% necessary.
139% \item [package] extracts the code as a standalone package, formatted for
140% either \LaTeXe\ or Plain~\TeX.
141% \item [latex2e] inserts extra identification code for a \LaTeXe\ package.
142% \item [plain] inserts some extra code for a Plain \TeX\ package.
143% \item [macro] just extracts the raw code, for inclusion in another package.
144% \item [test] extracts some code for testing the current implementation.
145% \end{description}
146%
147%
148% \implementation
149%
150% \section{Implementation}
151%
152% \subsection{The main macro}
153%
154% We start outputting code here. If this is a Plain~\TeX\ package, we must
155% make \lit{@} into a letter.
156%
157% \begin{macrocode}
158%<*macro|package>
159%<+plain>\catcode`\@=11
160% \end{macrocode}
161%
162% \begin{macro}{\doafter}
163%
164% The idea is to say \syntax{"\\doafter" <token> <group>} and expect the
165% \synt{token} to be processed after the group has finished its stuff,
166% even if it contains |\aftergroup| things. My eternal gratitude goes to
167% Peter Schmitt, who came up with most of the solution implemented here;
168% I've just tidied up some very minor niggles and things later.
169%
170% Let's start with some preamble. I'll save the (hopefully) primitive
171% |\aftergroup| in a different token.
172%
173% \begin{macrocode}
174\let\@@aftergroup\aftergroup
175% \end{macrocode}
176%
177% Now to define the `user' interface. It takes a normal undelimited
178% argument, although this must be a single token; otherwise eveything will
179% go wrong. It assumes that the token following is some kind of group
180% opening thing (an explicit or implicit character with catcode~1, or
181% a |\begingroup| token). To make this work, I'll save the token,
182% together with an |\@@aftergroup| (to save an |\expandafter| later) in
183% a temporary macro which no-one will mind me using, and then look ahead at
184% the beginning-group token.
185%
186% \begin{macrocode}
187\def\doafter#1{%
188 \def\@tempa{\@@aftergroup#1}%
189 \afterassignment\doafter@i\let\@let@token%
190}
191% \end{macrocode}
192%
193% I now have the token in |\@let@token|, so I'll put that in. I'll then
194% make |\aftergroup| do my thing rather than the normal thing, and queue
195% the tokens |\@prepare@after| and the |\doafter| argument for later use.
196%
197% \begin{macrocode}
198\def\doafter@i{%
199 \@let@token%
200 \let\aftergroup\@my@aftergroup%
201 \@@aftergroup\@prepare@after\@tempa%
202}
203% \end{macrocode}
204%
205% \end{macro}
206%
207% \begin{macro}{\@my@aftergroup}
208%
209% Now the cleverness begins. We keep two macros (Peter's original used
210% count registers) which keep counts of the numbers of |\aftergroup|s,
211% both locally and globally. Let's call the local counter~$n$ and the
212% global one $N$. Every time we get a call to our |\aftergroup| hack,
213% we set~$n := n+1$ and~$N := n$, and leave the token given to us for later
214% processing. When we actually process an |\aftergroup| token properly,
215% set~$N := N-1$ to indicate that it's been handled; when they're all done,
216% we'll have $N=n$, which is exactly what we'd have if there weren't any
217% to begin with.
218%
219% \begin{macrocode}
220\def\ag@cnt@local{0 }
221\let\ag@cnt@global\ag@cnt@local
222% \end{macrocode}
223%
224% Now we come to the definition of my version of |\aftergroup|. I'll just
225% add the token |\@after@token| before every |\aftergroup| token I find.
226% This means there's two calls to |\aftergroup| for every one the user makes,
227% but these things aren't all that common, so it's OK really. I'll also
228% bump the local counter, and synchronise them.
229%
230% \begin{macrocode}
231\def\@my@aftergroup{%
232 \begingroup%
233 \count@\ag@cnt@local%
234 \advance\count@\@ne%
235 \xdef\ag@cnt@global{\the\count@\space}%
236 \endgroup%
237 \let\ag@cnt@local\ag@cnt@global%
238 \@@aftergroup\@after@token\@@aftergroup%
239}
240% \end{macrocode}
241%
242% \end{macro}
243%
244% Now what does |\@after@token| we inserted above actually do? Well, this
245% is more exciting. There are actually two different variants of the
246% macro, which are used at different times.
247%
248% \begin{macro}{\@after@token}
249%
250% The default |\@after@token| starts a group, which will `catch'
251% |\aftergroup| tokens which I throw at it. I put the two counters into
252% some scratch count registers. (There's a slight problem here: Plain \TeX\
253% only gives us one. For the sake of evilness I'll use |\clubpenalty| as the
254% other one. Eeeek.) I then redefine |\@after@token| to the second
255% variant, and execute it. The |\@start@after@group| macro starts the
256% group, because this code is shared with |\@prepare@after| below.
257%
258% \begin{macrocode}
259\def\@after@token{%
260 \@start@after@group%
261 \@after@token%
262}
263\def\@start@after@group{%
264 \begingroup%
265 \count@\ag@cnt@global%
266 \clubpenalty\ag@cnt@local%
267 \let\@after@token\@after@token@i%
268}
269% \end{macrocode}
270%
271% \end{macro}
272%
273% \begin{macro}{\@after@token@i}
274%
275% I have $|\count@| = N$ and $|\@tempcnta| = n$. I'll decrement~$N$,
276% and if I have $N = n$, I know that this is the last token to do, so I
277% must insert an |\@after@all| after the token. This will close the group,
278% and maybe insert the original |\doafter| token if appropriate.
279%
280% \begin{macrocode}
281\def\@after@token@i{%
282 \advance\count@\m@ne%
283 \ifnum\count@=\clubpenalty%
284 \global\let\ag@cnt@global\ag@cnt@local%
285 \expandafter\@after@aftertoken\expandafter\@after@all%
286 \else%
287 \expandafter\@@aftergroup%
288 \fi%
289}
290% \end{macrocode}
291%
292% Finally, establish a default meaning for |\@after@all|.
293%
294% \begin{macrocode}
295\let\@after@all\endgroup
296% \end{macrocode}
297%
298% \end{macro}
299%
300% \begin{macro}{\@prepare@after}
301%
302% If this group is handled by |\doafter|, then the first |\aftergroup| token
303% isn't |\@after@token|; it's |\@prepare@after|.
304%
305% There are some extra cases to deal with:
306% \begin{itemize}
307% \item If $N=n$ then there were no |\aftergroup| tokens, so we have an easy
308% job. I'll just let the token do its stuff directly.
309% \item Otherwise, $N>n$, and there are |\aftergroup| tokens. I'll open
310% the group, and let |\@after@token| do all the handling.
311% \end{itemize}
312%
313% \begin{macrocode}
314\def\@prepare@after{%
315 \ifx\ag@cnt@local\ag@cnt@global\else%
316 \expandafter\@prepare@after@i%
317 \fi%
318}
319\def\@prepare@after@i#1{%
320 \@start@after@group%
321 \def\@after@all{\@@aftergroup#1\endgroup}%
322}
323% \end{macrocode}
324%
325% \end{macro}
326%
327% \begin{macro}{\@after@aftertoken}
328%
329% This is where all the difficulty lies. The next token in the stream is
330% an |\aftergroup| one, which could be more or less anything. We have an
331% argument, which is some code to do \emph{after} the token has been
332% |\aftergroup|ed.
333%
334% If the token is anything other than a brace (i.e., an explicit character
335% of category~1 or~2) then I have no problem; I can scoop up the token with
336% an undelimited macro argument. But the only way I can decide if this token
337% is a brace (nondestructively) is with |\futurelet|, which makes the token
338% implicit, so I can't decide whether it's really dangerous.
339%
340% There is a possible way of doing this\footnote{Due to Peter Schmitt,
341% again.} which relates to nobbling the offending token with |\string| and
342% sifting through the results. The problem here involves scooping up all the
343% tokens of a |\string|ed control sequence, which may turn out to be
344% `|\csname\endcsname|' or something equally horrid.
345%
346% The solution I've used is much simpler: I'll change |\bgroup| and |\egroup|
347% to stop them from being implicit braces before comparing.
348%
349% \begin{macrocode}
350\def\@after@aftertoken#1{%
351 \let\bgroup\relax\let\egroup\relax%
352 \toks@{#1}%
353 \futurelet\@let@token\@after@aftertoken@i%
354}
355\def\@after@aftertoken@i{%
356 \ifcat\noexpand\@let@token{%
357 \@@aftergroup{%
358 \else\ifcat\noexpand\@let@token}%
359 \@@aftergroup}%
360 \else%
361 \def\@tempa##1{\@@aftergroup##1\the\toks@}%
362 \expandafter\expandafter\expandafter\@tempa%
363 \fi\fi%
364}
365% \end{macrocode}
366%
367% \end{macro}
368%
369%
370% Phew!
371%
372% \begin{macrocode}
373%<+plain>\catcode`\@=12
374%</macro|package>
375% \end{macrocode}
376%
377% \subsection{Test code}
378%
379% The following code gives |\doafter| a bit of a testing. It's based on
380% the test suite I gave to comp.text.tex, although it's been improved a
381% little since then.
382%
383% The first thing to do is define a control sequence with an \lit{@} sign
384% in its name, so we can test catcode changes. This also hides an
385% |\aftergroup| within a macro, making life more difficult for prospective
386% implementations.
387%
388% \begin{macrocode}
389%<*test>
390\catcode`\@=11
391\def\at@name{\aftergroup\saynine}
392\def\saynine{\say{ix}}
393\catcode`\@=12
394% \end{macrocode}
395%
396% Now define a command to write a string to the terminal. The name will
397% probably be familiar to REXX hackers.
398%
399% \begin{macrocode}
400\def\say{\immediate\write16}
401% \end{macrocode}
402%
403% Test one: This is really easy; it just tests that the thing works at all.
404% If your implementation fails this, it's time for a major rethink.
405%
406% \begin{macrocode}
407\say{Test one... (1--2)}
408\def\saytwo{\say{ii}}
409\doafter\saytwo{\say{i}}
410% \end{macrocode}
411%
412% Test two: Does |\aftergroup| work?
413%
414% \begin{macrocode}
415\say{Test two... (1--4)}
416\def\saythree{\say{iii}}
417\def\sayfour{\say{iv}}
418\doafter\sayfour{\say{i}\aftergroup\saythree\say{ii}}
419% \end{macrocode}
420%
421% Test three: Test braces and |\iffalse| working as they should. Several
422% proposed solutions based on |\write|ing the group to a file get upset by
423% this test, although I forgot to include it in the torture test. It also
424% tests whether literal braces can be |\aftergroup|ed properly. (Added a new
425% test here, making sure that |\bgroup| is left as an implicit token.)
426%
427% \begin{macrocode}
428\say{Test three... (1--4, `\string\bgroup', 5)}
429\def\sayfive{\say{v}}
430\doafter\sayfive{%
431 \say{i}%
432 \aftergroup\say%
433 \aftergroup{%
434 \aftergroup\romannumeral\aftergroup3%
435 \aftergroup}%
436 \iffalse}\fi%
437 \aftergroup\def%
438 \aftergroup\sayfouretc%
439 \aftergroup{%
440 \aftergroup\say%
441 \aftergroup{%
442 \aftergroup i%
443 \aftergroup v%
444 \aftergroup}%
445 \aftergroup\say%
446 \aftergroup{%
447 \aftergroup\string%
448 \aftergroup\bgroup%
449 \aftergroup}%
450 \aftergroup}%
451 \aftergroup\sayfouretc%
452 \say{ii}%
453}
454% \end{macrocode}
455%
456% Test four: Make sure the implementation isn't leaking things. This just
457% makes sure that |\aftergroup| is its normal reasonable self.
458%
459% \begin{macrocode}
460\say{Test four... (1--3)}
461{\say{i}\aftergroup\saythree\say{ii}}
462% \end{macrocode}
463%
464% Test five: Nesting, aftergroup, catcodes, grouping. This is the `torture'
465% test I gave to comp.text.tex, slightly corrected (oops) and amended. It
466% ensures that nested groups and |\doafter|s work properly (the latter is
467% actually more likely than might be imagined).
468%
469% \begin{macrocode}
470\say{Test five... (1--14)}
471\def\sayten{\say{x}}
472\def\saythirteen{\say{xiii}}
473\def\sayfourteen{\say{xiv}}
474\doafter\sayfourteen\begingroup%
475 \say{i}%
476 {\say{ii}\aftergroup\sayfour\say{iii}}%
477 \def\saynum{\say{viii}}%
478 \doafter\sayten{%
479 \say{v}%
480 \def\saynum{\say{vii}}%
481 \catcode`\@=11%
482 \aftergroup\saynum%
483 \say{vi}%
484 \at@name%
485 \saynum%
486 }%
487 \say{xi}%
488 \aftergroup\saythirteen%
489 \say{xii}%
490\endgroup
491\end
492%</test>
493% \end{macrocode}
494%
495% That's it. All present and correct.
496%
497% \Finale
498%
499\endinput