LaTeX 2e 的逐字环境和不同的输入编码

LaTeX 2e 的逐字环境和不同的输入编码

inputenc-package 提供了为后续 tex 输入选择输入编码的方法。

如果我理解正确的话,LaTeX 2ε 内核的逐字环境确实会改变一些 catcode,以便将内容标记为普通字符标记,然后收集输入行,直到找到包含短语的行\end{verbatim}

我的问题是:

这个假设是否正确:您只能在以下输入编码中使用逐字环境:其中符号\end{vrbati,具有与 LaTeX 2e 内核本身的编码相同的代码点m}

(所有常见的输入编码都是这种情况,因此这个问题有点无意义。不过,我还是很感谢你的澄清。)

答案1

你说的“LaTeX 2e-kernel 本身的编码”是什么意思?

在这种情况下,“LaTeX 2ε-kernel”是什么意思?

您是指文本文件 latex.ltx 吗?例如,可以从中转储格式文件/.fmt 文件或者创建/生成核心转储或二进制文件?

关于格式文件/核心转储/二进制文件:在标记化期间,在预处理阶段,所有内容都会转换为(La)TeX 的内部字符表示方案(对于传统(La)TeX 引擎为 ASCII,对于现代 TeX 引擎(如 Lua(La)TeX 或 Xe(La)TeX )为 UTF-8)。

因此,当转储格式文件或创建二进制文件时,写入 latex.ltx 的编码不再重要。

重要的是:

当 (la)tex 引擎读取、预处理和标记您的输入时,这必须产生一组标记,根据通过 LaTeX 2ε 内核提供的标记定义,(la)tex 引擎会搜索检测 verbatim 环境的结束。

是因为它可能。


Donald Ervin Knuth 的 TeXbook 第 8 章:您键入的字符中有一个危险的段落,其中写道:

TeX 始终使用附录 C 中的内部字符代码来表示标准 ASCII 字符,而不管读取的文件中实际出现的外部编码方案是什么。因此,即使您的计算机通常处理 EBCDIC 或其他非 ASCII 方案,TeX 内部的 b 也是 98;TeX 软件已经设置为将文本文件转换为内部代码,并在写入文本文件时转换回外部代码。设备无关 (dvi) 输出文件使用 TeX 的内部代码。这样,TeX 能够在所有计算机上给出相同的结果。

使用 (La)TeX,处理输入的第一阶段是读取该输入并预处理和标记该输入并将生成的标记放入标记流中。

(La)TeX 读取、预处理和标记输入的源可以是文本文件或您“动态”输入的控制台。

在读取和预处理输入时,将字符从外部代码转换为内部代码,然后立即进行标记,这可能意味着用其他字节替换从输入中读取的字节获取标记。将文本文件/输入中出现的字符从外部代码转换为内部代码的过程不是在“标记级别”进行,而是在“输入字符级别”进行,即 TeX 从输入文件中读取字符以对其进行标记(并在标记化后将标记插入到标记流中)。

