[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