11

I would like to write a custom class that loads the biblatex package, but I am having trouble with option clashes. For example, the following MWE gives me an error

% arara: pdflatex
% arara: biber
% arara: pdflatex
% arara: pdflatex

\RequirePackage{filecontents}

\begin{filecontents*}{myclass.cls}
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2015/12/29 My MWE class]
\LoadClassWithOptions{article}
\PassOptionsToPackage{backend=biber}{biblatex}
\RequirePackage{biblatex}
\endinput
\end{filecontents*}

\documentclass{myclass}
\usepackage[style=authoryear]{biblatex}
\addbibresource{biblatex-examples.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

LaTeX Error: Option clash for package biblatex.

The error is pretty clear. The class loads biblatex with the backend=biber option and then again in the document with the backend=biber and authoryear options.

I tried making the class only load the biblatex package with the \AtBeginDocument hook (and the \AtEndPreamble hook from the etoolbox package) if it is not loaded in the preamble.

\AtBeginDocument{\@ifpackageloaded{biblatex}{}{\RequirePackage{biblatex}}}

This apparently is too late to load the biblatex package. The only way I can get it to work is to patch the \document macro

\preto{\document}{\endgroup\@ifpackageloaded{biblatex}{}{\RequirePackage{biblatex}\begingroup}}{}{}

How should a class load the biblatex package?

moewe
  • 175,683
StrongBad
  • 20,495
  • 1
    Untested: I think you should define options that are really passed to biblatex. –  Dec 29 '15 at 16:24
  • 1
    Don't do \RequirePackage{biblatex} in the class. – egreg Dec 29 '15 at 16:26
  • @ChristianHupfer but the user would then need to do \PassOptionsToPackage{biblatex}{...} prior to \documentclass which seems strange. – StrongBad Dec 29 '15 at 16:26
  • @egreg so I cannot have a class that provides the biblatex package? The user needs to specify it? – StrongBad Dec 29 '15 at 16:27
  • By the way, biber is the default back-end – egreg Dec 29 '15 at 16:27
  • 1
    @StrongBad: No, I meant \documentclass[authoryear]{myclass}, i.e. something that is not handled by article (which is the effective class in the background) is then passed to biblatex. The user should load biblatex then. –  Dec 29 '15 at 16:27
  • 3
    You can specify options to biblatex with \ExecuteBibliographyOptions in the document preamble. – egreg Dec 29 '15 at 16:31
  • @egreg: A biblatexsetup like \hypersetup would be nice, however. Joseph should be poked about this –  Dec 29 '15 at 16:33
  • @ChristianHupfer it has one, but the documentation says it cannot handle the backend or style as those have to be loadtime. – StrongBad Dec 29 '15 at 16:34
  • @StrongBad: Really? Well I don't use bibliography stuff very often. –  Dec 29 '15 at 16:40
  • Related: Set biblatex options after loading has a list of loading-time options, all others can be set with \ExecuteBibliographyOptions later on. – moewe Dec 30 '15 at 07:52

3 Answers3

7

Unfortunately, style=... can only be given in the optional argument to \usepackage[...]{biblatex}, so if you want to leave the authors free to choose the style they prefer you cannot load biblatex in the class.

What you can do is to specify the options you do want:

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2015/12/29 My MWE class]
\LoadClassWithOptions{article}
\PassOptionsToPackage{backend=biber}{biblatex}
\endinput

I tried and, specifying backend=bibtex in the document is ineffective. You could also add a fatal error:

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2015/12/29 My MWE class]
\LoadClassWithOptions{article}
\PassOptionsToPackage{backend=biber}{biblatex}
\AtBeginDocument{%
  \@ifpackageloaded{biblatex}{}
    {\ClassError{myclass}{Fatal: biblatex not loaded}
       {You must load biblatex, I'll end here}\@@end}%
}
\endinput
egreg
  • 1,121,712
4

One option is to add an option to the class to suppress loading the biblatex package in the class. This gives a default of loading biblatex with the default values, but if the user wants to manually load biblatex, then they need to provide the class option.

% arara: pdflatex
% arara: biber
% arara: pdflatex
% arara: pdflatex

\RequirePackage{filecontents}

\begin{filecontents*}{myclass.cls}
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2015/12/29 My MWE class]
\newif\ifnobiblatex
\DeclareOption{nobiblatex}{\nobiblatextrue}
\ProcessOptions\relax
\LoadClassWithOptions{article}
\PassOptionsToPackage{backend=biber}{biblatex}
\ifnobiblatex%
\AtBeginDocument{%
  \@ifpackageloaded{biblatex}{}
    {\ClassError{myclass}{Fatal: biblatex not loaded}
       {You must load biblatex, I'll end here}\@@end}%
}
\else\RequirePackage{biblatex}\fi
\endinput
\end{filecontents*}

\documentclass[nobiblatex]{myclass}
\usepackage[style=authoryear]{biblatex}
\addbibresource{biblatex-examples.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}
StrongBad
  • 20,495
3

Here's a trial solution with \DeclareOption{authoryear}{...} (for example)

Make sure to use \LoadClassWithOptions{...} before \DeclareOption, otherwise myclass will complain about authoryear.

More sophisticated approaches require a better option handling of course, especially the option values.

\RequirePackage{filecontents}

\begin{filecontents*}{myclass.cls}
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2015/12/29 My MWE class]
\LoadClassWithOptions{article}
\DeclareOption{authoryear}{\PassOptionsToPackage{style=authoryear}{biblatex}}
\ProcessOptions
\endinput
\end{filecontents*}

\documentclass[authoryear]{myclass}
\usepackage{biblatex}
\addbibresource{biblio.bib}

\begin{document}
\cite{Lam94}
\printbibliography
\end{document}
  • 1
    There are a huge number of styles and not all are known to the class writer. – StrongBad Dec 29 '15 at 16:45
  • @StrongBad: That's true, of course. Perhaps, it's really not the best idea to load this huge package biblatex by the class already (or trying to provide option wrappers) –  Dec 29 '15 at 17:28