Single link in (Author, Year) citation style using natbib and hyperref
Linking postnotes in \citep
was already addressed in a previous question. To set punctuation in black text, you can patch natbib's internal punctuation commands. These patches can be deferred to the beginning of your document to account for the fact that the punctuation commands are redefine-able (with, say, \bibpunct
) at any point in your document preamble.
\documentclass{article}
\usepackage{natbib}
\usepackage[colorlinks]{hyperref}
\usepackage{etoolbox}
\makeatletter
% count citations
\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*}{}{}
% all punctuation black
\AtBeginDocument{%
\preto\NAT@sep{\textcolor{black}\bgroup}%
\appto\NAT@sep{\egroup}%
\preto\NAT@aysep{\textcolor{black}\bgroup}%
\appto\NAT@aysep{\egroup}%
\preto\NAT@yrsep{\textcolor{black}\bgroup}%
\appto\NAT@yrsep{\egroup}%
\preto\NAT@cmt{\textcolor{black}\bgroup}%
\appto\NAT@cmt{\egroup}%
\preto\NAT@open{\textcolor{black}\bgroup}%
\appto\NAT@open{\egroup}%
\preto\NAT@close{\textcolor{black}\bgroup}%
\appto\NAT@close{\egroup}}
\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{citet}: \citet[e.g.][pp.~1--10]{companion} \\
\cmd{citet}: \citet[pp.~1--10]{companion,adams:rest,adams:life} \\
\cmd{cite}: \cite[e.g.][p.~100]{adams:life}; \cite{adams:rest} \\
\cmd{citep}: \citep[e.g.][p.~1--10]{adams:rest,adams:life} \\
\cmd{citetext}; \cmd{citealp}:
\citetext{see \citealp[pp.~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}
Fiddling around with my problem, and using egreg's solution to an earlier post, I found a solution which works for my specific case:
I defined new commands \mycitet
and \mycitep
in this way
\usepackage{twoopt}
\usepackage{ifthen}
\newcommand\black[1]{\textcolor[rgb]{0,0,0}{#1}}
\newcommandtwoopt{\mycitet}[3][aa][bb]{%
\ifthenelse{\equal{#1}{aa}} % if nargin == 1
{\hyperlink{cite.#3}{\citeauthor{#3} \black{(}\citeyear{#3}\black{)}}} % \citet{key}
{\ifthenelse{\equal{#2}{bb}} % elseif nargin == 2
{\hyperlink{cite.#3}{\citeauthor{#3} \black{(}\citeyear{#3}\black{,}~#1\black{)}}} % \citet[pg]{key}
{\ifthenelse{\equal{#1}{}} % elseif #1 = []
{\hyperlink{cite.#3}{\citeauthor{#3} \black{(}\citeyear{#3}\black{,}~#2\black{)}}} % \citet[][pg]{key}
{\ifthenelse{\equal{#2}{}} % elseif #2 == []
{\hyperlink{cite.#3}{\citeauthor{#3} \black{(#1~}\citeyear{#3}\black{)}}} % \citet[eg][]{key}
% % else
{\hyperlink{cite.#3}{\citeauthor{#3} \black{(#1~}\citeyear{#3}\black{,}~#2\black{)}}} % \citet[eg][pg]{key}}
}
}
}
}
\makeatletter
\newcommand{\multicite}[1]{% taken from egreg, see link
\@tempswafalse
\@for\next:=#1\do
{\if@tempswa;~\else\@tempswatrue\fi
\hyperlink{cite.\next}{\citeauthor{\next}\black{,~}\citeyear{\next}}%
}%
}
\makeatother
\newcommandtwoopt{\mycitep}[3][aa][bb]{%
\ifthenelse{\equal{#1}{aa}} % if nargin == 1
{(\multicite{#3})} % \citep{key(s)}
{\ifthenelse{\equal{#2}{bb}} % elseif nargin == 2
{(\hyperlink{cite.#3}{\citeauthor{#3}\black{,~}\citeyear{#3}\black{,~}#1})} % \citep[pg]{key}
{\ifthenelse{\equal{#1}{}} % elseif #1 = []
{(\hyperlink{cite.#3}{\citeauthor{#3}\black{,~}\citeyear{#3}\black{,~}#2})} % \citep[][pg]{key}
{\ifthenelse{\equal{#2}{}} % elseif #2 == []
{(#1~\multicite{#3})} % \citep[eg][]{key(s)}
% % else
{(#1~\hyperlink{cite.#3}{\citeauthor{#3}\black{,~}\citeyear{#3}\black{,~}#2})} % \citep[eg][pg]{key}}
}
}
}
}
and for demonstration purposes I also changed the document to
\begin{document}
\begin{tabular}{lll}
& Audrey & me, myself and I \\
\hline\hline
citet\{key\} & \citet{author08} & \mycitet{author08} \\
citet[pg]\{key\} & \citet[pg.7]{author08} & \mycitet[pg.7]{author08} \\
citet[ ][pg]\{key\} & \citet[][pg.7]{author08} & \mycitet[][pg.7]{author08} \\
citet[eg][ ]\{key\} & \citet[e.g.][]{author08} & \mycitet[e.g.][]{author08} \\
citet[eg][pg]\{key\} & \citet[e.g.][pg.7]{author08} & \mycitet[e.g.][pg.7]{author08} \\
\hline
citep\{key\} & \citep{author08} & \mycitep{author08} \\
citep[pg]\{key\} & \citep[pg.7]{author08} & \mycitep[pg.7]{author08} \\
citep[ ][pg]\{key\} & \citep[][pg.7]{author08} & \mycitep[][pg.7]{author08} \\
citep[eg][ ]\{key\} & \citep[e.g.][]{author08} & \mycitep[e.g.][]{author08} \\
citep[eg][pg]\{key\} & \citep[e.g.][pg.7]{author08} & \mycitep[e.g.][pg.7]{author08} \\
\hline
citep\{key1,key2\} & \citep{author08,buthor90} & \mycitep{author08,buthor90} \\
citep[eg][ ]\{key1,key2\} & \citep[e.g.][]{author08,buthor90} & \mycitep[e.g.][]{author08,buthor90} \\
\end{tabular}
\bibliographystyle{plainnat}
\bibliography{\jobname}
\end{document}
to obtain exactly what I want:
However, while this may serve prefectly as a demonstration of what I want, I would prefer a general solution to this specific one as
- this approach does not adapt the parentheses to \bibliographystyle automatically
- it might mess up other commands if I
\let\citep\mycitep
and\let\citet\mycitet
PS: Can somebody explain how egreg's snippet knows that ',' is my delimiter?