According to the TeXbook the two tokens following \if are expanded and compared? It seems then that \if\char98\char98 T \else F \fi should be the same as \if bb T \else F \fi which does return T. What is wrong with my interpretation?
- 603,163
- 131
1 Answers
The \char primitive is not expandable, so its "expansion" is itself, and not "the character whose code is 98". Since the 98 afterwards is not consumed, the next token is 9, and that's different from the \char token, so you hit the false path.
One way to do this as you want is to \chardef\x=98; then \if\x\x will return true. Another way is to do \if ^^62^^62; as TeX by Topic tells me on p.44, the ^^ syntax is parsed way before expansions are made (it's actually an input syntax), and therefore ^^62 is one single character. Note (see egreg's comment) that ^^62 is in hexadecimal, while \char98 is decimal (0x62 = 98).
Maybe I should expand on that "input syntax" comment. There are two kinds of characters in TeX: input characters, which are what you write in a .tex file, and printable characters, which are what issue a typesetting directive to TeX. In the jargon of the TeXbook, an input character belongs to TeX's "eyes", and an output character to its "stomach". Between those two is the "mouth", where the macro language lives, and \if belongs to that language. By contrast, although \char is recognized by the eyes as being a token, its actual function is not known until the stomach, which is when absorbs its arguments and becomes a printable character.
A normal character like a is both input and printable under the usual catcodes, so \if aa works as expected, but to get an input character by charcode into \if you need to use a syntax that is recognized by the eyes, and for that, we have ^^.
- 37,958
-
1Pay attention that
^^98refers to the ASCII code0x98(hexadecimal), so writing^^98\char98will print two different characters. – egreg Jul 08 '12 at 08:45 -
4Note that
\if^^62^^62is equivalent to\ifbb, an undefined control sequence. The conversion is done very early on. You need to put a space there. – Bruno Le Floch Jul 08 '12 at 09:54 -
-
@RyanReich A limitation of
\if ^^xy^^XYis that one cannot passxyorXYas arguments:\if ^^#1would be interpreted exactly like\if c1(and taking the false path). – egreg Jul 09 '12 at 09:53 -
@egreg: there is one exception: using
\scantokens. Assuming that backslash, caret, and hexadecimal digits have their usual category code, and (minor constraint)\escapecharis printable,\def\hexchar#1{\expandafter\expandafter\expandafter\@gobble\expandafter\string\scantokens{\^%^#1\noexpand}}. – Bruno Le Floch Jul 09 '12 at 11:56 -
@egreg For the audience: the reason for that is, naturally, that
^^#is interpreted as being an input character whose hex code is that of#, plus or minus 64, which givesc. Like Bruno said, it's done before tokens are interprted, so TeX doesn't know you wanted a macro parameter character there. This is why\scantokenshelps, since it rewinds the input process on its argument, in which#1has already been substituted. – Ryan Reich Jul 09 '12 at 16:13
\char98has an action comparable to the printer fishing out a "b" from the case and it's performed at a very later stage than macro expansion, that is, when everything has been decided about the paragraph shape and glyphs to use (among other things) and the printer has to produce the paragraph by putting letters together. – egreg Jul 08 '12 at 08:48