marcel@cs.caltech.edu (Marcel van der Goot) (05/03/91)
debi erpenbeck (dje@lanl.gov) asked how to test whether an argument is empty: > \ifx#1=\empty > \if#1=\empty > \ifcat#1=\empty This is a good instance of the problem Raymond Chen (raymond@math.berkeley.edu) mentioned in a different posting [Re: Is there a Tex short-reference handbook (not Knuth)?]: I've found that many of the TeX misunderstandings are not problems with primitives and macros, but rather with the more fundamental way TeX scans and expands tokens. Here's what goes wrong with your attempted solutions: 1. If you look it up (ch. 20), you'll see that \if, \ifcat, and \ifx all should be followed by two tokens, without `=' sign in between. (\ifnum and \ifdim use an `=' sign). 2. Take for instance \ifx#1=\empty. Now suppose #1 is indeed empty. When TeX comes across `#1' it substitutes the argument; therefore, in this case it substitutes nothing at all. In other words, if #1 is empty, the test is equivalent to \ifx=\empty, which compares an equals sign with the macro \empty. (If the equals sign is omitted, you would be comparing the macro \empty with whatever token follows it.) 3. Take \ifx#1=\empty again. Suppose #1 is an equals sign. In that case \ifx is followed by two equal signs, which means that the test is true. If you omit the equals sign, the test would be true if #1 was the macro \empty, rather than just empty. (The test can also be true if #1 consists of more than one token.) Anyway, what you should remember about all this is that \if etc. compare tokens, and that `#1' is not a token: it's value (which consists of tokens) is substsituted. Here are two methods that work: With \ifx: \def\firstmacro#1% {\def\tmp{#1}% \ifx\tmp\empty \message{Arg1 is empty}% \else\message{Arg1 is not empty}% \fi } With \if: \def\secondmacro#1% {\if.#1.% you can use another character instead of `.' \message{Arg1 is empty}% \else\message{Arg1 is not empty}% \fi } The second solution will only work if #1 cannot possibly start with a dot. Also, the behavior with respect to expansion of #1 is different: \firstmacro{} --> empty \firstmacro{\empty} --> not empty \secondmacro{} --> empty \secondmacro{\empty} --> empty If you replace \def\tmp in \firstmacro by \edef\tmp: \firstmacro{\empty} --> empty Marcel van der Goot .---------------------------------------------------------------- | Blauw de viooltjes, marcel@vlsi.cs.caltech.edu | Rood zijn de rozen; | Een rijm kan gezet | Met plaksel en dozen. |