通过阅读 TeX 源代码,似乎该input_ln
过程负责在输入时从行中删除尾随空格(在考虑类别代码之前)。代码中有一段非常简短的摘录
if buffer[last-1]<>" " then last_nonblank:=last;
end;
测试似乎专门针对空格,而不是制表符。但是,在进行一些测试时,我发现 TeX 还会删除制表符(无论 catcode 如何)。例如,运行
echo -e "\\\\catcode9=12\\\\show\\t%" | tex
正确显示the character <tab>
,但省略则%
没有输出。
那么... TeX 的哪个部分会删除尾随制表符?
答案1
以下是在 texlive(以及大概其他 web2c 发行版)中的运行情况:
- 变更文件tex.ch删除了 Knuth 的定义
input_ln
; - 在将 web 转换为 c 时,下划线丢失了;
生成的 C 代码
#includes
texmfmp 库确实#define inputln(stream, flag) input_line (stream)
函数
input_line()
定义在texmfmp.c尾随空格被截断如下:/* Trim trailing whitespace. */ while (last > first && ISBLANK (buffer[last - 1])) --last;
ISBLANK()
定义在c-ctype.h作为#define ISBLANK(c) (isascii (c) && isblank (c))
其中的
isblank()
意思是(至少对于通常的区域设置)“是空格或制表符”。
我认为这种行为可能是一个“错误”,因为它偏离了 TeXbook:在第 8 章第 46 页中,Knuth 写道:
TeX 会删除
<space>
输入行右端出现的任何字符(编号 32)。然后,它会在行<return>
的右端插入一个字符(编号 13),但它不会在错误恢复期间使用“I”插入的行尾放置任何其他内容。请注意,它<return>
被视为行中实际存在的字符;您可以通过更改其 catcode 来获得特殊效果。
在其他地方,我们了解到 plain tex 将 的 catcode 设置为<tab>
10(空格),并使其与(和)\<tab>
相同。\<space>
\<return>
另一方面,我可以想象如果不跳过标签可能会造成混淆,所以这样做是有一定意义的。
答案2
我认为该get_next
过程(从第 332 节“获取下一个标记”开始)负责丢弃标签。
第 343 节“从外部文件输入...”cur_char
从加载buffer
并设置cur_cmd
为 的 catcode cur_char
;然后将loc
(索引)推进buffer
1。在第 344 节“必要时更改状态...”中,如果语句的所有情况都不case
匹配,TeX 则不执行任何操作。因此,当 state
为skip_blanks
,且cur_cmd
为 10(空格)时,othercases
标签将匹配,TeX 将跳转到switch
第 343 节开头的标签。loc
将递增,制表符(或空格)将被有效丢弃。
第 347 节“处理涉及空格的情况...”将 TeX 置于该状态,并且在遇到非空格字符时skip_blanks
将 TeX 退出。skip_blanks