[Tex/LaTex] How to print and assign category codes

tex-core

Consider the code below, which after giving me some trouble (especially with catcode 9 and 15), prints all the category codes up to catcode 15.

\documentclass{minimal}
\parindent0pt
\begin{document}
\the\catcode`\\  \ control character  \\
\the\catcode`{  \ open curly\\
\the\catcode`}  \ closing curly \\
\the\catcode`$  \ dollar\\
\the\catcode`&  \ alignment\\
\the\catcode`\ 
\ space \\\the\catcode`#  \ sharp\\
\the\catcode`^ \ hat \\
\the\catcode`_ \ underscore \\
\number\catcode`\  \ space \\
\catcode `\y=9
\the\catcode`\y    \ ignored character \\
\the\catcode`a \ letters\\
\number\catcode`@  \ restricted  \\
\number\catcode`~ \ tilde \\
\the\catcode`\%   \ comment\\ 
\catcode`\z = 15 
\the\catcode`\z  \ invalid character \\
\def\test{}
%\catcode `\t=16
\ifcat\test 16  16  control sequence\fi
\end{document}

Now, getting TeX to print the catcode 16, has me puzzled. For starters if you uncomment the line, %\catcode \t=16 you get,

! Invalid code (16), should be in the range 0..15. 
  l.23 \catcode\t=16

but, if you test with \ifcat a control sequence is definitely equal to category code 16. So my question is, how can I coerce TeX to say sixteen for a control sequence and how come the error message says 16 is an invalid code, but the TeXbook says it is?

Mildy related question How do I get the category code of a character that is the value of a control sequence?

Best Answer

There's really no category code 16. This code is assigned to control sequences (not \let to a character) only for the purposes of \ifcat.

Similarly, character code 256 is assigned to the same tokens for the purposes of \if.

You can get category codes 9 and 15 with

\the\catcode`\^^@
\the\catcode`\^^?

(these are the only characters that have those category codes in the default setting, bytes 0 and 127).

Notice also that \ifcat doesn't compare a token with a number, but two tokens:

\ifcat ab
\ifcat a1

The first evaluates to true, the second to false.

Quoting from the TeXbook, page 209:

\ifcat<token1><token2> (test if category codes agree)
TeX will expand macros following \if until two unexpandable tokens are found. If either token is a control sequence, TeX considers it to have character code 256 and category code 16, unless the current equivalent of that control sequence has been \let equal to a non-active character token.

The key word is considers. Look at page 38:

A token is either (a) a single character with an attached category code, or (b) a control sequence.

Section 506 of "TeX, the program" tells the truth about this: if the next token is not an active character or is a control sequence (not let to a character), then the variable *cur_chr* gets the value 256.

Related Question