6

I use this code to prevent hyperlinks if the target of the link is presented on the same page as the reference: \newcommand*{\myref}[1]{\ifnumequal{\thepage}{\getpagerefnumber{#1}}{\ref*{#1}}

However, I just realised that the code does not work if the hyperlink is in the first paragraph on a new page, see the minimal working example below. Does anyone have any idea what is wrong? Any help is much appreciated!

\documentclass{article}
\usepackage{hyperref}
\usepackage{etoolbox} 
\usepackage{lipsum}
\makeatletter
\newcommand*{\myref}[1]{\ifnumequal{\thepage}{\getpagerefnumber{#1}}{\ref*{#1}}{\ref{#1}}}
\makeatother

\begin{document}
\section{first page}
Figures on first page \myref{fig:1} and second page \myref{fig:2}. \LaTeX consider this to be on page \thepage  %%% links to figure 2 but not 1 - correct

Figures on first page \myref{fig:1} and second page \myref{fig:2}. \LaTeX consider this to be on page \thepage %%% links to figure 2 but not 1 - correct

\begin{figure}[ht]
\centering
\rule{6cm}{3cm}
\caption{Figure caption text} \label{fig:1}
\end{figure}

\lipsum[1-3]
\section{second page}
Figures on first page \myref{fig:1} and second page \myref{fig:2} %%% links to figure 2 but not 1 - incorrect!

Figures on first page \myref{fig:1} and second page \myref{fig:2} %%% links to figure 1 but not 2 - correct

\begin{figure}[ht]
\centering
\rule{6cm}{3cm}
\caption{Figure caption text} \label{fig:2}
\end{figure}
\end{document}
  • I would say this is because the page counter still has the value even 1 on the second page on the top (first paragraph) so the comparison jumps to the false branch. You can see this, if you insert a \thepage between the two lines Figures on .. in the lower half of your document –  Jan 14 '15 at 13:34
  • thepage is the typeset page, not a number -> \value{page}. – Johannes_B Jan 14 '15 at 13:38
  • 2
    the page counter shows how many pages have been shipped out at the point the code is executed, this is more or less unconnected to the page on which the surrounding text finally appears. TeX may process ahead before breaking off a page, or the output routine can insert any number of float pages. The only way to access the number is to use \label and \pageref to find the value used on the previous run. this is what packages like varioref do to vary the reference text depending whether or not it is a same-page reference. – David Carlisle Jan 14 '15 at 13:43
  • 1
    @Johannes_B true, but both have the wrong number. – David Carlisle Jan 14 '15 at 13:43
  • Thanks for the feedback, I have edited the MWE, and indeed \thepage is 1 in the first paragraph on page 2. As I interpret David Carlisle comment, there is no easy way to prevent links to the same page as the target. – user1570707 Jan 14 '15 at 15:08
  • @user1570707 it's easy enough for Heiko:-) – David Carlisle Jan 14 '15 at 20:28

1 Answers1

9

Because of the asynchronous output routine, the page number is usually unknown, when TeX processes a paragraph. Therefore a label at the place of the reference is needed to get the page number:

\usepackage{hyperref}
\usepackage{etoolbox} 

\makeatletter
\newcounter{myref}
\renewcommand*{\themyref}{myref:\the\value{myref}}
\newcommand*{\myref}[1]{%
  \leavevmode
  \stepcounter{myref}%
  \label{\themyref}%
  \ifnumequal{\getpagerefnumber{\themyref}}{\getpagerefnumber{#1}}%
    {\ref*{#1}}{\ref{#1}}%
}
\makeatother
Heiko Oberdiek
  • 271,626