我对内核钩子的理解是,添加到钩子只会影响添加后的实例。对于文档内钩子来说,这似乎是正确的。例如,
\begin{quote}
some text
\end{quote}
\AddToHook{env/quote/before}{HOOK CODE}
\begin{quote}
some text
\end{quote}
仅HOOK CODE
出现在第二个quote
环境之前。
在一个包文件中,我试图找出在加载另一个包时产生错误的最佳方式。为了解决之前加载的不兼容包的问题,可以等到begindocument
,但我想知道错误是否可以更快出现(节省加载其他包的几毫秒时间等)。我试过了
\AddToHook{package/incompatpkg/before}{\PackageError{mypkg}{Error!}{}}
并且它工作正常,即使mypkg
是在之后加载的incompatpkg
。
简单的测试表明,如果\AddToHook
出现在incompatpkg
加载之后,则“添加”的代码将在添加时执行,而不是在添加之前执行incompatpkg
(根据我对 TeX 工作原理的理解,这是不可能的;这就是我们有辅助文件的原因)。如果incompatpkg
没有加载,则不会执行代码。
下面的例子显示了我begindocument
通过这个实现了在之前出错的目标;这个错误tikz
发生在加载之后但在tcolorbox
加载之前。
\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\AddToHook{package/amsmath/before}{\PackageError{mypkg}{Error!}{}}
\usepackage{tcolorbox}
\begin{document}
\end{document}
这是预期的行为吗?如果是,是否支持?对我来说,这是相当出乎意料的;在我看来,目前的行为\AddToHook{package/pkg/before}{CODE}
更像是
\IfPackageLoadedTF{pkg}
{CODE} % unexpected part: execute code immediately if pkg loaded
{\AddToHook{package/pkg/before}{CODE}} % do expected thing if pkg not loaded yet
答案1
正如 Ulrike 提到的,包含名称的包/类钩子是一次性钩子。
由于包和类只能加载一次,因此任何后续添加的内容都会默默地停留在钩子上并且不执行任何操作,没有任何警告。
但主要原因是,一个包可能想在另一个包加载后执行某些操作,但它无法知道该包是完全没有加载,稍后加载还是已经加载。如果已经加载,则立即执行该操作可以解决这种情况,而无需进行大量测试。
显然,对于“/before”,这不太可能有帮助,但这在一定程度上取决于使用钩子的原因。因此,人们可能必须测试包是否已在钩子中加载并发出警告,但如果稍后加载,则无需进行特殊处理。