8

I am using algpseudocode and algorithm packages to typeset pseudocode. I also use float, hyperref and caption packages. The problem is that when I reference a line in the pseudocode, the number is correct, but when I click it, the document moves to the beginning of the chapter and not the algorithm.

Minimal example:

\documentclass{book}
\usepackage{blindtext}
\usepackage{float}
\usepackage{hyperref}
\usepackage[hypcap]{caption}
\usepackage{algpseudocode}
\usepackage[chapter]{algorithm}

\begin{document}
\chapter{Heading}
Reference to the line \ref{line}.
\Blindtext
\begin{algorithm}
\begin{algorithmic}[1]
    \State Statement \label{line}
\end{algorithmic}
\caption{Example}
\label{alg}
\end{algorithm}
\Blindtext
\end{document}
7

There are two ways to do this. As said, just loading a new version of cleveref partially fixes the problem, links are now to line numbers rather than the start of the chapter; but when there are two or more algorithms hyperref's link doesn't distinguish the same line number in different algorithms. The simplest solution is just to load hyperref via

\usepackage[hypertexnames=false]{hyperref}

This changes all link names in to something unique, but not humanly recognisable/meaningful. If you think this is a blunderbust approach, then you can just define \theHALG@line appropriately, to give unique links, via

\providecommand\theHALG@line{\thealgorithm.\arabic{ALG@line}}

In hyperref each \thecounter has a corresponding \theHcounter which can be redefined the create unique identifiers. In your case, algorithm provides a unique container for your algorithmic environment, and so its number representation can be used to distinguish different instances.

Because of the @ symbols in the command names above, you will have to put this code between \makeatletter and \makeatother:

\documentclass{book}
\usepackage{lipsum}
\usepackage{algpseudocode}
\usepackage{float}
\usepackage[chapter]{algorithm}
\usepackage[hypcap]{caption}
\usepackage{hyperref}
\usepackage{cleveref}

\makeatletter
\providecommand\theHALG@line{\thealgorithm.\arabic{ALG@line}}
\makeatother

\begin{document}
\chapter{Heading}

Here's the first test to line \ref{test1} of Algorithm \ref{alg1}.\\
Here's the second test to line \ref{test2} of Algorithm \ref{alg1}.
Here's the first test to line \ref{test21} of Algorithm \ref{alg2}.\\
Here's the second test to line \ref{test22} of Algorithm \ref{alg2}.

\begin{algorithm}[p]
\begin{algorithmic}[1]
  \State Statement
    \State Statement
    \State Statement    
    \State Statement    \label{test1}
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement    \label{test2}
    \State Statement
\end{algorithmic}
\caption{Example}
\label{alg1}
\end{algorithm}

\begin{algorithm}[p]
\begin{algorithmic}[1]
  \State Statement
    \State Statement
    \State Statement    
    \State Statement    \label{test21}
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement
    \State Statement    \label{test22}
    \State Statement
\end{algorithmic}
\caption{Example}
\label{alg2}
\end{algorithm}

\end{document}
  • Your second solution doesn't work when the acmart document class is in use, as it seems it provides its own version of \theHALG@line (which doesn't work right). Using \renewcommand instead of \providecommand seems to do the job, though. – JAB Apr 2 '18 at 16:31
3

It seems like algorithmicx did not take hyperref into consideration, at least not fully...

The macro \ALG@step is in charge of writing out the line numbers (taken from algorithmicx.sty):

\def\ALG@step%
   {%
   \addtocounter{ALG@line}{1}%
   \addtocounter{ALG@rem}{1}%
   \ifthenelse{\equal{\arabic{ALG@rem}}{\ALG@numberfreq}}%
      {\setcounter{ALG@rem}{0}\alglinenumber{\arabic{ALG@line}}}%
      {}%
   }%

Note how the line numbers are stepped using \addtocounter{ALG@line}{1}. This doesn't set a hyper-target - an anchor to which a link can jump. Inside, it should use \refstepcounter{ALG@line}. If you use/add to your preamble

\makeatletter
\def\ALG@step%
   {%
   \refstepcounter{ALG@line}% Step and anchor for hyperref
   \stepcounter{ALG@rem}% Regular step (equivalent to \addtocounter{ALG@rem}{1})
   \ifthenelse{\equal{\arabic{ALG@rem}}{\ALG@numberfreq}}%
      {\setcounter{ALG@rem}{0}\alglinenumber{\arabic{ALG@line}}}%
      {}%
   }%
\makeatother

your hyperlinks should work fine.


It should be mentioned that the optional argument of the algorithmic environment is meant to show line numbers with steps. For example, it allows one to only show every second line number. It may seem odd then to jump to (say) line 2 when there is no line 2 visibly marked in the algorithm. The above adjustment allows one to do just that.

1

Use \hypertarget and \hyperlink:

\documentclass{book}
\usepackage{blindtext}
\usepackage{algpseudocode}
\usepackage{float}
\usepackage[hypcap]{caption}
\usepackage{hyperref}
\usepackage[chapter]{algorithm}

\begin{document}
\chapter{Heading}
Reference to the line 1 of Alg. \hyperlink{line}{\ref{alg1}}.
Reference to the line 8 of Alg. \hyperlink{line8}{\ref{alg1}}.
\Blindtext
\begin{algorithm}
\begin{algorithmic}[1]\hypertarget{line}{}
    \State Statement 
    \State Statement 
    \State Statement 
    \State Statement 
    \State Statement 
    \State Statement 
    \State Statement \hypertarget{line8}{}
    \State Statement 
\end{algorithmic}
\caption{Example}\label{alg1}
\label{alg}
\end{algorithm}
\Blindtext
\end{document}
  • Thanks for the quick response. Actually, a \phantomsection helps in jumping to the beginning of the algorithm, but not the specified line. Try adding a few more \States, and add a \label to the last one. You will see that a \ref will print the correct line number, but clicking it does not jump to the right one. (Though we can add a \phantomsection to each referenced line.) – M.S. Dousti Jan 26 '14 at 13:25
  • ok, see my edited answer – user2478 Jan 26 '14 at 13:42
  • Thanks. Unfortunately, your edited answer did not quite work for me: First, it does not print the line number automatically, and second, it does not link to it (rather, it links to the algorithm itself). However, I took your excellent idea of using \phantomsections, and turned it into a working solution. Please check my answer. – M.S. Dousti Jan 26 '14 at 14:14
1

I took an idea, originally conceived by @Herbert, and used it in my answer. The idea is to use \phantomsection before each \label which refers to some line of the algorithm. As this repeated pattern calls for defining a new macro, I defined \plabel as follows:

\newcommand\plabel[1]{\phantomsection\label{#1}}

Here's a minimal working example:

\documentclass{book}
\usepackage{lipsum}
\usepackage{algpseudocode}
\usepackage{float}
\usepackage[hypcap]{caption}
\usepackage{hyperref}
\usepackage[chapter]{algorithm}

\newcommand\plabel[1]{\phantomsection\label{#1}}

\begin{document}
\chapter{Heading}

Here's the first test to line \ref{test1} of Algorithm \ref{alg}.\\
Here's the second test to line \ref{test2} of Algorithm \ref{alg}.

\begin{algorithm}[p]
\begin{algorithmic}[1]
    \State Statement
    \State Statement
    \State Statement    
    \State Statement    \plabel{test1}
    \State Statement
    \State Statement
    \State Statement    \plabel{test2}
    \State Statement
\end{algorithmic}
\caption{Example}\label{alg1}
\label{alg}
\end{algorithm}

\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.