[Tex/LaTex] Extract all citations from .tex file

bibtex

Is there a fool-proof way to extract all bibtex citation-keys that are cited in a .tex file?

I do not mean regular-expression magic on the .tex-file because this is bound to cause problems when switching between natbib, apacite etc. which all use different citation commands. Also, citations made using \nocite{*} will not be included …

I though about looking into the .bbl file which does contain all references included in the final document but the format of the .bbl file differs vastly between packages as well such that the key-extraction is difficult.

Best Answer

The citations are contained in the .aux file.

\usepackage{atveryend}
\makeatletter
\let\origcitation\citation
\AtEndDocument{\def\mycites{\@gobble}%
  \def\citation#1{\g@addto@macro\mycites{,#1}\origcitation{#1}}}
\AtVeryEndDocument{\typeout{***^^JCited keys: \mycites^^J***}}
\makeatother

This will show on screen and in the .log file, at the end of the LaTeX run, a message such as

***
Cited keys: xxx,yyy,*
***

It would be possible to avoid the appearance of *, but I don't think it's worthy the trouble. Only actually cited keys will appear (BibTeX uses \citation{*} as a signal for including the whole database).

One can output the citations to an auxiliary file, instead:

\makeatletter
\let\origcitation\citation
\AtEndDocument{\def\mycites{}%
  \def\citation#1{\g@addto@macro\mycites{#1^^J}\origcitation{#1}}}
\AtVeryEndDocument{\newwrite\citeout\immediate\openout\citeout=\jobname.cit
  \immediate\write\citeout{\mycites}\immediate\closeout\citeout}
\makeatother

Then, if the file is test.tex, the citation keys will be saved in the file test.cit one per line.

Related Question