![TeX 引擎如何获知操作系统的行尾标记和文件编码?](https://linux22.com/image/360976/TeX%20%E5%BC%95%E6%93%8E%E5%A6%82%E4%BD%95%E8%8E%B7%E7%9F%A5%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9A%84%E8%A1%8C%E5%B0%BE%E6%A0%87%E8%AE%B0%E5%92%8C%E6%96%87%E4%BB%B6%E7%BC%96%E7%A0%81%EF%BC%9F.png)
TeX 引擎逐行处理输入文件(The TEXbook,第 46 页)。引擎将从文件中读取第一行,进行一些预处理(见下文),然后开始处理。处理完该行后,将从文件中读取下一行,依此类推。
从文件中读取下一行的过程实际上是与 TeX 引擎分开且独立的;具体来说,它“忽略”了类别代码的概念,并且实际上无法访问类别代码表。因此,就此过程而言,输入行的定义方式与操作系统定义的方式相同。例如,在 Windows 系统上,行尾用 CR-LF 组合表示,而在 Linux 系统上,行尾用 LF 表示。行尾标记(如果有)不包含在读取过程返回的字节列表中(TeX by Topic,第 29 页)。
读入该行之后,在引擎开始处理它之前,该行会经过一些预处理:
- (The TEXbook,第 43 页)字符将从输入文件中表示的任何编码转换为 ASCII 编码。例如,如果文件是用 EBCDIC 编码的,那么表示数字 129(EBCDIC 的小写字母 a 的代码点)的字节将被表示数字 97(ASCII 的小写字母 a 的代码点)的字节替换。
- (The TEXbook,第 46 页)所有尾随空格(ASCII 32)都将被删除。
- (The TEXbook,第 46 页)在行尾附加一个回车符(ASCII 13)。
该行现在已经准备好由 TeX 引擎进行处理,并且被移交给标记器。
如上面的描述所示,TeX 引擎依赖于以下参数:
- 操作系统的行尾标记
- 输入文件的编码
并且如果不知道它们的值就甚至无法开始处理输入文件。
这些参数是否可以由用户自定义,还是在源代码中硬编码?如果是前者,那么如何为 pdftex 等自定义这些参数?
如果是后者,那么它们是硬编码的什么意思:
- 从某种意义上说,每个发行版都是根据稍微不同的源代码构建的,并且根据特定的行尾标记/文件编码配置进行定制?
- 从某种意义上说,源代码在运行时测试这些值?
- 从某种意义上说,源代码使用了一些可移植的 API 来读取行和字符?
引用的参考文献
- Knuth, Donald Ervin。TEXbook:Addison-Wesley,1991 年。
- Eijkhout,Victor。TeX by Topic:Addison-Wesley,1992 年。
答案1
记录终止符取决于操作系统,但基于 Web2C 的 TeX 发行版(TeX Live 和 MiKTeX)可以动态决定它。我创建了三个相同的文件,其中包含
abc
def
\bye
但使用不同的行终止符;以下是十六进制转储:
> hexdump testeol-lf.tex
0000000 61 62 63 0a 64 65 66 0a 5c 62 79 65 0a
000000d
> hexdump testeol-cr.tex
0000000 61 62 63 0d 64 65 66 0d 5c 62 79 65 0d
000000d
> hexdump testeol-crlf.tex
0000000 61 62 63 0d 0a 64 65 66 0d 0a 5c 62 79 65 0d 0a
0000010
如果我编译它们,我会得到
> pdftex testeol-lf
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017) (preloaded format=pdftex)
restricted \write18 enabled.
entering extended mode
(./testeol-lf.tex [1{/usr/local/texlive/2017/texmf-var/fonts/map/pdftex/updmap/
pdftex.map}] )</usr/local/texlive/2017/texmf-dist/fonts/type1/public/amsfonts/c
m/cmr10.pfb>
Output written on testeol-lf.pdf (1 page, 10842 bytes).
Transcript written on testeol-lf.log.
> pdftex testeol-cr
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017) (preloaded format=pdftex)
restricted \write18 enabled.
entering extended mode
(./testeol-cr.tex [1{/usr/local/texlive/2017/texmf-var/fonts/map/pdftex/updmap/
pdftex.map}] )</usr/local/texlive/2017/texmf-dist/fonts/type1/public/amsfonts/c
m/cmr10.pfb>
Output written on testeol-cr.pdf (1 page, 10842 bytes).
Transcript written on testeol-cr.log.
> pdftex testeol-crlf
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017) (preloaded format=pdftex)
restricted \write18 enabled.
entering extended mode
(./testeol-crlf.tex [1{/usr/local/texlive/2017/texmf-var/fonts/map/pdftex/updma
p/pdftex.map}] )</usr/local/texlive/2017/texmf-dist/fonts/type1/public/amsfonts
/cm/cmr10.pfb>
Output written on testeol-crlf.pdf (1 page, 10842 bytes).
Transcript written on testeol-crlf.log.
这应该清楚表明 TeX 引擎被设置为查找记录终止符、“猜测”它并采取相应的行动。事实上,这三个 PDF 文件仅在时间戳上有所不同。
至于转换成 ASCII,TeX 使用两个内部数组,称为异或和韓國(请参阅tex.web
)了解更多信息。本质上,异或定义从输入到 ASCII 的转换以供内部使用,而韓國定义从内部 ASCII 到任何想要的转换(但它被初始化为身份映射)。
这异或数组可以在运行时通过使用 TCX 文件进行更改(texdoc web2c
有关详细信息,请参阅第 4.4.2 节)。基于 EBCDIC(或其他编码)的实现需要使用更改文件来定义正确的异或大批。
一些 TeX 扩展,特别是 MLTeX 和 encTeX,允许更改韓國以多种方式排列(texdoc web2c
有关 MLTeX 和texdoc enctex
encTeX 请参阅)。