web2cTeX 中的回车和换行

web2cTeX 中的回车和换行

在 web2cTeX (TeX Live) 中我观察到了这种行为:

(在运行以下每个 perl 命令之后:“tex xyz.tex;xdvi xyz.dvi”)

  1. 每个\r\n分别产生一行:

    perl -e 'print "\\obeylines a\rb\\bye"' > xyz.tex
    perl -e 'print "\\obeylines a\nb\\bye"' > xyz.tex
  1. \r\n以各种方式组合起来产生两行(因此 - 一个段落),正如预期的那样,除了一种情况:

    perl -e 'print "a\r\rb\\bye"' > xyz.tex
    perl -e 'print "a\r\nb\\bye"' > xyz.tex # why?
    perl -e 'print "a\n\rb\\bye"' > xyz.tex
    perl -e 'print "a\n\nb\\bye"' > xyz.tex

--
\r = ASCII '15
\n = ASCII '12

在我看来,底层 C 库(如果与此有关的话)不应该\r\n作为行尾,因为我使用的是 Linux,而不是 Windows。

所以请有人解释一下为什么\r\n不被单独处理。

答案1

使用TeX输入行有三个步骤。

  • 使用系统相关程序从文件中读取该行readln
  • 行尾标记(如果存在)被删除,其前的空格(如果存在)也被删除,其余部分保存到行缓冲区。
  • \endlinechar如果行缓冲区为非负数(^^M默认情况下为 ASCII 13 别名),则按值附加行缓冲区。请注意^^M,默认情况下,catcode 为 5,这就是为什么行尾在 TeX 中的行为与行为相同。

系统相关readln程序在 web2c TeX 文件中实现,src/texk/web2c/lib/eofeoln.c其中:

void
readln (FILE *f)
{
    int c;
    while ((c = getc (f)) != '\n' && c != '\r' && c != EOF)
        ;
    if (c == '\r' && (c = getc (f)) != '\n' && c != EOF)
        ungetc (c, f);
}

请注意,这里处理特殊情况 CRLF。

答案2

TeX 依靠“更改文件”进行系统相关的调整。这些调整之一是让 TeX 知道操作系统使用什么方法来标记记录的结尾(不太正式地说,是文本文件中的一行)。

不同的操作系统对此有不同的想法:

  1. CR+LF(例如 MS-DOS)
  2. CR(例如,Mac OS 10 之前的版本)
  3. LF(例如,Unix)
  4. 对于使用固定长度记录的系统,没有任何内容

在 TeX 的最初实现中,这是按字面意思理解的;例如 OzTeX 使用 CR 作为记录终止符,而来自 DOS 系统且未经转换的文件可能会被错误编译,因为某些 DOS 编辑器使用 LF+CR 作为记录终止符。

为了提高不同文件系统之间的可移植性,Web2C 的开发人员决定“记录终止符不可知”。当 TeX 打开文件时,会检查其第一行并确定使用的记录终止符;然后将其更改为 LF 并传递给 TeX 进行进一步处理。

如果你

perl -e 'print "\\obeylines a\rb\r\\input zzz \\bye"' > xyz.tex
perl -e 'print "\\obeylines c\nd\\bye"' > zzz.tex

输出pdftex xyz将是

A
B
C
D

但的输出也pdftex '\catcode`^^L=12 \input xyz'不会有所不同(请plain.tex注意

\catcode`\^^L=\active \outer\def^^L{\par}

因此^^L将被解释为外部\par;通过将其 catcode 设置为 12,我们告诉它是可打印的,但即使\n在中用作记录终止符,也不会出现任何内容zzz.tex

因此,人们不必知道文件来自哪个操作系统:输入它就会做“正确的事”。

因此,任何基于 Web2C 的 TeX 发行版在输入相同文件时都会表现相同。

哪个源文件可以做到这一点?我不知道,但我不会阅读完整的资料。

相关内容