[Tex/LaTex] Manual citation formatting

bibliographiescitingharvard-stylehyperref

First off: I don't want to use bibtex for this; I want to typeset my bibliography myself.

Looking at the source2e.pdf document I found out about redefining \@cite and \@biblabel, and got my citation style pretty much set up with this.

The problem which remains now is this: I'd like to allow for two different ways of citing a person. (This seems to be called “harvard style”.) One would be in the body of the text:

… as John Doe (1900) demonstrated …

while the other one would be parenthesized:

… has already been demonstrated (John Doe 1900).

Now my problem is the different handling of the year, which has to be parenthesized in one form but not in the other. Of course, I'd need two different commands for the different citations. But so far, every attempt at splitting up the citation label has failed, at least if I want to also use hyperref. Without that package, the following seems to satisfy my requirements:

\documentclass{article}
% \usepackage{hyperref}
\makeatletter
\def\@cite#1#2{ ({#1\if@tempswa , #2\fi})}
\def\@biblabel#1{}
\def\@cite@ofmt#1{\edef\my@tmp{#1}\expandafter\my@split\my@tmp}
\def\my@split#1(#2){\hbox{#1#2}}
\def\my@tcite#1#2{{#1\if@tempswa , #2\fi}}
\def\my@tsplit#1(#2){\hbox{#1(#2)}}
\newcommand\tcite[1]{{\let\@cite\my@tcite\let\my@split\my@tsplit\cite{#1}}}
\makeatother
\begin{document}
\ldots has already been demonstrated \cite{JohnDoe}.\par
\ldots as \tcite{JohnDoe} demonstrated \ldots\par
\ldots has already been demonstrated \cite{JohnDoe}.\par
\begin{thebibliography}{1}
\bibitem[John Doe (1900)]{JohnDoe}
John Doe, The famous book, 1900.
\end{thebibliography}
\end{document}

But with hyperref enabled, I get this error message:

! Undefined control sequence.
\hyper@@link ->\let \Hy@reserved@a 
                                   \relax \@ifnextchar [{\hyper@link@ }{\hyp...

Looking at the source code of hyperref.sty, I see that it does attempt to support compatibility with the harvard package. So I adjusted my example to this:

\documentclass{article}
\usepackage{harvard}
\usepackage{hyperref}
\begin{document}
\ldots has already been demonstrated \cite{JohnDoe}.\par
\ldots as \citeasnoun{JohnDoe} demonstrated \ldots\par
\ldots has already been demonstrated \cite{JohnDoe}.\par
\begin{thebibliography}{1}
\harvarditem{John Doe}{1900}{JohnDoe}
John Doe, The famous book, 1900.\par
\end{thebibliography}
\end{document}

But I keep getting

LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.

no matter how many times I process the document. And I don't get any hyperlinks.

How can I get harvard style citations with a manually set bibliography and with working hyperlinks for my citations?

I'm using texlive 2013, which includes hyperref.sty v6.83m from 2012/11/06 and harvard.sty version 2.0.5 apparently from 1994.

Best Answer

Building on your already very thorough answer:

To achieve full inter-operability between citation commands and the hyperref package, it's advisable to load the natbib and har2nat packages instead of the harvard package. (If you load natbib and har2nat, you should not load the harvard package.)

In the example below, note that \harvarditem and \citeasnoun are harvard-based macros that are "translated" transparently by the har2nat package into instructions that are understood by natbib. The macro \cite, which is also available in "Basic LaTeX" (i.e., without any citation-management packages being loaded), is modified by natbib to be usable for authoryear-style citations. Finally, \citet, \citep, \citealt, \citealp, and \citeauthor are macros provided directly by the natbib package.

enter image description here

\documentclass{article}
\usepackage{natbib,har2nat}
\usepackage[colorlinks=true,citecolor=blue]{hyperref}
\setlength\parindent{0pt} % just for this example
\begin{document}
\ldots\ has already been demonstrated \cite{JohnDoe}.

\ldots\ as \citeasnoun{JohnDoe} has demonstrated \ldots

\citet{JohnDoe}; \citealt{JohnDoe}

\citep{JohnDoe}; \citealp{JohnDoe}

\citeauthor{JohnDoe}

\begin{thebibliography}{99}
\harvarditem{Doe}{1900}{JohnDoe}
John Doe, {\em The Famous Book}, Forest Glen: The Buck Press. 1900.
\end{thebibliography}
\end{document}

Addendum: If you're building the bibliography entirely by hand anyway, there's no real reason to take a detour via \harvarditem{}{}{}... instructions and have them be "translated" into natbib-equivalent directives. Instead, just use the natbib-based syntax directly. (Doing so will also let you skip having to load har2nat). The preceding code would then look like this -- note the use of \bibitem instead of \harvarditem:

\documentclass{article}
\usepackage{natbib}
\usepackage[colorlinks=true,citecolor=blue]{hyperref}
\setlength\parindent{0pt} % just for this example
\begin{document}
\ldots\ has already been demonstrated \cite{JohnDoe}.

\ldots\ as \citeauthor{JohnDoe} has demonstrated \ldots

\citet{JohnDoe}; \citealt{JohnDoe}

\citep{JohnDoe}; \citealp{JohnDoe}

\begin{thebibliography}{99}
\bibitem[Doe(1900)]{JohnDoe}
John Doe, {\em The Famous Book}, Forest Glen: The Buck Press. 1900.
\end{thebibliography}
\end{document}
Related Question