![软件包不兼容:etoolbox、hyperref 和 bm,独立吗?](https://linux22.com/image/238784/%E8%BD%AF%E4%BB%B6%E5%8C%85%E4%B8%8D%E5%85%BC%E5%AE%B9%EF%BC%9Aetoolbox%E3%80%81hyperref%20%E5%92%8C%20bm%EF%BC%8C%E7%8B%AC%E7%AB%8B%E5%90%97%EF%BC%9F.png)
我正在尝试过渡到使用etoolbox
包,但似乎遇到了一些困难,它们似乎与hyperref
和bm
包有关,而在我看来,它们完全不相关。MWE 示例自定义以来就进行了编译,并表明在使用 \RemoveEToolbox
之前没有明显的问题。etoolbox
注释掉该\def\RemoveEToolbox{}
行会产生两个问题:
使用
\renewcommand
和usepackage{hyperref}
注释,结果为“失控的争论?段落在 \bm@test@token 完成之前就结束了”。包括
usepackage{hyperref}
(带\renewcommand
注释的)结果“未定义控制序列。\Call@AtVeryEndDocument ...cumentHook \@undefined”
但是如果取消注释该\renewcommand{\bm}{#1}
行(实际上没有任何\bm
),那么这似乎可以编译。
我已经使用这个有一段时间了,一切似乎都运行良好,但现在我尝试使用时etoolbox
似乎遇到了问题。
\documentclass{standalone}
\def\RemoveEToolbox{}% Shows that this works fine without {etoolbox}
\usepackage{amsmath}
\usepackage{xcolor}
\usepackage{bm}
\ifdefined\RemoveEToolbox
\newcommand*{\iftoggle}[3]{#2}% Default to true value of "if"
\else
\usepackage{etoolbox}
\newtoggle{paper}
\toggletrue{paper}
%\renewcommand{\bm}[1]{#1}% Why can't I have a normal \bm with {etoolbox}?
\fi
% \usepackage{hyperref}
\begin{document}
This document is intended for
\iftoggle{paper}{paper}{electronic}
distribution.
\bm{\textcolor{blue}{Solve $x^2-1=0$}}
\begin{align*}
a &= b\\
\iftoggle{paper}{
c &= d\\
}{}
e &= f\\
\end{align*}
\end{document}
答案1
问题是standalone
类和etoolbox
包都重新定义了document
环境。这会导致冲突。您可以通过etoolbox
使用在类之前加载来避免这种情况\RequirePackage
。我会尝试支持此包的正常功能,但要过一段时间才能有时间发布新版本的standalone
。
解决方法:
\def\RemoveEToolbox{}% Shows that this works fine without {etoolbox}
\ifdefined\RemoveEToolbox
\newcommand*{\iftoggle}[3]{#2}% Default to true value of "if"
\else
\RequirePackage{etoolbox}
\newtoggle{paper}
\toggletrue{paper}
%\renewcommand{\bm}[1]{#1}% Why can't I have a normal \bm with {etoolbox}?
\fi
\documentclass{standalone}
\usepackage{amsmath}
\usepackage{xcolor}
\usepackage{bm}
% \usepackage{hyperref}
\begin{document}
This document is intended for
\iftoggle{paper}{paper}{electronic}
distribution.
\bm{\textcolor{blue}{Solve $x^2-1=0$}}
\begin{align*}
a &= b\\
\iftoggle{paper}{
c &= d\\
}{}
e &= f\\
\end{align*}
\end{document}
更新 2011/12/21
由于更改了修补环境的方式,因此的新版本 1.0standalone
与 配合良好。但是,新的默认设置会忽略段落分隔符,因此在使用 时会出现问题。您可以使用class 选项轻松修复此问题。etoolbox
document
align*
varwidth
答案2
(Martin 已经发布了答案,但还有更多内容!)问题是由于 的定义存在问题而产生的\@@end
。这是 LaTeX 内核存储 TeX\end
原语的地方(以便\end
可以重复用于环境)。该bm
包对依赖于它是原语的各种测试进行了测试\@@end
。发生的事情etoolbox
是
\patchcmd\enddocument
{\deadcycles}
{\let\AfterEndDocument\@firstofone
\@afterenddocumenthook
\deadcycles}
{}
{\let\etb@@end\@@end
\def\@@end{%
\let\AfterEndDocument\@firstofone
\@afterenddocumenthook
\etb@@end}}
它试图修补\enddocument
,如果不能,则改变 的定义\@@end
。在标准类中,补丁有效(它寻找\deadcycles
),所以一切都很好。另一方面,这失败了,因为standalone
它重新定义\enddocument
为
\def\sa@@enddocument{%
%\let\document\sa@orig@document
\let\enddocument\sa@orig@enddocument
\endinput
}
因此在这种情况下,etoolbox
它是否会进行“后备”修补,然后测试会bm
失败。
如果你不需要结束文档钩子,那么修复很容易
\makeatletter
\let\@@end\etb@end
\makeatother
我现在已经承担了维护etoolbox
和已对代码进行了修复。现在采取的方法是\@@end
使用钩子尽可能延迟重新定义\AtEndDocument
。