6

I have a document that uses breqn, thm-restate (thmtools), and cleveref. I can't get it to compile.

Here is a minimal example:

\documentclass{article}

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

\begin{document}

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

\end{document}

The output of pdflatex contains many errors like this:

! 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}

I have tried multiple (I think all) orders to load the packages.

My feeling is that this can be fixed by changing the definition of \cref@ifstreq but this is beyond my current LaTeX skills.

Is there a workaround? Should I report a bug? (In which of the packages?)

I use TeX Live 2019, which has breqn 0.98g, thm-restate/thmtools 67, and cleveref 0.21.4. These are all the latest packages from CTAN except for thmtools, which I tried to update to 68 but that did not help either.

1 Answer 1

10

Wow, that's a nice finding (if you can call it that). . .

The order doesn't matter, but all three packages play a role in this (though cleveref is innocent).

First, breqn redefines LaTeX's \@ifstar to use \@temp(a|b|c) instead of \reserved@(a|b|c) (see here about these), so when you define a macro \def\test{\@ifstar{A}{B}}, then use \test\else, \@tempc ends up becoming the same as \else (which is dangerous).

thmtools's code does so that \begin{restatable}{theorem}{foo} eventually becomes \expandafter\foo\ifprint\else*\fi, then the \expandafter expands the \ifprint (the name is actually \ifthmt@thisistheone) which, in your case, is true, because you used \begin{restatable}, not \begin{restatable*}. After the \expandafter finishes you are left with \foo\else*\fi (yes, this is bad :-).

Now guess what is the first thing \foo does?
YES! \@ifstar, and now \@tempc is \else.

cleveref is just unfortunate enough to use \@tempc in \cref@ifstreq here:

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

which is fine, until \@tempc is the same as \else. The \ifx test is false, so you have:

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

and you can see where this is going. . .

Here's a patch that fixes thm-restate. The patch changes the \expandafter\foo\ifprint\else*\fi thing to make sure that the entire \if...\fi block is completely expanded before \foo (thus \@ifstar) has the chance to look at it.

\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

Full document:

\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}
5
  • Thanks, that was quick! So could this have been avoided by either breqn or cleveref following the suggestion in tex.stackexchange.com/questions/447584/… to add a unique prefix to their scratch macros? Commented Feb 10, 2020 at 19:41
  • 1
    @real-or-random Yes, that would have avoided this problem. Although I think the guilty party here is thmtools: if it had been more cautious with its expansion, the other packages using \@tempc wouldn't have been a problem. This same error can hapen with thmtools and other packages (other than cleveref and breqn), but then it would require another unfortunate combination (which I looked for but couldn't find right now). Commented Feb 10, 2020 at 20:02
  • Unfortunately thmtools is not maintained currently, not even the email address of the previous maintainer is active. I'll try to reach out to the maintainers of breqn or cleveref to see if they're willing to implement a workaround. Commented Feb 12, 2020 at 13:27
  • @real-or-random Oh, yes, I forgot to mention that. I'd say you go for breqn: the maintainer is more active than cleveref's. Also cleveref is innocent in this issue. The problem really is thmtools being sloppy with its expansion and breqn using a generic, all purpose token to do something that needs to be done more carefully. Commented Feb 12, 2020 at 13:38
  • 2
    This has been fixed in breqn v0.98h, relased on 2020-02-16, see github.com/wspr/breqn/commit/…. Commented Feb 17, 2020 at 10:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .