因此我开始学习纯 TeX(或者我认为是纯 TeX),这非常有趣且有益。我还开始编写一些宏/包供我个人使用。由于对于主文档,我(仍然)使用 LaTeX 以及许多高级包,因此我编写的包是用纯 TeX、纯 LaTeX 还是使用 等编写并不重要xparse
……etoolbox
但我想知道:
什么是编写软件包的良好做法?特别是如果有一天我想分发该软件包。一方面,纯 TeX 功能更强大、更便携和更静态(输出不会随时间或跨不同编译器而改变)。另一方面,由于程序员(我)没有完全理解一般使用情况中的所有细微差别,它更容易出错。一个例子是命令的稳健性,但我相信更有经验的人可以给出更多新手陷阱的例子。
如果我确实在包中使用 LaTeX,那么依赖其他包(如
xparse
或)的优点和缺点是什么?etoolbox
另外,我如何才能确定(无需深入研究发行版附带的文件)一个普通的旧命令是 TeX 原语还是 LaTeX 内核命令 - 是不是所有 LaTeX 内核命令都至少有一个,
@
而没有 TeX 原语有这个?如果我在软件包中将 TeX 与其中一些 LaTeX 内核命令混合在一起,可以吗?(我认为它们非常稳定,在各个版本之间变化不大?)
答案1
从技术上讲,使用纯文本 tex 不是一个选择,纯文本是将文件输入plain.tex
initex 后生成的格式,而该文件根本不在 LaTeX 中使用。
然而,确实许多在纯 TeX 中定义的命令在 LaTeX 中都有同名的命令定义,并且在某些情况下,定义是相同的。
LaTeX 格式的命令和标准类是用“低级”宏和 TeX 基元的混合编写的,它们或多或少类似于纯文本。在编写它们的时候(1985-1993 年),做任何其他事情都是不可能的,现在称为 xparse 的早期版本当时已经可用,但没有足够的内存来处理任何实际文档,甚至测试文档也需要“一段时间...”
现在要看情况了。当然,使用较低级别的接口总是在机器时间上更有效率,但在开发和维护方面,在人类时间上可能效率较低。这适用于任何计算语言,而不仅仅是 TeX。对于大多数人来说,大多数时候最好在高级系统中编写代码,但对于某些核心代码,在特定于处理器的机器代码汇编器中编写代码仍然有效,因为人类专家仍然可以比编译器做得更好。
如果您使用低级命令,那么它可能更有效,但您可能会破坏某些东西。最近有人在这里提出了一个问题,当时有人去了\def\box{....}
,然后想知道为什么事情不起作用。同样,如果您的文档还使用更高级的包,例如 expl3 或 pgf,那么如果您通过记录的包接口更新这些包所需的结构,那么这些结构在内部一致性的可能性远高于您仅使用\let
或插入一些新值\def
。
另一方面,如果像通常的情况那样,您的定义是现有定义的变体或扩展,那么以相同的样式对其进行编码是有意义的,这不仅便于代码重用,而且出于文档原因,可以更容易地看到差异。因此,不可能一概而论地建议对于 latex2e,所有包都应该用 expl3 或其他语言编写。
另一个推动低级代码的考虑因素是,您可能希望包与纯 tex(以及可能的 context 或 eplain 或 lollipop 或...)一起使用,而无需加载定义层(例如expl3-generic
或 )miniltx.tex
。ltluatex
例如,低级 luatex 支持的代码被编写为与纯 TeX 一起使用,即使它是作为 LaTeX 基础的一部分分发的。
因此,如果您要开始编写一个全新的代码,并且想要为代码提供自然的界面和可记录的结构,我会使用 expl3。如果您要调整或修改现有代码,或者有其他现实世界的限制,那么情况就会变得很复杂,最终结果通常是一种妥协。
LaTeX 内核本身是非常稳定,并且(除了针对 luatex 等新引擎进行的一些更改)自 20 世纪 90 年代 LaTeX2e 稳定以来并没有真正改变。自 2015 年发布以来,已经添加了一些错误修复,但它们都由源文件中的条件代码保护,这允许latexrelease
包在必要时将定义回退到早期版本。
答案2
所以我开始学习纯 TeX
好的欢迎:)
1. 编写软件包的良好做法是什么?
通常,普通 TeX 用户不使用第三方软件包。他们从plain.tex
文件固定点开始,然后执行自己的宏。但存在“重新发明轮子”的问题。例如,他们必须为目录、颜色、参考文献、参考书目等执行自己的宏。所以,我做了一个宏欧佩克并将其发布为公开版本。主要原则是简单,请参阅概括。第二个原则是:
不要试图用大量的关键字、标识符和新语法来创造新的语言水平。只提供简单的默认宏,并说:“如果你需要不同的东西,就重新定义它们。”这是典型的纯 TeX 方法。最强大的语言是现成的:TeX 宏语言。
\newcont
如果您在软件包中仅使用 TeX 基元和基本纯 TeX 宏(如allocator),那么您的代码将适用于任何地方:例如纯 TeX、LaTeX 和 ConTeXt。不幸的是,LaTeX 软件包中没有观察到这种“良好做法”。例如,qrcode.sty
宏可用于 QR 码打印结果\hrule
,基元。但这个宏是 TeX 基元(如、)基本纯 TeX 宏(如)和 LaTeX 宏(如、、 )\vrule
的混合体\def
\advance
\newcount
\newcommand
\addtocounter
\newcounter
。恕我直言,这是非常糟糕的做法。qrcode.sty
例如,不适用于纯 TeX 或 ConTeXt。因此,我从中删除了 LaTeX 特性qrcode.sty
并发布了qrcode.tex
这里。
2. 如果我确实在软件包中使用 LaTeX,那么优点和缺点是什么……
抱歉,我看不出有什么优势。结果是 LaTeX 特有的,依赖于 LaTeX,这不是个好主意。TeX 宏语言足够强大。
3. 另外,我如何才能确定(不深入研究发行版附带的文件)一个普通的旧命令是否是 TeX 原语
例如,你在 TeXbook 的索引中看到的内容。或者在我的书中TeXbook 纳鲁比,附录 B 列出了plain.tex
包括解释的所有 TeX 基元和宏。这里使用的标记 e、h、v、m 表示控制序列是可扩展的、水平的、垂直的或数学模式基元。而 [plain] 表示普通的 TeX 宏。
您无法通过字符的存在来区分 LaTeX 宏和普通 TeX 宏@
,因为普通 TeX@
也包含控制序列。不幸的是,这对于名称空间来说不是一个好主意。也就是说,TeX 无法处理名称空间,而将某些内容放入每个新分配的控制序列的规则只是解决这个问题的痛苦实验。但普通 TeX 用户知道 TeX 基元,他/她能够根据这个“只有一个名称空间”分配新名称。