结合使用 breqn、thm-restate 和 cleveref 时出现“Extra \else”错误

结合使用 breqn、thm-restate 和 cleveref 时出现“Extra \else”错误

我有一个文档使用了breqnthm-restate( thmtools) 和cleveref。我无法让它编译。

这是一个简单的例子:

\documentclass{article}

\usepackage{thm-restate}
\usepackage{breqn}
\usepackage{cleveref}

\begin{document}

\begin{restatable}{theorem}{foo}
  Test
\end{restatable}

\end{document}

pdflatex 的输出包含许多类似这样的错误:

! Extra \else.
<argument> \else 

l.11 \end{restatable}

! Extra \else.
\cref@ifstreq ... \@firstoftwo \else \let \@tempc 
                                                  \@secondoftwo \fi \expanda...
l.11 \end{restatable}

! Extra \else.
\cref@ifstreq ...i \expandafter \endgroup \@tempc 
                                                  {#3}{#4}

我已尝试了多个(我想是全部)命令来加载包裹。

我的感觉是,这可以通过改变定义来解决这个问题,\cref@ifstreq但这超出了我目前的 LaTeX 技能。

有解决方法吗?我应该报告错误吗?(在哪个软件包中?)

我使用 TeX Live 2019,它有breqn0.98g、thm-restate/ thmtools67 和cleveref0.21.4。这些都是 CTAN 的最新软件包,除了thmtools,我尝试将其更新到 68,但这也没有帮助。

答案1

哇,这是一个很好的发现(如果你可以这么称呼它的话)。。。

顺序并不重要,但是所有三个包都发挥了作用(尽管cleveref是无辜的)。

首先,breqn重新定义 LaTeX\@ifstar\@temp(a|b|c)代替\reserved@(a|b|c)(见这里关于这些),所以当你定义一个宏时\def\test{\@ifstar{A}{B}},然后使用\test\else\@tempc最终会变得与相同\else(这是很危险的)。

thmtools的代码\begin{restatable}{theorem}{foo}最终会变成\expandafter\foo\ifprint\else*\fi,然后\expandafter扩展\ifprint(名称实际上是\ifthmt@thisistheone),在您的情况下,这是正确的,因为您使用了\begin{restatable},而不是\begin{restatable*}。完成后,\expandafter您只剩下\foo\else*\fi(是的,这很糟糕:-)。

现在猜猜第一件事是什么\foo
是的!\@ifstar,现在\@tempc\else

cleveref只是不幸\@tempc\cref@ifstreq这里使用:

    \ifx\@tempa\@tempb%
      \let\@tempc\@firstoftwo%
    \else%
      \let\@tempc\@secondoftwo%
    \fi%

这很好,直到\@tempc与相同\else\ifx测试为假,因此您有:

    \iffalse
    \@tempc % \else
      \@firstoftwo%
    \else%
      \let\@tempc\@secondoftwo%
    \fi%

你也可以看到这是怎么回事……

这是一个修复 的补丁thm-restate。该补丁改变了这种\expandafter\foo\ifprint\else*\fi情况,以确保整个块在有机会查看它\if...\fi之前完全展开。\foo\@ifstar

\usepackage{xpatch} % Needs to be loaded before breqn
\makeatletter % The patch needs to appear after thm-restate is loaded
\xpatchcmd\thmt@restatable % fixing thm-restatable
  {\csname #3\@xa\endcsname\ifthmt@thisistheone\else*\fi}
  {\begingroup\edef\x{\endgroup
     \expandafter\noexpand\csname #3\endcsname
       \ifthmt@thisistheone\else*\fi}\x
  }{}{\FailedToPatch}
\makeatother

完整文档:

\documentclass{article}
\usepackage{xpatch} % Needs to be loaded before breqn

\usepackage{thm-restate}
\usepackage{breqn}
\usepackage{cleveref}

\makeatletter % The patch needs to appear after thm-restate is loaded
\xpatchcmd\thmt@restatable % fixing thm-restatable
  {\csname #3\@xa\endcsname\ifthmt@thisistheone\else*\fi}
  {\begingroup\edef\x{\endgroup
     \expandafter\noexpand\csname #3\endcsname
       \ifthmt@thisistheone\else*\fi}\x
  }{}{\FailedToPatch}
\makeatother

\begin{document}
\begin{restatable}{theorem}{foo}
  Test
\end{restatable}
\end{document}

相关内容