23

I am using the bioinfo style with natbib and hyperref, using the (Author, Year) style citations. pdflatex produces two link boxes for each citation: one for the Author and one of the Year. I would prefer to get a single link for the entire [(Author, Year)] rather than ([Author], [Year]). I can turn off PDF link boxes and uses colors instead to somewhat improve the appearance of this, but I'd still prefer to just have a single link.

Thanks in advance for any suggestions on how to fix this.

Here is a minimal example:

\documentclass{article}

\usepackage{natbib}
\usepackage{hyperref}
\begin{filecontents}{\jobname.bib}
@book{adams80,
  title = {The Restaurant at the End of the Universe},
  author = {Douglas Adams},
  series = {The Hitchhiker's Guide to the Galaxy},
  publisher = {Pan Macmillan},
  year = {1980}
}
\end{filecontents}
\begin{document}

A theory about the inexplicability of the Universe has been proposed by \citet{adams80}.

\bibliographystyle{plainnat}
\bibliography{\jobname}

\end{document}
Alan Munn
  • 218,180
IanSR
  • 331

1 Answers1

25

The two links are created by the command \hyper@natlinkbreak, which is defined by hyperref.sty. To remove the break you can revert back to the provisional definition from natbib.sty by inserting the following lines into your preamble:

\makeatletter
\renewcommand\hyper@natlinkbreak[2]{#1}
\makeatother

The results with this simple fix aren't great; links generated by \cite and \citet don't include the postnote and closing bracket, which looks funny. This can be resolved somewhat by patching the internal natbib macros using etoolbox. Spurious closing brackets are tedious to avoid in compact citations. The patches below side-step this issue by suppressing compact labels in \citet and its variants.

\documentclass{article}
\usepackage{natbib}
\usepackage{hyperref}
\usepackage{etoolbox}

\makeatletter

\pretocmd{\NAT@citex}{%
  \let\NAT@hyper@\NAT@hyper@citex
  \def\NAT@postnote{#2}%
  \setcounter{NAT@total@cites}{0}%
  \setcounter{NAT@count@cites}{0}%
  \forcsvlist{\stepcounter{NAT@total@cites}\@gobble}{#3}}{}{}
\newcounter{NAT@total@cites}
\newcounter{NAT@count@cites}
\def\NAT@postnote{}

% include postnote and \citet closing bracket in hyperlink
\def\NAT@hyper@citex#1{%
  \stepcounter{NAT@count@cites}%
  \hyper@natlinkstart{\@citeb\@extra@b@citeb}#1%
  \ifnumequal{\value{NAT@count@cites}}{\value{NAT@total@cites}}
    {\ifNAT@swa\else\if*\NAT@postnote*\else%
     \NAT@cmt\NAT@postnote\global\def\NAT@postnote{}\fi\fi}{}%
  \ifNAT@swa\else\if\relax\NAT@date\relax
  \else\NAT@@close\global\let\NAT@nm\@empty\fi\fi% avoid compact citations
  \hyper@natlinkend}
\renewcommand\hyper@natlinkbreak[2]{#1}

% avoid extraneous postnotes, closing brackets
\patchcmd{\NAT@citex}
  {\ifNAT@swa\else\if*#2*\else\NAT@cmt#2\fi
   \if\relax\NAT@date\relax\else\NAT@@close\fi\fi}{}{}{}
\patchcmd{\NAT@citex}
  {\if\relax\NAT@date\relax\NAT@def@citea\else\NAT@def@citea@close\fi}
  {\if\relax\NAT@date\relax\NAT@def@citea\else\NAT@def@citea@space\fi}{}{}

\makeatother

\begin{filecontents}{\jobname.bib}
@Book{companion,
  author = {Goossens, Michel and Mittelbach, Frank and Samarin, Alexander},
  title = {The LaTeX Companion},
  edition = {1},
  publisher = {Addison-Wesley},
  location = {Reading, Mass.},
  year = {1994}}
@Book{adams,
  title = {The Restaurant at the End of the Universe},
  author = {Douglas Adams},
  series = {The Hitchhiker's Guide to the Galaxy},
  publisher = {Pan Macmillan},
  year = {1980}}
\end{filecontents}

\renewcommand{\baselinestretch}{1.25}

\begin{document}
\noindent
cite: \cite{adams}, \cite{companion} \\
citet: \citet{adams}, \citet[see][p. 20]{adams} \\
multi citet: \citet{companion,adams} \\
citep: \citep{adams}, \citep[see][p. 20]{companion} \\
multi citep: \citep{companion,adams} \\
citetext, citealp: \citetext{see \citealp{companion}, or even better \citealp{adams}} \\
citeauthor: \citeauthor{adams}, \citeauthor{companion} \\
citeyear: \citeyear{adams}, \citeyear{companion} \\
\bibliographystyle{plainnat}
\bibliography{\jobname}
\end{document}

enter image description here

David Carlisle
  • 757,742
Audrey
  • 28,881
  • 2
    I think this should be implemented into natbib. Splitting citations into two elements is not a great way of handling the same link (have to switch back from biblatex/biber, causes me all kind of headaches, including this...). – Jörg Apr 19 '14 at 12:31
  • I totally agree, that's pretty insane. – Franck Dernoncourt Jul 17 '14 at 21:06
  • 1
    @Audrey With Audrey's code, if you have the same author for different years and use the command, for example, \citet{Coleman_1988, Coleman_1990} you will get: Coleman(1988); Coleman(1990). How is it possible to get a compact format, i.e., Coleman(1988, 1990)? It is clear that Audrey's code is made to act this way. See for example the part of her code regarding the inclusion of postnote and \citet closing brackets in hyperlink. – Pantelis Kazakis Aug 07 '17 at 08:03
  • This is fantastic, thanks for contributing this. I agree with @PantelisKazakis that this could be tweaked to better supported condensed author lists, though there is no clearly best behavior that I can see. Using [ and ] to delimit where a hyperlink is contained, I would suggest either [Coleman (1988], [1990)] or Coleman ([1988], [1990]). – Micah Smith May 30 '21 at 17:41