For some reason I do not understand, cleveref
produces wrong references to line numbers of listings produces with the algorithm2e
package. I hope that I did not miss a simple solution …
My example is the following:
\documentclass[paper=A4, fontsize=11pt]{scrbook}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[linesnumbered]{algorithm2e}
\usepackage{hyperref}
\usepackage{cleveref}
\begin{document}
\begin{algorithm}
Do something\;
Do something else\;\label{line}
\end{algorithm}
line~\ref{line} vs.\ \cref{line}.
\end{document}
The output (which you can also check online) is
The \ref
command works as expected (and refers to line 2) but the \cref
command always refers to line 1 (no matter how many lines there are and which line I try to reference).
Does anybody know a solution to this problem?
Best Answer
You found an oversight in the
cleveref
package. First,algorithm2e
numbers the lines with theAlgoLine
counter, andcleveref
does not track that. So we need ato get that sorted.
Next,
cleveref
hacks into the\label
command to write another label for its own use. In your example, the.aux
containsThe second line is written by
cleveref
. The offending part here is{[line][1][]1}
, which is actually the content of\cref@currentlabel
. Why is it wrong? While\label
looks at\@currentlabel
,cleveref
uses its own\cref@currentlabel
to determine what is been labeled. In order to keep that up to date,cleveref
hacks into\refstepcounter
, and updates\cref@currentlabel
there. This works fine whenalgorithm2e
is used withouthyperref
, but whenhyperref
is also loaded, theAlgoLine
counter is updated with\stepcounter
, andcleveref
does not hack into that! This also means thatcleveref
will fail on all counters that are not (only) manipulated with\refstepcounter
.The solution is to also hack into
\stepcounter
, and update\cref@currentlabel
there, too. The code for doing so is the same as for\refstepcounter
. The complete code is then