Skip to content

Commit

Permalink
Merge pull request #88 from mcmtroffaes/feature/bibliography-tags
Browse files Browse the repository at this point in the history
Support bibliography key prefixes.
  • Loading branch information
mcmtroffaes committed Oct 20, 2015
2 parents d740298 + a953d61 commit 2daeafc
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 3 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
language: python
sudo: false
python:
- "3.4"
- "3.3"
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
0.3.3 (in development)
----------------------

* Add per-bibliography key prefixes, enabling local bibliographies to
be used in isolation from each other (see issue #87, reported by
marscher).

0.3.2 (20 March 2015)
---------------------

Expand Down
52 changes: 52 additions & 0 deletions doc/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,45 @@ use the ``labelprefix`` option.
:notcited:
:labelprefix: B
.. _section-key-prefixing:

Key Prefixing
~~~~~~~~~~~~~

.. versionadded:: 0.3.3

If you have multiple bibliographies, and you would like entries to be
repeated in different documents, then use the ``keyprefix`` option.

For example, suppose you have two documents, and you would like to cite
``boole1854`` in both of these doucments, with the bibliography entries
showing in both of the documents. In one document you could have:

.. code-block:: rest
See :cite:`a-boole1854`
.. bibliography:: refs.bib
:labelprefix: A
:keyprefix: a-
whilst in the other document you could have:

.. code-block:: rest
See :cite:`b-boole1854`
.. bibliography:: refs.bib
:labelprefix: B
:keyprefix: b-
The bibliographies will then both generate an entry for ``boole1854``,
with links and backlinks as expected.

.. seealso::

:ref:`section-local-bibliographies`

Filtering
~~~~~~~~~

Expand Down Expand Up @@ -282,9 +321,22 @@ The filter expression supports:
that is less or equal than 2003; any entries that do not
specify a year would be omitted.

.. _section-local-bibliographies:

Local Bibliographies
~~~~~~~~~~~~~~~~~~~~

Both the ``keyprefix`` and ``filter`` options can be used
to achieve local bibliographies.

The ``filter`` system for local bibliographies is the simplest one to
use, but offers the least amount of flexibility. In particular, it
can only be used if no citation key is used in more than one
document. This is not always satisfied. If you need to cite the same
reference in multiple documents with references to multiple local
bibliographies, use the ``keyprefix`` system; see
:ref:`section-key-prefixing`.

To create a bibliography that includes only citations that were cited
in the current document, use the following filter:

Expand Down
16 changes: 13 additions & 3 deletions sphinxcontrib/bibtex/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,10 @@ def _get_bibliography_entries(self, docname, id_, warn):
for bibfile in bibcache.bibfiles:
data = self.bibfiles[bibfile].data
for entry in six.itervalues(data.entries):
cited_docnames = self.get_cited_docnames(entry.key)
# beware: the prefix is not stored in the data
# to allow reusing the data for multiple bibliographies
cited_docnames = self.get_cited_docnames(
bibcache.keyprefix + entry.key)
visitor = _FilterVisitor(
entry=entry,
docname=docname,
Expand All @@ -307,7 +310,10 @@ def _get_bibliography_entries(self, docname, id_, warn):
if success:
# entries are modified in an unpickable way
# when formatting, so fetch a deep copy
yield copy.deepcopy(entry)
# and return this copy with prefixed key
entry2 = copy.deepcopy(entry)
entry2.key = bibcache.keyprefix + entry.key
yield entry2

def get_bibliography_entries(self, docname, id_, warn):
"""Return filtered bibliography entries, sorted by citation order."""
Expand Down Expand Up @@ -352,7 +358,7 @@ class BibliographyCache(collections.namedtuple(
'BibliographyCache',
"""bibfiles style encoding
list_ enumtype start labels labelprefix
filter_ curly_bracket_strip
filter_ curly_bracket_strip keyprefix
""")):

"""Contains information about a bibliography directive.
Expand Down Expand Up @@ -387,6 +393,10 @@ class BibliographyCache(collections.namedtuple(
This bibliography's string prefix for pybtex generated labels.
.. attribute:: keyprefix
This bibliography's string prefix for citation keys.
.. attribute:: filter_
An :class:`ast.AST` node, containing the parsed filter expression.
Expand Down
2 changes: 2 additions & 0 deletions sphinxcontrib/bibtex/directives.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class BibliographyDirective(Directive):
'encoding': directives.encoding,
'disable-curly-bracket-strip': directives.flag,
'labelprefix': directives.unchanged,
'keyprefix': directives.unchanged,
}

def run(self):
Expand Down Expand Up @@ -124,6 +125,7 @@ def run(self):
curly_bracket_strip=(
'disable-curly-bracket-strip' not in self.options),
labelprefix=self.options.get("labelprefix", ""),
keyprefix=self.options.get("keyprefix", ""),
labels={},
bibfiles=[],
)
Expand Down
2 changes: 2 additions & 0 deletions test/issue87/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
extensions = ['sphinxcontrib.bibtex']
exclude_patterns = ['_build']
7 changes: 7 additions & 0 deletions test/issue87/contents.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Contents
========

.. toctree::

doc0
doc1
9 changes: 9 additions & 0 deletions test/issue87/doc0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
doc0
----

:cite:`tag0-2009:mandel`
:cite:`tag0-2003:evensen`

.. bibliography:: test.bib
:labelprefix: A
:keyprefix: tag0-
8 changes: 8 additions & 0 deletions test/issue87/doc1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
doc1
----

:cite:`tag1-2009:mandel`

.. bibliography:: test.bib
:labelprefix: B
:keyprefix: tag1-
27 changes: 27 additions & 0 deletions test/issue87/test.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@Misc{2009:mandel,
author = {Jan Mandel},
title = {A Brief Tutorial on the Ensemble {K}alman Filter},
howpublished = {arXiv:0901.3725v1 [physics.ao-ph]},
month = jan,
year = {2009},
OPTnote = {},
OPTannote = {},
archivePrefix = {arXiv},
eprint = {0901.3725},
primaryClass = {physics.ao-ph}
}

@Article{2003:evensen,
author = {Geir Evensen},
title = {The Ensemble {K}alman Filter: theoretical formulation and practical implementation},
journal = {Ocean Dynamics},
year = {2003},
OPTkey = {},
volume = {53},
number = {4},
pages = {343--367},
OPTmonth = {},
OPTnote = {},
OPTannote = {},
doi = {10.1007/s10236-003-0036-9}
}
38 changes: 38 additions & 0 deletions test/test_issue87.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
test_issue87
~~~~~~~~~~~~
Test bibliography tags.
"""

import os.path
import re

from sphinx_testing.util import path, with_app

srcdir = path(__file__).dirname().joinpath('issue87').abspath()


def teardown_module():
(srcdir / '_build').rmtree(True)


@with_app(srcdir=srcdir, warningiserror=True)
def test_issue87(app, status, warning):
app.builder.build_all()
with open(os.path.join(app.outdir, "doc0.html")) as stream:
output = stream.read()
assert re.search(
'class="reference internal" href="#tag0-2009-mandel"', output)
assert re.search(
'class="reference internal" href="#tag0-2003-evensen"', output)
assert re.search('AMan09', output)
assert re.search('AEve03', output)
with open(os.path.join(app.outdir, "doc1.html")) as stream:
output = stream.read()
assert re.search(
'class="reference internal" href="#tag1-2009-mandel"', output)
assert not re.search(
'class="reference internal" href="#tag1-2003-evensen"', output)
assert re.search('BMan09', output)
assert not re.search('BEve03', output)

0 comments on commit 2daeafc

Please sign in to comment.