在普通的 TeX 中,\bye
标记 TeX 文档的结束。但为什么需要这样的命令呢?TeX 应该能够自己看到,文件在这里停止,并且没有更多内容可以查找。我不明白为什么需要命令来告诉它这一点。
我意识到 LaTeX 也有这样的命令,\end{document}
;但这个命令看起来很自然,因为它与 创建了对称性\begin{document}
。
答案1
原因在于定义:
\outer\def\bye{\par\vfill\supereject\end}
因此,它\bye
不仅会发出\end
(这本身会发出\par
,但不会\vfill
):它还会执行\supereject
,即
\def\supereject{\par\penalty-\@MM}
为什么会有 -20000 的惩罚?原因在于输出例程:
\def\plainoutput{\shipout\vbox{\makeheadline\pagebody\makefootline}%
\advancepageno
\ifnum\outputpenalty>-\@MM \else\dosupereject\fi}
如果触发输出例程的惩罚大于 -20000,则在推进页码后不会执行任何特殊操作。否则\dosupereject
将采取行动:
\def\dosupereject{\ifnum\insertpenalties>\z@ % something is being held over
\line{}\kern-\topskip\nobreak\vfill\supereject\fi}
\supereject
该宏通过重复调用直到\insertpenalties
不再为正,确保所有待处理的插入都已发出。
可以\supereject
随时调用(这就是\par
在开始时的原因),例如在某一章节开始时。
来自对问题和答案的评论的一些更多想法
TeX 可以交互运行,如果主输入文件在没有命令的情况下结束,它将进入交互状态\end
(如果运行模式不是交互的,则“紧急停止”)。由于这种可能的交互性,隐含的\end
命令是不可取的。
只有少数操作系统会<EOF>
在文件末尾添加隐含标记,可以是^^D
(EOT) 或^^Z
。该^^Z
字符过去常添加到 MS-DOS 文件,但并非所有文本编辑器都兼容。
根据操作系统和 shell,在交互式提示符下按 Control-D 可以停止执行,但不\end
执行任何命令。
由于 TeX 会保存文件堆栈\input
,因此它知道何时到达主文件的末尾,因此可能的功能可以是“\end
到达主文件末尾时插入标记”。但是,还应该有一个“禁用自动\end
”功能以允许在文件末尾进行交互。TeX 中有一个类似的功能:当由于发现 而从水平模式切换到垂直模式时<vertical command>
,TeX 会添加一个\par
标记(这不再是原始的\par
)。但是,“自动”的情况\end
非常不同:将段落分成文件是常见的 TeX 活动,而主文件的结尾只会发生一次。
终止符\end
允许为其添加结构。可以重新定义\end
(在保留原始副本之后)以执行其他簿记业务\bye
。因此
\let\TeXend\end
\outer\def\bye{\par\vfill\supereject\TeXend}
可以考虑,但这不是 Knuth 的选择(也不是我的选择)。
最后,在主文件末尾加上\end
(或\bye
或) 允许在结束标记后添加注释和附加材料,否则这是不可能的。由于大多数编程语言都要求明确终止程序,我不明白为什么 TeX 应该例外。\end{document}