34

I'm using hyperref for links in pdflatex and I have the following problem: when a bibliography citation spans across a page-break (which usually occurs with long author names), then an additional green link frame is visible at the footer and the link links the whole header of the following page.

Code (with the list of all packages I'm using):

\documentclass[a4paper,12pt,oneside]{book}

\synctex=1 % synchronize with texmaker

\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[left=3.5cm, right=2cm, top=3.5cm, bottom=2.5cm]{geometry} % sizes
\usepackage{newcent}  % font, Century Schoolbook
\usepackage{graphicx} % include graphics
\usepackage{setspace} % control line spacing
\usepackage{amssymb}  % math
\usepackage{amsmath}  % math
\usepackage{amsthm}   % theorems
\usepackage{cite}     % numeric citations
\usepackage{epigraph} % quotations
\usepackage{booktabs} % nice looking tables
\usepackage{url}      % recognize urls
\usepackage{hyperref} % links in PDF
\usepackage{enumitem} % enhanced enumerations
\usepackage{fancyhdr} % fancy headers and footers
\usepackage{color}    % allow colors
\usepackage{pdfpages} % include assignment PDFs
\usepackage{texshade} % sequence alignments


\usepackage{lipsum} % just for the sake of this example

\fancyhead{}
\fancyhead[LO]{\nouppercase{\textsc{\leftmark}}}
\fancyhead[RO]{\nouppercase{\textsc{\thepage}}}
\fancyfoot{}
\setlength{\headheight}{15pt}

\begin{document}

\onehalfspacing
\mainmatter
\pagestyle{fancy}

\chapter{An Example Chapter}

\lipsum
Stuff stuff stuff stuff stuff stuff
Stuff stuff stuff stuff stuff stuff
Stuff stuff stuff
\cite{reference}
Stuff stuff stuff stuff stuff stuff
Stuff stuff stuff stuff stuff stuff
Stuff stuff stuff

\bibliographystyle{apalike}
\bibliography{references}

\end{document}

BibTeX file references.bib:

@Article{reference,
   Author="LongSurnameOfTheFirstAuthor, D.  and LongSurnameOfTheSecondAuthor, R. ",
   Title="Example text",
   Journal="Journal of example articles",
   Year="2004",
   Volume="21",
   Number="12",
   Pages="2326--2339",
   Month="Dec",
   Note={[DOI:\href{http://www.example.com}{example}]}
}

Output:

How can I get rid of this?

I'm using pdfTeX 3.1415926-1.40.10-2.2 (TeX Live 2009/Debian) and BibTeX 0.99c (TeX Live 2009/Debian).

4

2 Answers 2

13

This bad behavior is a very old misfeature of hyperref that, unfortunately, hasn't yet been solved. See http://tug.org/applications/hyperref/ftp/README

12 TODO
[...]
* PostScript driver: the current implementation doesn't relly support nested links. The start positions should be remembered in a stack, but there are complications with page breaks.
* ...

This happens also with pdflatex

4
  • Thank you, I "solved" it by adding some filler text before the citation so it appears on the next page as a whole. May 6, 2012 at 11:19
  • 1
    TODO in 2012, still TODO in 2016? At least in TexLive 2015 this issue is still there. Is there already now a real workarround without side effects?
    – robert
    Jun 8, 2016 at 13:50
  • @robert I'm afraid so.
    – egreg
    Jun 8, 2016 at 13:50
  • 1
    What about 2023? Again 7 years later...? May 24 at 12:28
6

Limitation of links in pdfTeX

\pdfendlink for breakable links. This way, the text can flow as naturally as possible. But this has its limitations. It does not even need a page break to show one of them:

\documentclass[a5paper]{article}
\usepackage[allbordercolors={0 0 1}]{hyperref}
\begin{document}
Hello \vadjust{\hbox{Oops}} World!
\href{http://www.example.org/}{This is a link\\broken across lines}
\end{document}

Result

  • Oops is linked despite given outside the link in the TeX code.
  • Also it is debatable, whether the top link box should span until the end of line.

pdfTeX just takes the material between \pdfstartlink and \pdfendlink and converts the stuff into link boxes. It uses an heuristics based on the group/boxing level to exclude some of the stuff. This works sometimes at page breaks, sometimes it works partially, sometimes it does not succeed at all.

I have already given an example for a page break in this answer.

Workaround: Preventing links across pages

The following workaround puts labels in front and behind a link, which internally uses \hyper@link@. If the page references are not the same, then the link starts and ends on different pages. In this case the link is put into a \mbox and the second label is suppressed to have a marker that remembers this decision in the following LaTeX runs.

Of course, this is not free of side-effects and problems:

  • Glue components are ignored, e.g. spaces uses their natural width and cannot be stretched or shrunk inside \mbox.

  • Since the page break is prevented, it is much harder for TeX to find different line breaks. The example below triggers an "Overfull \hbox warning".

  • If the link is put into a \mbox, the information is no longer available, whether the link would go across a page boundary. As the document changes, the .aux files should be deleted from time to time.

  • Because of the labels, an additional LaTeX run is needed for the links.

Full example:

\documentclass[12pt]{article}
\usepackage[a5paper,hmargin=10mm,vmargin=20mm]{geometry}

\usepackage{cite}     % numeric citations
\usepackage{hyperref} % links in PDF
\usepackage{fancyhdr} % fancy headers and footers

\usepackage{lipsum} % just for the sake of this example

\fancyhead{}
\fancyhead[LO]{\nouppercase{\textsc{\leftmark}}}
\fancyhead[RO]{\nouppercase{\textsc{\thepage}}}
\fancyfoot{}
\setlength{\headheight}{15pt}

\usepackage{zref-abspage}

\makeatletter
\newcounter{lnkpg}
\renewcommand*{\thelnkpg}{lnkpg\the\value{lnkpg}}
\newcommand*{\org@hyper@link@}{}
\let\org@hyper@link@\hyper@link@
\protected\def\hyper@link@[#1]#2#3#4{%
  \def\lnkpg@callorg{%
    \org@hyper@link@[{#1}]{#2}{#3}{#4}%
  }%
  \stepcounter{lnkpg}%
  \zref@labelbyprops{\thelnkpg a}{abspage}%
  \zref@refused{\thelnkpg a}%
  \zref@ifrefundefined{\thelnkpg a}{%
    \lnkpg@callorg
    \zref@labelbyprops{\thelnkpg b}{abspage}%
  }{%
    \zref@ifrefundefined{\thelnkpg b}{%
      \mbox{\lnkpg@callorg}%
    }{%
      \edef\lnkpg@a{\zref@extractdefault{\thelnkpg a}{abspage}{0}}%
      \edef\lnkpg@b{\zref@extractdefault{\thelnkpg b}{abspage}{0}}%
      \ifx\lnkpg@a\lnkpg@b
        \lnkpg@callorg
        \zref@labelbyprops{\thelnkpg b}{abspage}%
      \else
        \mbox{\lnkpg@callorg}%
      \fi
    }%
  }%
}
\makeatother

\begin{document}

\pagestyle{fancy}

\lipsum[2]\lipsum[2]\lipsum[2]\lipsum[4]
Stuff stuff stuff stuff stuff stuff
Stuff stuff stuff stuff stuff stuff
Stuff stuff stuff
\cite{reference}
Stuff stuff stuff stuff stuff stuff
Stuff stuff stuff stuff stuff stuff
Stuff stuff stuff

\begin{thebibliography}{}

\bibitem[LongSurnameOfTheFirstAuthor and LongSurnameOfTheSecondAuthor,
  2004]{reference}
LongSurnameOfTheFirstAuthor, D. and LongSurnameOfTheSecondAuthor, R. (2004).
\newblock Example text.
\newblock {\em Journal of example articles}, 21(12):2326--2339.
\newblock [DOI:\href{http://www.example.com}{example}].

\end{thebibliography}

\end{document}

Page 1 Page 2

1
  • Awesome Heiko. Based on this I build a "hyperlink broken over different pages" detector. However it is not working for biblatex. Maybe you have some ideas. See my post: tex.stackexchange.com/questions/334380/…
    – robert
    Oct 16, 2016 at 19:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .