其中第31节tex.web
写道:
行尾的空白被删除;因此,要么 |last==first| (这种情况下该行完全为空白)要么 |buffer[last-1]!=' '|。
由于行尾空格不可见,因此存在尾随空格时输入的内容与不存在尾随空格时输入的内容应该相同。由此我可以推断,如果不删除尾随空格,TeX 的行为会有所不同。
为什么需要删除尾随空格?有人知道tex.web
如果输入行中存在尾随空格,哪个部分的工作方式会有所不同吗?或者一些示例输入?
答案1
我相信您已经给出了一个很好的理由来说明为什么忽略尾随空格并非完全不合理:由于大多数人都看不到它们,因此根据它们的存在而有不同的行为可能会非常令人困惑(请注意,我确实看到了尾随空格,因为我(setq-default show-trailing-whitespace t)
的 Emacs 配置中有)。可能还有其他我不知道的原因——我只是在回复您的评论在这里。
因此,关于您对示例输入的请求,如果不忽略尾随空格,该请求的行为会有所不同,我建议以下内容(属于ShreevatsaR 设想的类别:对于 ASCII 空格字符,catcode 不同于 10):
\def\visiblespace{{\tt\char32 }}
\obeyspaces\let =\visiblespace
abc def ghi
\par
\bye
我在后面留了三个空格ghi
(不幸的是,这里看不到它们)。使用未经修改的 TeX 引擎的输出为:
ghi
我希望修改后的引擎不会忽略尾随空格,之后会出现三个“可见空格” 。
附录
下面是另外两个示例,这次使用 ASCII 空间的标准类别代码 (10):
-
{\endlinechar=`X abc} d\par \bye
后面有一个空格
abc}
。微妙之处:终止符是在给定行的标记化开始之前附加的。因此,每行都根据行末的当前值\endlinechar
终止\endlinechar
以前的行。这里,在结束括号和不可见的尾随空格之后,X
在 TeX 开始标记之前,已经附加了一个字符作为行终止符abc
。 -
{\let\par=X\obeylines% abc }d\par \bye
后面有一个尾随空格
abc
。
在这两种情况下,未经修改的 TeX 引擎都会输出:
我希望您修改后的引擎能够abc Xd
在两种情况下打印。
答案2
在 TeXLive 2018 中,“剥离空白”的解释被更正为仅剥离空格而不是制表符,因此您可以通过将 texlive 2017 与任何更高版本(此处为 texlive 2020)进行比较来查看效果
考虑普通的 TeX
\catcode9\active\def {X}
one two three
one two
three
\bye
这有两个制表符(U+0009),本网站将删除它们,因此我在这里将它们显示为 T:
\catcode9\active\defT{X}
one two three
one twoT
three
\bye
在 texlive2017 中,标签被剥离,你得到
在 TeXlive2020 中你将获得
答案3
原因是为了在不同的操作系统上获得规范化的输入。
在编写 TeX 时,一些操作系统使用固定长度记录,因为它们基于打孔卡(具有固定长度记录的典型系统)。其中一些系统用 NUL 字符填充记录(对应于列上没有打孔)
其他则用空白填充,例如 IBM 的 OS360 和 VM/CMS(参见https://tex.stackexchange.com/a/389871/4427)。
通过使用类别代码 9(忽略)解决了 NUL 字符的问题,对于空格,解决方案是在标记化之前读取记录时将其删除。为空格指定类别代码 13 并将其定义为不会\space
排版空格,因为删除发生在标记化之前,并且每个类别代码为 32 的字符都会被删除;删除后,会\endlinechar
添加(但尚未标记化)。
一些 TeX 实现(尤其是 TeX Live)过去也会删除 TAB,但现在这种情况不再发生。
无论如何,尾随空格是无法发现的,并且可能会在输出中产生意外。TeX78 有一种不同的方法来处理结束行,但 TeX82\endlinechar
除了删除空格之外还引入了类别代码 5。