不兼容示例

不兼容示例

[如果我的陈述有误,请纠正我]

总结: pdftex并表现出不同的行为。这些差异是什么以及为什么存在这些差异xetexluatex


我知道有三个引擎实现了 TeX 并支持原生 PDF 输出:pdftex和。不幸的是xetexluatex它们并不完全兼容。

pdftexpdftex是一个 ɛ-TeX 引擎,向下兼容 Knuth-TeX,也就是说,和的排版输出不会有差异tex(断点、分页符、连字符、维度等都是确切地相同)。

不兼容示例

xetex这对于和来说并不成立luatex。我只知道一个明显的不兼容性,稍后我将通过 MWE 对此进行支持。为了避免连字符,Knuth 在 TeXbook 练习 5.1 中提出了几种替代方案

{shelf}fulshelf{}ful等;甚至shelf\/ful,这样得到的是 shelfful (w/ 连字符) 而不是 shelfful (w/o 连字符)。事实上,后一种想法 — — 插入斜体校正 — — 更可取,因为 TeX 会在连字后自行重新插入 ff 连字shelf{}ful。(附录 H 指出,连字会放入不包含“显式字距”的带连字的单词中,而斜体校正就是显式字距。)但斜体校正可能太多(尤其是在斜体字体中);shelf{\kern0pt}ful通常是最好的。

因此,以下 plainTeX 文档应始终导致 ff 连字符被禁用

shelf{}ful
\bye

pdftex

tex和的输出pdftex符合预期

在此处输入图片描述

路特克斯

luatex我得到了

在此处输入图片描述

西特克斯

xetex得到的结果与pdftex

在此处输入图片描述

但只要我加载 OpenType 字体

\font\test="CMU Serif" \test
shelf{}ful
\bye

连字符再次出现

在此处输入图片描述

另一个例子(结果发现是一个错误)

代码

${}\limits$
\bye

会排版而不会出现任何抱怨luatex,而它会抛出错误

! Limit controls must follow a math operator.

pdftexxetex

此示例还会针对luatex版本 > beta-0.79.1 抛出相应的错误。

概括

最后我的问题可以归结为几点:

  • xetexluatex之间有何不兼容性pdftex
  • 为什么设计师选择破坏与 Knuth 的兼容性?
  • 我可以通过做出特定的设计选择(例如用\kern0pt而不是来打破连字符{})来恢复兼容性吗?

注意:请不要太纠结于这个例子。我并不是在寻求这个特定问题的解决方案。如果您正在寻找解决方案,请访问这些链接


已知不兼容列表

我在这里收集了一些问题/答案的链接,指出了一些不兼容问题。它旨在帮助那些正在考虑更换引擎但想知道需要注意什么的用户。

答案1

pdfTeX 旨在提供与 Knuth 的 TeX 的完全兼容性,因此如果未启用 e-TeX 扩展,则应以相同的方式运行。

