Source code for bibolamazi.filters.util.auxfile
# -*- coding: utf-8 -*-
################################################################################
# #
# This file is part of the Bibolamazi Project. #
# Copyright (C) 2013 by Philippe Faist #
# philippe.faist@bluewin.ch #
# #
# Bibolamazi is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# Bibolamazi is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with Bibolamazi. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
"""
Utilities (actually for now, utility) to parse .aux files from LaTeX documents.
"""
import os
import os.path
import re
import logging
logger = logging.getLogger(__name__)
from bibolamazi.core.bibfilter import BibFilterError #, BibFilter
rx_bibolamazibib_suffix = re.compile(r'(\.bibolamazi)?\.bib$', flags=re.IGNORECASE)
[docs]def get_action_jobname(jobname, bibolamazifile):
"""
If `jobname` is non-None and nonempty, then return `jobname`. Otherwise,
find the basename of the bibolamazifile, and return that.
.. versionadded:: 4.3
Added function :py:func:`get_action_jobname()`.
"""
if jobname:
return jobname
# use bibolamazi file base name
jobname = rx_bibolamazibib_suffix.sub('', os.path.basename(bibolamazifile.fname()))
logger.debug("Using jobname \"%s\" guessed from bibolamazi file name", jobname)
return jobname
# BibTeX uses "\citation{}", BibLatex uses "\abx@aux@cite{}" in aux file... support both
rx_citation_aux_macro_pat = r'(?:\\citation|\\abx@aux@cite)'
[docs]def get_all_auxfile_citations(jobname, bibolamazifile, filtername, search_dirs=None,
callback=None, return_set=True):
r"""
Get a list of bibtex keys that a specific LaTeX document cites, by
inspecting its .aux file.
Look for the file ``<jobname>.aux`` in the current directory, or in the
search directories `search_dirs` if given. Parse that file for commands of
the type ``\citation{..}``, and collect all the arguments of such
commands. These commands are generated by calls to the ``\cite{}`` command
in the LaTeX document.
Return a python set (unless `return_set=False`) with the list of all bibtex
keys that the latex document cites.
Note: latex/pdflatex must have run at least once on the document already.
Arguments:
- `jobname`: the base name of the TEX file; the AUX file that is searched
for is "<jobname>.aux". The `jobname` is expected to be non-empty; see
:py:func:`get_action_jobname()` for help on that.
- `bibolamazifile`: The bibolamazifile relative to which we are analyzing
citations. This is used to determine in which directory(ies) to search
for the AUX file.
- `filtername`: The name of the filter that is calling this function.
Used for error messages and logs.
- `search_dirs`: list of directories in which to search for the AUX file.
These may be absolute paths or relative paths; the latter are
interpreted as being relative to the bibolamazifile's location.
- `callback`: A python callable can be specified in this argument. It
will be called for each occurrence of a citation in the document, with
the citation key as single argument.
- `return_set`: If True (the default), then this function returns a python
`set` with all the citation keys encountered. Set this to False if
you're going to ignore the return value of this function.
"""
logger.debug("%s: Retrieving citations from job name %r", filtername, jobname)
citations_list = set()
if (search_dirs is None):
search_dirs = ['.', '_cleanlatexfiles']
allaux = None
for maybeauxfile in (os.path.join(bibolamazifile.fdir(), searchdir, jobname+'.aux')
for searchdir in search_dirs):
try:
with open(maybeauxfile, 'r') as auxf:
logger.debug("%s: Reading auxfile %r", filtername, maybeauxfile)
allaux = auxf.read()
except IOError:
pass
if not allaux:
raise BibFilterError(
filtername,
("Can't analyze citations [filter {filtername}]: can't find file \"{jobname}.aux\". "
"Please run latex on your document before running bibolamazi.").format(
filtername=filtername,
jobname=jobname
)
)
#
# parse allaux for \citation{...}
#
for citation in re.finditer(rx_citation_aux_macro_pat + r'\s*\{(?P<citekey>[^\}]+)\}', allaux):
for citekey in (x.strip() for x in citation.group('citekey').split(',')):
if return_set:
citations_list.add(citekey)
if callback is not None:
callback(citekey)
if return_set:
return citations_list
return