LaTeX 是否允许使用命名空间来消除包冲突的风险?

LaTeX 是否允许使用命名空间来消除包冲突的风险?

我经常会sty因为诸如变量名之类的简单问题而遇到不同文件之间的冲突。

最新的一个是proof.sty(允许将证明自动移动到附录)和llncs.sty(许多会议和期刊都要求确保外观和感觉一致)之间,它们都定义了一个名为的变量exercise,因此产生冲突。

一种解决方案是期望每个sty文件在其所有变量前面加上所实现库的名称,但这不是一个干净的解决方案。LaTeX 中是否有任何方法可以提供一些封装,或者至少定义一些局部变量,因为我认为这是现代编程语言中的用法?

答案1

(La)TeX 中没有封装,但即使有封装,由于作者命令的性质,它仍然可能存在问题。我的意思是什么?由于 (La)TeX 本质上是一种标记语言,如果您要开发一个包,例如为标记练习提供宏,那么在用户级别,您很可能希望提供:

\begin{exercise}
\end{exercise}

命令类型而不是\begin{MXexercise}。但是为了尽量减少与其他包的问题和冲突,包和类作者确实使用了前缀和符号@。一个很好的例子是 LaTeX3 约定,尽管在我看来,这种极端保守的方法可能会损害代码的可读性。

TeX 还具有分组机制,您可以在其中本地定义宏和其他命令。组之间的任何内容都是本地定义的。例如:

\def\acommand{43}

    \bgroup
       \def\acommand{42}
       In group \acommand
    \egroup

Outside group \acommand

以上代码将在组外打印 43,但在组内打印 42。\bgroup\egroup只是 的简写形式{}。您可以根据需要嵌套任意数量的组,效果相同。

我认为,好的做法是让软件包专注于单一目的并尽量减少作者命令。在内部,它们可以使用前缀或后缀来避免冲突。

对于类作者来说,类本身应该加载一组推荐的软件包以供其常用使用,并且类需要应用任何补丁。有些类走向另一个极端(例如 KOMA 和 Memoir),定义自己的软件包或将功能合并到主代码中。

我理解你的痛苦,因为我已经是 的用户hyperref很长时间了。但是,冲突可以通过以下方式轻松绕过:

\usepackage{packageA}
\let\oldcommand\culprit % command from package A causing errors in package B.
\let\culprit\undefined

\usepackage{packageB}

如果您想使用\culprit某处,请做相反的操作。

答案2

savesym包裹提供了一种将处理多重定义宏的责任转嫁给用户的方法。目前,这可能是您处理不周全的宏命名的最佳选择。

进入幻想领域,软件包作者采用以下策略并不难:

  • 全部它们的宏在包“命名空间”中。我赞成这种约定,我在我的ytableau 包,使用命名空间作为后缀而不是前缀,因此宏可以按字母顺序索引。\ytableaushort@YT等等。

  • 提供所有公开可用的宏名称列表,格式为\ThisPackageDefinesMacros{ytableaushort, ydiagram, ytableausetup}\ThisPackageDefinesEnvironments{ytableau}。或者,\newcommand\newenvironment宏可以用执行此操作的软件包版本替换(例如\RequirePackage软件包应该使用的宏而不是\usepackage)。这些只会将其内容转储到一些将被解析的内部列表宏中...

  • 然后,包的用户可以使用诸如\UsingMacros[ytableau]{ytableaushort, ydiagram}或 之类的命令来显示他们想要的宏(可能是所有宏)。(为了方便起见,第一个参数应默认为最后加载的包。为了进一步方便起见,如果您不想挑选,\UsingEnvironments[ytableau]{ytableau}可能应该有类似的内容。)\UsingAllMacros[ytableau]

这些宏应该是 LaTeX 本身提供的标准工具,或者至少是独立于其他包的包提供的标准工具(即每个人都不应该尝试定义自己的“使用”宏)。我花了十分钟来编写这样一个东西,但当然,除非大多数包都将其编辑到代码中,否则它将毫无用处。

这也可以回答我们可以轻松找到包中定义的所有命令、标记等等吗?,我认为值得好好回答一下。TeX 是一种过时的编程语言,但这并不意味着它不能用来提供一些现代的便利。

答案3

有最简单的名字包装,叫什么块结构

\def\foo{\begingroup{%
  \def\bar{bar}\endgroup}

其中\bar仅在 的分组内可用\foo,即词汇范围\foo在调用.的组内
(带参数,例如:\def\foo#1{{\def\bar##1{##1}\bar{#1}}}

我不知道为什么在 TeX 中不经常使用块;这可能有原因。

相关内容