这是 TeX 扁平命名空间的另一个牺牲品,也是开始使用 LaTeX3 的另一个原因……
我今天注意到algorithm2e
和keystroke
包发生冲突。更具体地说,它们都定义了一个名为的命令\Return
:
- 是排版
algorithm2e
伪\Return
代码的命令返回关键词; - in
keystroke
是\Return
排版的命令Return。
两个包都\Return
使用 定义它们的命令\newcommand
;因此,如果两个包都加载,当 LaTeX 遇到第二个 时会返回错误\newcommand\Return
。
我通过赋予 一个新的、独特的名称来解决这个问题,keystroke
该\Return
名称不会与我迄今为止使用的任何内容冲突,如下所示:
\documentclass{article}
\usepackage{keystroke}
\let\ksReturn\Return
\let\Return\relax
\usepackage{algorithm2e}
\begin{document}
\Return \quad \ksReturn
\end{document}
这有效,但我有一个问题:
作为用户(不是软件包编写者/维护者),在不更改任何 .sty 文件的情况下,修复两个不同软件包中定义的同名但不同的命令之间的冲突的最佳做法是什么?我的方法会产生任何有害的副作用吗(除了我的新名称可能会产生不同的冲突)?
附注:keystroke
是一个相当古老的软件包。在撰写本文时,当前版本可追溯到 2000 年 11 月,而 的当前版本algorithm2e
发布时间较晚,为 2013 年 1 月。
编辑:一个问题较少、功能更强大的用于排版菜单序列、路径和键盘快捷键的软件包,非常出色menukeys
包裹。
答案1
首先,保存冲突的标识符:
\usepackage{keystroke}
\let\keystroke@Return\Return
\let\Return\undefined
\usepackage{algorithm2e}
\let\algorithmtwoe@Return\Return
\let\Return\undefined
然后定义两个宏来设置正确的绑定。
\def\keystroke@setupbindings{%
\let\Return\keystroke@Return
}
\def\algorithmtwoe@setupbindings{%
\let\Return\algorithmtwoe@Return
}
最后使用 修补入口点,\Return
以便它们以适当的@setupbindings
宏开始。您可以通过在令牌寄存器中加载该入口点的替换文本并使用 重新定义入口点来以编程方式执行此操作\edef
:
% Some code that loads the expansion text of \entrypoint in toks0
\edef\entrypoint{\noexpand\keystroke@setupbindings\the\toks0}
实现最大程度的通用性是不可能的,因为据我所知,在 TeX 中不可能恢复宏的应用模板。但如果你真的需要,你可以\patch
这样编写宏:
\patch\entrypoint\keystroke@setupbindings
与上面的伪代码执行相同的操作。不过,处理\long
修饰符\outer
和带有参数的宏可能有点繁琐,因此半手动修补相关宏可能比较合适。
编辑 — 嗯,实际上可以恢复宏的应用程序模板,我应该很清楚这一点,因为我在我的巴西 TeX格式!:-) 这里是未经测试的纯 TeX 翻译:
\begingroup
\edef\next{%
\gdef\noexpand\toksloadmeaning@A
##1\noexpand\and##2\expandafter
\ignore\string\macro:##3->##4\noexpand\stop{%
##1{##3}##2{##4}%
}}
\next
\endgroup
\def\toksloadcsmeaning#1\to#2\and#3{%
\begingroup
\toks0={#2}%
\toks2={#3}%
\edef\next{\noexpand\toksloadmeaning@A\the\toks0 \noexpand\and\the\toks2 %
\meaning#1\noexpand\stop
}%
\expandafter\endgroup\next
}
\toksloadcsmeaning\controlsequence\to{\toks1}\and{\toks3}
令牌寄存器包含\toks1
应用程序模板和\toks3
宏的含义。有了这个,编写\patch
宏应该是小菜一碟。