Source code for sphinxcontrib.bibtex.directives

"""
    .. autoclass:: BibliographyDirective

        .. automethod:: run

    .. autofunction:: process_start_option
"""

import ast  # parse(), used for filter
import sphinx.util

from docutils.parsers.rst import Directive, directives
from sphinx.util.console import standout

from .bibfile import normpath_filename
from .cache import BibliographyCache
from .nodes import bibliography


logger = sphinx.util.logging.getLogger(__name__)


[docs]def process_start_option(value): """Process and validate the start option value of a :rst:dir:`bibliography` directive. If *value* is ``continue`` then this function returns -1, otherwise *value* is converted into a positive integer. """ if value == "continue": return -1 else: return directives.positive_int(value)
[docs]class BibliographyDirective(Directive): """Class for processing the :rst:dir:`bibliography` directive. Parses the bibliography files, and produces a :class:`~sphinxcontrib.bibtex.nodes.bibliography` node. .. seealso:: Further processing of the resulting :class:`~sphinxcontrib.bibtex.nodes.bibliography` node is done by :class:`~sphinxcontrib.bibtex.transforms.BibliographyTransform`. """ required_arguments = 0 optional_arguments = 1 final_argument_whitespace = True has_content = False option_spec = { 'cited': directives.flag, 'notcited': directives.flag, 'all': directives.flag, 'filter': directives.unchanged, 'style': directives.unchanged, 'list': directives.unchanged, 'enumtype': directives.unchanged, 'start': process_start_option, 'labelprefix': directives.unchanged, 'keyprefix': directives.unchanged, }
[docs] def run(self): """Process .bib files, set file dependencies, and create a node that is to be transformed to the entries of the bibliography. """ env = self.state.document.settings.env # create id and cache for this node # this id will be stored with the node # and is used to look up additional data in env.bibtex_cache # (implementation note: new_serialno only guarantees unique # ids within a single document, but we need the id to be # unique across all documents, so we also include the docname # in the id) id_ = 'bibtex-bibliography-%s-%s' % ( env.docname, env.new_serialno('bibtex')) if "filter" in self.options: if "all" in self.options: logger.warning(standout(":filter: overrides :all:")) if "notcited" in self.options: logger.warning(standout(":filter: overrides :notcited:")) if "cited" in self.options: logger.warning(standout(":filter: overrides :cited:")) try: filter_ = ast.parse(self.options["filter"]) except SyntaxError: logger.warning( standout("syntax error in :filter: expression") + " (" + self.options["filter"] + "); " "the option will be ignored" ) filter_ = ast.parse("cited") elif "all" in self.options: filter_ = ast.parse("True") elif "notcited" in self.options: filter_ = ast.parse("not cited") else: # the default filter: include only cited entries filter_ = ast.parse("cited") if self.arguments: bibfiles = [normpath_filename(env, bibfile) for bibfile in self.arguments[0].split()] else: bibfiles = list(env.bibtex_cache.bibfiles.keys()) bibcache = BibliographyCache( list_=self.options.get("list", "citation"), enumtype=self.options.get("enumtype", "arabic"), start=self.options.get("start", 1), style=self.options.get( "style", env.app.config.bibtex_default_style), filter_=filter_, labelprefix=self.options.get("labelprefix", ""), keyprefix=self.options.get("keyprefix", ""), labels={}, bibfiles=bibfiles, ) if (bibcache.list_ not in set(["bullet", "enumerated", "citation"])): logger.warning( "unknown bibliography list type '{0}'.".format(bibcache.list_)) for bibfile in bibfiles: env.note_dependency(bibfile) # if citations change, bibtex.json changes, and so might entries env.note_dependency( normpath_filename(env, "bibtex.json", env.app.config.master_doc)) env.bibtex_cache.bibliographies[env.docname][id_] = bibcache return [bibliography('', ids=[id_])]