You are on page 1of 5

58 TUGboat, Volume 9 (1988), No.

accomplish a complete expansion, one should use Here is an application of these macros (Examples 4
\edef, where further expansion can be prevented and 5 ) where one string is extracted from a set of
only with \noexpand. This example (using \zz as two strings.
a n argument to \xx), which would not work with % Define macro \a. In practice, \a
\expand& ter,does work with \edef: % would most likely be defined
% Equivalent to "\def\temp{\xx [ABC] )I1. % by a \read, or by a mark.
\edef\temp~\noexpand\xx\zz) \def\aC(First part){Second part))
\temp
As a side remark: Example 1 can also be pro- % Example 4: Generates "First part".
grammed without \expandafter,by using \edef: % Pick out first part of \a.
% Equivalent to "\def\temp{\xx [ABC])" . \expandafter\PickFirstOfTwo\a
\edef\tempC\noexpand\xx\yy)
\temp % Example 5: Generates "Second part".
% Pick out second part of \a.
Example 3 \expandafter\PickSecondOfTwo\a
In this example, (tokenl) is a definition. Let us analyze Example 4: \PickFirstOfTwo is
saved because of the \expandafter and \a is
\def \xxi\yy)
expanded to (First part3CSecond part). The
\expandafter\def\xx(This is fun)
two strings inside curly braces generated this way
\expandafter will temporarily suspend \def,which form the arguments of \PickFirstOfTwo, which
causes \xx being replaced by its replacement text is re-inserted in front of (First part)(Second
which is \yy. This example is therefore equivalent part). Finally, the macro call to \PickFirstOfTwo
to will be executed, leaving only First part on the
\def\yy(This is fun) main token list.
Naturally the above \Pick. . . macros could be
Examples 4 and 5: Using \expandafter to extended to pick out x arguments from y arguments,
pick out arguments where x 5 y, to offer a theoretical example.
Assume the following macro definitions \Pick. . .
Example 6: \expandafter and \read
of two macros: which both have two arguments and
which print only either the first argument or the The \expandafter can be used in connection with
second one. These macros can be used to pick out \read, which allows the user to read information
parts of some text stored in another macro. from a file, typically line by line. Assume that a
% \PickFirstOfTwo file being read in by the user contains one number
% This macro is called with two per line. Then an instruction like \read\stream
% arguments, but only the first to \InLine defines \InLine as the next line from
% argument is echoed. The second the input file. Assume, as an example, the following
% one is dropped. input file:
% #I: repeat this argument 12
% #2: drop this argument 13
\def\PickFirstOfTwo #1#2{#1) 14
Then the first execution of \read\stream to \In-
% \PickSecondOfTwo Line is equivalent to \def\InLine{12J, the second
* ----------------
---------------- one to \def\InLine{13u), and so forth. The space
% #1 and #2 of \PickFirstOfTwo ending the replacement text of \InLine comes from
% are reversed in their role. the end-of-line character in the input file.
% #I: drop this argument This trailing space can be taken out by defining
% #2: repeat this argument another macro \InLineNoSpace with otherwise the
\def\PickSecondOfTwo #1#2{#2) same replacement text. The space contained in
the replacement text of \InLine matches the space
which forms the delimiter of the first parameter of
\temp in the following. Here, the macro \reach
reads one line from the input file and defines the
TUGboat, Volume 9 (1988), No. 1

Example 8: Forcing the partial expansion of


token lists of \writes % Call macro to extract substring
\expandafter can be used to force the expansion % from \xx.
of the first token of a delayed \write. Remember % Prints "TTXXTT".
that unless \write is preceded by \immediate, \expandafter\extract\xx\Del
the expansion of the token list of a \write is de- % which is equivalent to:
layed until the \write operation is really executed, \extract This is fun\aaa TTXXTT
as side effect of the \shipout instruction in the \bbb That's it\Del
output routine. So, when given the instruction In a "real life example" \xx would be defined
\write\stream<\x\y\zl, will try to expand through some other means like a \read. There is
\x, \ y and \z when the \shipout is performed, not no reason to go to that much trouble just to print
when this \write instruction is given. TTXXTT.
There are applications where we have to expand
Example 10: Testing o n the presence of a
the first token (\x in our example) immediately, in
substring
other words, at the time the \write instruction
is given, not when the \write instruction is later Now let us solve the following problem: We would
actually performed as side effect of \shipout. This like to test whether or not a macro's replacement
can be done by: text contains a specific substring. In our example,
\def \ws(\write\stream) we will test for the presence of abc in \xx's replace-
\let\ex = \expandafter ment text. For that purpose we define a macro
\ex\ex\ex\ws\exC\x\y\z) \@TestSubS as follows: (\@Del is a delimiter):
Going back to our explanation of multiple \ex- \def \@Testsubs #labc#2\@Del{. . .)
pandafters: \us corresponds to \a,C to \b,and \x Now look at the following source:
to c. In other words \x will be expanded (!!), and \def \XXCAABBCC)
( will be inserted back in front of it (it cannot % #1 of \@Testsubs is AABBCC.
be expanded). Finally, \ws will be expanded into \expandafter\@TestSubS\xx abc\@Del
\write\stream. Now \write will be performed \def\xx(AABBabcDD)
and the token list of the \write will be saved % #1 of \@Testsubs is AABB.
without expansion. But observe that \x was al- \expandafter\@TestSubS\xx abc\QDel
ready expanded. \y and \z, on the other hand, Observe that
will be expanded when the corresponding \shipout 1. If \xx does not contain the substring abc
instruction is performed. we are searching for, then #1 of \@Testsubs
Example 9: Extracting a substring becomes the same as \xx.
2. In case \xx does contain the substring abc,
Assume that a macro \xx (without parameters) then #I of \@Testsubs becomes that part of
expands to text which contains the two tokens \aaa \xx which occurs before the abc in \xx.
and \bbb embedded in it somewhere. You would We can now design \Ifsubstring. It is a
like to extract the tokens between \aaa and \bbb. simple extension of the above idea, with a test
Here is how this could be done: added at the end to see whether or not # I of
% Define macro to extract substring \@Testsubs is the same as \xx.
% from \xx. \catcode'@ = I1
\def\xx(This is fun\aaa TTXXTT % This conditional is needed because
\bbb That's it) % otherwise we would have to call the
% following macro \IfNotSubString.
% Define macro \extract with three \newif\if@TestSubString
7, delimited parameters. % \Ifsubstring
% Delimiters are \aaa, \bbb, and \Del. 7 ============
% Macro prints substring contained % This macro evaluates to a conditional
% between \aaa and \bbb. % which is true iff #l's replacement
\def\extract #l\aaa#2\bbb#3\Del(#2) % text contains #2 as substring.
TUGboat, Volume 9 (1988), No. 1

% #1: Some string Macros for Outlining


% #2: substring to test for whether it
James W. Walker
% is in #i or not.
Department of Mathematics
\def\IfSubString #1#21%
University of South Carolina
\edef\QMainString{#l)%
\def\@TestSubS ##1#2##2\@DelC% The purpose of this note is to describe stand-
\edef\@TestTemp{##l))% alone macros for the preparation of outlines in the
\expandafter\QTestSubS standard format. For instance, the desired output
\@MainString#2\QDel might look like:
\if x\@MainString\@TestTemp
\QTestSubStringf alse Vegetables
\else A. Green ones
\QTestSubStringtrue 1. lettuce
\fi a. iceberg
\if@TestSubString b. leaf
3 2. Broccoli, almost universally despised
\catcode'@ = 12 by children. The strong flavor is only
made palatable by quick stir-frying.
Example 11: \expandafter and \csname
B. white ones
A character string enclosed between \csname and 1. potatoes
\endcsname expands to the token formed by the 2. turnips
character string. \csname a?a-4\endcsname, for
instance, forms the token \a?a-4. If you wanted to 11. Animals.
use this token in a macro definition you have to do 111. Minerals.
it the following way:
\expandaf ter Notice that a topic is allowed to be a paragraph,
\def \csname a?a-4\endcsnameI. . .3 not just one line, as in topic I.A.2. I wanted
The effect of the \expandafter is of course to to take care of the counting and indentation
give \csname a chance to form the requested token as painlessly as possible. Something like this
rather than defining a new macro called \csname. can be done in I4M using nested enumerate
environments, but I wanted the input format to be
Summary even simpler.
These examples have shown some typical applica- When typing an outline, it is natural to show
tions of \expandafter. Some were presented to the structure by indenting with the tab key. This
"exercise your brains a little bit". I recommend is particularly easy if one has a text editor with an
that you take the examples and try them out; automatic indentation feature. With that feature,
there is very little input to enter. I also encourage hitting the Return key produces a new line with the
you to tell Barbara Beeton or me what you think same amount of indentation as the previous line.
about tutorials in TUGboat. There are many more When the input is typed this way, we can tell the
subjects which could be discussed and which may indentation level of a topic by counting tabs. We
be of interest to you. also need to mark the beginning of a topic, since
This article is, as briefly mentioned in the not every line begins a new topic. I chose to mark a
introduction, an adaptation of a section of my new topic with a pound sign (#). Thus, the input
book, Another Look At m, which I am currently to produce the outline above could look something
finishing. The book, now about 800 pages long, like:
grew out of my teaching and consulting experience.
The main emphasis of the book is to give concrete
and useful examples in all areas of m. It contains,
to give just one example, 100 (!!) \halign tables.
In this book you should be able to find an answer
to almost any T j$ problem.

You might also like