Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am using natbib for citations and often have to

  1. reference specific page numbers of sources, and
  2. reference sources in the possessive.

I am using hyperref for internal hyperlinks and I have not been able to find a way for hyperref to link either the possessive or the page numbers (in some cases - it seems to work with citet). MWE shown below, with a partial solution found on this site. Any suggestions?

\documentclass{article}
\usepackage{natbib}
  \def\citeaposay#1{\citeauthor{#1}'s (\citeyear{#1})}
\usepackage{etoolbox}

% This code is from 
%http://tex.stackexchange.com/questions/24136/natbib-and-hyperref-for-author-year-style-produces-two-links

\makeatletter

% Current citation \cite or \citet?
\newbool{NAT@bool@patch}

% Closing parenthesis already printed in hyperlink?
\newtoggle{NAT@tog@close}

% Flag \cite and \citet
\pretocmd{\citet}
  {\global\booltrue{NAT@bool@patch}}
  {}% Do nothing if patch works
  {}% Do nothing if patch fails

\pretocmd{\cite}
  {\global\booltrue{NAT@bool@patch}}
  {}% Do nothing if patch works
  {}% Do nothing if patch fails

% Don't print postnote if already printed in hyperlink
\newcommand\NAT@postnote[1]{%
  \iftoggle{NAT@tog@close}
    {}
    {#1}}

% Don't print closing bracket if already printed in hyperlink
% NB: We have to reset this so that all brackets are printed in multi-citations
\renewcommand\NAT@@close{%
  \ifbool{NAT@bool@patch}
    {\iftoggle{NAT@tog@close}
       {\global\togglefalse{NAT@tog@close}}
       {}}
    {\ifNAT@par\NAT@close\fi}}

% Patch main cite command to issue new postnote command
\patchcmd{\NAT@citex}
  {\else\NAT@cmt#2}
  {\else\NAT@postnote{\NAT@cmt#2}}
  {}% Do nothing if patch works
  {}% Do nothing if patch fails

% Patch main cite command to include postnote/closing bracket in hyperlink
\patchcmd{\NAT@citex}
  {\@citea\NAT@hyper@{%
     \NAT@nmfmt{\NAT@nm}%
     \hyper@natlinkbreak{\NAT@spacechar\NAT@@open\if*#1*\else#1\NAT@spacechar\fi}%
       {\@citeb\@extra@b@citeb}%
     \NAT@date}}
  {\@citea\NAT@hyper@{%
     \NAT@nmfmt{\NAT@nm}%
     \hyper@natlinkbreak{\NAT@spacechar\NAT@@open\if*#1*\else#1\NAT@spacechar\fi}%
       {\@citeb\@extra@b@citeb}%
     \ifbool{NAT@bool@patch}
       {\global\toggletrue{NAT@tog@close}%
        \NAT@date%
        \ifNAT@swa\else\if*#2*\else\NAT@cmt#2\fi\fi%
        \NAT@close}
       {\NAT@date}}}
  {}% Do nothing if patch works
  {}% Do nothing if patch fails

% Reset flags after citation is printed
\apptocmd{\NAT@citex}
  {\global\boolfalse{NAT@bool@patch}%
   \global\togglefalse{NAT@tog@close}}
  {}% Do nothing if patch works
  {}% Do nothing if patch fails

% Don't break hyperlinks between name and year
\renewcommand\hyper@natlinkbreak[2]{#1}

\makeatother

\usepackage{hyperref}
\hypersetup{
    colorlinks=true,
   citecolor=red 
}

\begin{filecontents}{\jobname.bib}
@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}

\begin{document}
\bibpunct[]{(}{)}{;}{a}{,}{,}

\noindent
citet with page numbers: \citet[:23-25]{adams} is a good book. (here both parentheses should be hyperlinked) \\
citep with page numbers: As suggested by him \citep[:23-25]{adams}. (here :23-25 should be hyperlinked)\\
citeyear with page numbers: As suggested by him (\citeyear[:23-25]{adams}). (here :23-25 should be hyperlinked)\\
citeaposay with possessive: \citeaposay{adams} book suggests... (here 's should be hyperlinked)

\bibliographystyle{plainnat}
\bibliography{\jobname}

\end{document} 
share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

Including all postnotes in the hyperlink requires patches to both the \NAT@citex and \NAT@cite macros. A possessive suffix can be appended in the name format in the definition of a new citation command. The example below is adapted from \citet.

\documentclass{article}
\usepackage{natbib}
\usepackage[colorlinks]{hyperref}
\usepackage{etoolbox}

\makeatletter

\DeclareRobustCommand\citepos
  {\begingroup\def\NAT@nmfmt##1{{\NAT@up##1's}}%
   \NAT@swafalse\let\NAT@ctype\z@\NAT@partrue
   \@ifstar{\NAT@fulltrue\NAT@citetp}{\NAT@fullfalse\NAT@citetp}}

\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}}
    {\if*\NAT@postnote*\else\NAT@cmt\NAT@postnote\global\def\NAT@postnote{}\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}{}{}
\patchcmd{\NAT@cite}{\if*#3*}{\if*\NAT@postnote*}{}{}

\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:life,
  title = {Life, the Universe and Everything},
  author = {Adams, Douglas},
  series = {The Hitchhiker's Guide to the Galaxy},
  publisher = {Pan Macmillan},
  year = {1980}}
@book{adams:rest,
  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}

\newcommand{\cmd}[1]{\textbackslash\texttt{#1}}
\begin{document}
\noindent
\cmd{citepos}: \citepos[e.g.][100]{adams:life}; \citepos{adams:rest,companion} \\
\cmd{citet}: \citet[1--10]{companion,adams:rest,adams:life} \\
\cmd{cite}: \cite[e.g.][100]{adams:life}; \cite{adams:rest} \\
\cmd{citep}: \citep[e.g.][1--10]{adams:rest,adams:life} \\
\cmd{citetext}; \cmd{citealp}:
\citetext{see \citealp[10]{adams:rest}; or even better \citealp{adams:life}} \\
\cmd{citeauthor}: \citeauthor{adams:life}; \citeauthor{companion} \\
\cmd{citeyear}: \citeyear{adams:life}; \citeyear{adams:rest} \\
\bibliographystyle{plainnat}
\bibliography{\jobname}
\end{document}

enter image description here

share|improve this answer
    
Brilliant! Thank you. –  Agnar Nov 11 '12 at 4:16
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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