[texhax] Can't use \d (dot below) with \edef
Oleg Katsitadze
olegkat at gmail.com
Tue Jun 19 12:51:05 CEST 2007
On Mon, Jun 18, 2007 at 02:59:26PM -0700, Wenlin Institute wrote:
> \edef\test{\d{u}}\bye
Why are you using \edef? Generally it is not a good idea to fully
expand arbitrary macros. If you have to use \d inside some other
\edef'd macro, add \noexpand in front of \d:
\edef\test{...\noexpand\d{u}...}
The reason for the failure is obscure, but if you are curious: \d
calls \o at lign; \o at lign calls \oalign. When TeX was parsing \oalign,
it saw ## and converted it into a single token #. When the
replacement text of \oalign is substituted back into the body of \d,
TeX sees this _single_ # and expects it to be followed either by
another # (which would become literal #) or by a number (which would
be replaced by an argument of \d). TeX sees neither, therefore it
complains.
Here is a minimal example to illustrate the problem (or maybe confuse
you even more :). \tracingall provides useful debugging info.
First, run this:
--------------------%<--------------------
\tracingall
\def\b#1{\halign{##\cr#1\cr}}% ## become #
\edef\a#1{#1\b{b}}
\a{a}
\bye
-------------------->%--------------------
TeX complains as before. Now we put four #'s in \b:
--------------------%<--------------------
\tracingall
\def\b#1{\halign{####\cr#1\cr}}% #### become ##
\edef\a#1{#1\b{b}}
\a{a}
\bye
-------------------->%--------------------
Works, but now we can't use \b directly, because it contains two #'s
in \halign's preamble. Now try this:
--------------------%<--------------------
\tracingall
\def\b#1{\halign{##1\cr#1\cr}}% ##1 become #1
\edef\a#1{#1\b{b}}
\a{a}
\bye
-------------------->%--------------------
Definition of \a passes, but TeX complains about the missing # in
\halign's preamble when we try to use \a.
HTH,
Oleg
More information about the texhax
mailing list