我想编写一个可以修改另一个包的命令的包。假设该命令来自\includegraphics
包graphicx
,那么在mynewpack.sty
文件中我有类似以下内容:
\let\latex@includegraphics\includegraphics
\renewcommand\includegraphics[2][]{<some tex code> \latex@includegraphics[#1]{#2}}
如果在我的main.tex
文件中我有这个
\usepackage{graphicx}
\usepackage{mynewpack}
一切顺利,graphicx
定义\includegraphics
命令并mynewpack
重新定义它。
但是如果切换这两个包的加载,我不明白会发生什么。我预计会出现错误,因为在包尚未加载时mynewpack.sty
我使用了。相反,没有产生任何错误,但包含没有任何效果(我认为这是因为它之前已加载并恢复为默认设置)。includegraphics
graphicx
mynewpack
graphicx
graphicx
includegraphics
为什么在这种情况下我没有收到我预期的错误?
我该如何解决这个问题?我的想法是graphicx
直接从 中加载包mynewpack
,但我不知道如果用户还在graphicx
中添加包会发生什么main.tex
。另一种可能性是使用一些内部命令mynewpack.sty
来延迟 的重新定义,includegraphics
直到所有其他包都加载完毕,但我不知道这个命令是否存在...
答案1
假设你的包中有
\let\latex@includegraphics\includegraphics
\newcommand\variant@includegraphics[2][]{<code>\latex@includegraphics[#1]{#2}
然后,在某些情况下,你说
\let\includegraphics\variant@includegraphics
(例如作为环境的“开始”部分)。
如果graphicx
在你的包之前加载,则不会有问题;否则,在第一个执行\includegraphics
时将不会被定义,而是保持未定义状态。\let
\latex@includegraphics
当graphicx
在包之后加载时,调用\includegraphics
时不在您的第二个 的范围内\let
。但在该范围内,当 TeX 尝试扩展\latex@includegraphics
未定义的 时,您将收到错误。如果没有,请检查您加载的另一个包是否定义了\latex@includegraphics
)。
因此,每当您想要修改命令的行为(不更改其主要语法,如果原始语法中未包含,则可能添加 *-variant 或可选参数),您需要确保在向其添加\let
新的控制序列时定义了该命令。因此你应该说
\RequirePackage{graphicx}
因此,最终用户是先加载还是后加载它并不重要。如果用户加载graphicx
选项,可能会出现问题,因此您应该在包的文档中说明这graphicx
是必需的,因此如果需要将选项传递给它,应该提前加载它。
实际上,情况\includegraphics
相当复杂。有些包做修改它,特别是一些与 TikZ 相关的。那么最好使用\LetLtxMacro
而不是\let
。但是,如果有人使用 变*
体(罕见用法,但可能),这将会中断,因此您必须在文档中说明*
不支持该变体,并且clip
必须指定 选项。