[comp.text] controlling macro expansion

gaynor@busboys.rutgers.edu (Silver) (01/10/90)

How do I control the expansion of macros?  F'rinstance, suppose I wanted to
define the macro \foo to expand to exactly what it did before but also with a
bar on the end?  In pseudolatex, this is what I'd like to say:

  \newcommand{\foo}{foo}                % \foo --> foo
  \renewcommand{\foo}{\expand{\foo}bar} % \foo --> foobar

Several examples and references along these lines would be really appreciated!

Thanks muchly, [Ag] gaynor@topaz.rutgers.edu

dhosek@jarthur.Claremont.EDU (dhosek) (01/10/90)

In article <Jan.10.02.29.09.1990.1907@busboys.rutgers.edu> gaynor@topaz.rutgers.edu writes:
>How do I control the expansion of macros?  F'rinstance, suppose I wanted to
>define the macro \foo to expand to exactly what it did before but also with a
>bar on the end?  In pseudolatex, this is what I'd like to say:

>  \newcommand{\foo}{foo}                % \foo --> foo
>  \renewcommand{\foo}{\expand{\foo}bar} % \foo --> foobar

>Several examples and references along these lines would be really appreciated!

Well, part of the problem is that \newcommand is quite limited in what
it can do. To do any fancy macro stuff, I fear, you have to descend to 
the level of (gasp) plain TeX. As for references, I highly recommend that
you read the appropriate chapters of the TeXbook. It'll confuse you and
you probably won't be much better off, but it'll make the rest of us
feel better. Once you've accomplished that, You'll probably want to find
a copy of Stephan v. Bechtolsheim's _TeX in Practice_ (aka _Another Look
at TeX_) published by Springer-Verlag. I've heard rumors that actual copies
of this book were present at the DECUS meeting last spring. However, to 
date, I have neither seen a (post-publication, not one of the Xeroxed ones
svb sold himself prior to publication) copy nor an advertisement.

Fortunately, again, interesting pieces of his book have been excerpted in
TUGboat (in particular, TB 9#1, "A tutorial on \expandafter" pp.57-61 and
TB 9#3 "A tutorial on \futurelet" pp. 276-8) and might be of interest.
Actually, you may want to browse through as many TUGboat back issues as
you can get your hands on. Also of interest might be the TUG courses in
plain TeX and macro writing.

So of course, now it's time to give you all TUG's address. phone number,
and e-mail address (couldn't you see this coming? ;-):
  TeX Users Group
  P.O. Box 9506
  Providence, RI 02940 (USA)
  401-751-7760
  tug@math.ams.com
(wow! I managed to get it all (except the phone number) from memory!)

But enough of this references stuff. You wanted examples. And examples
ye shall have.

First of all, I'll assume that you can figure out the basics of \def
all by yourself. I will however point out two useful commands for 
debugging TeX macros. One is \message (this is also supported by \LaTeX).
It takes its argument and displays it on the terminal. Thus

   \message{Hi mom!}

Will produce Hi mom! on the terminal.

The other command is \meaning. This expands to the meaning of whatever
follows it. We're concerned with macros here, so we'll just look at
what happens if we type:

   \def\foo{bar}
   \def\foobar{\foo bar}
   \message{\meaning\foo \meaning\bar}

The output produced from this will be:

   macro:->bar macro:->\foo bar

So, now, how can we get \meaning\bar to print "barbar" rather than
"\foo bar"? One approach is to use \edef. This tells TeX to expand 
everything in the macro as much as possible when making the definition.
For example,

   \edef\himom{\foo bar}
   \message{\meaning\himom}

will produce the output

   macro:->barbar

Now, however, sometimes you don't want everything in a macro expanded and
instead you just want to expand one portion of the macro instead (this
would be useful in making major additions to LaTeX's point size commands,
for example). This gets a little trickier. To handle this, you will
need to use the \expandafter command. The way \expandafter works is it
causes the token after the token following it to be expanded. Thus, if
you were to type

   \expandafter(\himom

TeX would expand \himom before it processed the (. Now, let's assume that
we would like to define a macro \doodah to be the expansion of \himom
followed by \foo, unexpanded. The way that we would do this would be 
to type

   \expandafter\def\expandafter\doodah\expandafter{\himom \foo}
      1          5     2          6       3       7  4     8  9

(the numbers indicate the order in which TeX will process each token.
What we have done here is tell TeX to skip ahead to \himom, expand that,
then go back and deal with the definition normally.

There is one more way of dealing with partial expansion. Let's say
that you had a great deal of stuff that should be expanded fully
followed by a macro that shouldn't be expanded at all. You can do this
by typing:

    \edef\expandedstuff{ lots of crud goes here}
    \def\mymacro{\expandedstuff \notexpanded}

You should be able to see how this works now. You may want to use 
\expandafter to further expand \expandedstuff at this point, so you 
can reuse the control sequence name \expandedstuff.

-dh
-- 
"Odi et amo, quare id faciam, fortasse requiris?
   nescio, sed fieri sentio et excrucior"          -Catullus
D.A. Hosek.                        UUCP: uunet!jarthur!dhosek
                               Internet: dhosek@hmcvax.claremont.edu