[Tex/LaTex] Scope of catcode change for escape character

catcodesmacrosplain-tex

In the following macro, I change the category code for the escape character (\) to "other" (12):

\def\xxA{\begingroup
  \catcode`\\ = 12
  \gdef\xxB ##1z{\tt ##1\endgroup}
  \xxB}

How the heck does this work? It seems like after I redefine \ then the rest of the definition should not parse. Yet the input:

\xxA\bar\ba\xxAz

produces the output:

\bar\ba\xxA

Clearly, the escape character is not interpreted in the argument. What is going on here?

Best Answer

When TeX scans a definition it doesn't expand any control sequence and doesn't perform any assignment. Each token is absorbed and transformed in the internal form which is independent of any external representation with characters.

When you use \xxA TeX determines it's a parameterless macro, so it replaces it with the replacement text:

|begingroup|catcode`|\=12 |gdef|xxB#1z{|tt #1|endgroup} |xxB

Here I've represented the tokens with their "external form"; in order to distinguish symbolic tokens already read by TeX I use the pipe, but it's only for writing them in some way: the characters are not really present.

Now TeX opens the group and performs the category code assignment and globally defines the token |xxB as shown. At the end TeX finds a space (which is passed to the stomach) followed by |xxB and determines that it's a macro with a delimited parameter, so it proceeds to scan more tokens. In your example it finds \bar\ba\xxAz but now the backslash has category code 12, so the argument to |xxB is \bar\ba\xxA (all characters), so it removes the macro and the parameters (up to the z) and replaces them with

|tt \bar\ba\xxA|endgroup

(again the pipe precedes symbolic tokens already read). The characters are printed, the group is closed and the category code of the backslash is restored.

Related Question