答案1
让我们看看:如果你尝试
\tt
{\catcode‘\>=2 >
\bye
你得到No pages of output.
另一方面,
\tt
{\catcode`\>=2>
\bye
你得到输出,正是“>”和
(\end occurred inside a group at level 1)
### simple group (level 1) entered at line 3 ({)
### bottom level
解释很简单:在第二种情况下,字符>
在类别代码分配完成之前就被标记化,因此它具有类别代码 12。使用是\tt
为了避免在输出中出现“¿”。
实际上\catcode`\<=1
没有任何影响,没有它你也会得到相同的输出(和相同的警告)。
我只会使用h
和删除\par
那些没用的东西,只会使分析变得复杂:
{\catcode`\>=2>h{\catcode`\>=2>h
您有以下令牌列表:
{
1 |catcode|
`
12 |>|
=
12 2
12 >
12 h
11 {
1 |catcode|
`
12 |>|
=
12 2
12 >
2 h
11
你能看出区别吗?第一个>
类别代码为 12,原因如上所述,但第二个类别代码为 2,因为分配已执行。因此,第二个赋值实际上是在组中执行的,并且基本上没有任何作用。但您还会看到添加\catcode`\<=1
没有任何作用。
输出为“>hh”,关于未封闭组的警告也一样,因为初始的{
1不平衡,而第二个是>
2平衡的。
边注
代码
\catcode`\>=2
\catcode`>=2
在其标准类别代码为 12时是完全等效的>
。转义字符是一种安全措施,实际上只有当字符的类别代码为 0、5、9、14 或 15 时才需要。例如,您不能使用以下方式将活动类别代码分配给^^@
(字节 0)
\catcode`^^@=13
因为通常^^@
有类别代码 9(忽略)。相反
\catcode`\^^@=13
就可以了。在\obeylines
宏中你会发现
\catcode`\^^M\active
为了同样的原因。
答案2
{\catcode`\>=2>hello\par
\catcode`\<=1
{\catcode`\>=2>hello\par
\bye
\catcode
<=1` 在这里不相关。MWE:
{\catcode`\>=2>hello\par
{\catcode`\>=2>hello\par
\bye
当 TeX 读取第一行时,>
它有其标准含义,即产生一个标点符号。因此,因为 TeX 读取>
前评估2
并改变的含义>
,标点符号在输出流中产生。
然后 TeX 评估2
并更改类别代码。也就是说,它改变了 的含义>
。然后它继续执行该行。
当 TeX 读取下一行时,>
不再具有该含义。它现在具有类别代码2
,因此它是一个组结束标记,如}
。因此,当 TeX 在评估2
this 之前读取它时,它会将其读取为组的结尾,而不是排版指令。
然后 TeX 评估2
并改变类别(实际上并没有改变任何东西)。然后它继续执行该行。
因此第二行相当于
{\catcode`\>=2}hello\par
>
按照设计,它会生成 ¿,就像Q
生成 Q 一样。这就是您输入标点符号的方式。在 LaTeX 中,使用默认字体编码会得到相同的符号,这并不奇怪,因为它只是默认的 TeX 编码 (OT1)。如果您使用的是较新的编码,例如T1
,您可以使用 生成相同的符号\textquestionmarkdown
。
也就是说,>
产生该特定符号的原因与产生该符号的原因完全相同\textquestionmarkdown
:这就是 TeX 被告知要扩展这些标记的方式(>
在一种情况下是宏)。
要查看此内容,请尝试
>hello\par
{\catcode`\>=2>hello\par
{\catcode`\>=2>hello\par
\bye
重写 Knuth 的示例可能会更容易,使用更熟悉的东西。考虑一下
{\catcode`\Q=2Qhello\par
{\catcode`\Q=2Qhello\par
\bye