是什么导致了词汇表和 amsmath 之间这种奇怪的相互作用?

是什么导致了词汇表和 amsmath 之间这种奇怪的相互作用?

MWE:从大型文档中大量精简;XeLaTeX;完整的 TeXLive2012 完全更新:

\documentclass{memoir}
\usepackage{fixltx2e}
\usepackage{amsmath}
\usepackage{mathspec}
\usepackage{glossaries}
\usepackage{lipsum}
\begin{document}
\lipsum[1]
\end{document}

失败并显示“!包 mathspec 错误:‘amsmath’ 必须比‘mathspec’ 更早加载。”

现在,如果我消除glossaries,或者将其移到文件中 mathspec 的上方,一切就都正常了。但每当任何东西获得新的依赖项时,就必须对包进行排序,这不太方便。无论如何,我在 mathspec 之前加载 amsmath,不是吗?

对此我真的很困惑。任何解释都非常感谢。

(顺便说一句,不是严格MWE,因为它也失败了article

答案1

问题在于datatool,由 加载的子包之一包含datatool-base以下行

\RequirePackage{amsmath}

mathspec设置了一个(非常差的)检查,以防在其后加载,即使已经加载amsmath,也会触发错误amsmath已经当另一个包需要它时才加载。

LaTeX 的正常设置是不会重新加载软件包的,所以 by 的调用datatool-base应该是完全无害的mathspec。这无疑是一个错误。


包裹mathspec上写着

\let\original@RequirePackage\RequirePackage
\renewcommand\RequirePackage[2][]{
  \ifstrequal{#2}{amsmath}
    {\PackageError{mathspec}
       {`amsmath' must be loaded earlier than `mathspec'}
       {Edit the document so that `amsmath' is required earlier than `mathspec'.}}
    {\relax}
  \original@RequirePackage[#1]{#2}}
\@onlypreamble\RequirePackage
\let\usepackage\RequirePackage
\@onlypreamble\usepackage

在我看来,这是非常糟糕的代码:\RequirePackage被重新定义为检查其强制参数是否确切地 amsmath.所以,如果有人说

\usepackage{mathspec}
\usepackage{amsmath,amsthm}

检查将失败,amsmath之后将顺利加载mathspec

从包裹里的评论来看,仅有的之所以amsmath应该先加载,mathspec是因为 的定义存在问题\varTheta。这个问题可以通过修改第 103-106 行来更轻松地解决,这些行的内容如下

103 \ifdef{\varTheta}
104   {\let\eu@cm@varTheta\varTheta}
105   {\relax}
106 \let\varTheta\Theta

进入

\AtBeginDocument{
  \ifdef{\varTheta}
    {\let\eu@cm@varTheta\varTheta}
    {}
\let\varTheta\Theta
}

并删除重新定义的最后一行\RequirePackage


mathspec在软件包修复之前,有一种解决方法:

\documentclass{memoir}
\usepackage{fixltx2e}
\usepackage{amsmath}
\usepackage{mathspec}

\makeatletter % undo the wrong changes made by mathspec
\let\RequirePackage\original@RequirePackage
\let\usepackage\RequirePackage
\makeatother

\usepackage{glossaries}
\usepackage{lipsum}
\begin{document}
\lipsum[1]
\end{document}

相关内容