我最近对我的一个旧文档做了一些扩展,但它无法编译。幸运的是,我知道包排序问题,尤其是臭名昭著的 hyperref 包。但是,除了反复试验之外,我不知道还有什么方法可以系统地找到包的正确顺序。除了反复试验之外,是否有系统的方法来决定正确的包加载顺序?
例如,当我同时使用feyn
和nicematrix
包时,顺序就无关紧要了。但是,如果我首先另外加载 amsmath 包,那么我需要先加载 nicematrix 包,然后再加载 feyn 包。我在这两个包的文档中都没有找到有关加载顺序的任何内容 :-(
任何人都可以尝试的示例:
\documentclass{article}
\usepackage{amsmath}
\usepackage{feyn}
\usepackage{nicematrix} % should come before the feyn package
\begin{document}
\begin{equation}
\begin{pNiceArray}{cc}[first-row,first-col]
& 1 & 2 \\
3 & a & b \\
4 & c & d
\end{pNiceArray}
\end{equation}
\begin{equation}
\Diagram{\vertexlabel^a \\
fd \\
& g\vertexlabel_{\mu,c} \\
\vertexlabel_b fu\\
}
= ig\gamma_\mu (T^c)_{ab}
\end{equation}
\end{document}
答案1
这里没有通用规则,你也无法在单独的软件包文档中找到任何内容,如果软件包 A 设置了\foo=1
,软件包 B 设置了\foo=2
,那么加载顺序取决于你想要的\foo
是 1 还是 2,或者软件包 A需要 \foo
为 1 且 packageB需要如果是 2,那么这些包是不兼容的,并且不能一起加载,除非你修补其中一个以使用不同的名称。
ctan 上有数千个软件包,个别软件包可能会针对主要核心软件包进行测试,amsmath
但通常不会针对所有贡献软件包的组合进行测试。
在最近的 latex 版本中,我们添加了钩子机制,允许您挂接到包加载中,并控制钩子的运行顺序,而不受包加载顺序的影响。这可以解决这里的一些问题,但一般问题是无法解决的。
但是你在这里给出的案例是软件包中已记录feyn
。该软件包有些大胆地将其设置为!
active,因此它将与很多东西不兼容,但它提供了一个不这样做的选项。如果您使用
\usepackage[noglobalbang]{feyn}
没有错误。
只有当您向维护人员报告并他们决定采取特殊措施避免已知问题时,才能避免包冲突。
这里feyn
最好使用
\edef!{\string!}
而不是
\def!{\char`\!} % ! produces this character everywhere
将其“正常”定义!
为仅在排版上下文中\char`\!
产生,例如尝试!
\typeout{hello!}
类似地nicematrix
,可以(可能)在本地确保已知活动标点符号的 catcode,从而保护自己免受使字符在序言中处于活动状态的软件包的侵害。(虽然实际上它不应该这样做。)
答案2
CTAN 上有大约 5000 个软件包,虽然并非所有软件包都适用于 LaTeX,但大多数都是。正如 David 在他的回答中所写,软件包 A 和 B 之间可能存在 4 种关系:
- 他们是独立的
- 它们不兼容(因为它们以某种方式互相覆盖)
- A 必须在 B 之前加载(
A<B
) - B 必须在 A 之前加载
不幸的是,即使这样也过于简单了,因为如果A<B
A 和 C 是独立的,或者 A<C
人们会认为加载 A、B、C 应该可以工作。但是,如果 B 更改了 A 的某些代码以允许两个包相互协作,并且这种更改最终可能与 C 不兼容,那么情况可能并非如此。
正如 David 所提到的,引入的钩子管理最终应该在许多情况下有所帮助,因为大多数不兼容性是由于包 A 和 B 彼此不了解而导致的,它们都扩展/更改了一些内部 LaTeX 命令,并且在彼此不了解的情况下覆盖了对方所做的修改。使用钩子管理后,它们都可以进行更改,甚至可以定义执行这些更改的顺序规则。这并不能解决所有问题(例如更改字符的 catcode),但它在许多情况下会有所帮助。
话虽如此,但小问题是它要求包使用钩子机制,而不是进行无条件覆盖。我们强烈呼吁这样做,只要包仍然有活跃的维护者,我们就会看到钩子使用量的增加,通过“钩化”更多的 LaTeX 内部结构,我们预计这种趋势将继续下去。
但是,它并不能解决任何此类问题,例如,不兼容的包可能永远不兼容,无论它们是否使用钩子。
尽管如此,我想知道,如果有一个志愿者项目可以建立一个包间关系数据库(也许允许用户(以适度的方式)做出贡献),这是否会有很大的帮助(或没有)。因此,数据库可以或多或少是一个简单的文件,例如
A, B, <, version-A, version-B, date checked % A must be before B
A, C, X, version-A, version-C, date checked % A and C are incompatible
然后可能会有一个(latex)包构建依赖项尝试并执行或建议排序。
再进一步思考一下,就可以以某种方式考虑版本/日期。
应该(并且可能)有一种方法可以大多数(如果不是全部)自动验证依赖性检查。
只是一个想法。我认为如果这样的功能可用,那么对社区来说这将是一项很棒的服务,但我想让它顺利运行并不容易。事实上,如果我没记错的话,有些开发人员曾经尝试过自己做这样的事情。我猜那个包仍然在 ctan 上,但我忘了它的名字是什么了。