How is \catcode handled?

\centerline is defined by \def\centerline#1{\line{\hss#1\hss}} but \line is defined by \def\line{\hbox to\hsize}. It means that \line{next text} does not take the next text as parameter. The next text is processed inside \hbox primitive in main processor of TeX. If there is an assignment (like \catcode setting) then this is done immediately and then next characters are read (and tokenized). On the other hand, \centerline{next text} reads the next text as a parameter first. All characters are tokenized in this state, but assignment is not done. After parameter is read and tokenized then in is used in the context \hbox...{..next text..} but all characters are tokenized here. So, \catcode setting has no effect now. Only, of course, the \the\catcode report is changed. This report prints the value used by token processor for next characters, which are not tokenized already.


Some complements to wipet's good answer.

The definitions in plain.tex are as follows (lines 575–578):

\def\line{\hbox to\hsize}
\def\leftline#1{\line{#1\hss}}
\def\rightline#1{\line{\hss#1}}
\def\centerline#1{\line{\hss#1\hss}}

You can notice that \line is just shorthand for \hbox to\hsize, so the call

\line{\hss"hello world\the\catcode`\ "\hss}

becomes

\hbox to\hsize{\hss"hello world\the\catcode`\ "\hss}

One might think that such a call will obey the same rules as

\centerline{\hss"hello world\the\catcode`\ "\hss}

that is, {\hss"hello world\the\catcode`\ "\hss} is absorbed as an argument to \hbox, but there's a fundamental difference between the two cases.

You should be aware of this, because you're defining active " to do \hbox\bgroup and macros taking an argument don't allow such a syntax for denoting the start of the argument. On page 278 of the TeXbook, you find the syntax for \hbox:

\hbox⟨box specification⟩{⟨horizontal mode material⟩}

and such notation means that the braces can also be implicit characters having category code 1 and 2 respectively. In these cases, the material inside these braces is only scanned after { is processed (here, also after the material in \everyhbox and possibly \afterassignment has been inserted). The matching } will start the operation of converting the horizontal list into a box.

In particular,

\hbox{\catcode`\ =12 a b}

will perform the category code assignment and the space will be absorbed with category code 12.

To the contrary, \centerline{\catcode`\ =12 a b} will absorb the argument tokenizing it (as explained by Petr). When TeX is absorbing an argument, it performs no expansion and no assignment; if the argument is undelimited (as in the case of \centerline), the argument will be the next token (after skipping explicit space tokens) unless this token is a left brace (explicit character with category code 1), when the argument will be the tokens up to the matching right brace (explicit character with category code 2). Tokenization is performed, so the spaces will be of category code 10.


Is it possible to solve this problem? Yes, with e-TeX.

\catcode`\"=\active
\def"#1"{%
  \leavevmode\hbox{%
    \catcode`\ =12
    \tt
    \scantokens{#1\relax}%
  }%
}

\line{\hss X"hello world"X\hss}
\centerline{X"hello world"X}
\bye

enter image description here