16

In answering this question I came across an unusual feature of hyperref.

The issue is that sometimes the hyperlinks generated by hyperref and \pageref point back to the first page of the document rather than to the page that they are supposed to go to. Here is a MWE:

\documentclass{article}
\usepackage[colorlinks]{hyperref}
\begin{document}
Page 1\newpage
Page 2\label{page2}\newpage
Page 3: Here is a link to \pageref{page2}
\end{document}

Clicking on the link on page 3 takes you back to page 1 rather than to page 2, even though the pdf file says that the link is on page 2. For the record, I note that the page numbers are in arabic (roman is known to cause problems) and I am using TeXLive 2014 and pdflatex.

Now this particular issue is known and is apparently NOT a bug because label does not create an anchor so there is nothing to link to. Indeed, if I change my minimal working example to:

\documentclass{article}
\usepackage[colorlinks]{hyperref}
\begin{document}
Page 1\newpage
\newcounter{acounter}\refstepcounter{acounter}
Page 2\label{page2}\newpage
Page 3: Here is a link to \pageref{page2}
\end{document}

The link on page 3 now correctly sends me back to page 2.

Interestingly, if instead I write

\documentclass{article}
\usepackage[colorlinks]{hyperref}
\begin{document}
\newcounter{acounter}\refstepcounter{acounter}
Page 1\newpage
Page 2\label{page2}\newpage
Page 3: Here is a link to \pageref{page2}
\end{document}

then my hyperlink is again wrong as it sends me back to page 1. Arguably, as there is no anchor on the current page hyperref is justified in being confused. On the other hand, since latex does correctly produce the correct page number I think that hpyerref should produce correct hyperlinks in all of these cases.

So my question: what should hyperref do in these cases?

Judging from the link above, these are probably not bugs...personally, I wonder why \label doesn't create a hyperlink anchor.

  • 2
    When \label is not just after a stepped counter, no anchor is set; \phantomsection\label{...} in these cases should do. – egreg Jul 26 '14 at 15:41
  • 1
    You need to create the proper hyperref anchor via \phantomsection. – Werner Jul 26 '14 at 15:42
  • 1
    @egreg @werner So what creates the anchor "normally". Is it \refstepcounter? Wouldn't it make more sense for \label to create it? If \refstepcounter creates the anchor but there is no subsequent \label then the anchor isn't needed...I'm just like to understand the logic here. – Andrew Jul 26 '14 at 15:47
  • @Andrew No, that's not possible: \label must go after a number is stepped, in order to know what number it should refer to. One might think to a \pagelabel command for this case; when LaTeX was released, hyperlinks did not exist. – egreg Jul 26 '14 at 15:55
  • @Andrew: I think you might be equally negative about hyperref if \label was used to place the anchor, since then you would typically find yourself jumping to the line below a section title rather than the title itself. This is the case with \captions (where the \refstepcounter occurs), but luckily the structure of a float containing a \caption is somewhat predictable... and hypcap was born). – Werner Jul 26 '14 at 16:04
14

hyperref points its hyperlink to the last anchor, and this anchor is set via the macro \refstepcounter. Indeed, hyperref redefines the traditional \refstepcounter to insert the appropriate anchor (see \hyper@refstepcounter in hyperref.dtx).

This is important from the point of view of the hyperlink. Here is a showcase that highlights the motivation:

\documentclass{article}
\usepackage{hyperref}
\newcommand{\hlabel}{\phantomsection\label}
\begin{document}

\section{A section}\label{sec:hyp1}

See section~\ref{sec:hyp1}.

\section{Another section}\hlabel{sec:hyp2}

See section~\ref{sec:hyp2}.

\end{document}

In the above example \hlabel has been deliberately made to insert an anchor (thereby ignoring whatever other anchors are set), in-line with your request. This anchor is set using \phantomsection.

Clicking on the link sec:hyp1 jumps you back to the actual section title. Hey, that's awesome! Clicking on sec:hyp2 jumps you to just below the sectional title. Not so awesome, since you don't know which section the jump is in. Of course, this discussion might seem trivial and depend on your PDF zoom level, but I hope the point is made clear.

As such, there is a separation between the placement of the anchor and the placement of the \label. If need be, it allows you to gauge your own destination for the hyperlink. However, in general, the hyperlink should typically jump to where the counter was stepped.

As an aside, the predictability of floats with \captions (in terms of the their structure) is exactly the reason why the package hypcap was born. That is, by clicking on the hyperlink associated with the caption/float counter stepping, you can jump to where the float actually starts.

  • Thanks for this. I didn't know about hycap and \hlabel which is why I've given you the tick. So hyperref puts the anchor at the point where the counter is stepped, assuming that this will be close to where the counter being referenced actually appears in the PDF file. Generally a \label will be further away from the anchor so I agree that this probably the best choice. – Andrew Jul 27 '14 at 3:34
10

Let's see how \label works. The purpose of \label is to write a note in the .aux file for later retrieval with \ref or \pageref. The command uses immediately the current value of \@currentlabel and, at shipout time, the current page number.

The value of \@currentlabel is set (locally) by a \refstepcounter command to the current representation of the counter's value; it can be set manually, of course. This is the reason why a \label command should follow \caption, for example: it is \caption that steps the relevant counter.

With hyperref the annotation is more complex. In the classical setting, a code such as

\section{A title}\label{x}

writes something like

\newlabel{x}{{1}{1}}

The second argument is the pair {<counter representation>}{<page number>}. With hyperref the same code could write

\newlabel{x}{{1}{1}{A title}{section.1}{}}

and the second argument is a 5-tuple: counter representation, page number, title or caption (in case the counter refers to a title or a caption), and the hypertext anchor. The fifth group is reserved for other purposes. Also the anchor is set by \refstepcounter, because it must refer to the place where subsequent hyperlinks should point to.

One clearly sees that it's impossible to have \label set the anchor, because there's no way to know where this anchor should point to: the counter has already been stepped and handing the job of setting the anchor to \label would result in a wrong point.

If you try setting a \label far away from the stepping of a counter, you'll see that the first parts of the second argument to \newlabel still contain the “old” information, precisely the information contained in \@currentlabel (and the other similar macros used by hyperref) at the same group level.

For a \label to be used only for \pageref one has to manually set an anchor:

\phantomsection\label{y}

would write out an annotation such as

\newlabel{y}{{1}{8}{abc}{section*.1}{}}

where the anchor name is assigned in a unique way. Of course the counter representation (the first item in the second argument to \newlabel) will bear “random” information that should not be relied upon.

Why a \pagelabel command doesn't exist? Simple: when LaTeX was released, hypertexts were not even being thought of. You can define your own:

\newcommand{\pagelabel}[1]{\phantomsection\label{#1}}
  • Shouldn't hyperref package add \phantomsection to each \label automatically, so it can create hyperlink to proper destination? I certainly don't understand full scope of this issue, but I would think of it as one of the basic features of hyperref package to link properly to any label. – Rafal Jul 4 '15 at 12:40
  • @Rafal No, it doesn't, because usually you want the link to point where \refstepcounter is issued, not at \label. – egreg Jul 4 '15 at 17:11

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.