[Tex/LaTex] Is it possible to load biblatex with a class that has already loaded natbib

biblatexincompatibilitynatbibrevtex

A while ago I asked a meta question on how big a question can be. I was wondering in particular about breaking open REVTeX and reorganising the goo within to replace the natbib bits with bits that play more nicely with biblatex. This would surely be a large undertaking. Joseph Wright pointed out that

  • This is probably a bad idea (REVTeX produces a pretty funky bbl file and it's difficult to tell how important the internals of that are to the publisher).
  • A better question would be about getting biblatex to work when natbib is around too.

As the second point proposes a question of broader relevance than the one I originally intended to ask, and there is the possibility of a solution that would require much less effort than rewriting a class, I'm asking it here. Essentially I'd be using a solution just for my own notes, which often get remixed into papers in a REVTeX class, so for publication I'd have to default to the standard way. It's a start though! So:

Is it possible to load biblatex with a class that has already loaded natbib?

The first error can be produced with this MWE:

\documentclass[reprint,aps,pra]{revtex4-1}
\usepackage{biblatex}

\begin{document}
\title{MWE}
\author{Mark S.\ Everitt}
\pacs{}
\maketitle

\section{Introduction}
stuff

\end{document}

and the error is:

/usr/local/texlive/2011/texmf-dist/tex/latex/biblatex/biblatex.sty:382: LaTeX Error: Command \bibhang already defined.
           Or name \end... illegal, see p.192 of the manual.

Best Answer

Working with the assumption here that we are simply trying to ignore natbib entirely, all that needs to happen is that the various name clashes need to be dealt with. Setting up a demo where natbib is deliberately loaded before biblatex, it seems that the macros \bibhang, \citename, \bibfont and \Citeauthor need to be undefined. At the same time, it's necessary to deal with \ver@natbib.sty, which is the internal macro LaTeX uses to track the fact that natibib has been loaded. It's this macro that biblatex uses in \@ifpackageloaded to issue a warning about natbib. Thus the following builds fine for me:

\begin{filecontents}{\jobname.bib}
@article{Test,
  journal = "J. Irrep. Res.",
  author  = "Other, A. N.",
  year    = "2011",
  title   = "Some things I did"
}
\end{filecontents}
\documentclass{article}
\usepackage{natbib}
% Start of 'ignore natbib' hack
\let\bibhang\relax
\let\citename\relax
\let\bibfont\relax
\let\Citeauthor\relax
\expandafter\let\csname ver@natbib.sty\endcsname\relax
% End of 'ignore natbib' hack
\usepackage{biblatex}
\addbibresource{\jobname.bib}
\begin{document}
\cite{Test}
\printbibliography
\end{document}

To get things working with REVTeX, I find that I also need to undefined \textcite. There is then a second issue, as REVTeX alters the definition of \MakeUppercase and \MakeLowercase. Thus I've copied the originals from latex.ltx and restored them:

\begin{filecontents}{\jobname.bib}
@article{Test,
  journal = "J. Irrep. Res.",
  author  = "Other, A. N.",
  year    = "2011",
  title   = "Some things I did"
}
\end{filecontents}
\documentclass{revtex4}
\let\bibhang\relax
\let\citename\relax
\let\bibfont\relax
\let\Citeauthor\relax
\let\textcite\relax
\makeatletter
\DeclareRobustCommand{\MakeUppercase}[1]{{%
      \def\i{I}\def\j{J}%
      \def\reserved@a##1##2{\let##1##2\reserved@a}%
      \expandafter\reserved@a\@uclclist\reserved@b{\reserved@b\@gobble}%
      \protected@edef\reserved@a{\uppercase{#1}}%
      \reserved@a
   }}
\DeclareRobustCommand{\MakeLowercase}[1]{{%
      \def\reserved@a##1##2{\let##2##1\reserved@a}%
      \expandafter\reserved@a\@uclclist\reserved@b{\reserved@b\@gobble}%
      \protected@edef\reserved@a{\lowercase{#1}}%
      \reserved@a
   }}
\makeatother
\expandafter\let\csname ver@natbib.sty\endcsname\relax
\usepackage{biblatex}
\addbibresource{\jobname.bib}
\begin{document}
\cite{Test}
\printbibliography
\end{document}

(The changes are actually to internal macros used by robust commands, so simply coping using \let before the document class line will not work here without some extra effort.)

For REVTeX 4.1, it seems you need

\renewcommand{\bibliography}[1]{}

after \begin{document} as REVTeX tries to use it at the end of the document, which gives an error with biblatex.

Related Question