[Tex/LaTex] Macros with # as the last parameter

macros

Knuth hid a special rule for delimited arguments in exercise 20.5 of the TeXbook.

If the very last character of the
parameter text is #, so that this #
is immediately followed by {, TeX
will behave as if the { had been
inserted at the right end of both the
parameter text and the replacement
text.

This means that a macro can be defined as,

\def\a#1#{#1}

calling it as \a 10 will give a runaway argument error whereas calling it as \a{12}, will compile with no trouble.

I struggled to find a practical application for such macros even after looking at TeX by Topic, TeXbook and LaTeX source.

Here is my take on it, create some commands to typeset and do some calculations for fractions, as for example those found in basic arithmetic texbooks. You type this,

\[\FRAC ADD{3}{8}+{1}{7}\]
\[\FRAC SUB{5}{8}-{1}{7}\]
\[\FRAC MUL{5}{8}x{13}{1201}\]

and you get this:

enter image description here

Here is the code,

\documentclass{article} 
\begin{document}
%% macro factory
\def\FRAC#1#{\csname #1\endcsname}
%% add
\def\ADD#1#2+#3#4{%
  \frac{#1}{#2}+\frac{#3}{#4}=
  \frac{\the\numexpr(#4*#1)+(#3*#2)}{\the\numexpr#2*#4}
}
%% subtract
\def\SUB#1#2-#3#4{%ok top
  \frac{#1}{#2}-\frac{#3}{#4}=
  \frac{\the\numexpr(#4*#1)-(#3*#2)}{\the\numexpr(#2*#4)}
}
%% multiply
\def\MUL#1#2x#3#4{%
  \frac{#1}{#2}\times\frac{#3}{#4}=
  \frac{\the\numexpr(#1*#3)}
  {\the\numexpr#2*#4}
}
%% testing
\[\FRAC ADD{3}{8}+{1}{7}\]
\[\FRAC SUB{5}{8}-{1}{7}\]
\[\FRAC MUL{5}{8}x{13}{1201}\]
\end{document}

Are there any practical applications for such macros? Are there any special precautions one should take? Why would Knuth include this facility in the first place?

Best Answer

This trick of catching until the first open brace can be used in many situations.

  • As other posters said, it allows to catch an optional argument expandably if it is not the last. It is possible in principle to get this to be fully robust with respect to nesting, but not implemented yet.

  • It can be used to parse the body of a definition provided by the user, to change it to fit your purposes while keeping a natural syntax. (More on parsing def below.)

  • I've used this trick primarily to parse a token list expandably without losing any brace. For instance,

    • to expandably uppercase or lowercase a given string (see this answer)

    • to fully expand a token list expandably (almost as well as the luatex primitive \expanded (see this answer)

    • to expand tokens selectively, or in the reverse order

    • to write a primitive macro expander (i.e. take a file, and expand user-defined macros)

    so basically any situation where you need to be careful with braces, but cannot use \futurelet.

This trick only works if there is only one character with catcode 1 (begin group character). Also, we need to be able to put a sentinel at the end of the token list that we are manipulating: otherwise, in the absence of opening brace, we would get a runaway argument.

On parsing a definition: say that you want to give the user an easy way of defining a macro which possibly takes arguments, and always produces a boxed math result. Say that you also want the parameter text to be arbitrary. Either you let the user do everything, or you parse the definition using the trick you ask about.

%non-user-friendly
\def\foo_#1^#2#3#4{\fbox{$\sum_{#1}^{#2} \frac{#3}{#4}$}}

%more user friendly (perhaps)
\boxeddef\foo_#1^#2#3#4{\sum_{#1}^{#2} \frac{#3}{#4}}

To do that:

\documentclass{article}
\makeatletter
\def\boxeddef#1#2#{\boxeddef@aux{#1}{#2}}
\def\boxeddef@aux#1#2#3{\def#1#2{\fbox{$#3$}}}
\makeatother
\begin{document}
%\def\foo#1#2#3#4{\fbox{$\sum_{#1}^{#2} \frac{#3}{#4}$}}
\boxeddef\foo_#1^#2#3#4{\sum_{#1}^{#2} \frac{#3}{#4}}
\[
\foo_{a}^{b}{C}{D}
\]
\end{document}