有不同的 TeX 发行版。
例如,在 TeX 发行版 MiKTeX 的手册中(MiKTeX 手册,修订版 2.9.6809,Christian Schenk,https://miktex.org/download/ctan/systems/win32/miktex/doc/2.9/miktex.pdf) 您可以读到,使用 MiKTeX 的 TeX 二进制文件,可以通过所谓的 .tcx 文件(TeX 字符翻译文件)确定转换为内部代码(ASCII)和转换回外部代码的规则。

inputenc 包仅适用于 8 位引擎,其中转换为内部代码的例程不会用其他字节替换从输入读取的字节。换句话说:inputenc 包仅适用于 8 位引擎,其中外部代码/外部编码包含 ASCII 码作为子集。
这是因为 inputenc 包执行其自己的字符替换例程。它不会在“输入字符级别”执行它们,但它会在“标记级别”执行它们,方法是使字符处于活动状态并定义它们以扩展为不同字符代码的非活动字符。由于 TeX 的将字符从外部代码转换为内部代码的例程,该替换例程在标记级别运行,因此它没有关于事先在“输入字符级别”发生了哪些字节替换的信息。

假设您使用 LaTeX 2ε 引擎,默认情况下,该引擎会处理 latin1 编码的文件(7 位 ASCII 是 8 位 latin 1 的子集)。使用这种引擎,从外部代码转换为内部代码并不意味着需要用其他字节替换输入的字节。
粗略地说,使用这种引擎,由于标记 .tex 输入文件中的字符而产生的字符标记的字符代码与 latin1 编码中相应输入字符的代码点数相对应。

您不能这样做,但是 - 只是为了好玩 - 假设使用此引擎,您可以加载 inputenc 包,以便您可以向引擎“提供”一个以 ASCII 不是子集的编码进行编码的文件,例如某些 EBCDIC 变体:

EBCDIC 编码字符序列的代码点数量与 ASCII\end{verbatim}编码字符序列的代码点数量不同\end{verbatim}。引擎在标记化时不会执行任何转换,因此它将从输入中获取 EBCDIC 字节以获取 ASCII 字节,因此将 EBCDIC 编码的输入序列标记化为\end{verbatim}字符标记序列,其字符代码对应于 EBCDIC 编码中这些字符的代码点数量。但是逐字环境的机制将搜索字符标记序列,其字符代码对应于 ASCII 编码中这些字符的代码点数量。
因此逐字机制将被破坏。

但这个问题不会成为一个大问题,因为它会被一个更大的问题所覆盖:

例如,在 ASCII 中编码反斜杠和控制序列标记名称 a 的字节与在 EBCDIC 中编码相同的字节不同。但当标记化结束时,inputenc 的例程就会开始起作用。因此,在这种情况下,在 EBCDIC 编码中表示反斜杠和控制序列名称的 EBCDIC 字节序列被错误地用作 ASCII 字节。例如,用于编码反斜杠的 EBCDIC 字节在 ASCII/latin 1 中不编码反斜杠,因此标记化用于表示控制序列标记的 EBCDIC 编码序列将不会被标记为控制序列标记,但可能会被标记为任何字符标记序列。

此外,类别代码也可能是一个问题:Inputenc 通过使字符处于活动状态并定义它们以扩展为其他非活动字符来进行转换。因此,您至少需要使所有那些字符处于活动状态,其中它们的代码点数在 ASCII 中表示的字符与在 EBCDIC 中表示的字符不同。因此,在这种情况下,对 EBCDIC 编码的输入字符序列进行标记的结果(该序列应表示控制序列标记)可能包含一些活动字符标记,这些标记实际上不应该被这样标记,而应该被视为控制序列标记名称的一部分,其中形成名称的字节序列应该从 EBCDIC 转换为内部代码 = ASCII / UTF-8,但事实并非如此。

针对这一问题,本文“LaTeX 2ε 编码接口——目的、概念和未解决的问题”,作者:Frank Mittelbach,布尔诺,1995 年 6 月,https://www.latex-project.org/publications/1995-FMi-CsTUG-encoding-concepts.pdf,您可能会感兴趣:第 7 节:输入编码:LaTeX 2ε 解决方案说:

  • 7 位可打印 ASCII 被认为本质上是透明的
  • 输入编码通过名称声明
  • 每个命名编码定义了 128–255 之间的字符数(子集)到 LaTeX 2ε 内部编码的映射
  • 输入编码针对整个文档或其部分进行声明

例外情况是 LaTeX 的标准转义字符(因为它们不会被传递)和目前不可打印的 ASCII 字符。 例如,这意味着不支持 EBCDIC 之类的编码(任何变体)。这并不完全令人惊讶,因为为了能够支持输入编码,它必须至少在明确定义的位置具有形成 TeX 命令语言的字符。

(“以任何形式”之后缺少右括号不是引用错误,而是原文中缺少右括号。;-))

答案2

您的假设是错误的:TeX 只查看字节。

当逐字模式的设置确实\catcode`\\=12要将反斜杠变成可打印字符时,TeX 实际上将类别代码 12 分配给字节 92。执行分配后,每次读取输入时扫描字节 92 时,它都会转换为类别代码 12 的字符标记。

输入编码是通过激活某些字节(类别代码 13)并为其分配适当的定义来实现的。输入编码可能使其\成为一个活跃的角色,但在处理逐字模式时,这并不相关。

如果您指的是诸如 EBCDIC 之类的奇异编码,那么这一点再次变得无关紧要,因为所有字节在进行标记化检查之前都会被转换成 ASCII。

相关内容