[Tex/LaTex] Print bibliography only when references are cited

auxiliary-filesbiblatexbibliographiesmla-style

The root question here is how can one print a bibliography only when there are sources to be cited?

BACKGROUND
I'm working on expanding a small package (originally by Jackson Taylor and Becca Funke) that formats a paper according to the MLA 13 standard. (This format is commonly used in literature-based classes.)

The package currently provides basic formatting goodies like (something that looks like) a customized /maketitle and the proper running header (Last \thepage). I'm trying to make it a bit more functional/robust. This includes a growing list of features:

  • Natural use of \author
  • \date support
  • Optional title page and abstract
  • More robust bibliography handling
  • General customization of 'customizable' things, such as "Works Cited" / "References" / etc.

MEATY BACKGROUND
Currently, mla13 will print the bibliography whenever you tell it to. Since this is always at the end of a MLA paper, I've just used the appropriate commands to execute it at \end{document}. This little bit of automation has caused a problem — how can the references be intelligently printed? That is, if there are no sources to be cited, it's a little awkward for there to be a blank page called 'Works Cited.'

MEAT
Using biblatex, is it possible to check and see if any source has been cited within the document? I've taken a look at the job.bbl file, and it seems that if one could check to see if the string \entry is not found in the file, this would suffice as a switch. I've checked into the primitives \read and \readline, but I honestly don't have much of a clue as to how to apply the information (I don't really understand it all that well, either).

Is the way I described possible, and if so, how? Is there a better way for this to be done?

Best Answer

The command

\printbibliography[heading=<heading>,...]

doesn't print anything when the bbl file contains no entries. If it's cited entries in the bbl file you want to consider, then use a category. The command

\printbibliography[heading=<heading>,category=<category>,...]

won't print anything provided that <category> is empty and the additional options settings in ... exclude check and filter. The example below considers the article document class. Its default bibliography heading doesn't issue a page break, but we can redefine it using \defbibheading. Default heading definitions for the standard, KOMA-script and memoir document classes can be found in biblatex.def.

\documentclass{article}
\usepackage[defernumbers]{biblatex}

% add every cited article to a category
% (nb: this excludes entries accessed via \nocite)
\DeclareBibliographyCategory{cited}
\AtEveryCitekey{\addtocategory{cited}{\thefield{entrykey}}}

% define bibliography heading that issues a page break
\defbibheading{bibliography}[\refname]{%
  \clearpage
  \section*{#1}%
  \markboth{\MakeUppercase{#1}}{\MakeUppercase{#1}}}

\addbibresource{biblatex-examples.bib}
\begin{document}
Filler text.
% More filler text \parencite{companion}.
\printbibliography[heading=bibliography,title={Works cited},category=cited]
\end{document}

Use of \AtEveryCitekey prints a bibliography only for explicitly cited entries, excluding those accessed via \nocite. To consider all entries in the bbl file that would otherwise be printed use:

\makeatletter
\AtDataInput{\iftoggle{blx@skipbib}{}{\addtocategory{cited}{\thefield{entrykey}}}}
\makeatother

An empty \printbibliography generates a warning in the log. To avoid this you can use a boolean flag to indicate citations.

\documentclass{article}
\usepackage[defernumbers]{biblatex}

\newbool{anycited}
\AtEveryCitekey{%
  \ifbool{anycited}{}{\global\booltrue{anycited}}}

\newrobustcmd*{\printworkscited}{%
  \ifbool{anycited}{\printbibliography}{\printnothing}}
\def\printnothing[#1]{}

\defbibheading{bibliography}[\refname]{%
  \clearpage
  \section*{#1}%
  \markboth{\MakeUppercase{#1}}{\MakeUppercase{#1}}}

\addbibresource{biblatex-examples.bib}
\begin{document}
Filler text.
% More filler text \parencite{companion}.
\printworkscited[heading=bibliography,title={Works cited}]
\end{document}

With this document, biber will issue a warning about no citations. There isn't much you can do about that. Hooking \printbibliography into \end{document} might seem convenient, but you are forcing a biber run onto your users. This wouldn't make much sense to me when writing an essay that doesn't use any bibliographic data. You can probably side-step some of these issues with BibTeX, at the cost of many biblatex features.