[Tex/LaTex] A problem with thmtools and cleveref

clevereftheoremsthmtools

I am trying to use thmtools and cleveref and I am getting a quite peculiar error. Here's a minimal example.

\documentclass{article}

\usepackage{thmtools}
\usepackage{cleveref}

\declaretheorem[name=Lemma,Refname={Lemma,Lemmas}]{lem}
\declaretheorem[name=Proposition,Refname={Proposition,Proposition}]{prop}
\declaretheorem[name=Theorem,Refname={Theorem,Theorems}]{thr}

\begin{document}

  \begin{lem}\label{lem1}
    A lemma.
  \end{lem}

  \begin{prop}\label{prop1}
    A proposition.
  \end{prop}

  \begin{thr}\label{thr1}
    A theorem.
  \end{thr}

  \Cref{lem1}, \Cref{prop1} and \Cref{thr1}.

\end{document}

When I run pdflatex (using a fresh default installation of TeXLive 2011) I receive a message:

LaTeX Warning: Cref  reference format for label type `prop' undefined on input line 24.

and the final sentence is rendered in the pdf file as "Lemma 1, ?? 1 and Theorem 1." The weird thing is that if I use only two \declaretheorem definitions, then everything is fine. If I change the order of definitions, then it is always the second one that yields a warning.

Any ideas about what is happening here and how to fix it?

Best Answer

There is a bug in thm-autoref.sty. Part of the set-up for cleverefs magic is left to the start of the document. So cleveref maintains a list of all the label types that it has been told about so that when it gets to the \begin{document} hook, it can iterate through them and finish the necessary configuration.

Examining this list for your document (well, my slightly extended version) reveals that it is:

\thmt@envname ,\thmt@envname ,\thmt@envname ,\thmt@envname ,thr,equation,\@nil

That doesn't look right! \thmt@envname is getting processed four times here. In my code, then \thmt@envname is prop which happens to be the last one in my list of \declaretheorems (for your code it would be thr - I experimented with permutations a bit). So something isn't being expanded when it should. After playing a bit of Ultimate Code Frisbee (chasing definitions from one place to another), I tracked it down to a definition in thm-autoref.sty, specifically the definition of \thmt@refnamewithcomma. It reads:

\def\thmt@refnamewithcomma #1#2#3,#4,#5\@nil{%
  \@xa\def\csname\thmt@envname #1utorefname\endcsname{#3}%
  \ifcsname #2refname\endcsname
    \csname #2refname\endcsname{\thmt@envname}{#3}{#4}%
  \fi
}

Clearly, we need to expand the \thmt@envname. One way to do this is with two \expandafters:

\def\thmt@refnamewithcomma #1#2#3,#4,#5\@nil{%
  \@xa\def\csname\thmt@envname #1utorefname\endcsname{#3}%
  \ifcsname #2refname\endcsname
    \csname #2refname\expandafter\endcsname\expandafter{\thmt@envname}{#3}{#4}%
  \fi
}

So if you put that at the top of your document (within \makeatletter ... \makeatother) it will fix this problem. Warning The same command is used for autoref, I don't know if this will break that (though it really aught not to do so).

Here's a full example:

\documentclass{article}

\usepackage{cleveref}
\usepackage{thmtools}

\makeatletter
\def\thmt@refnamewithcomma #1#2#3,#4,#5\@nil{%
  \@xa\def\csname\thmt@envname #1utorefname\endcsname{#3}%
  \ifcsname #2refname\endcsname
    \csname #2refname\expandafter\endcsname\expandafter{\thmt@envname}{#3}{#4}%
  \fi
}
\makeatother

\declaretheorem[name=Theorem,Refname={Theorem,Theorems}]{thr}
\declaretheorem[name=Lemma,Refname={Lemma,Lemmas}]{lem}
\declaretheorem[name=Corollary,Refname={Corollary,Corollaries}]{cor}
\declaretheorem[name=Proposition,Refname={Proposition,Proposition}]{prop}
\begin{document}

  \begin{lem}\label{lem1}
    A lemma.
  \end{lem}

  \begin{prop}\label{prop1}
    A proposition.
  \end{prop}

  \begin{thr}\label{thr1}
    A theorem.
  \end{thr}

  \begin{cor}\label{cor1}
    A Corollary.
  \end{cor}

  \Cref{lem1}, \Cref{prop1}, \Cref{thr1}, and \Cref{cor1}.

\end{document}

Result:

(Oh - something doesn't like standalone. Oh dear, back to more traditional tools.)

fixed cleveref and thmtools