XeTeX 基于 e-TeX 代码,不会破坏与 Knuth 的 TeX 的任何兼容性,除非绝对必要(IE除非与添加新功能有关,否则不会重新实现算法。但是,有些地方还是存在差异。正如问题中所述,XeTeX 可以加载系统字体。完成此操作后,将使用一种新方法在页面上放置框。可能只有那些深入参与该代码的人才能评论是否绝对有必要不支持打破{}连字符的方法,但如上所述无论如何都行不通。经典 TeX 语法的扩展也发生了变化。例如,允许使用两个以上字符^以访问完整的 Unicode 范围。但是,如http://wiki.contextgarden.net/Encodings_and_Regimes这会导致代码在 8 位和 Unicode TeX 引擎中执行不同的操作:

\def\"{0}\expandafter\def\csname^^^^^00022\endcsname{1}
\ifnum\"=0 \message{tex82}\else\message{newstuff}\fi

LuaTeX 则完全不同。设计者决定重新审视 Knuth 的许多决定:LuaTeX 手册涵盖了细节(相当多)。例如,{}禁止连字符是故意的,与 LuaTeX 如何处理输入并将其表示在内部数据结构中有关。LuaTeX 将连字符视为语言不属于字体。因此,如果语言不变,LuaTeX 可以使用不同的字体对单词进行连字。因此,连字由每种语言的原语控制。(LuaTeX 还可以对段落的第一个单词进行连字,而 Knuth 的 TeX 则不具备此功能,现在这已成为一项“功能”。)在扩展原语以支持 Unicode 方面,LuaTeX 也存在与 XeTeX 相同的问题:例如,请参见上面的演示。

值得注意的是,由于 LuaTeX 支持回调,引擎未更改的功能可能会被 Lua 代码更改。一个明显的例子就是\font原语。它不是由引擎扩展的,而是由基于 Lua 的字体加载器扩展的:普通和 LaTeX 用户在这里共享相同的代码,而 ConTeXt 有自己的(相关)加载器。

对于 XeTeX 和 LuaTeX 来说,值得注意的是,数学模式的扩展允许使用许多额外的 Unicode 数学参数(所有前缀\Umath...)意味着如果这些额外的数据点可用,数学模式间距可能会改变,主要是在使用 Unicode 数学字体时。

所有这些的底线是,如果你有一个为 pdfTeX、e-TeX 或 TeX90 编写的 8 位文档,你应该能够使用 pdfTeX 来处理它而不加改变。XeTeX 将对几乎所有相同格式的文件给出相同的结果假设它们不包含任何引擎测试或类似内容,并假设不包含特定于驱动程序的代码(XeTeX 在所有情况下都使用 xdvipdfmx 驱动程序,pdfTeX 可能使用 dvips、dvipdfmx 或直接 PDF 输出)。LuaTeX 可能会更改此类文档的行为,包括但不限于连字符、换行、连字形成等。


如果仅从基元的角度来看待这个问题,我们必须决定是否将 XeTeX 和 LuaTeX 与 TeX90、e-TeX 或 pdfTeX1.40 进行比较。这个问题似乎集中在“当前”引擎上,因此我将以 pdfTeX 1.40 作为“参考”(它结合了 e-TeX 对 TeX90 的修改以及一系列附加基元)。如上文所述,一些行为是 XeTeX 和 LuaTeX 中的变化。我会尽可能地记录任何在此背景下似乎很重要的 TeX90/e-TeX/pdfTeX 变体。LuaTeX 手册中提供了相当多的信息。

<number>由于 XeTeX 和 LuaTeX 允许 Unicode 输入,因此字符后面跟着的基元会受到以下更改的影响:

  • \char
  • \lccode
  • \uccode
  • \catcode
  • \sfcode
  • \efcode(仅限 LuaTeX:见下文)
  • \lpcode
  • \rpcode
  • \chardef

这些都接受较新引擎的完整 Unicode 范围(最大 0x10FFFF):pdfTeX(如 e-TeX 和 TeX90)仅允许 8 位范围(最大 0xFF)。

LuaTeX 将允许的寄存器范围扩展到 e-TeX 的范围之外。因此,虽然 pdfTeX 和 XeTeX 允许最多 32767 个 box、count、dimen、muskip、ma​​rks 和 toks 寄存器,但 LuaTeX 允许 16 位范围(最大为 65535)。这会影响基元

  • \count
  • \dimen
  • \skip
  • \muskip
  • \marks
  • \toks
  • \countdef
  • \dimendef
  • \skipdef
  • \muskipdef
  • \toksdef
  • \box
  • \unhbox
  • \unvbox
  • \copy
  • \unhcopy
  • \unvcopy
  • \wd
  • \ht
  • \dp
  • \setbox
  • \vsplit

XeTeX 扩展了该\font原语,允许使用语法加载系统字体

\font⟨name⟩="⟨font identifier⟩⟨font options⟩:⟨font features⟩" ⟨TeX font options⟩

其中⟨font identifier⟩可以用方括号给出文件名,也可以不带方括号,而是使用“友好”(系统)名称。LuaTeX 中不是这种情况:如上所述,LuaTeX 通常与基于 Lua 的字体加载器一起使用,该加载器会修改原始通过回電。

LuaTeX 允许将文件名放在括号中作为原始语法,例如

\input{file name}

这会影响原语

  • \font(注意:这纯粹与字体的文件名有关)
  • \input
  • \openin
  • \openout

pdfTeX 为 e-TeX 添加了许多原语,一些与 PDF 创建相关,一些用于微排版,还有一些用于通用实用程序。由于 XeTeX 直接基于 e-TeX 而不是 pdfTeX,因此它只在移植过来时才包含其中一些原语。一些原语也被重命名,因为它们与 PDF 无关。因此 XeTeX 包含由 pdfTeX 引入的以下概念:

  • \lpcode
  • \rpcode
  • \pdfpageheight
  • \pdfpagewidth
  • \pdfsavepos
  • \pdflastxpos
  • \pdflastypos
  • \ifincsname
  • \ifprimitive\ifpdfprimitive以 pdfTeX 格式)
  • \primitive\pdfprimitive以 pdfTeX 格式)
  • \strcmp\pdfstrcmp以 pdfTeX 格式)
  • \shellescape\pdfshellescape以 pdfTeX 格式)
  • \normaldeviate(TL'19 及以后,\pdfnormaldeviate以 pdfTeX 格式)
  • \uniformdeviate(TL'19 及以后,\pdfuniformdeviate以 pdfTeX 格式)
  • \randomseed(TL'19 及以后,\pdfrandomseed以 pdfTeX 格式)
  • \setrandomseed(TL'19 及以后,\pdfsetrandomseed以 pdfTeX 格式)
  • \elapsedtime(TL'19 及以后,\pdfelapsedtime以 pdfTeX 格式)
  • \resettimer(TL'19 及以后,\pdfresettimer以 pdfTeX 格式)
  • \filedump(TL'19 及以后,\pdffiledump以 pdfTeX 格式)
  • \filemoddate(TL'19 及以后,\pdffilemoddate以 pdfTeX 格式)
  • \filesize(TL'19 及以后,\pdffilesize以 pdfTeX 格式)
  • \mdfivesum(TL'19 及以后,\pdfmdfivesum以 pdfTeX 格式)

但不是例如\efcode(如上所述),\pdfliteral或许多其他。

LuaTeX 基于 pdfTeX,保留了其中引入的一些基元,重命名了一些基元以删除“pdf”,并删除了其他基元。除了在 pdfTeX 1.40 中标记为实验性或已弃用的基元外,LuaTeX 还删除了以下基元:

  • \pdfelapsedtime
  • \pdfescapehex
  • \pdfescapename
  • \pdfescapestring
  • \pdffiledump
  • \pdffilemoddate
  • \pdffilesize
  • \pdflastmatch
  • \pdfmatch
  • \pdfmdfivesum
  • \pdfresettimer
  • \pdfshellescape
  • \pdfstrcmp
  • \pdfunescapehex

并提供

  • \primitive
  • \ifprimitive
  • \ifabsnum
  • \ifabsdim

名称中没有“pdf”。它还将所有“后端”概念(与生成 PDF 输出有关)移动到三个新原语,这些原语实现了\pdf...pdfTeX 中各种与 PDF 相关的原语的功能。

目前,XeTeX 和 pdfTeX 使用 'TeX--XeT' 模型进行从右到左排版,而 LuaTeX 使用从 Omega/Aleph 派生的模型。因此,它不具备原语

  • \TeXXeTstate
  • \beginR
  • \beginL
  • \endR
  • \endL

(请注意,有建议称 XeTeX 可能在某个阶段从 TeX--XeT 转移到 Omega 模型。)

\endlinecharLuaTeX 还改变了和的行为\newlinechar:最大值为 127,而设置任何低于零的值都会存储 -1。

XeTeX 和 LuaTeX添加TeX 的新基元,这些基元的行为当然需要适当的引擎。特别要注意的是,\Umath...两个引擎都提供了用于 Unicode 数学处理的新基元()。这两个功能也都可用\suppressfontnotfounderror

答案2

在 LuaTeX 中,\pdf...pdfTeX 的几个原语被删除或重命名,如约瑟夫·赖特的回答

因此,有些软件包在 LuaLaTeX 中无法使用,例如,xypic包裹来源) 或者gridset包裹(仅限旧版本,已修复)。

有几种解决方案可用于修复这些问题:

  • pdftexcmds包裹定义一些命令,例如\pdf@elapsedtime(注意名称的变化,@添加)可以在 pdfTeX 和 LuaTeX 中运行。---来源

    仅当您是包开发人员并且想要编写与 pdfTeX 和 LuaTeX 兼容的代码时,此选项才有用。

  • luatex85兼容包可以用来定义\pdfsaveposLuaTeX中的etc.等命令---来源

    我不确定在新编写的包中使用兼容包是否有任何缺点 - 另一种方法是在包代码中手动检查是否使用了 pdfTeX/XeTeX 或 LuaTeX,并使用相应的原语。

答案3

我不知道 XeTeX,但 LuaTeX 提供了使用 Lua 程序执行某些操作的可能性,而无需 shell 转义。例如,可以逐字节检查任意文件(不仅仅是 TeX)的内容,并根据结果动态更改 TeX 的操作。

如今,许多此类功能已经融入各种软件包中(距离最初的问题已经过去了很长时间)。可以在软件包 *.sty 文件中调用 Lua,但扩展代码通常放在单独的 *.lua 文件中。如果您浏览各种 TeX 软件包,您会到处看到此类代码。例如,当字体被 TeX 使用时,可以(并且已经实现)更改字体的一些内部属性。可以了解图像文件的一些属性,而无需调用单独的图形程序。

正如前面提到的,我们特意决定做一些与原始 TeX 不同的事情。目前,LuaTeX 已经发展得很好了。

相关内容