# algorithm2e noend option produces wrong label

I have a problem with the algorithm2e package. I want to reference the end of a block, e.g., a for-loop, in my text. Therefore, I place a label behind the closing bracket of the for statement. When I configure the package to produce an "end" line, the label correctly points to this line. But if I use the option "noend", the label points to the for statement instead of the last line of the for-loop. Here is an example:

\documentclass[]{scrartcl}
\usepackage[algo2e, noline]{algorithm2e}
\begin{document}
\begin{algorithm2e}
\For {...} { a = b\; }\label{x}
\end{algorithm2e}
Reference: \ref{x}
\end{document}


The output would look somehow like this:

1 for ... do

2 a = b

3 end

Reference: 3

When I reference label x in my text, I get a correct reference to line 3.

With the noend option for package algorithm2e, I get the following output:

1 for ... do

2 a = b

Reference: 1

Label x now creates a reference to line 1 instead of line 2.

I guess it depends on how latex handles labels. I can fix it by putting the label behind the last line of my for-loop. But then the label would point to line 2 instead of 3 when I want to show "end" lines again.

Is there a possibility that always generates the correct reference independent of the option that I am using?

-
It's not clear what you want to reference. Can you please show a minimal working example (MWE)? –  egreg Feb 28 '13 at 22:53
@egreg He wrote that the reference should point to line 2 instead of 1. Actually, I would expect that, too. Nonetheless it might be a feature of algorithm2e. –  mafp Feb 28 '13 at 23:39
@egreg The previous example was working, but I tried to make it more precise. Hope it is clear now which reference is wrong with the "noend" option –  Sven Viehmeier Mar 1 '13 at 9:59

You most certainly triggered a bug in algorithm2e. While the manual is not very clear on that, I guess the behaviour of the end version is correct, and the label should refer to the last line of the block. The reason for this bug is that \label picks up \@currentlabel, but algorithm2e uses its own counter AlgoLine, and this is not pushed to \@currentlabel in all situations. The funny thing is that algorithm2e has special code for label handling when hyperref is loaded, and then everything works correct. So your recipe is: 1. Inform the maintainer of algorithm2e about this bug. 2a. Use the hyperref package. 2b. If you don't want to use hyperref, the following code defines a new labeling command, \elabel, which works as expected:

\documentclass{article}

\usepackage[lined,linesnumbered,noend]{algorithm2e}
\usepackage{hyperref}

\makeatletter
\def\elabel#1{\label{#1}}%
}{%
\def\elabel#1{\@bsphack \protected@write \@auxout {}{\string \newlabel {#1}{{\theAlgoLine }{\thepage }}}\@esphack}%
}
\makeatother

\begin{document}
\SetAlgoShortEnd%
\begin{algorithm}%
\For {...} { a = b\; }                \label{ya}\elabel{ya2}
\end{algorithm}%
\textbackslash{}label gives \ref{ya}, \textbackslash{}elabel is \ref{ya2}%

\SetAlgoNoEnd%
\begin{algorithm}%
\For {...} { a = b }\label{xa}\elabel{xa2}
\end{algorithm}%
\textbackslash{}label is \ref{xa}, \textbackslash{}elabel is \ref{xa2}%
\end{document}


-
@Jubobs While I am fine with your edit, I am afraid the consensus on this site is against it. –  mafp Mar 2 '13 at 16:28
@mapf Ok. I wanted to correct a typo, but couldn't due to the 6-character limitation; therefore, I changed one more word. Sorry, and I totally understand. –  Jubobs Mar 2 '13 at 19:23

Without being too disruptive to the internal workings of the package I think the simplest thing to do is just make a label before or after the } depending on the end style. You can define a \label variant that does nothing or makes a label depending on the option set.

\documentclass[]{scrartcl}
\usepackage[algo2e,noend,linesnumbered]{algorithm2e}
\newcommand\Aendlabel[1]{\ifthenelse{\boolean{algocf@optnoend}}{}{\label{#1}}}
\newcommand\Anoendlabel[1]{\ifthenelse{\boolean{algocf@optnoend}}{\label{#1}}{}}
\begin{document}
\begin{algorithm2e}
\For {...} { a = b\; \Anoendlabel{x}}\Aendlabel{x}
\end{algorithm2e}
Reference: \ref{x}
\end{document}


delete the noend option and you get:

\documentclass[]{scrartcl}
\usepackage[algo2e,linesnumbered]{algorithm2e}
\newcommand\Aendlabel[1]{\ifthenelse{\boolean{algocf@optnoend}}{}{\label{#1}}}
\newcommand\Anoendlabel[1]{\ifthenelse{\boolean{algocf@optnoend}}{\label{#1}}{}}
\begin{document}
\begin{algorithm2e}
\For {...} { a = b\; \Anoendlabel{x}}\Aendlabel{x}
\end{algorithm2e}
Reference: \ref{x}
\end{document}

-
Great! Your fix is a bit unwieldy but does the trick. I guess that's the best that can be done until the issue gets fixed in a subsequent release of algorithm2e. Unless someone comes up with something better soon, my bounty is yours. –  Jubobs Mar 1 '13 at 17:58