Friday, March 25, 2011

Better APA-style: working around hyperref and apacite problems

I'm writing an article in LaTeX using APA style, so I'm using the popular
apa.cls style. It defaults to using apacite for citations and references, which works well enough.

But if I have a URL field in the BibTeX, like I always do in JabRef to remember where I found things, it prints it for each reference wasting a lot of space and not breaking lines properly. I also like the URLs I do show to be clickable hyperlinks, and my citations and cross-references as well. You can usually do this using hyperref, but a lot of things break when using apacite and hyperref together. Here's the top of the file:
\documentclass[jou]{apa}
\usepackage{hyperref}
And here is the output of pdflatex:
! Undefined control sequence.
\hyper@@link ->\let \Hy@reserved@a
\relax \@ifnextchar [{\hyper@link@ }{\hyp...
l.83 \cite{Aris09Visual}
...
! Argument of \@@cite has an extra }.

\par
l.83 \cite{Aris09Visual}
...
Runaway argument?
>{\hyper@link@ }\def \reserved@b {\hyper@link@ [link]}\futurelet \@let@token \E
TC.
! Paragraph ended before \@@cite was complete.

\par
l.83 \cite{Aris09Visual}
Other people have had this problem before, but there aren't any great solutions. See the end for a good solution using biblatex-apa instead of apacite. If you insist on using apacite, there are instructions here for how to make things mostly work:
The simplest way to fix the problem is to put a single
instance of \protect into hyperref.sty.

Turn this:
   \def\bibcite#1#2{%
\@newl at bel{b}{#1\@extra at binfo}{%
\hyper@@link[cite]{}{cite.#1\@extra at b@citeb}{#2}%
into this:
   \def\bibcite#1#2{%
\@newl at bel{b}{#1\@extra at binfo}{%
\protect\hyper@@link[cite]{}{cite.#1\@extra at b@citeb}{#2}%
This occurs at
line 3972 in hyperref.sty [2007/02/07 v6.75r
and at
line 4939 in hyperref.sty [2008/04/05 v6.77l
(line 8328 of the corresponding hyperref.dtx ).
but this breaks the citations. Later they added additional code to the tex file:
It's really just a matter of executing APA's version of \bibcite
before doing the extra stuff that hyperref needs to create the hyper-linking (which seems to work just fine).

For example, the following coding seems to work OK.
\usepackage{apacite}
\let\APAbibcite\bibcite %%%% add this line

\usepackage{color}
\definecolor{darkblue}{rgb}{0.0,0.0,0.3}
\usepackage[bookmarks=true]{hyperref}
\hypersetup{
pdfauthor={Salvatore Enrico Indiogine},
pdftitle={},
pdfsubject={TAMU EDCI},
pdfkeywords={},
pdfcreator={LaTeX with hyperref package},
pdfproducer={dvips + ps2pdf},
colorlinks,breaklinks,
linkcolor={darkblue},
urlcolor={darkblue},
anchorcolor={darkblue},
citecolor={darkblue}}

%%%% add the following 2 lines
\let\HYPERbibcite\bibcite
\def\bibcite#1#2{\APAbibcite{#1}{#2}\HYPERbibcite{#1}{#2}}
This fixes most problems, but there are still warnings and ampersands missing in the references.

A better solution for me was to use biblatex-apa with biblatex instead of apacite.

First replace \bibliography{...} at the end of your tex file with \printbibliography. Then modify the the top to look like this (note the noapacite option for apa.cls).
\documentclass[jou,noapacite]{apa} %%%% apacite is buggy with hyperref

\usepackage{color}

\usepackage[]{hyperref}
\hypersetup{
pdfauthor={AUTHORS},
pdftitle={TITLE},
pdfkeywords={KEYWORDS},
colorlinks,breaklinks,
linkcolor={blue},
urlcolor={blue},
anchorcolor={blue},
citecolor={blue}}

%%%% bilatex-apa
\usepackage[american]{babel}
\usepackage{csquotes}
\usepackage[style=apa,hyperref,doi,url]{biblatex}
\DeclareLanguageMapping{american}{american-apa}
\bibliography{}

12 comments:

  1. Hi Cody, the 2nd fix using \printbibliography works great. My dissertation has a main.tex which does a \include for each chapter's .tex file. Is there a way to use this \printbibliography approach so that it prints a seperate reference section for each chapter?

    ReplyDelete
  2. @G.T. Sure, Biblatex gives an easy way to do separate references by section. Try this for each section:

    \begin{refsegment}
    \input{introduction}
    \end{refsegment}
    \printbibliography[segment=1]

    \begin{refsegment}
    \input{relatedwork}
    \end{refsegment}
    \printbibliography[segment=2]

    ReplyDelete
  3. Hey there, thanks so much for that. Hyperref and the APA style drive me crazy. I now got it to give me output including all the linking for citations but I end up without parentheses around the citation.
    Also, my bibliography turns out strangly, as it displays my reference titles in lowercase except for the first letter. My .bib is ok though and I guess this problem is not connected to hyperref.
    You have any idea, on what could be wrong?

    ReplyDelete
  4. @shkelda, when using biblatex-apa to get the various parenthesis around citations you need to use \parencite or \textcite instead of the regular \cite command. See the biblatex-apa style examples for more info.

    The APA style requires all the titles in lowercase except for the first letter. If you want particular words capitalized, like proper nouns, you can surround them with curly braces in the bibtex in three ways:

    1) Surround specific letters:
    title = {{T}ime{M}atrix: analyzing temporal social networks...},

    2) Surround specific words:
    title = {{TimeMatrix}: analyzing temporal social networks...},

    2) Surround the entire sentence to preserve all the capitals:
    title = {{TimeMatrix: analyzing temporal social networks...}},

    ReplyDelete
  5. Also, the JabRef reference manager can automatically add the curly braces as necessary in titles. To set it up, go to Options->Preferences->File and put 'title' (w/o the apostrophes) in the 'Store the following fields with braces around the capital letters:' field.

    ReplyDelete
  6. Hey Cody, that solved all my problems! Just great, thanks so much for that, as my hair already started falling out. Cheers, Peter

    ReplyDelete
  7. Thanks, Cody. It's great somebody managed to provide a proper solution to this!

    ReplyDelete
  8. Hi Cody,

    I'm struggling with the following problem:
    How to obtain an in-text apa citation with an apostrophe that would look like this:

    Sommer's (1990) point of view is ...

    I searched in the web, but didn't find anything appropriate.
    I'd appreciate any help.

    ReplyDelete
    Replies
    1. With apacite: \citeauthor{Sommer1990}'s \citeyear{Sommer1990}

      Delete
  9. I'm sorry @achacy, I don't know of a way to do that. You could build your own function. biblatex-apa's \citeauthor{key} command gets you the 'Sommer', and it has a \citeyear{key} command to get the '1990'.

    ReplyDelete
  10. Thank you anyway. I decided to circumvent the problem by using a different structure, so that I don't need the 's.

    ReplyDelete
  11. Great! This worked for me! Thanks.

    ReplyDelete