\documentclass[12pt,a4paper]{article} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage[english]{babel} \usepackage[margin=1in]{geometry} \usepackage[svgnames]{xcolor} \usepackage[colorlinks, linkcolor={blue}, urlcolor={blue}]{hyperref} \usepackage{tcolorbox} \tcbuselibrary{listings} \newcommand{\checkcites}{\texttt{checkcites}} \newcommand{\email}[1]{\small\texttt{#1}} \newcommand{\version}{Version 1.0i from December 18, 2012.} \newenvironment{infoblock}[1] {\par\addvspace{\medskipamount} \begin{tcolorbox}[colframe=DarkTurquoise,coltitle=black,fonttitle=\bfseries,title=#1]} {\end{tcolorbox}\addvspace{\medskipamount}} \newenvironment{terminal} {\par\addvspace{\medskipamount} \begin{tcolorbox}[colframe=DarkTurquoise]} {\end{tcolorbox}\par\addvspace{\medskipamount}} \title{The \checkcites\footnote{\version}\ \ script} \author{% Enrico Gregorio\\\email{Enrico dot Gregorio at univr dot it}\\[3ex] Paulo Roberto Massa Cereda\\\email{cereda at users dot sf dot net}% } \date{} \begin{document} \maketitle \tableofcontents \section{Introduction} \label{sec:intro} \checkcites\ is a Lua script written for the sole purpose of detecting unused or undefined references from both \LaTeX{} auxiliary or bibliography files. We use \emph{unused reference} to refer to the reference present the bibliography file --~with the \verb|.bib| extension~-- but not cited in the \verb|.tex| file. The \emph{undefined reference} is exactly the opposite, that is, the items cited in the \texttt{.tex} file, but not present in the \verb|.bib| file. The original idea came from a question posted in the \href{http://tex.stackexchange.com}{TeX.sx community} about \href{http://tex.stackexchange.com/questions/43276}{how to check which bibliography entries were not used}. We decided to write a script to check references. We opted for Lua, since it's a very straightforward language and it has an interpreter available on every modern \TeX\ distribution. \begin{infoblock}{Attention!} \checkcites\ is known to run with the most recent \verb|texlua| and \verb|lua| interpreters. Unfortunately, the code is incompatible with interpreters prior to the Lua 5.1 language specification. \end{infoblock} \section{How the script works} \label{sec:howto} \checkcites\ uses the generated \verb|.aux| file to start the analysis. The first step is to extract all citations found, in the form of \verb|\citation{a}|. For every \verb|\citation| line found, \checkcites\ will extract the citations and add them to a table, even for multiple citations separated by commas, like \verb|\citation{a,b,c}|. Then the citations table has all duplicate values removed --~in other words, the table becomes a set. Let's call $A$ the set of citations. \begin{infoblock}{Attention!} If \verb|\citation{*}| is found, \checkcites\ will issue a message telling that \verb|\nocite{*}| is in the \verb|.tex| document, but the script will do the check nonetheless. \end{infoblock} At the same time \checkcites\ also looks for bibliography data, in the form of \verb|\bibdata{a}|. Similarly, for every \verb|\bibdata| line found, the script will extract the bibliography data and add them to a table, even if they are separated by commas, like \verb|\bibdata{d,e,f}|. The table has all duplicate values removed. \begin{infoblock}{Attention!} If no \verb|\bibdata| command is found, the script ends. There's nothing to do in this case. \end{infoblock} Now, \checkcites\ will extract all entries from the bibliography files found in the previous step. For every element in the bibliography data table, the script will look for entries like \verb|@BOOK|, \verb|@ARTICLE| and so forth --~we actually use pattern matching for this~-- and add their identifiers to a table. The script treats all \verb|.bib| files as if they were only one. After all files have been analyzed and all entries' identifiers extracted, the table has all duplicate values removed. Let's call $B$ the set of bibliography entries. \begin{infoblock}{Attention!} If \checkcites\ cannot find a certain bibliography file --~that is, a \verb|.bib| file~-- the script ends. Make sure to put the correct name of the bibliography file in your \verb|.tex| file. \end{infoblock} Now we have both sets $A$ and $B$. In order to get all unused references in the \verb|.bib| files, we compute the set difference \[ B - A = \{ x : x \in B, x \notin A \}. \] Similarly, in order to get all undefined references in the \verb|.tex| file, we compute the set difference \[ A - B = \{ x : x \in A, x \notin B \}. \] If there are either unused or undefined references, \checkcites\ will print them in a list format. In Section~\ref{sec:usage} there's a more complete explanation on how to use the script. \section{Usage} \label{sec:usage} \checkcites\ is very easy to use. First of all, let's define two files that will be used here to explain the script usage. Here's our sample bibliography file \verb|example.bib|, with five fictional entries. \begin{tcblisting}{colframe=DarkTurquoise,coltitle=black,listing only, title=Bibliography file, fonttitle=\bfseries, listing options={columns=fullflexible,basicstyle=\ttfamily}} @BOOK{foo:2012a, title = {My Title One}, publisher = {My Publisher One}, year = {2012}, editor = {My Editor One}, author = {Author One} } @BOOK{foo:2012b, title = {My Title Two}, publisher = {My Publisher Two}, year = {2012}, editor = {My Editor Two}, author = {Author Two} } @BOOK{foo:2012c, title = {My Title Three}, publisher = {My Publisher Three}, year = {2012}, editor = {My Editor Three}, author = {Author Three} } @BOOK{foo:2012d, title = {My Title Four}, publisher = {My Publisher Four}, year = {2012}, editor = {My Editor Four}, author = {Author Four} } @BOOK{foo:2012e, title = {My Title Five}, publisher = {My Publisher Five}, year = {2012}, editor = {My Editor Five}, author = {Author Five} } \end{tcblisting} The second file is our main \LaTeX{} document, \verb|document.tex|. \begin{tcblisting}{colframe=DarkTurquoise,coltitle=black,listing only, title=Main document, fonttitle=\bfseries, listing options={columns=fullflexible,basicstyle=\ttfamily}} \documentclass{article} \begin{document} Hello world \cite{foo:2012a,foo:2012c}, how are you \cite{foo:2012f}, and goodbye \cite{foo:2012d,foo:2012a}. \bibliographystyle{plain} \bibliography{example} \end{document} \end{tcblisting} Open a terminal and run \verb|checkcites|: \begin{terminal} \begin{verbatim} $ checkcites \end{verbatim} \tcblower \begin{verbatim} checkcites.lua -- a reference checker script (v1.0i) Copyright (c) 2012 Enrico Gregorio, Paulo Roberto Massa Cereda Usage: checkcites.lua [--all | --unused | --undefined] file.aux --all Lists all unused and undefined references. --unused Lists only unused references in your 'bib' file. --undefined Lists only undefined references in your 'tex' file. If no flag is provided, '--all' is set by default. Be sure to have all your 'bib' files in the same directory. \end{verbatim} \end{terminal} If you don't have \checkcites\ installed with your \TeX\ distribution, you can run the standalone script \verb|checkcites.lua| with either \verb|texlua| or \verb|lua|. We recommend to use \verb|texlua|, as it's shipped with all the modern \TeX\ distributions: \begin{terminal} \begin{verbatim} $ texlua checkcites.lua \end{verbatim} \end{terminal} When you run \checkcites\ without providing any argument to it, the script usage will be printed, as seen in the previous output. The only required argument is the auxiliary file --~with the \verb|.aux| extension~-- which is generated when you compile your main \verb|.tex| file. For example, if your main document is named \verb|foo.tex|, you probably have a \verb|foo.aux| file too. Let's compile our sample document \verb|document.tex|: \begin{terminal} \begin{verbatim} $ pdflatex document.tex \end{verbatim} \end{terminal} After running \verb|pdflatex| on our \verb|.tex| file, there's now a \verb|document.aux| file in our work directory. \begin{tcblisting}{colframe=DarkTurquoise,coltitle=black,listing only, title=Auxiliary file, fonttitle=\bfseries, listing options={columns=fullflexible,basicstyle=\ttfamily}} \relax \citation{foo:2012a} \citation{foo:2012c} \citation{foo:2012f} \citation{foo:2012d} \citation{foo:2012a} \bibstyle{plain} \bibdata{example} \end{tcblisting} Now we can run \checkcites\ on the \verb|document.aux| file: \begin{terminal} \begin{verbatim} $ checkcites document.aux \end{verbatim} \tcblower \begin{verbatim} checkcites.lua -- a reference checker script (v1.0i) Copyright (c) 2012 Enrico Gregorio, Paulo Roberto Massa Cereda I found 4 citation(s). Great, there's only one 'bib' file. Let me check it. I found 5 reference(s). Unused reference(s) in your bibliography file(s): 2 - foo:2012b - foo:2012e Undefined reference(s) in your TeX file: 1 - foo:2012f \end{verbatim} \end{terminal} As we can see in the script output, \checkcites\ analyzed both \verb|.aux| and \verb|.bib| files and found two unused references in the bibliography file --~\verb|foo:2012b| and \verb|foo:2012e|~-- and one undefined reference in the document --~\verb|foo:2012f|. \checkcites\ allows a command line switch that will tell it how to behave. For example, \begin{terminal} \begin{verbatim} $ checkcites --unused document.aux \end{verbatim} \end{terminal} The \verb|--unused| flag will make the script only look for unused references in the \verb|.bib| file. The argument order doesn't matter, you can also run \begin{terminal} \begin{verbatim} $ checkcites document.aux --unused \end{verbatim} \end{terminal} The script will behave the same. Similarly, you can use \begin{terminal} \begin{verbatim} $ checkcites --undefined document.aux \end{verbatim} \end{terminal} The \verb|--undefined| flag will make the script only look for undefined references in the \verb|.tex| file. If you want \checkcites\ to look for both unused and undefined references, run: \begin{terminal} \begin{verbatim} $ checkcites --all document.aux \end{verbatim} \end{terminal} If no special argument is provided, the \verb|--all| flag is set as default. \section{License} \label{sec:license} This script is licensed under the \href{http://www.latex-project.org/lppl/}{LaTeX Project Public License}. If you want to support \LaTeX{} development by a donation, the best way to do this is donating to the \href{http://www.tug.org/}{TeX Users Group}. \begin{infoblock}{Official code repository} \url{http://github.com/cereda/checkcites} \end{infoblock} \end{document}