考虑以下test.tex
:
\ERROR
a
如果我们运行tex
它,并开始逐个跳过标记,我们会得到以下结果:
(test.tex
! Undefined control sequence.
l.1 \ERROR
? 1
l.2 a
? 1
l.2 a
? 1
)
如我们所见,第一个1
命令跳过了行尾。然后我们看到TeX刚刚读完a
,即将读到行尾字符。我们用第二条1
命令跳过它。
然后我们看到的是同样的图片。好像什么都没发生。只有在第三个1
命令之后,我们才会看到TeX已经进一步过去了。
为什么TeX\ERROR
从第一次开始就跳过行尾,但是a
从第二次开始就只能跳过行尾吗?
另外,奇怪的是,如果*
在输出中未显示的最后一个之后,我们说\end
,tex
则说:
*\end
<*> \end
?
而不是终止。
编辑
考虑以下 6 个测试文件:
控制字_at_eol.tex 控制字_not_at_eol.tex 非空间_at_eol.tex 非空间_不_在_eol.tex 空间_at_eol.tex 空间不位于_eol.tex
以下是我得到的结果:
control-word_at_eol.tex
: 读取控制字后立即跳过空格和 ^^M
control-word_not_at_eol.tex
:读取控制字后不会跳过空格
non-space_at_eol.tex
:读完控制符号后立即跳过空格,不跳过 ^^M
non-space_not_at_eol.tex
:读取控制符号后不会跳过空格
space_at_eol.tex
:空格,^^M和(!!!)读取控制符号后立即跳过控制符号的名称
space_not_at_eol.tex
:读取控制符号后不会跳过空格
对 egreg 的回答中“实际上是三个”的解释:
最后一组行有三行 + 两行。输入是
\def\c{\count1=}
\def\g{\global\count1=}
\def\s{\showthe\count1}
\c1\s\g2\s
This is TeX, Version 3.14159265 (preloaded format=plain 2020.9.24)
(z.tex
> 1.
<to be read again>
\global
\g ->\global
\count 1=
l.4 \c1\s\g
2\s
? 1
<recently read> \global
\g ->\global
\count 1=
l.4 \c1\s\g
2\s
? 1
\g ->\global \count
1=
l.4 \c1\s\g
2\s
?
答案1
你可以通过不同的输入更好地理解这一点
\ERROR xyz
a
如果你跑tex
上去,你会得到
This is TeX, Version 3.14159265 (TeX Live 2019) (preloaded format=tex)
(./igor.tex
! Undefined control sequence.
l.1 \ERROR
xyz
? 1
l.1 \ERROR x
yz
错误行分为两部分(如果 TeX 在扩展过程中发现错误,则分为三部分);这里顶行显示 TeX 在输入文件中已经走了多远,底行显示等待读取的内容。请注意,位于\ERROR
顶行,因此它已被读取并删除。两行之间的轻微错位是因为 TeX 用尾随空格表示控制字,但空格“不存在”,而且,无论如何,它不再相关,因为它位于顶行。
当1
你删除下一个标记后,TeX 就会再次停止显示上下文。
你的尝试有什么结果?
\ERROR
a
让我们一步一步来看:
! Undefined control sequence.
l.1 \ERROR
?
底行没有显示任何内容,因为该行已结束。行尾已转换为类别代码^^M
,生成的空间已在标记化过程中被吞噬\ERROR
。TeX 处于状态否(新行的开始)。
如果你输入1
后回车,你会得到
? 1
l.2 a
?
TeX 已进入状态米因为它已读a
(并忽略了它);底行没有显示任何内容,原因与之前相同。请注意,^^M
仍未读。
再输入一个1
即可
? 1
l.2 a
?
吞噬的令牌现在是 TeX 生成的空间,^^M
并且进入状态否再次。
再输入一个1
:
? 1
)
*
表示)
文件已结束; *
表示 TeX 正在等待输入。这又是“顶行/底行”格式:没有什么可以忽略的,但 TeX 遵循指令并想要忽略某事。
类型\end
:
<*> \end
?
再次强调,“顶行/底行”:顶行显示到目前为止已读入的内容。没有行号,因此 TeX 显示<*>
以表示在交互式会话中直接输入的内容以及在上一条1
指令之后忽略的内容。
现在按回车键会显示*
提示:TeX 正在等待输入。
答案2
为什么 TeX 第一次执行时会跳过 \ERROR 后的行尾,而第二次执行时却只跳过 \ERROR 后的行尾?
TeX 会删除行尾的所有空格(一些较旧的实现也会错误地删除制表符),然后如果\endlinechar
在 0-255 范围内,则将该字符添加到行尾),在纯文本和乳胶中默认为 13(控制 M)。
与^M
catcode 5 一样,它通常充当空格,因此在标记时被吞噬\ERROR
,这解释了前两行不同的行为。
如果你删除 2 个 token,则\end
有效
! Undefined control sequence.
l.1 \ERROR
? 1
l.2 a
? 1
l.2 a
?
)
*\end
No pages of output.
在这里使用pdftex
。
三个 1 得到
! Undefined control sequence.
l.1 \ERROR
? 1
l.2 a
? 1
l.2 a
? 1
)
*\end
<*> \end
因为最后的 1 吞噬了下一个标记,但这就是\end
您将要添加的......