\catcode 是如何处理?

\catcode 是如何处理?

\centerline是相同的\line{\hss#1\hss}

那么为什么在下一个示例中,\line空间可见,而在下一个示例中\centerline却不可见?在这两种情况下,空间都有正确的 catcode 12。

\catcode`\"=\active
\def"{\leavevmode\hbox\bgroup\let"=\egroup\catcode`\ =12\tt}
\line{\hss"hello world\the\catcode`\ "\hss}
\centerline{"hello world\the\catcode`\ "}
\bye

在此处输入图片描述

答案1

对 wipet 的好答案的一些补充。

中的定义plain.tex如下(第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}}

您可能会注意到,这\line只是的简写\hbox to\hsize,因此调用

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

变成

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

有人可能会认为,这样的调用将遵循与

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

即被{\hss"hello world\the\catcode`\ "\hss}吸收作为的论据\hbox,但这两种情况有着根本的区别。

您应该意识到这一点,因为您正在定义 active"来执行操作\hbox\bgroup,而接受参数的宏不允许使用这样的语法来表示参数的开始。在 TeXbook 的第 278 页,您可以找到语法\hbox

\hbox⟨盒子规格⟩ {⟨横模材质⟩}

并且这种表示法意味着括号也可以是隐式分别具有类别代码 1 和 2 的字符。在这些情况下,这些括号内的材料仅在{处理后才被扫描(这里,也是在材料被插入后\everyhbox\afterassignment。匹配}将启动将水平列表转换为框的操作。

尤其,

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

将执行类别代码分配该空间将被吸收为类别代码 12。

相反,\centerline{\catcode`\ =12 a b}将吸收参数并对其进行标记化(如 Petr 所解释的)。当 TeX 吸收参数时,它不执行扩展和赋值;如果参数未分隔(如 的情况\centerline),则参数将是下一个标记(跳过显式空格标记后),除非此标记是左括号(类别代码为 1 的显式字符),此时参数将是匹配的右括号(类别代码为 2 的显式字符)之前的标记。执行标记化,因此空格的类别代码为 10。


有可能解决这个问题吗?可以,使用 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

在此处输入图片描述

答案2

\centerline由 定义\def\centerline#1{\line{\hss#1\hss}},但\line由 定义\def\line{\hbox to\hsize}。这意味着\line{next text}不将下一个文本作为参数。下一个文本\hbox在 TeX 主处理器的原语内部处理。如果有赋值(如\catcode设置),则会立即完成,然后读取(和标记化)下一个字符。另一方面,\centerline{next text}首先将下一个文本作为参数读取。在此状态下,所有字符都将被标记化,但尚未完成赋值。读取并标记化参数后,然后在上下文中使用,\hbox...{..next text..}但此处所有字符都将被标记化。因此,\catcode设置现在没有效果。当然,只有\the\catcode报告发生了变化。此报告打印标记处理器对尚未标记化的下一个字符使用的值。

相关内容