[med-svn] [sphinxcontrib-bibtex] 01/04: Imported Upstream version 0.3.2
Kevin Murray
daube-guest at moszumanska.debian.org
Mon Sep 28 12:37:33 UTC 2015
This is an automated email from the git hooks/post-receive script.
daube-guest pushed a commit to branch master
in repository sphinxcontrib-bibtex.
commit 588db65dba384c47bc4db4ca825b61a188ffa95c
Author: Kevin Murray <spam at kdmurray.id.au>
Date: Mon Sep 28 21:52:28 2015 +1000
Imported Upstream version 0.3.2
---
.travis.yml | 27 ++
CHANGELOG.rst | 158 +++++++++
INSTALL.rst | 28 ++
LICENSE.rst | 26 ++
MANIFEST.in | 14 +
README.rst | 45 +++
VERSION | 1 +
doc/Makefile | 153 +++++++++
doc/api.rst | 12 +
doc/api/cache.rst | 1 +
doc/api/directives.rst | 1 +
doc/api/interface.rst | 1 +
doc/api/nodes.rst | 1 +
doc/api/roles.rst | 1 +
doc/api/transforms.rst | 1 +
doc/changes.rst | 7 +
doc/conf.py | 248 ++++++++++++++
doc/index.rst | 26 ++
doc/license.rst | 5 +
doc/make.bat | 190 +++++++++++
doc/quickstart.rst | 13 +
doc/related.rst | 27 ++
doc/usage.rst | 462 +++++++++++++++++++++++++++
release_checklist.txt | 40 +++
requirements.txt | 7 +
setup.cfg | 8 +
setup.py | 53 +++
sphinxcontrib/__init__.py | 13 +
sphinxcontrib/bibtex/__init__.py | 136 ++++++++
sphinxcontrib/bibtex/cache.py | 393 +++++++++++++++++++++++
sphinxcontrib/bibtex/directives.py | 218 +++++++++++++
sphinxcontrib/bibtex/nodes.py | 17 +
sphinxcontrib/bibtex/roles.py | 43 +++
sphinxcontrib/bibtex/transforms.py | 127 ++++++++
test/bibfile_out_of_date/conf.py | 2 +
test/bibfile_out_of_date/contents.rst | 3 +
test/bibfile_out_of_date/test_new.bib | 16 +
test/bibfile_out_of_date/test_old.bib | 16 +
test/bibfilenotfound/conf.py | 2 +
test/bibfilenotfound/contents.rst | 1 +
test/citationnotfound/conf.py | 2 +
test/citationnotfound/contents.rst | 3 +
test/citationnotfound/test.bib | 0
test/custom_style/conf.py | 17 +
test/custom_style/contents.rst | 4 +
test/custom_style/test.bib | 27 ++
test/filter/bitand.rst | 6 +
test/filter/bitor.rst | 6 +
test/filter/conf.py | 2 +
test/filter/contents.rst | 20 ++
test/filter/false.rst | 6 +
test/filter/gt.rst | 6 +
test/filter/gte.rst | 6 +
test/filter/in.rst | 6 +
test/filter/key.rst | 6 +
test/filter/lt.rst | 6 +
test/filter/lte.rst | 6 +
test/filter/noteq.rst | 6 +
test/filter/notin.rst | 6 +
test/filter/or.rst | 6 +
test/filter/set.rst | 6 +
test/filter/test.bib | 18 ++
test/filter/title.rst | 6 +
test/filter_fix_author_keyerror/conf.py | 2 +
test/filter_fix_author_keyerror/contents.rst | 3 +
test/filter_fix_author_keyerror/test.bib | 4 +
test/filter_option_clash/conf.py | 2 +
test/filter_option_clash/contents.rst | 5 +
test/filter_option_clash/test.bib | 0
test/filter_syntax_error/conf.py | 2 +
test/filter_syntax_error/contents.rst | 26 ++
test/filter_syntax_error/test.bib | 5 +
test/invalid_cite_option/conf.py | 2 +
test/invalid_cite_option/contents.rst | 2 +
test/invalid_cite_option/test.bib | 0
test/issue1/2012/07/24/hello_world_.rst | 11 +
test/issue1/conf.py | 28 ++
test/issue1/master.rst | 8 +
test/issue1/refs.bib | 6 +
test/issue14/conf.py | 2 +
test/issue14/contents.rst | 7 +
test/issue14/doc1.rst | 6 +
test/issue14/doc2.rst | 6 +
test/issue14/test1.bib | 4 +
test/issue14/test2.bib | 4 +
test/issue14_2/conf.py | 2 +
test/issue14_2/contents.rst | 7 +
test/issue14_2/doc1.rst | 7 +
test/issue14_2/doc2.rst | 7 +
test/issue14_2/test1.bib | 4 +
test/issue14_2/test2.bib | 4 +
test/issue15/conf.py | 2 +
test/issue15/contents.rst | 5 +
test/issue15/test.bib | 8 +
test/issue17/conf.py | 11 +
test/issue17/contents.rst | 2 +
test/issue17/somemodule.py | 6 +
test/issue2/adoc1.rst | 4 +
test/issue2/adoc2.rst | 4 +
test/issue2/conf.py | 2 +
test/issue2/contents.rst | 10 +
test/issue2/test.bib | 4 +
test/issue4/conf.py | 2 +
test/issue4/contents.rst | 3 +
test/issue4/test.bib | 4 +
test/issue61/conf.py | 2 +
test/issue61/contents.rst | 6 +
test/issue61/refs.bib | 9 +
test/issue62/conf.py | 2 +
test/issue62/contents.rst | 9 +
test/issue62/doc1.rst | 56 ++++
test/issue62/doc2.rst | 46 +++
test/issue62/refs.bib | 128 ++++++++
test/issue62/summary.rst | 47 +++
test/issue77/conf.py | 21 ++
test/issue77/contents.rst | 5 +
test/issue77/test.bib | 27 ++
test/issue80/conf.py | 2 +
test/issue80/contents.rst | 15 +
test/issue80/doc0.rst | 2 +
test/issue80/doc1.rst | 4 +
test/issue80/doc2.rst | 4 +
test/issue80/doc3.rst | 4 +
test/issue80/doc4.rst | 4 +
test/issue80/doc5.rst | 4 +
test/issue80/doc6.rst | 4 +
test/issue80/doc7.rst | 4 +
test/issue80/doc8.rst | 4 +
test/issue80/doc9.rst | 4 +
test/issue80/refs.bib | 85 +++++
test/latex_refs/conf.py | 7 +
test/latex_refs/contents.rst | 7 +
test/latex_refs/test.bib | 10 +
test/list_bullet/conf.py | 2 +
test/list_bullet/contents.rst | 3 +
test/list_bullet/test.bib | 16 +
test/list_citation/conf.py | 2 +
test/list_citation/contents.rst | 4 +
test/list_citation/test.bib | 16 +
test/list_enumerated/conf.py | 2 +
test/list_enumerated/contents.rst | 14 +
test/list_enumerated/test.bib | 16 +
test/list_enumerated/test2.bib | 16 +
test/list_enumerated/test3.bib | 16 +
test/list_invalid/conf.py | 2 +
test/list_invalid/contents.rst | 2 +
test/list_invalid/test.bib | 0
test/path.py | 198 ++++++++++++
test/sphinx/Makefile | 130 ++++++++
test/sphinx/conf.py | 2 +
test/sphinx/contents.rst | 25 ++
test/sphinx/make.bat | 170 ++++++++++
test/sphinx/subfolder/test.bib | 12 +
test/sphinx/test.bib | 275 ++++++++++++++++
test/sphinx/test2.bib | 53 +++
test/sphinx/zbibliography.rst | 59 ++++
test/test_bibfile_out_of_date.py | 54 ++++
test/test_bibfilenotfound.py | 26 ++
test/test_citationnotfound.py | 26 ++
test/test_custom_style.py | 28 ++
test/test_filter.py | 73 +++++
test/test_filter_fix_author_keyerror.py | 20 ++
test/test_filter_option_clash.py | 28 ++
test/test_filter_syntax_error.py | 28 ++
test/test_invalid_cite_option.py | 26 ++
test/test_issue1.py | 27 ++
test/test_issue14.py | 33 ++
test/test_issue14_2.py | 27 ++
test/test_issue15.py | 29 ++
test/test_issue17.py | 20 ++
test/test_issue2.py | 26 ++
test/test_issue4.py | 25 ++
test/test_issue61.py | 26 ++
test/test_issue62.py | 85 +++++
test/test_issue77.py | 26 ++
test/test_issue80_parallel.py | 27 ++
test/test_issue80_serial.py | 19 ++
test/test_latex_refs.py | 26 ++
test/test_list_bullet.py | 32 ++
test/test_list_citation.py | 32 ++
test/test_list_enumerated.py | 44 +++
test/test_list_invalid.py | 28 ++
test/test_sphinx.py | 37 +++
test/util.py | 251 +++++++++++++++
184 files changed, 5639 insertions(+)
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..2e98360
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,27 @@
+language: python
+python:
+ - "3.4"
+ - "3.3"
+ - "2.7"
+ - "pypy"
+branches:
+ only:
+ - develop
+install:
+ - "pip install Tinkerer" # Tinkerer is required for tests
+ - "pip install ."
+ - "if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install coveralls check-manifest flake8; fi"
+script:
+ - "if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then check-manifest; fi"
+ - "if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then flake8; fi"
+ - "pushd doc"
+ - "if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then make html; fi"
+ - "popd"
+ - "pushd test"
+ - "if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then coverage run --source=sphinxcontrib.bibtex `type -p nosetests`; fi"
+ - "if [[ $TRAVIS_PYTHON_VERSION != '2.7' ]]; then nosetests; fi"
+ - "popd"
+after_success:
+ - "pushd test"
+ - "if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then coveralls; fi"
+ - "popd"
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..e3fe33e
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,158 @@
+0.3.2 (20 March 2015)
+---------------------
+
+* Document how to create custom label styles (see issue #77, reported
+ by tino).
+
+* Disable parallel_read_safe for Sphinx 1.3 and later (see issue #80,
+ reported by andreacassioli).
+
+0.3.1 (10 July 2014)
+--------------------
+
+* Fix for ``type_.lower()`` bug: pybtex 0.18 expects type to be a
+ string (this fixes issue #68 reported by jluttine).
+
+0.3.0 (4 May 2014)
+------------------
+
+* **BACKWARD INCOMPATIBLE**
+ The alpha style is now default, so citations are labelled in a way
+ that is more standard for Sphinx. To get the old behaviour back, add
+ ``:style: plain`` to your bibliography directives.
+
+* **BACKWARD INCOMPATIBLE**
+ :meth:`~sphinxcontrib.bibtex.cache.Cache.is_cited` has been removed.
+ Use :meth:`~sphinxcontrib.bibtex.cache.Cache.get_cited_docnames` instead,
+ which will return an empty list for keys that are not cited.
+
+* Improved support for local bibliographies (see issues #52, #62, and
+ #63; test case provided by Boris Kheyfets):
+
+ - New ``docname`` and ``docnames`` filter identifiers.
+
+ - Filter expressions now also support set literals and the operators
+ ``in``, ``not in``, ``&``, and ``|``.
+
+ See documentation for details.
+
+* Multiple comma-separated citation keys per cite command (see issue
+ #61, suggested by Boris Kheyfets).
+
+* Add support for pypy and Python 3.4.
+
+* Drop support for Python 2.6 and Python 3.2.
+
+* Drop 2to3 and instead use six to support both Python 2 and 3 from a
+ single code base.
+
+* Simplify instructions for custom styles.
+
+* Various test suite improvements.
+
+0.2.9 (9 October 2013)
+----------------------
+
+* Upgrade to the latest pybtex-docutils to produce more optimal html output
+ (specifically: no more nested ``<span>``\ s).
+
+* Remove latex codec code, and rely on latexcodec package instead.
+
+* :class:`FilterVisitor` has been removed from the public API.
+ Use :meth:`~sphinxcontrib.bibtex.cache.Cache.get_bibliography_entries`
+ instead.
+
+* Fix upstream Sphinx bug concerning LaTeX citation hyperlinks
+ (contributed by erikb85; see pull request #45).
+
+* Fix most pylint warnings, refactor code.
+
+0.2.8 (7 August 2013)
+---------------------
+
+* Use pybtex-docutils to remove dependency on pybtex.backends.doctree.
+
+0.2.7 (4 August 2013)
+---------------------
+
+* Integrate with coveralls.io, first release with 100% test coverage.
+
+* Minor bug fixes and code improvements.
+
+* Remove ordereddict dependency for Python 2.7 and higher (contributed
+ by Paul Romano, see pull requests #27 and #28).
+
+* New ``:filter:`` option for advanced filtering (contributed by
+ d9pouces, see pull requests #30 and #31).
+
+* Refactor documentation of advanced features.
+
+* Document how to create custom pybtex styles (see issues #25, #29,
+ and #34).
+
+* Code is now mostly pep8 compliant.
+
+0.2.6 (2 March 2013)
+--------------------
+
+* For unsorted styles, citation entries are now sorted in the order
+ they are cited, instead of following the order in the bib file, to
+ reflect more closely the way LaTeX handles unsorted styles
+ (addresses issue #15).
+
+* Skip citation label warnings on Sphinx [source] links (issue #17,
+ contributed by Simon Clift).
+
+0.2.5 (18 October 2012)
+-----------------------
+
+* Duplicate label detection (issue #14).
+
+* New ``:labelprefix:`` option to avoid duplicate labels when having
+ multiple bibliographies with a numerical label style (addresses
+ issue #14).
+
+0.2.4 (24 August 2012)
+----------------------
+
+* New options for the bibliography directive for rendering the
+ bibliography as bullet lists or enumerated lists: ``:list:``,
+ ``:enumtype:``, and ``:start:``.
+
+* Minor latex codec fixes.
+
+* Turn exception into warning when a citation cannot be relabeled
+ (fixes issue #2).
+
+* Document LaTeX encoding, and how to turn it off (issue #4).
+
+* Use pybtex labels (fixes issue #6 and issue #7).
+
+* Cache tracked citation keys and labels, and bibliography enumeration
+ counts (fixes issues with citations in repeated Sphinx runs).
+
+* Bibliography ids are now unique across documents (fixes issue that
+ could cause the wrong bibliography to be inserted).
+
+* The plain style is now the default (addresses issue #9).
+
+0.2.3 (30 July 2012)
+--------------------
+
+* Document workaround for Tinkerer (issue #1).
+
+* Use tox for testing.
+
+* Full 2to3 compatibility.
+
+* Document supported versions of Python (2.6, 2.7, 3.1, and 3.2).
+
+0.2.2 (6 July 2012)
+-------------------
+
+* Documentation and manifest fixes.
+
+0.2.1 (19 June 2012)
+--------------------
+
+* First public release.
diff --git a/INSTALL.rst b/INSTALL.rst
new file mode 100644
index 0000000..5ad7c6f
--- /dev/null
+++ b/INSTALL.rst
@@ -0,0 +1,28 @@
+Install the module with ``pip install sphinxcontrib-bibtex``, or from
+source using ``python setup.py install``. Then add:
+
+.. code-block:: python
+
+ extensions = ['sphinxcontrib.bibtex']
+
+to your project's Sphinx configuration file ``conf.py``.
+
+Minimal Example
+---------------
+
+In your project's documentation, you can then write for instance:
+
+.. code-block:: rest
+
+ See :cite:`1987:nelson` for an introduction to non-standard analysis.
+
+ .. bibliography:: refs.bib
+
+where refs.bib would contain an entry::
+
+ @Book{1987:nelson,
+ author = {Edward Nelson},
+ title = {Radically Elementary Probability Theory},
+ publisher = {Princeton University Press},
+ year = {1987}
+ }
diff --git a/LICENSE.rst b/LICENSE.rst
new file mode 100644
index 0000000..565f57a
--- /dev/null
+++ b/LICENSE.rst
@@ -0,0 +1,26 @@
+| sphinxcontrib-bibtex is a Sphinx extension for BibTeX style citations
+| Copyright (c) 2011-2014 by Matthias C. M. Troffaes
+| All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..08b9f54
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,14 @@
+include VERSION
+include README.rst
+include INSTALL.rst
+include CHANGELOG.rst
+include LICENSE.rst
+include requirements.txt
+recursive-include doc *
+recursive-include test *
+global-exclude *.pyc
+exclude .gitignore
+exclude .travis.yml
+exclude release_checklist.txt
+prune doc/_build
+
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..40bbb26
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,45 @@
+sphinxcontrib-bibtex
+====================
+
+|travis| |coveralls| |downloads| |version| |license|
+
+A Sphinx extension for BibTeX style citations.
+
+This extension allows `BibTeX <http://www.bibtex.org/>`_
+citations to be inserted into documentation generated by
+`Sphinx <http://sphinx.pocoo.org/>`_, via
+a ``bibliography`` directive, and a ``cite`` role, which
+work similarly to LaTeX's ``thebibliography`` environment
+and ``\cite`` command.
+
+For formatting, the extension relies on
+`pybtex <http://pybtex.sourceforge.net/>`_
+written by Andrey Golovizin.
+The extension is inspired by Matthew Brett's
+`bibstuff.sphinxext.bibref <https://github.com/matthew-brett/bibstuff>`_.
+
+* Download: http://pypi.python.org/pypi/sphinxcontrib-bibtex/#downloads
+
+* Documentation: http://sphinxcontrib-bibtex.readthedocs.org/
+
+* Development: http://github.com/mcmtroffaes/sphinxcontrib-bibtex/
+
+.. |travis| image:: https://travis-ci.org/mcmtroffaes/sphinxcontrib-bibtex.png?branch=develop
+ :target: https://travis-ci.org/mcmtroffaes/sphinxcontrib-bibtex
+ :alt: travis-ci
+
+.. |coveralls| image:: https://coveralls.io/repos/mcmtroffaes/sphinxcontrib-bibtex/badge.png?branch=develop
+ :target: https://coveralls.io/r/mcmtroffaes/sphinxcontrib-bibtex?branch=develop
+ :alt: coveralls.io
+
+.. |downloads| image:: https://pypip.in/d/sphinxcontrib-bibtex/badge.png
+ :target: http://pypi.python.org/pypi/sphinxcontrib-bibtex/
+ :alt: downloads
+
+.. |version| image:: https://pypip.in/v/sphinxcontrib-bibtex/badge.png
+ :target: http://pypi.python.org/pypi/sphinxcontrib-bibtex/
+ :alt: latest version
+
+.. |license| image:: https://pypip.in/license/sphinxcontrib-bibtex/badge.png
+ :target: http://pypi.python.org/pypi/sphinxcontrib-bibtex/
+ :alt: license
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..d15723f
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.3.2
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..6419911
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/sphinxcontrib-bibtex.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/sphinxcontrib-bibtex.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/sphinxcontrib-bibtex"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/sphinxcontrib-bibtex"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/doc/api.rst b/doc/api.rst
new file mode 100644
index 0000000..a6c8861
--- /dev/null
+++ b/doc/api.rst
@@ -0,0 +1,12 @@
+Extension API
+~~~~~~~~~~~~~
+
+.. toctree::
+ :maxdepth: 2
+
+ api/interface
+ api/roles
+ api/nodes
+ api/directives
+ api/transforms
+ api/cache
diff --git a/doc/api/cache.rst b/doc/api/cache.rst
new file mode 100644
index 0000000..cf5673a
--- /dev/null
+++ b/doc/api/cache.rst
@@ -0,0 +1 @@
+.. automodule:: sphinxcontrib.bibtex.cache
diff --git a/doc/api/directives.rst b/doc/api/directives.rst
new file mode 100644
index 0000000..778d5e2
--- /dev/null
+++ b/doc/api/directives.rst
@@ -0,0 +1 @@
+.. automodule:: sphinxcontrib.bibtex.directives
diff --git a/doc/api/interface.rst b/doc/api/interface.rst
new file mode 100644
index 0000000..7f50f05
--- /dev/null
+++ b/doc/api/interface.rst
@@ -0,0 +1 @@
+.. automodule:: sphinxcontrib.bibtex
diff --git a/doc/api/nodes.rst b/doc/api/nodes.rst
new file mode 100644
index 0000000..eb62f79
--- /dev/null
+++ b/doc/api/nodes.rst
@@ -0,0 +1 @@
+.. automodule:: sphinxcontrib.bibtex.nodes
diff --git a/doc/api/roles.rst b/doc/api/roles.rst
new file mode 100644
index 0000000..c601028
--- /dev/null
+++ b/doc/api/roles.rst
@@ -0,0 +1 @@
+.. automodule:: sphinxcontrib.bibtex.roles
diff --git a/doc/api/transforms.rst b/doc/api/transforms.rst
new file mode 100644
index 0000000..8937b3e
--- /dev/null
+++ b/doc/api/transforms.rst
@@ -0,0 +1 @@
+.. automodule:: sphinxcontrib.bibtex.transforms
diff --git a/doc/changes.rst b/doc/changes.rst
new file mode 100644
index 0000000..2eb28cc
--- /dev/null
+++ b/doc/changes.rst
@@ -0,0 +1,7 @@
+:tocdepth: 1
+
+Changes
+=======
+
+.. include:: ../CHANGELOG.rst
+
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 0000000..d25ab99
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,248 @@
+# -*- coding: utf-8 -*-
+#
+# sphinxcontrib-bibtex documentation build configuration file, created by
+# sphinx-quickstart on Thu Jun 13 13:56:25 2013.
+#
+# This file is execfile()d with the current directory set to its containing
+# dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+# -- General configuration -----------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.doctest',
+ 'sphinx.ext.intersphinx',
+ 'sphinx.ext.todo',
+ 'sphinx.ext.coverage',
+ 'sphinx.ext.pngmath',
+ 'sphinx.ext.viewcode']
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'sphinxcontrib-bibtex'
+copyright = u'2011-2014, Matthias C. M. Troffaes'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The full version, including alpha/beta/rc tags.
+with open("../VERSION", "rt") as version_file:
+ release = version_file.read().strip()
+# The short X.Y version.
+version = '.'.join(release.split('.')[:2])
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+# language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+# today = ''
+# Else, today_fmt is used as the format for a strftime call.
+# today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+# default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+# add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+# add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+# show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+# modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+# html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+# html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+# html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+# html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+# html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+# html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+# html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+# html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+# html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+# html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+# html_additional_pages = {}
+
+# If false, no module index is generated.
+# html_domain_indices = True
+
+# If false, no index is generated.
+# html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+# html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+# html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+# html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+# html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+# html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+# html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'sphinxcontrib-bibtexdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ # 'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ # 'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ # 'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass
+# [howto/manual]).
+latex_documents = [
+ ('index', 'sphinxcontrib-bibtex.tex',
+ u'sphinxcontrib-bibtex Documentation',
+ u'Matthias C. M. Troffaes', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+# latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+# latex_use_parts = False
+
+# If true, show page references after internal links.
+# latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+# latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+# latex_appendices = []
+
+# If false, no module index is generated.
+# latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'sphinxcontrib-bibtex', u'sphinxcontrib-bibtex Documentation',
+ [u'Matthias C. M. Troffaes'], 1)
+]
+
+# If true, show URL addresses after external links.
+# man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'sphinxcontrib-bibtex', u'sphinxcontrib-bibtex Documentation',
+ u'Matthias C. M. Troffaes', 'sphinxcontrib-bibtex',
+ 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+# texinfo_appendices = []
+
+# If false, no module index is generated.
+# texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+# texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+# texinfo_no_detailmenu = False
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {
+ 'python': ('http://docs.python.org/', None),
+ 'sphinx': ('http://sphinx.pocoo.org/', None),
+}
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 0000000..d463c3e
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,26 @@
+Welcome to sphinxcontrib-bibtex's documentation!
+================================================
+
+:Release: |release|
+:Date: |today|
+
+Contents
+--------
+
+.. toctree::
+ :maxdepth: 2
+
+ quickstart
+ usage
+ api
+ changes
+ license
+ related
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/doc/license.rst b/doc/license.rst
new file mode 100644
index 0000000..fbf968e
--- /dev/null
+++ b/doc/license.rst
@@ -0,0 +1,5 @@
+License
+=======
+
+.. include:: ../LICENSE.rst
+
diff --git a/doc/make.bat b/doc/make.bat
new file mode 100644
index 0000000..e8894e4
--- /dev/null
+++ b/doc/make.bat
@@ -0,0 +1,190 @@
+ at ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+set I18NSPHINXOPTS=%SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\sphinxcontrib-bibtex.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\sphinxcontrib-bibtex.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+:end
diff --git a/doc/quickstart.rst b/doc/quickstart.rst
new file mode 100644
index 0000000..d8680a8
--- /dev/null
+++ b/doc/quickstart.rst
@@ -0,0 +1,13 @@
+Getting Started
+===============
+
+Overview
+--------
+
+.. include:: ../README.rst
+ :start-line: 5
+
+Installation
+------------
+
+.. include:: ../INSTALL.rst
diff --git a/doc/related.rst b/doc/related.rst
new file mode 100644
index 0000000..29f4ca1
--- /dev/null
+++ b/doc/related.rst
@@ -0,0 +1,27 @@
+Related Projects
+================
+
+Below is a list of projects which include functionality that is
+similar or related to sphinxcontrib-bibtex.
+If you know of any other, leave a message on the issue tracker.
+
+* Andrey Golovizin's `pybtex <http://pybtex.sourceforge.net/>`_,
+ a general purpose Python library for working with bibtex files.
+ Drives sphinxcontrib-bibtex.
+
+* Matthew Brett's `bibstuff <https://github.com/matthew-brett/bibstuff>`_.
+ Includes a Sphinx extension similar to sphinxcontrib-bibtex,
+ as well as an assorted collection of bibtex tools.
+ This is a fork of Dylan W. Schwilk and Alan G. Isaac's
+ `bibstuff on google code <https://code.google.com/p/bibstuff/>`_
+ which is apparently no longer maintained.
+
+* wnielson's
+ `sphinx-natbib <https://bitbucket.org/wnielson/sphinx-natbib>`_.
+ Similar to sphinxcontrib-bibtex but appears to be stalled in alpha stage.
+ Interestingly, supports natbib-style citations.
+ Apparently no longer maintained.
+
+* Jeff Terrace's Sphinx Thesis Resource
+ `sphinxtr <https://github.com/jterrace/sphinxtr>`_,
+ a fork of Sphinx which includes a fork of sphinx-natbib.
diff --git a/doc/usage.rst b/doc/usage.rst
new file mode 100644
index 0000000..7def6c3
--- /dev/null
+++ b/doc/usage.rst
@@ -0,0 +1,462 @@
+Usage
+=====
+
+Roles and Directives
+--------------------
+
+.. rst:role:: cite
+
+ Create a citation to a bibliographic entry. For example:
+
+ .. code-block:: rest
+
+ See :cite:`1987:nelson` for an introduction to non-standard analysis.
+
+ which would be equivalent to the following LaTeX code:
+
+ .. code-block:: latex
+
+ See \cite{1987:nelson} for an introduction to non-standard analysis.
+
+ Multiple comma-separated keys can be specified at once:
+
+ .. code-block:: rest
+
+ See :cite:`1987:nelson,2001:schechter`.
+
+ .. note::
+
+ Due to a docutils implementation detail, Sphinx's LaTeX backend
+ will not actually generate ``\cite`` commands. Instead, all
+ references, including citation references, are managed using
+ ``\hyperref`` and ``\label`` commands.
+ See https://github.com/mcmtroffaes/sphinxcontrib-bibtex/issues/10
+
+.. rst:directive:: .. bibliography:: refs.bib [...]
+
+ Create bibliography for all cited references. The ``all`` flag
+ forces all references to be included (equivalent to ``\nocite{*}``
+ in LaTeX). The ``notcited`` flag causes all references that were
+ not cited to be included. The ``cited`` flag is recognized as well
+ but is entirely optional. For example:
+
+ .. code-block:: rest
+
+ .. rubric:: References
+
+ .. bibliography:: refs.bib
+ :cited:
+
+ which would be roughly equivalent to the following LaTeX code:
+
+ .. code-block:: latex
+
+ \begin{thebibliography}{1}
+ \bibitem{1987:nelson}
+ Edward~Nelson
+ \newblock {\em Radically Elementary Probability Theory}.
+ \newblock Princeton University Press, 1987.
+ \end{thebibliography}
+
+ Note that, unlike LaTeX, the :rst:dir:`bibliography` directive does
+ not generate a default section title.
+
+ .. warning::
+
+ Sphinx may not be able to create an entry for :rst:role:`cite` keys
+ when your :rst:dir:`bibliography` directive
+ resides in a different document;
+ see :ref:`issue-unresolved-citations`
+ for more information and workarounds.
+
+ You can also pick a bibliography style, using the ``style`` option.
+ The ``alpha`` style is the default.
+ Other supported styles are ``plain``, ``unsrt``, and ``unsrtalpha``.
+
+ .. code-block:: rest
+
+ .. bibliography:: refs.bib
+ :style: unsrt
+
+ .. warning::
+
+ Sphinx will attempt to resolve references to the bibliography
+ across all documents, so you must take care that no citation key
+ is included more than once.
+
+ You can also set the encoding of the bibliography files, using the
+ ``encoding`` option.
+
+ .. code-block:: rest
+
+ .. bibliography:: refs.bib
+ :encoding: latex+latin
+
+ Note that, usually, you want to prepend your encoding with
+ ``latex+``, in order to convert LaTeX control characters to unicode
+ characters (for instance, to convert ``\'e`` into ``é``). The latex
+ codec is invoked by default, for your convenience. Be sure to write
+ ``\%`` when you intend to format a percent sign.
+
+.. XXX not documenting disable-curly-bracket-strip for now; might remove it
+
+ Finally, curly brackets are automatically removed when the bib file
+ is parsed. Usually, this is what you want. If you desire to disable
+ this behaviour, use the ``disable-curly-bracket-strip`` option:
+
+ .. code-block:: rest
+
+ .. bibliography:: refs.bib
+ :disable-curly-bracket-strip:
+
+Advanced Features
+-----------------
+
+Bullet Lists and Enumerated Lists
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 0.2.4
+
+You can change the type of list used for rendering the
+bibliography. By default, a paragraph of standard citations is
+generated. However, instead, you can also generate a bullet list,
+or an enumerated list.
+
+.. code-block:: rest
+
+ .. bibliography:: refs1.bib
+ :list: bullet
+ :all:
+
+ .. bibliography:: refs2.bib
+ :list: enumerated
+ :all:
+
+Note that citations to these types of bibliography lists will not
+be resolved.
+
+For enumerated lists, you can also specify the type (default is
+``arabic``), and the start of the sequence (default is ``1``).
+
+.. code-block:: rest
+
+ .. bibliography:: refs2.bib
+ :list: enumerated
+ :enumtype: upperroman
+ :start: 3
+ :all:
+
+The enumtype can be any of
+``arabic`` (1, 2, 3, ...),
+``loweralpha`` (a, b, c, ...),
+``upperalpha`` (A, B, C, ...),
+``lowerroman`` (i, ii, iii, ...), or
+``upperroman`` (I, II, III, ...).
+
+The start can be any positive integer (1, 2, 3, ...) or
+``continue`` if you wish the enumeration to continue from the last
+:rst:dir:`bibliography` directive.
+This is helpful if you split up your bibliography but
+still want to enumerate the entries continuously.
+
+Label Prefixing
+~~~~~~~~~~~~~~~
+
+.. versionadded:: 0.2.5
+
+If you have multiple bibliographies, and experience duplicate labels,
+use the ``labelprefix`` option.
+
+.. code-block:: rest
+
+ .. rubric:: References
+
+ .. bibliography:: refs.bib
+ :cited:
+ :labelprefix: A
+
+ .. rubric:: Further reading
+
+ .. bibliography:: refs.bib
+ :notcited:
+ :labelprefix: B
+
+Filtering
+~~~~~~~~~
+
+.. versionadded:: 0.2.7
+
+Whilst the ``cited``, ``all``, and ``notcited`` options
+will cover many use cases,
+sometimes more advanced selection of bibliographic entries is desired.
+For this purpose, you can use the ``filter`` option:
+
+.. code-block:: rest
+
+ .. bibliography:: refs.bib
+ :list: bullet
+ :filter: author % "Einstein"
+
+The string specified in the filter option must be a valid Python
+expression.
+
+.. note::
+
+ The expression is parsed using :func:`ast.parse`
+ and then evaluated using an :class:`ast.NodeVisitor`,
+ so it should be reasonably safe against malicious code.
+
+The filter expression supports:
+
+* The boolean operators ``and``, ``or``.
+
+* The unary operator ``not``.
+
+* The comparison operators ``==``, ``<=``, ``<``, ``>=``, and ``>``.
+
+* Regular expression matching using the ``%`` operator, where the left
+ hand side is the string to be matched, and the right hand side is
+ the regular expression. Matching is case insensitive. For example:
+
+ .. code-block:: rest
+
+ .. bibliography:: refs.bib
+ :list: bullet
+ :filter: title % "relativity"
+
+ would include all entries that have the word "relativity" in the title.
+
+ .. note::
+
+ The implementation uses :func:`re.search`.
+
+* Single and double quoted strings, such as ``'hello'`` or ``"world"``.
+
+* Set literals, such has ``{"hello", "world"}``, as well as
+ the set operators ``&``, ``|``, ``in``, and ``not in``.
+
+ .. versionadded:: 0.3.0
+
+* Various identifiers, such as:
+
+ - ``type`` is the entry type, as a lower case string
+ (i.e. ``"inproceedings"``).
+
+ - ``key`` is the entry key, as a lower case string
+ (this is because keys are considered case insensitive).
+
+ - ``cited`` evaluates to ``True`` if the entry was cited in the document,
+ and to ``False`` otherwise.
+
+ - ``docname`` evaluates to the name of the current document.
+
+ .. versionadded:: 0.3.0
+
+ - ``docnames`` evaluates to a set of names from which the entry is cited.
+
+ .. versionadded:: 0.3.0
+
+ - ``True`` and ``False``.
+
+ - ``author`` is the entry string of authors
+ in standard format (last, first), separated by "and".
+
+ - ``editor`` is similar to ``author`` but for editors.
+
+ - Any other (lower case) identifier evaluates to a string
+ containing the value of
+ the correspondingly named field, such as
+ ``title``, ``publisher``, ``year``, and so on.
+ If the item is missing in the entry
+ then it evaluates to the empty string.
+ Here is an example of how one would typically write an expression
+ to filter on an optional field:
+
+ .. code-block:: rest
+
+ .. bibliography:: refs.bib
+ :list: bullet
+ :filter: cited and year and (year <= "2003")
+
+ which would include all cited entries that have a year
+ that is less or equal than 2003; any entries that do not
+ specify a year would be omitted.
+
+Local Bibliographies
+~~~~~~~~~~~~~~~~~~~~
+
+To create a bibliography that includes only citations that were cited
+in the current document, use the following filter:
+
+.. code-block:: rest
+
+ .. bibliography:: refs.bib
+ :filter: docname in docnames
+
+More generally, you can create bibliographies for
+citations that were cited from specific documents only:
+
+.. code-block:: rest
+
+ .. bibliography:: refs.bib
+ :filter: {"doc1", "doc2"} & docnames
+
+This bibliography will include all citations that were cited from
+:file:`doc1.rst` or :file:`doc2.rst`. Another hypothetical example:
+
+.. code-block:: rest
+
+ .. bibliography:: refs.bib
+ :filter: cited and ({"doc1", "doc2"} >= docnames)
+
+This bibliography will include all citations that were cited
+in :file:`doc1.rst` or :file:`doc2.rst`, but nowhere else.
+
+Custom Formatting, Sorting, and Labelling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:mod:`pybtex` provides a very powerful way to create and register new
+styles, using setuptools entry points,
+as documented here: http://pybtex.sourceforge.net/plugins.html
+
+Simply add the following code to your ``conf.py``:
+
+.. code-block:: python
+
+ from pybtex.style.formatting.unsrt import Style as UnsrtStyle
+ from pybtex.style.template import toplevel # ... and anything else needed
+ from pybtex.plugin import register_plugin
+
+ class MyStyle(UnsrtStyle):
+
+ def format_XXX(self, e):
+ template = toplevel [
+ # etc.
+ ]
+ return template.format_data(e)
+
+ register_plugin('pybtex.style.formatting', 'mystyle', MyStyle)
+
+Now ``mystyle`` will be available to you as a formatting style:
+
+.. code-block:: rest
+
+ .. bibliography:: refs.bib
+ :style: mystyle
+
+An minimal example is available here:
+https://github.com/mcmtroffaes/sphinxcontrib-bibtex/tree/develop/test/custom_style
+
+The formatting code uses a very intuitive template engine.
+The source code for ``unsrt`` provides many great examples:
+http://bazaar.launchpad.net/~pybtex-devs/pybtex/trunk/view/head:/pybtex/style/formatting/unsrt.py
+
+The above example only demonstrates a custom formatting style plugin.
+It is also possible to register custom author/editor naming plugins
+(using the ``pybtex.style.names`` group)
+labelling plugins
+(using the ``pybtex.style.labels`` group),
+and sorting plugins
+(using the ``pybtex.style.sorting`` group).
+A minimal example demonstrating how to create a custom label style
+is available here:
+https://github.com/mcmtroffaes/sphinxcontrib-bibtex/tree/develop/test/issue77
+
+Known Issues and Workarounds
+----------------------------
+
+Tinkerer
+~~~~~~~~
+
+To use the bibtex extension with `Tinkerer <http://www.tinkerer.me/>`_,
+be sure to specify the bibtex extension first in your ``conf.py`` file::
+
+ extensions = ['sphinxcontrib.bibtex', 'tinkerer.ext.blog', 'tinkerer.ext.disqus']
+
+Encoding: Percent Signs
+~~~~~~~~~~~~~~~~~~~~~~~
+
+When using the LaTeX codec (which is by default), be sure to write
+``\%`` for percent signs at all times (unless your file contains a
+genuine comment), otherwise the bibtex lexer will ignore the remainder
+of the line.
+
+If you don't want any LaTeX symbols to be reinterpreted as unicode,
+use the option ``:encoding: utf`` (without the ``latex+`` prefix).
+
+.. _issue-unresolved-citations:
+
+Unresolved Citations Across Documents
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you cite something that has its bibliography in another document,
+then, at the moment, the extension may, or may not, realise that it
+has to add this citation.
+There are a few ways to work around this problem:
+
+* Use the option ``:all:`` in the :rst:dir:`bibliography`
+ directive (which will simply cause all entries to be included).
+
+* Ensure that the :rst:dir:`bibliography` directive is processed after
+ all :rst:role:`cite`\ s. Sphinx appears to process files in an
+ alphabetical manner. For instance, in case you have only one file
+ containing a :rst:dir:`bibliography` directive, simply name that
+ file :file:`zreferences.rst`.
+
+Hopefully, this limitation can be lifted in a future release.
+
+Duplicate Labels When Using ``:style: plain``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+With ``:style: plain``, labels are numerical,
+restarting at ``[1]`` for each :rst:dir:`bibliography` directive.
+Consequently, when inserting multiple :rst:dir:`bibliography` directives
+with ``:style: plain``,
+you are bound to get duplicate labels for entries.
+There are a few ways to work around this problem:
+
+* Use a single bibliography directive for all your references.
+
+* Use the ``labelprefix`` option, as documented above.
+
+* Use a style that has non-numerical labelling,
+ such as ``:style: alpha``.
+
+Citation Links Broken When Using LaTeX Backend
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is a known bug in Sphinx's latex writer,
+which has been fixed upstream:
+
+https://bitbucket.org/birkenfeld/sphinx/pull-request/171
+
+https://bitbucket.org/birkenfeld/sphinx/pull-request/173
+
+Mismatch Between Output of HTML and LaTeX Backends
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sphinx's LaTeX writer currently collects all citations together,
+and puts them on a separate page, with a separate title,
+whereas the html writer puts citations
+at the location where they are defined.
+This issue will occur also if you use regular citations in Sphinx:
+it has nothing to do with sphinxcontrib-bibtex per se.
+
+To get a closer match between the two outputs,
+you can tell Sphinx to generate a rubric title only for html:
+
+.. code-block:: rest
+
+ .. only:: html
+
+ .. rubric:: References
+
+ .. bibliography:: refs.bib
+
+This code could be placed in your :file:`zreferences.rst`.
+
+The current aim is to fix Sphinx's LaTeX writer
+to match the html output more closely.
+The issue is tracked here:
+
+https://github.com/mcmtroffaes/sphinxcontrib-bibtex/issues/48
diff --git a/release_checklist.txt b/release_checklist.txt
new file mode 100644
index 0000000..e25f821
--- /dev/null
+++ b/release_checklist.txt
@@ -0,0 +1,40 @@
+* git checkout -b release/x.x.x
+* VERSION: set final version
+* CHANGELOG.rst:
+ - set release date
+ - all important changes are documented
+* doc:
+ - all new features are properly documented
+ - all new features have versionadded
+ - all workarounds are properly documented
+ - fixed workarounds are removed
+ - git clean -xfd
+ - python setup.py install --user && cd doc && make html
+* make pull request on github
+ - travis build passes
+ - coverage at 100%
+ - on github, merge release/x.x.x into develop and delete the release branch
+ - git remote update --prune && git checkout develop && git merge --ff-only origin/develop
+* create and register source zip
+ - git clean -xfd
+ - python setup.py register
+ - python setup.py sdist bdist_wheel upload
+* test upload
+ - pip uninstall sphinxcontrib-bibtex
+ - pip install --user -U sphinxcontrib-bibtex
+ - cd sphinxcontrib-bibtex/test
+ - nosetests
+* push release
+ - git checkout master && git merge --ff-only develop
+ - git tag -a -m "Tagging version x.x.x" x.x.x
+ - git push origin master
+ - git push --tags
+ - git checkout develop
+ - git branch -d release/x.x.x
+* activate new version on readthedocs.org
+* prep for next cycle
+ - git checkout develop
+ - VERSION: bump to x.x.xa0
+ - CHANGELOG.rst: bump to x.x.x (in development)
+ - git commit -a -m "Version bump. [ci skip]"
+ - git push origin develop
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..212ea41
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,7 @@
+latexcodec>=0.3.0
+pybtex>=0.17
+pybtex-docutils>=0.2.0
+six>=1.4.1
+Sphinx>=1.0
+oset>=0.1.3
+
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..4b28df6
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,8 @@
+[nosetests]
+with-coverage=1
+cover-package=sphinxcontrib.bibtex
+cover-branches=1
+cover-html=1
+
+[wheel]
+universal=1
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..44c7b3b
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+
+import io
+from setuptools import setup, find_packages
+import sys
+
+
+def readfile(filename):
+ with io.open(filename, encoding="utf-8") as stream:
+ return stream.read().split("\n")
+
+readme = readfile("README.rst")[5:] # skip title and badges
+requires = readfile("requirements.txt")
+version = readfile("VERSION")[0].strip()
+
+if sys.version_info < (2, 7):
+ requires.append('ordereddict>=1.1')
+
+setup(
+ name='sphinxcontrib-bibtex',
+ version=version,
+ url='https://github.com/mcmtroffaes/sphinxcontrib-bibtex',
+ download_url='http://pypi.python.org/pypi/sphinxcontrib-bibtex',
+ license='BSD',
+ author='Matthias C. M. Troffaes',
+ author_email='matthias.troffaes at gmail.com',
+ description=readme[0],
+ long_description="\n".join(readme[2:]),
+ zip_safe=False,
+ classifiers=[
+ 'Development Status :: 4 - Beta',
+ 'Environment :: Console',
+ 'Environment :: Web Environment',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: BSD License',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Programming Language :: Python :: Implementation :: PyPy',
+ 'Topic :: Documentation',
+ 'Topic :: Utilities',
+ ],
+ platforms='any',
+ packages=find_packages(),
+ include_package_data=True,
+ install_requires=requires,
+ namespace_packages=['sphinxcontrib'],
+)
diff --git a/sphinxcontrib/__init__.py b/sphinxcontrib/__init__.py
new file mode 100644
index 0000000..35d34fc
--- /dev/null
+++ b/sphinxcontrib/__init__.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinxcontrib
+ ~~~~~~~~~~~~~
+
+ This package is a namespace package that contains all extensions
+ distributed in the ``sphinx-contrib`` distribution.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+__import__('pkg_resources').declare_namespace(__name__)
diff --git a/sphinxcontrib/bibtex/__init__.py b/sphinxcontrib/bibtex/__init__.py
new file mode 100644
index 0000000..7477236
--- /dev/null
+++ b/sphinxcontrib/bibtex/__init__.py
@@ -0,0 +1,136 @@
+# -*- coding: utf-8 -*-
+"""
+ Sphinx Interface
+ ~~~~~~~~~~~~~~~~
+
+ .. autofunction:: setup
+ .. autofunction:: init_bibtex_cache
+ .. autofunction:: purge_bibtex_cache
+ .. autofunction:: process_citations
+ .. autofunction:: process_citation_references
+ .. autofunction:: check_duplicate_labels
+"""
+
+import docutils.nodes
+from sphinxcontrib.bibtex.cache import Cache
+from sphinxcontrib.bibtex.nodes import bibliography
+from sphinxcontrib.bibtex.roles import CiteRole
+from sphinxcontrib.bibtex.directives import BibliographyDirective
+from sphinxcontrib.bibtex.transforms import BibliographyTransform
+import six
+
+
+def init_bibtex_cache(app):
+ """Create ``app.env.bibtex_cache`` if it does not exist yet.
+
+ :param app: The sphinx application.
+ :type app: :class:`sphinx.application.Sphinx`
+ """
+ if not hasattr(app.env, "bibtex_cache"):
+ app.env.bibtex_cache = Cache()
+
+
+def purge_bibtex_cache(app, env, docname):
+ """Remove all information related to *docname* from the cache.
+
+ :param app: The sphinx application.
+ :type app: :class:`sphinx.application.Sphinx`
+ :param env: The sphinx build environment.
+ :type env: :class:`sphinx.environment.BuildEnvironment`
+ """
+ env.bibtex_cache.purge(docname)
+
+
+def process_citations(app, doctree, docname):
+ """Replace labels of citation nodes by actual labels.
+
+ :param app: The sphinx application.
+ :type app: :class:`sphinx.application.Sphinx`
+ :param doctree: The document tree.
+ :type doctree: :class:`docutils.nodes.document`
+ :param docname: The document name.
+ :type docname: :class:`str`
+ """
+ for node in doctree.traverse(docutils.nodes.citation):
+ key = node[0].astext()
+ try:
+ label = app.env.bibtex_cache.get_label_from_key(key)
+ except KeyError:
+ app.warn("could not relabel citation [%s]" % key)
+ else:
+ node[0] = docutils.nodes.label('', label)
+
+
+def process_citation_references(app, doctree, docname):
+ """Replace text of citation reference nodes by actual labels.
+
+ :param app: The sphinx application.
+ :type app: :class:`sphinx.application.Sphinx`
+ :param doctree: The document tree.
+ :type doctree: :class:`docutils.nodes.document`
+ :param docname: The document name.
+ :type docname: :class:`str`
+ """
+ # sphinx has already turned citation_reference nodes
+ # into reference nodes, so iterate over reference nodes
+ for node in doctree.traverse(docutils.nodes.reference):
+ # exclude sphinx [source] labels
+ if isinstance(node[0], docutils.nodes.Element):
+ if 'viewcode-link' in node[0]['classes']:
+ continue
+ text = node[0].astext()
+ if text.startswith('[') and text.endswith(']'):
+ key = text[1:-1]
+ try:
+ label = app.env.bibtex_cache.get_label_from_key(key)
+ except KeyError:
+ app.warn("could not relabel citation reference [%s]" % key)
+ else:
+ node[0] = docutils.nodes.Text('[' + label + ']')
+
+
+def check_duplicate_labels(app, env):
+ """Check and warn about duplicate citation labels.
+
+ :param app: The sphinx application.
+ :type app: :class:`sphinx.application.Sphinx`
+ :param env: The sphinx build environment.
+ :type env: :class:`sphinx.environment.BuildEnvironment`
+ """
+ label_to_key = {}
+ for info in env.bibtex_cache.get_all_bibliography_caches():
+ for key, label in six.iteritems(info.labels):
+ if label in label_to_key:
+ app.warn(
+ "duplicate label for keys %s and %s"
+ % (key, label_to_key[label]))
+ else:
+ label_to_key[label] = key
+
+
+def setup(app):
+ """Set up the bibtex extension:
+
+ * register directives
+ * register nodes
+ * register roles
+ * register transforms
+ * connect events to functions
+
+ :param app: The sphinx application.
+ :type app: :class:`sphinx.application.Sphinx`
+ """
+
+ app.add_directive("bibliography", BibliographyDirective)
+ app.add_role("cite", CiteRole())
+ app.add_node(bibliography)
+ app.add_transform(BibliographyTransform)
+ app.connect("builder-inited", init_bibtex_cache)
+ app.connect("doctree-resolved", process_citations)
+ app.connect("doctree-resolved", process_citation_references)
+ app.connect("env-purge-doc", purge_bibtex_cache)
+ app.connect("env-updated", check_duplicate_labels)
+ # Parallel read is not safe at the moment: in the current design,
+ # the document that contains references must be read last for all
+ # references to be resolved.
+ return {'parallel_read_safe': False}
diff --git a/sphinxcontrib/bibtex/cache.py b/sphinxcontrib/bibtex/cache.py
new file mode 100644
index 0000000..0f1b32a
--- /dev/null
+++ b/sphinxcontrib/bibtex/cache.py
@@ -0,0 +1,393 @@
+# -*- coding: utf-8 -*-
+"""
+ Cached Information
+ ~~~~~~~~~~~~~~~~~~
+
+ Classes and methods to maintain any information that is stored
+ outside the doctree.
+
+ .. autoclass:: Cache
+ :members:
+
+ .. autoclass:: BibfileCache
+ :members:
+
+ .. autoclass:: BibliographyCache
+ :members:
+"""
+
+import sys
+import six
+if sys.version_info < (2, 7): # pragma: no cover
+ from ordereddict import OrderedDict
+else: # pragma: no cover
+ from collections import OrderedDict
+
+import ast
+import collections
+import copy
+from oset import oset
+import re
+
+
+def _raise_invalid_node(node):
+ """Helper method to raise an exception when an invalid node is
+ visited.
+ """
+ raise ValueError("invalid node %s in filter expression" % node)
+
+
+class _FilterVisitor(ast.NodeVisitor):
+
+ """Visit the abstract syntax tree of a parsed filter expression."""
+
+ entry = None
+ """The bibliographic entry to which the filter must be applied."""
+
+ cited_docnames = False
+ """The documents where the entry is cited (empty if not cited)."""
+
+ def __init__(self, entry, docname, cited_docnames):
+ self.entry = entry
+ self.docname = docname
+ self.cited_docnames = cited_docnames
+
+ def visit_Module(self, node):
+ if len(node.body) != 1:
+ raise ValueError(
+ "filter expression cannot contain multiple expressions")
+ return self.visit(node.body[0])
+
+ def visit_Expr(self, node):
+ return self.visit(node.value)
+
+ def visit_BoolOp(self, node):
+ outcomes = (self.visit(value) for value in node.values)
+ if isinstance(node.op, ast.And):
+ return all(outcomes)
+ elif isinstance(node.op, ast.Or):
+ return any(outcomes)
+ else: # pragma: no cover
+ # there are no other boolean operators
+ # so this code should never execute
+ assert False, "unexpected boolean operator %s" % node.op
+
+ def visit_UnaryOp(self, node):
+ if isinstance(node.op, ast.Not):
+ return not self.visit(node.operand)
+ else:
+ _raise_invalid_node(node)
+
+ def visit_BinOp(self, node):
+ left = self.visit(node.left)
+ op = node.op
+ right = self.visit(node.right)
+ if isinstance(op, ast.Mod):
+ # modulo operator is used for regular expression matching
+ if not isinstance(left, six.string_types):
+ raise ValueError(
+ "expected a string on left side of %s" % node.op)
+ if not isinstance(right, six.string_types):
+ raise ValueError(
+ "expected a string on right side of %s" % node.op)
+ return re.search(right, left, re.IGNORECASE)
+ elif isinstance(op, ast.BitOr):
+ return left | right
+ elif isinstance(op, ast.BitAnd):
+ return left & right
+ else:
+ _raise_invalid_node(node)
+
+ def visit_Compare(self, node):
+ # keep it simple: binary comparators only
+ if len(node.ops) != 1:
+ raise ValueError("syntax for multiple comparators not supported")
+ left = self.visit(node.left)
+ op = node.ops[0]
+ right = self.visit(node.comparators[0])
+ if isinstance(op, ast.Eq):
+ return left == right
+ elif isinstance(op, ast.NotEq):
+ return left != right
+ elif isinstance(op, ast.Lt):
+ return left < right
+ elif isinstance(op, ast.LtE):
+ return left <= right
+ elif isinstance(op, ast.Gt):
+ return left > right
+ elif isinstance(op, ast.GtE):
+ return left >= right
+ elif isinstance(op, ast.In):
+ return left in right
+ elif isinstance(op, ast.NotIn):
+ return left not in right
+ else:
+ # not used currently: ast.Is | ast.IsNot
+ _raise_invalid_node(op)
+
+ def visit_Name(self, node):
+ """Calculate the value of the given identifier."""
+ id_ = node.id
+ if id_ == 'type':
+ return self.entry.type.lower()
+ elif id_ == 'key':
+ return self.entry.key.lower()
+ elif id_ == 'cited':
+ return bool(self.cited_docnames)
+ elif id_ == 'docname':
+ return self.docname
+ elif id_ == 'docnames':
+ return self.cited_docnames
+ elif id_ == 'True':
+ return True
+ elif id_ == 'False':
+ return False
+ elif id_ == 'author' or id_ == 'editor':
+ if id_ in self.entry.persons:
+ return u' and '.join(
+ six.text_type(person) # XXX needs fix in pybtex?
+ for person in self.entry.persons[id_])
+ else:
+ return u''
+ else:
+ return self.entry.fields.get(id_, "")
+
+ def visit_Set(self, node):
+ return frozenset(self.visit(elt) for elt in node.elts)
+
+ def visit_Str(self, node):
+ return node.s
+
+ # NameConstant is Python 3.4 only so do not insist on coverage
+ def visit_NameConstant(self, node): # pragma: no cover
+ return node.value
+
+ def generic_visit(self, node):
+ _raise_invalid_node(node)
+
+
+class Cache:
+
+ """Global bibtex extension information cache. Stored in
+ ``app.env.bibtex_cache``, so must be picklable.
+ """
+
+ bibfiles = None
+ """A :class:`dict` mapping .bib file names (relative to the top
+ source folder) to :class:`BibfileCache` instances.
+ """
+
+ _bibliographies = None
+ """Each bibliography directive is assigned an id of the form
+ bibtex-bibliography-xxx. This :class:`dict` maps each docname
+ to another :class:`dict` which maps each id
+ to information about the bibliography directive,
+ :class:`BibliographyCache`. We need to store this extra
+ information separately because it cannot be stored in the
+ :class:`~sphinxcontrib.bibtex.nodes.bibliography` nodes
+ themselves.
+ """
+
+ _cited = None
+ """A :class:`dict` mapping each docname to a :class:`set` of
+ citation keys.
+ """
+
+ _enum_count = None
+ """A :class:`dict` mapping each docname to an :class:`int`
+ representing the current bibliography enumeration counter.
+ """
+
+ def __init__(self):
+
+ self.bibfiles = {}
+ self._bibliographies = collections.defaultdict(dict)
+ self._cited = collections.defaultdict(oset)
+ self._enum_count = {}
+
+ def purge(self, docname):
+ """Remove all information related to *docname*.
+
+ :param docname: The document name.
+ :type docname: :class:`str`
+ """
+ self._bibliographies.pop(docname, None)
+ self._cited.pop(docname, None)
+ self._enum_count.pop(docname, None)
+
+ def inc_enum_count(self, docname):
+ """Increment enumeration list counter for document *docname*."""
+ self._enum_count[docname] += 1
+
+ def set_enum_count(self, docname, value):
+ """Set enumeration list counter for document *docname* to *value*."""
+ self._enum_count[docname] = value
+
+ def get_enum_count(self, docname):
+ """Get enumeration list counter for document *docname*."""
+ return self._enum_count[docname]
+
+ def add_cited(self, key, docname):
+ """Add the given *key* to the set of cited keys for
+ *docname*.
+
+ :param key: The citation key.
+ :type key: :class:`str`
+ :param docname: The document name.
+ :type docname: :class:`str`
+ """
+ self._cited[docname].add(key)
+
+ def get_cited_docnames(self, key):
+ """Return the *docnames* from which the given *key* is cited.
+
+ :param key: The citation key.
+ :type key: :class:`str`
+ """
+ return frozenset([
+ docname for docname, keys in six.iteritems(self._cited)
+ if key in keys])
+
+ def get_label_from_key(self, key):
+ """Return label for the given key."""
+ for bibcache in self.get_all_bibliography_caches():
+ if key in bibcache.labels:
+ return bibcache.labels[key]
+ else:
+ raise KeyError("%s not found" % key)
+
+ def get_all_cited_keys(self):
+ """Yield all citation keys, sorted first by document
+ (alphabetical), then by citation order in the document.
+ """
+ for docname in sorted(self._cited):
+ for key in self._cited[docname]:
+ yield key
+
+ def set_bibliography_cache(self, docname, id_, bibcache):
+ """Register *bibcache* (:class:`BibliographyCache`)
+ with id *id_* for document *docname*.
+ """
+ assert id_ not in self._bibliographies[docname]
+ self._bibliographies[docname][id_] = bibcache
+
+ def get_bibliography_cache(self, docname, id_):
+ """Return :class:`BibliographyCache` with id *id_* in
+ document *docname*.
+ """
+ return self._bibliographies[docname][id_]
+
+ def get_all_bibliography_caches(self):
+ """Return all bibliography caches."""
+ for bibcaches in six.itervalues(self._bibliographies):
+ for bibcache in six.itervalues(bibcaches):
+ yield bibcache
+
+ def _get_bibliography_entries(self, docname, id_, warn):
+ """Return filtered bibliography entries, sorted by occurence
+ in the bib file.
+ """
+ # get the information of this bibliography node
+ bibcache = self.get_bibliography_cache(docname=docname, id_=id_)
+ # generate entries
+ 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)
+ visitor = _FilterVisitor(
+ entry=entry,
+ docname=docname,
+ cited_docnames=cited_docnames)
+ try:
+ success = visitor.visit(bibcache.filter_)
+ except ValueError as err:
+ warn("syntax error in :filter: expression; %s" % err)
+ # recover by falling back to the default
+ success = bool(cited_docnames)
+ if success:
+ # entries are modified in an unpickable way
+ # when formatting, so fetch a deep copy
+ yield copy.deepcopy(entry)
+
+ def get_bibliography_entries(self, docname, id_, warn):
+ """Return filtered bibliography entries, sorted by citation order."""
+ # get entries, ordered by bib file occurrence
+ entries = OrderedDict(
+ (entry.key, entry) for entry in
+ self._get_bibliography_entries(
+ docname=docname, id_=id_, warn=warn))
+ # order entries according to which were cited first
+ # first, we add all keys that were cited
+ # then, we add all remaining keys
+ sorted_entries = []
+ for key in self.get_all_cited_keys():
+ try:
+ entry = entries.pop(key)
+ except KeyError:
+ pass
+ else:
+ sorted_entries.append(entry)
+ sorted_entries += six.itervalues(entries)
+ return sorted_entries
+
+
+class BibfileCache(collections.namedtuple('BibfileCache', 'mtime data')):
+
+ """Contains information about a parsed .bib file.
+
+ .. attribute:: mtime
+
+ A :class:`float` representing the modification time of the .bib
+ file when it was last parsed.
+
+ .. attribute:: data
+
+ A :class:`pybtex.database.BibliographyData` containing the
+ parsed .bib file.
+
+ """
+
+
+class BibliographyCache(collections.namedtuple(
+ 'BibliographyCache',
+ """bibfiles style encoding
+list_ enumtype start labels labelprefix
+filter_ curly_bracket_strip
+""")):
+
+ """Contains information about a bibliography directive.
+
+ .. attribute:: bibfiles
+
+ A :class:`list` of :class:`str`\\ s containing the .bib file
+ names (relative to the top source folder) that contain the
+ references.
+
+ .. attribute:: style
+
+ The bibtex style.
+
+ .. attribute:: list_
+
+ The list type.
+
+ .. attribute:: enumtype
+
+ The sequence type (only used for enumerated lists).
+
+ .. attribute:: start
+
+ The first ordinal of the sequence (only used for enumerated lists).
+
+ .. attribute:: labels
+
+ Maps citation keys to their final labels.
+
+ .. attribute:: labelprefix
+
+ This bibliography's string prefix for pybtex generated labels.
+
+ .. attribute:: filter_
+
+ An :class:`ast.AST` node, containing the parsed filter expression.
+ """
diff --git a/sphinxcontrib/bibtex/directives.py b/sphinxcontrib/bibtex/directives.py
new file mode 100644
index 0000000..8d6927d
--- /dev/null
+++ b/sphinxcontrib/bibtex/directives.py
@@ -0,0 +1,218 @@
+"""
+ New Doctree Directives
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ .. autoclass:: BibliographyDirective
+
+ .. automethod:: run
+ .. automethod:: process_bibfile
+ .. automethod:: update_bibfile_cache
+ .. automethod:: parse_bibfile
+
+ .. autofunction:: process_start_option
+"""
+
+import ast # parse(), used for filter
+import os.path # getmtime()
+
+from docutils.parsers.rst import directives # for Directive.option_spec
+from sphinx.util.compat import Directive
+from sphinx.util.console import bold, standout
+
+from pybtex.database.input import bibtex
+from pybtex.database import BibliographyData
+
+from sphinxcontrib.bibtex.cache import BibliographyCache, BibfileCache
+from sphinxcontrib.bibtex.nodes import bibliography
+
+# register the latex codec
+import latexcodec # noqa
+
+
+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)
+
+
+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 = 1
+ optional_arguments = 0
+ 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,
+ 'encoding': directives.encoding,
+ 'disable-curly-bracket-strip': directives.flag,
+ 'labelprefix': directives.unchanged,
+ }
+
+ 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:
+ env.app.warn(standout(":filter: overrides :all:"))
+ if "notcited" in self.options:
+ env.app.warn(standout(":filter: overrides :notcited:"))
+ if "cited" in self.options:
+ env.app.warn(standout(":filter: overrides :cited:"))
+ try:
+ filter_ = ast.parse(self.options["filter"])
+ except SyntaxError:
+ env.app.warn(
+ 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")
+ 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", "alpha"),
+ filter_=filter_,
+ encoding=self.options.get(
+ 'encoding',
+ 'latex+' + self.state.document.settings.input_encoding),
+ curly_bracket_strip=(
+ 'disable-curly-bracket-strip' not in self.options),
+ labelprefix=self.options.get("labelprefix", ""),
+ labels={},
+ bibfiles=[],
+ )
+ if (bibcache.list_ not in set(["bullet", "enumerated", "citation"])):
+ env.app.warn(
+ "unknown bibliography list type '{0}'.".format(bibcache.list_))
+ for bibfile in self.arguments[0].split():
+ # convert to normalized absolute path to ensure that the same file
+ # only occurs once in the cache
+ bibfile = os.path.normpath(env.relfn2path(bibfile.strip())[1])
+ self.process_bibfile(bibfile, bibcache.encoding)
+ env.note_dependency(bibfile)
+ bibcache.bibfiles.append(bibfile)
+ env.bibtex_cache.set_bibliography_cache(env.docname, id_, bibcache)
+ return [bibliography('', ids=[id_])]
+
+ def parse_bibfile(self, bibfile, encoding):
+ """Parse *bibfile*, and return parsed data.
+
+ :param bibfile: The bib file name.
+ :type bibfile: ``str``
+ :return: The parsed bibliography data.
+ :rtype: :class:`pybtex.database.BibliographyData`
+ """
+ app = self.state.document.settings.env.app
+ parser = bibtex.Parser(encoding)
+ app.info(
+ bold("parsing bibtex file {0}... ".format(bibfile)), nonl=True)
+ parser.parse_file(bibfile)
+ app.info("parsed {0} entries"
+ .format(len(parser.data.entries)))
+ return parser.data
+
+ def update_bibfile_cache(self, bibfile, mtime, encoding):
+ """Parse *bibfile* (see :meth:`parse_bibfile`), and store the
+ parsed data, along with modification time *mtime*, in the
+ bibtex cache.
+
+ :param bibfile: The bib file name.
+ :type bibfile: ``str``
+ :param mtime: The bib file's modification time.
+ :type mtime: ``float``
+ :return: The parsed bibliography data.
+ :rtype: :class:`pybtex.database.BibliographyData`
+ """
+ data = self.parse_bibfile(bibfile, encoding)
+ env = self.state.document.settings.env
+ env.bibtex_cache.bibfiles[bibfile] = BibfileCache(
+ mtime=mtime,
+ data=data)
+ return data
+
+ def process_bibfile(self, bibfile, encoding):
+ """Check if ``env.bibtex_cache.bibfiles[bibfile]`` is still
+ up to date. If not, parse the *bibfile* (see
+ :meth:`update_bibfile_cache`), and store parsed data in the
+ bibtex cache.
+
+ :param bibfile: The bib file name.
+ :type bibfile: ``str``
+ :return: The parsed bibliography data.
+ :rtype: :class:`pybtex.database.BibliographyData`
+ """
+ env = self.state.document.settings.env
+ cache = env.bibtex_cache.bibfiles
+ # get modification time of bibfile
+ try:
+ mtime = os.path.getmtime(bibfile)
+ except OSError:
+ env.app.warn(
+ standout("could not open bibtex file {0}.".format(bibfile)))
+ cache[bibfile] = BibfileCache( # dummy cache
+ mtime=-float("inf"), data=BibliographyData())
+ return cache[bibfile].data
+ # get cache and check if it is still up to date
+ # if it is not up to date, parse the bibtex file
+ # and store it in the cache
+ env.app.info(
+ bold("checking for {0} in bibtex cache... ".format(bibfile)),
+ nonl=True)
+ try:
+ bibfile_cache = cache[bibfile]
+ except KeyError:
+ env.app.info("not found")
+ self.update_bibfile_cache(bibfile, mtime, encoding)
+ else:
+ if mtime != bibfile_cache.mtime:
+ env.app.info("out of date")
+ self.update_bibfile_cache(bibfile, mtime, encoding)
+ else:
+ env.app.info('up to date')
+ return cache[bibfile].data
diff --git a/sphinxcontrib/bibtex/nodes.py b/sphinxcontrib/bibtex/nodes.py
new file mode 100644
index 0000000..426aed9
--- /dev/null
+++ b/sphinxcontrib/bibtex/nodes.py
@@ -0,0 +1,17 @@
+"""
+ New Doctree Nodes
+ ~~~~~~~~~~~~~~~~~
+
+ .. autoclass:: bibliography
+"""
+
+from docutils import nodes
+
+
+class bibliography(nodes.General, nodes.Element):
+
+ """Node for representing a bibliography. Replaced by a list of
+ citations by
+ :class:`~sphinxcontrib.bibtex.transforms.BibliographyTransform`.
+ """
+ pass
diff --git a/sphinxcontrib/bibtex/roles.py b/sphinxcontrib/bibtex/roles.py
new file mode 100644
index 0000000..bbbd1f0
--- /dev/null
+++ b/sphinxcontrib/bibtex/roles.py
@@ -0,0 +1,43 @@
+"""
+ New Doctree Roles
+ ~~~~~~~~~~~~~~~~~
+
+ .. autoclass:: CiteRole
+ :show-inheritance:
+
+ .. automethod:: result_nodes
+"""
+
+from pybtex.plugin import find_plugin
+import pybtex.database
+from sphinx.roles import XRefRole # for :cite:
+
+
+class CiteRole(XRefRole):
+
+ """Class for processing the :rst:role:`cite` role."""
+ backend = find_plugin('pybtex.backends', 'docutils')()
+
+ def result_nodes(self, document, env, node, is_ref):
+ """Transform reference node into a citation reference,
+ and note that the reference was cited.
+ """
+ keys = node['reftarget'].split(',')
+ # Note that at this point, usually, env.bibtex_cache.bibfiles
+ # is still empty because the bibliography directive may not
+ # have been processed yet, so we cannot get the actual entry.
+ # Instead, we simply fake an entry with the desired key, and
+ # fix the label at doctree-resolved time. This happens in
+ # process_citation_references.
+ refnodes = [
+ self.backend.citation_reference(_fake_entry(key), document)
+ for key in keys]
+ for key in keys:
+ env.bibtex_cache.add_cited(key, env.docname)
+ return refnodes, []
+
+
+def _fake_entry(key):
+ entry = pybtex.database.Entry(type_="")
+ entry.key = key
+ return entry
diff --git a/sphinxcontrib/bibtex/transforms.py b/sphinxcontrib/bibtex/transforms.py
new file mode 100644
index 0000000..8e4cdcb
--- /dev/null
+++ b/sphinxcontrib/bibtex/transforms.py
@@ -0,0 +1,127 @@
+"""
+ New Doctree Transforms
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ .. autoclass:: BibliographyTransform
+ :show-inheritance:
+
+ .. autoattribute:: default_priority
+ .. automethod:: apply
+
+ .. autofunction:: node_text_transform
+
+ .. autofunction:: transform_curly_bracket_strip
+
+ .. autofunction:: transform_url_command
+"""
+
+import docutils.nodes
+import docutils.transforms
+
+from pybtex.plugin import find_plugin
+
+from sphinxcontrib.bibtex.nodes import bibliography
+
+
+def node_text_transform(node, transform):
+ """Apply transformation to all Text nodes within node."""
+ for child in node.children:
+ if isinstance(child, docutils.nodes.Text):
+ node.replace(child, transform(child))
+ else:
+ node_text_transform(child, transform)
+
+
+def transform_curly_bracket_strip(textnode):
+ """Strip curly brackets from text."""
+ text = textnode.astext()
+ if '{' in text or '}' in text:
+ text = text.replace('{', '').replace('}', '')
+ return docutils.nodes.Text(text)
+ else:
+ return textnode
+
+
+def transform_url_command(textnode):
+ """Convert '\\\\url{...}' into a proper docutils hyperlink."""
+ text = textnode.astext()
+ if '\\url' in text:
+ text1, _, text = text.partition('\\url')
+ text2, _, text3 = text.partition('}')
+ text2 = text2.lstrip(' {')
+ ref = docutils.nodes.reference(refuri=text2)
+ ref += docutils.nodes.Text(text2)
+ node = docutils.nodes.inline()
+ node += transform_url_command(docutils.nodes.Text(text1))
+ node += ref
+ node += transform_url_command(docutils.nodes.Text(text3))
+ return node
+ else:
+ return textnode
+
+
+class BibliographyTransform(docutils.transforms.Transform):
+
+ """A docutils transform to generate citation entries for
+ bibliography nodes.
+ """
+
+ # transform must be applied before references are resolved
+ default_priority = 10
+ """Priority of the transform. See
+ http://docutils.sourceforge.net/docs/ref/transforms.html
+ """
+
+ def apply(self):
+ """Transform each
+ :class:`~sphinxcontrib.bibtex.nodes.bibliography` node into a
+ list of citations.
+ """
+ env = self.document.settings.env
+ docname = env.docname
+ for bibnode in self.document.traverse(bibliography):
+ id_ = bibnode['ids'][0]
+ bibcache = env.bibtex_cache.get_bibliography_cache(
+ docname=docname, id_=id_)
+ entries = env.bibtex_cache.get_bibliography_entries(
+ docname=docname, id_=id_, warn=env.app.warn)
+ # locate and instantiate style and backend plugins
+ style = find_plugin('pybtex.style.formatting', bibcache.style)()
+ backend = find_plugin('pybtex.backends', 'docutils')()
+ # create citation nodes for all references
+ if bibcache.list_ == "enumerated":
+ nodes = docutils.nodes.enumerated_list()
+ nodes['enumtype'] = bibcache.enumtype
+ if bibcache.start >= 1:
+ nodes['start'] = bibcache.start
+ env.bibtex_cache.set_enum_count(
+ env.docname, bibcache.start)
+ else:
+ nodes['start'] = env.bibtex_cache.get_enum_count(
+ env.docname)
+ elif bibcache.list_ == "bullet":
+ nodes = docutils.nodes.bullet_list()
+ else: # "citation"
+ nodes = docutils.nodes.paragraph()
+ # remind: style.format_entries modifies entries in unpickable way
+ for entry in style.format_entries(entries):
+ if bibcache.list_ in ["enumerated", "bullet"]:
+ citation = docutils.nodes.list_item()
+ citation += backend.paragraph(entry)
+ else: # "citation"
+ citation = backend.citation(entry, self.document)
+ # backend.citation(...) uses entry.key as citation label
+ # we change it to entry.label later onwards
+ # but we must note the entry.label now;
+ # at this point, we also already prefix the label
+ key = citation[0].astext()
+ bibcache.labels[key] = bibcache.labelprefix + entry.label
+ node_text_transform(citation, transform_url_command)
+ if bibcache.curly_bracket_strip:
+ node_text_transform(
+ citation,
+ transform_curly_bracket_strip)
+ nodes += citation
+ if bibcache.list_ == "enumerated":
+ env.bibtex_cache.inc_enum_count(env.docname)
+ bibnode.replace_self(nodes)
diff --git a/test/bibfile_out_of_date/conf.py b/test/bibfile_out_of_date/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/bibfile_out_of_date/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/bibfile_out_of_date/contents.rst b/test/bibfile_out_of_date/contents.rst
new file mode 100644
index 0000000..f14410d
--- /dev/null
+++ b/test/bibfile_out_of_date/contents.rst
@@ -0,0 +1,3 @@
+.. bibliography:: test.bib
+ :style: plain
+ :all:
diff --git a/test/bibfile_out_of_date/test_new.bib b/test/bibfile_out_of_date/test_new.bib
new file mode 100644
index 0000000..2994674
--- /dev/null
+++ b/test/bibfile_out_of_date/test_new.bib
@@ -0,0 +1,16 @@
+ at Misc{test1,
+ author = {Mr. Test Eminence},
+ title = {Test 1},
+}
+ at Misc{test2,
+ author = {Mr. Test Frater},
+ title = {Test 2},
+}
+ at Misc{test3,
+ author = {Mr. Test Giggles},
+ title = {Test 3},
+}
+ at Misc{test4,
+ author = {Mr. Test Handy},
+ title = {Test 4},
+}
diff --git a/test/bibfile_out_of_date/test_old.bib b/test/bibfile_out_of_date/test_old.bib
new file mode 100644
index 0000000..6f1930a
--- /dev/null
+++ b/test/bibfile_out_of_date/test_old.bib
@@ -0,0 +1,16 @@
+ at Misc{test1,
+ author = {Mr. Test Akkerdju},
+ title = {Test 1},
+}
+ at Misc{test2,
+ author = {Mr. Test Bro},
+ title = {Test 2},
+}
+ at Misc{test3,
+ author = {Mr. Test Chap},
+ title = {Test 3},
+}
+ at Misc{test4,
+ author = {Mr. Test Dude},
+ title = {Test 4},
+}
diff --git a/test/bibfilenotfound/conf.py b/test/bibfilenotfound/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/bibfilenotfound/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/bibfilenotfound/contents.rst b/test/bibfilenotfound/contents.rst
new file mode 100644
index 0000000..5c1f74e
--- /dev/null
+++ b/test/bibfilenotfound/contents.rst
@@ -0,0 +1 @@
+.. bibliography:: unknown.bib
diff --git a/test/citationnotfound/conf.py b/test/citationnotfound/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/citationnotfound/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/citationnotfound/contents.rst b/test/citationnotfound/contents.rst
new file mode 100644
index 0000000..1185dbe
--- /dev/null
+++ b/test/citationnotfound/contents.rst
@@ -0,0 +1,3 @@
+:cite:`nosuchkey`
+
+.. bibliography:: test.bib
diff --git a/test/citationnotfound/test.bib b/test/citationnotfound/test.bib
new file mode 100644
index 0000000..e69de29
diff --git a/test/custom_style/conf.py b/test/custom_style/conf.py
new file mode 100644
index 0000000..f519ef7
--- /dev/null
+++ b/test/custom_style/conf.py
@@ -0,0 +1,17 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
+
+# create and register pybtex plugins
+
+from pybtex.style.formatting.unsrt import Style as UnsrtStyle
+from pybtex.style.template import words
+from pybtex.plugin import register_plugin
+
+
+class NoWebRefStyle(UnsrtStyle):
+
+ def format_web_refs(self, e):
+ # the following is just one simple way to return an empty node
+ return words['']
+
+register_plugin('pybtex.style.formatting', 'nowebref', NoWebRefStyle)
diff --git a/test/custom_style/contents.rst b/test/custom_style/contents.rst
new file mode 100644
index 0000000..daeff61
--- /dev/null
+++ b/test/custom_style/contents.rst
@@ -0,0 +1,4 @@
+.. bibliography:: test.bib
+ :style: nowebref
+ :all:
+ :list: bullet
diff --git a/test/custom_style/test.bib b/test/custom_style/test.bib
new file mode 100644
index 0000000..f77e079
--- /dev/null
+++ b/test/custom_style/test.bib
@@ -0,0 +1,27 @@
+ at 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}
+}
+
+ at 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}
+}
diff --git a/test/filter/bitand.rst b/test/filter/bitand.rst
new file mode 100644
index 0000000..1bf2ae4
--- /dev/null
+++ b/test/filter/bitand.rst
@@ -0,0 +1,6 @@
+Set
+---
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: {"doc1", "doc2"} & docnames
diff --git a/test/filter/bitor.rst b/test/filter/bitor.rst
new file mode 100644
index 0000000..15439a5
--- /dev/null
+++ b/test/filter/bitor.rst
@@ -0,0 +1,6 @@
+Set
+---
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: {"doc1", "doc2"} | docnames
diff --git a/test/filter/conf.py b/test/filter/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/filter/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/filter/contents.rst b/test/filter/contents.rst
new file mode 100644
index 0000000..7284c0a
--- /dev/null
+++ b/test/filter/contents.rst
@@ -0,0 +1,20 @@
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: author % "Second" and type == "misc"
+
+.. toctree::
+
+ or
+ noteq
+ lt
+ lte
+ gt
+ gte
+ key
+ false
+ title
+ in
+ notin
+ set
+ bitand
+ bitor
diff --git a/test/filter/false.rst b/test/filter/false.rst
new file mode 100644
index 0000000..eb3d078
--- /dev/null
+++ b/test/filter/false.rst
@@ -0,0 +1,6 @@
+False
+-----
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: False
diff --git a/test/filter/gt.rst b/test/filter/gt.rst
new file mode 100644
index 0000000..0448fd2
--- /dev/null
+++ b/test/filter/gt.rst
@@ -0,0 +1,6 @@
+Gt
+--
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: year > "2011"
diff --git a/test/filter/gte.rst b/test/filter/gte.rst
new file mode 100644
index 0000000..49f61a9
--- /dev/null
+++ b/test/filter/gte.rst
@@ -0,0 +1,6 @@
+Gte
+---
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: year >= "2011"
diff --git a/test/filter/in.rst b/test/filter/in.rst
new file mode 100644
index 0000000..4cdcae3
--- /dev/null
+++ b/test/filter/in.rst
@@ -0,0 +1,6 @@
+In
+--
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: "bla" in docnames
diff --git a/test/filter/key.rst b/test/filter/key.rst
new file mode 100644
index 0000000..4f5662a
--- /dev/null
+++ b/test/filter/key.rst
@@ -0,0 +1,6 @@
+Key
+---
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: key == "third"
diff --git a/test/filter/lt.rst b/test/filter/lt.rst
new file mode 100644
index 0000000..ae91df7
--- /dev/null
+++ b/test/filter/lt.rst
@@ -0,0 +1,6 @@
+Lt
+--
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: year < "2011"
diff --git a/test/filter/lte.rst b/test/filter/lte.rst
new file mode 100644
index 0000000..7ff7638
--- /dev/null
+++ b/test/filter/lte.rst
@@ -0,0 +1,6 @@
+Lte
+---
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: year <= "2011"
diff --git a/test/filter/noteq.rst b/test/filter/noteq.rst
new file mode 100644
index 0000000..bb30aa8
--- /dev/null
+++ b/test/filter/noteq.rst
@@ -0,0 +1,6 @@
+NotEq
+-----
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: year != "2011"
diff --git a/test/filter/notin.rst b/test/filter/notin.rst
new file mode 100644
index 0000000..ebf49c4
--- /dev/null
+++ b/test/filter/notin.rst
@@ -0,0 +1,6 @@
+Not In
+------
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: "bla" not in docnames
diff --git a/test/filter/or.rst b/test/filter/or.rst
new file mode 100644
index 0000000..12ac9c0
--- /dev/null
+++ b/test/filter/or.rst
@@ -0,0 +1,6 @@
+Or
+--
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: author % "First" or type == "article"
diff --git a/test/filter/set.rst b/test/filter/set.rst
new file mode 100644
index 0000000..1a01051
--- /dev/null
+++ b/test/filter/set.rst
@@ -0,0 +1,6 @@
+Set
+---
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: {"doc1", "doc2"} <= docnames
diff --git a/test/filter/test.bib b/test/filter/test.bib
new file mode 100644
index 0000000..5e44ead
--- /dev/null
+++ b/test/filter/test.bib
@@ -0,0 +1,18 @@
+ at Misc{second,
+ author = {B. Second},
+ title = {Tralalala},
+ year = {2010}
+}
+
+ at Article{third,
+ author = {B. Second},
+ title = {Heb je een ideetje},
+ journal = {Journal of Kaatje},
+ year = {2012}
+}
+
+ at Misc{first,
+ author = {A. First},
+ title = {Jakkamakka},
+ year = {2011}
+}
diff --git a/test/filter/title.rst b/test/filter/title.rst
new file mode 100644
index 0000000..13fbeec
--- /dev/null
+++ b/test/filter/title.rst
@@ -0,0 +1,6 @@
+Title
+-----
+
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: title and title % "jakka"
diff --git a/test/filter_fix_author_keyerror/conf.py b/test/filter_fix_author_keyerror/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/filter_fix_author_keyerror/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/filter_fix_author_keyerror/contents.rst b/test/filter_fix_author_keyerror/contents.rst
new file mode 100644
index 0000000..1246cac
--- /dev/null
+++ b/test/filter_fix_author_keyerror/contents.rst
@@ -0,0 +1,3 @@
+.. bibliography:: test.bib
+ :list: bullet
+ :filter: author % "Test"
diff --git a/test/filter_fix_author_keyerror/test.bib b/test/filter_fix_author_keyerror/test.bib
new file mode 100644
index 0000000..ea85e60
--- /dev/null
+++ b/test/filter_fix_author_keyerror/test.bib
@@ -0,0 +1,4 @@
+ at Misc{second,
+ title = {Tralalala},
+ year = {2010}
+}
diff --git a/test/filter_option_clash/conf.py b/test/filter_option_clash/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/filter_option_clash/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/filter_option_clash/contents.rst b/test/filter_option_clash/contents.rst
new file mode 100644
index 0000000..a8622eb
--- /dev/null
+++ b/test/filter_option_clash/contents.rst
@@ -0,0 +1,5 @@
+.. bibliography:: test.bib
+ :all:
+ :cited:
+ :notcited:
+ :filter: author % "Troffaes"
diff --git a/test/filter_option_clash/test.bib b/test/filter_option_clash/test.bib
new file mode 100644
index 0000000..e69de29
diff --git a/test/filter_syntax_error/conf.py b/test/filter_syntax_error/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/filter_syntax_error/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/filter_syntax_error/contents.rst b/test/filter_syntax_error/contents.rst
new file mode 100644
index 0000000..381eb77
--- /dev/null
+++ b/test/filter_syntax_error/contents.rst
@@ -0,0 +1,26 @@
+.. bibliography:: test.bib
+ :filter: $
+
+.. bibliography:: test.bib
+ :filter: yield author
+
+.. bibliography:: test.bib
+ :filter: author is title
+
+.. bibliography:: test.bib
+ :filter: False % title
+
+.. bibliography:: test.bib
+ :filter: title % False
+
+.. bibliography:: test.bib
+ :filter: ~title
+
+.. bibliography:: test.bib
+ :filter: "2000" <= year <= "2005"
+
+.. bibliography:: test.bib
+ :filter: author + title
+
+.. bibliography:: test.bib
+ :filter: author; title
diff --git a/test/filter_syntax_error/test.bib b/test/filter_syntax_error/test.bib
new file mode 100644
index 0000000..10773f8
--- /dev/null
+++ b/test/filter_syntax_error/test.bib
@@ -0,0 +1,5 @@
+ at misc{test,
+ author = {Mr. Tee},
+ title = {Baracuda},
+ year = {1553}
+}
\ No newline at end of file
diff --git a/test/invalid_cite_option/conf.py b/test/invalid_cite_option/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/invalid_cite_option/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/invalid_cite_option/contents.rst b/test/invalid_cite_option/contents.rst
new file mode 100644
index 0000000..fba257c
--- /dev/null
+++ b/test/invalid_cite_option/contents.rst
@@ -0,0 +1,2 @@
+.. bibliography:: test.bib
+ :thisisintentionallyinvalid:
diff --git a/test/invalid_cite_option/test.bib b/test/invalid_cite_option/test.bib
new file mode 100644
index 0000000..e69de29
diff --git a/test/issue1/2012/07/24/hello_world_.rst b/test/issue1/2012/07/24/hello_world_.rst
new file mode 100644
index 0000000..f02134c
--- /dev/null
+++ b/test/issue1/2012/07/24/hello_world_.rst
@@ -0,0 +1,11 @@
+Hello World!
+============
+
+:cite:`2011:BabikerIPv6`
+
+.. bibliography:: ../../../refs.bib
+
+.. author:: default
+.. categories:: none
+.. tags:: none
+.. comments::
diff --git a/test/issue1/conf.py b/test/issue1/conf.py
new file mode 100644
index 0000000..6d93857
--- /dev/null
+++ b/test/issue1/conf.py
@@ -0,0 +1,28 @@
+import tinkerer
+import tinkerer.paths
+project = 'My blog'
+tagline = 'Add intelligent tagline here'
+author = 'Mr Test'
+website = 'http://127.0.0.1/blog/html/'
+html_theme = "modern5"
+posts_per_page = 2
+
+extensions = [
+ 'sphinxcontrib.bibtex',
+ 'tinkerer.ext.blog',
+ 'tinkerer.ext.disqus']
+
+html_static_path = [tinkerer.paths.static]
+html_theme_path = [tinkerer.paths.themes]
+exclude_patterns = ["drafts/*"]
+
+# **************************************************************
+# Do not modify below lines as the values are required by
+# Tinkerer to play nice with Sphinx
+# **************************************************************
+
+master_doc = tinkerer.master_doc
+html_title = project
+html_use_index = False
+html_show_sourcelink = False
+html_add_permalinks = ""
diff --git a/test/issue1/master.rst b/test/issue1/master.rst
new file mode 100644
index 0000000..125c9e1
--- /dev/null
+++ b/test/issue1/master.rst
@@ -0,0 +1,8 @@
+Sitemap
+=======
+
+.. toctree::
+ :maxdepth: 1
+
+ 2012/07/24/hello_world_
+
diff --git a/test/issue1/refs.bib b/test/issue1/refs.bib
new file mode 100644
index 0000000..9ba43fd
--- /dev/null
+++ b/test/issue1/refs.bib
@@ -0,0 +1,6 @@
+ at InProceedings{2011:BabikerIPv6,
+ author = {H. Babiker and I. Nikolova and K. Chittimaneni},
+ title = {Deploying IPv6 in the Google Enterprise Network. Lessons learned.},
+ booktitle = {USENIX LISA 2011},
+ year = 2011,
+ note = {\url{http://static.usenix.org/events/lisa11/tech/full_papers/Babiker.pdf}} }
diff --git a/test/issue14/conf.py b/test/issue14/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/issue14/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/issue14/contents.rst b/test/issue14/contents.rst
new file mode 100644
index 0000000..8ec72f2
--- /dev/null
+++ b/test/issue14/contents.rst
@@ -0,0 +1,7 @@
+Contents
+========
+
+.. toctree::
+
+ doc1
+ doc2
diff --git a/test/issue14/doc1.rst b/test/issue14/doc1.rst
new file mode 100644
index 0000000..84b39d7
--- /dev/null
+++ b/test/issue14/doc1.rst
@@ -0,0 +1,6 @@
+Doc1
+====
+
+.. bibliography:: test1.bib
+ :style: plain
+ :all:
diff --git a/test/issue14/doc2.rst b/test/issue14/doc2.rst
new file mode 100644
index 0000000..33edfbc
--- /dev/null
+++ b/test/issue14/doc2.rst
@@ -0,0 +1,6 @@
+Doc2
+====
+
+.. bibliography:: test2.bib
+ :style: plain
+ :all:
diff --git a/test/issue14/test1.bib b/test/issue14/test1.bib
new file mode 100644
index 0000000..729a0f5
--- /dev/null
+++ b/test/issue14/test1.bib
@@ -0,0 +1,4 @@
+ at Misc{Test,
+ author = {Mr. Test},
+ title = {Test},
+}
diff --git a/test/issue14/test2.bib b/test/issue14/test2.bib
new file mode 100644
index 0000000..5517b78
--- /dev/null
+++ b/test/issue14/test2.bib
@@ -0,0 +1,4 @@
+ at Misc{Test2,
+ author = {Mr. Other Test},
+ title = {Another Test},
+}
diff --git a/test/issue14_2/conf.py b/test/issue14_2/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/issue14_2/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/issue14_2/contents.rst b/test/issue14_2/contents.rst
new file mode 100644
index 0000000..8ec72f2
--- /dev/null
+++ b/test/issue14_2/contents.rst
@@ -0,0 +1,7 @@
+Contents
+========
+
+.. toctree::
+
+ doc1
+ doc2
diff --git a/test/issue14_2/doc1.rst b/test/issue14_2/doc1.rst
new file mode 100644
index 0000000..3bb0de7
--- /dev/null
+++ b/test/issue14_2/doc1.rst
@@ -0,0 +1,7 @@
+Doc1
+====
+
+.. bibliography:: test1.bib
+ :all:
+ :style: plain
+ :labelprefix: A
diff --git a/test/issue14_2/doc2.rst b/test/issue14_2/doc2.rst
new file mode 100644
index 0000000..f3547f4
--- /dev/null
+++ b/test/issue14_2/doc2.rst
@@ -0,0 +1,7 @@
+Doc2
+====
+
+.. bibliography:: test2.bib
+ :all:
+ :style: plain
+ :labelprefix: B
diff --git a/test/issue14_2/test1.bib b/test/issue14_2/test1.bib
new file mode 100644
index 0000000..729a0f5
--- /dev/null
+++ b/test/issue14_2/test1.bib
@@ -0,0 +1,4 @@
+ at Misc{Test,
+ author = {Mr. Test},
+ title = {Test},
+}
diff --git a/test/issue14_2/test2.bib b/test/issue14_2/test2.bib
new file mode 100644
index 0000000..5517b78
--- /dev/null
+++ b/test/issue14_2/test2.bib
@@ -0,0 +1,4 @@
+ at Misc{Test2,
+ author = {Mr. Other Test},
+ title = {Another Test},
+}
diff --git a/test/issue15/conf.py b/test/issue15/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/issue15/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/issue15/contents.rst b/test/issue15/contents.rst
new file mode 100644
index 0000000..c7427b8
--- /dev/null
+++ b/test/issue15/contents.rst
@@ -0,0 +1,5 @@
+:cite:`first`
+:cite:`second`
+
+.. bibliography:: test.bib
+ :style: unsrt
diff --git a/test/issue15/test.bib b/test/issue15/test.bib
new file mode 100644
index 0000000..fba6fec
--- /dev/null
+++ b/test/issue15/test.bib
@@ -0,0 +1,8 @@
+ at Misc{second,
+ author = {B. Second},
+ title = {Test 2},
+}
+ at Misc{first,
+ author = {A. First},
+ title = {Test 1},
+}
diff --git a/test/issue17/conf.py b/test/issue17/conf.py
new file mode 100644
index 0000000..8a1f142
--- /dev/null
+++ b/test/issue17/conf.py
@@ -0,0 +1,11 @@
+import sys
+import os
+# viewcode extension specifically needed for this test
+extensions = [
+ 'sphinxcontrib.bibtex',
+ 'sphinx.ext.viewcode',
+ 'sphinx.ext.autodoc']
+# make sure we find the module
+sys.path.insert(0, os.path.abspath('.'))
+
+exclude_patterns = ['_build']
diff --git a/test/issue17/contents.rst b/test/issue17/contents.rst
new file mode 100644
index 0000000..e670b9a
--- /dev/null
+++ b/test/issue17/contents.rst
@@ -0,0 +1,2 @@
+.. automodule:: somemodule
+ :members:
diff --git a/test/issue17/somemodule.py b/test/issue17/somemodule.py
new file mode 100644
index 0000000..a221873
--- /dev/null
+++ b/test/issue17/somemodule.py
@@ -0,0 +1,6 @@
+"""Some module."""
+
+
+def somefunction():
+ """Some function."""
+ pass
diff --git a/test/issue2/adoc1.rst b/test/issue2/adoc1.rst
new file mode 100644
index 0000000..881a7a8
--- /dev/null
+++ b/test/issue2/adoc1.rst
@@ -0,0 +1,4 @@
+Doc1
+====
+
+:cite:`Test`
diff --git a/test/issue2/adoc2.rst b/test/issue2/adoc2.rst
new file mode 100644
index 0000000..5cf4a8d
--- /dev/null
+++ b/test/issue2/adoc2.rst
@@ -0,0 +1,4 @@
+Doc2
+====
+
+[Test]_
diff --git a/test/issue2/conf.py b/test/issue2/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/issue2/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/issue2/contents.rst b/test/issue2/contents.rst
new file mode 100644
index 0000000..7bc4158
--- /dev/null
+++ b/test/issue2/contents.rst
@@ -0,0 +1,10 @@
+Contents
+========
+
+.. toctree::
+
+ adoc1
+ adoc2
+
+.. bibliography:: test.bib
+ :style: plain
diff --git a/test/issue2/test.bib b/test/issue2/test.bib
new file mode 100644
index 0000000..729a0f5
--- /dev/null
+++ b/test/issue2/test.bib
@@ -0,0 +1,4 @@
+ at Misc{Test,
+ author = {Mr. Test},
+ title = {Test},
+}
diff --git a/test/issue4/conf.py b/test/issue4/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/issue4/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/issue4/contents.rst b/test/issue4/contents.rst
new file mode 100644
index 0000000..bdceca8
--- /dev/null
+++ b/test/issue4/contents.rst
@@ -0,0 +1,3 @@
+.. bibliography:: test.bib
+ :all:
+ :encoding: latex+utf
diff --git a/test/issue4/test.bib b/test/issue4/test.bib
new file mode 100644
index 0000000..ccd6cd4
--- /dev/null
+++ b/test/issue4/test.bib
@@ -0,0 +1,4 @@
+ at Misc{Test,
+ author = {Mr. T\'est☺},
+ title = {Test},
+}
diff --git a/test/issue61/conf.py b/test/issue61/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/issue61/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/issue61/contents.rst b/test/issue61/contents.rst
new file mode 100644
index 0000000..1afc37a
--- /dev/null
+++ b/test/issue61/contents.rst
@@ -0,0 +1,6 @@
+Contents
+========
+
+:cite:`testone,testtwo`
+
+.. bibliography:: refs.bib
diff --git a/test/issue61/refs.bib b/test/issue61/refs.bib
new file mode 100644
index 0000000..a04e473
--- /dev/null
+++ b/test/issue61/refs.bib
@@ -0,0 +1,9 @@
+ at Misc{testone,
+ author = {Mr. TestOne},
+ title = {TestOne},
+}
+
+ at Misc{testtwo,
+ author = {Mr. TestTwo},
+ title = {TestTwo},
+}
diff --git a/test/issue62/conf.py b/test/issue62/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/issue62/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/issue62/contents.rst b/test/issue62/contents.rst
new file mode 100644
index 0000000..9b02c4b
--- /dev/null
+++ b/test/issue62/contents.rst
@@ -0,0 +1,9 @@
+Contents
+========
+
+.. toctree::
+
+ doc1
+ doc2
+ summary
+
diff --git a/test/issue62/doc1.rst b/test/issue62/doc1.rst
new file mode 100644
index 0000000..5e7fc44
--- /dev/null
+++ b/test/issue62/doc1.rst
@@ -0,0 +1,56 @@
+2014-Feb-20
+###########
+
+JACS paper
+**********
+
+:cite:`fuhrmans_molecular_2012`
+
+
+Abstract
+========
+
+We present molecular dynamics simulations investigating the effect of
+a particular fusion peptide, the **influenza hemagglutinin fusion
+peptide** and some of its mutants, on the lipid phase diagram.
+
+We detect a systematic shift toward phases with more positive mean
+curvature in the presence of the peptides, as well as an occurrence of
+bicontinuous cubic phases, which indicates a stabilization of Gaussian
+curvature.
+
+To study the ability of the HA fusion peptide to modulate the lipid
+phase diagram, we focus on DOPE (dioleoylphosphatidylethanolamine) and
+DOPC (dioleoylphosphatidylcholine) lipids. These lipids were chosen as
+they display a broad range of phases, ranging from predominantly
+lamellar states for pure DOPC to inverted-hexagonal for pure DOPE, as
+well as the so-called rhombohedral phase ("stalk" phase) observed for
+mixed PC/PE systems at low hydration. The inverted phases and stalk
+phase.
+
+To construct the phase diagram, we performed self-assembly simulations
+of systems composed of 256 lipids and four peptides, corresponding to
+a mole fraction of peptides of almost 2%. The ratio of PC/PE,
+hydration level, and temperature were systematically varied. At each
+state point, multiple simulations were performed starting from a
+randomized initial distribution of the components. Each simulation was
+run for an effective time of 12 μs, which proved to be long enough for
+the system to adopt a stable phase.
+
+
+Calorimetry experiments:
+
+* :cite:`blume_apparent_1983`
+* :cite:`grabitz_relaxation_2002`
+
+Atomistic Monte-Carlo experiments:
+
+* :cite:`wustner_atomistic_2014`
+
+
+Bibliography
+************
+
+.. bibliography:: refs.bib
+ :labelprefix: A
+ :filter: docname in docnames
diff --git a/test/issue62/doc2.rst b/test/issue62/doc2.rst
new file mode 100644
index 0000000..88dce56
--- /dev/null
+++ b/test/issue62/doc2.rst
@@ -0,0 +1,46 @@
+2014-Mar-08
+###########
+
+
+How to test an ensemble
+***********************
+
+These are notes on :cite:`shirts_simple_2013`.
+
+
+Abstract
+========
+
+It is often difficult to quantitatively determine if a new molecular
+simulation algorithm or software properly implements sampling of the
+desired thermodynamic ensemble.
+
+We present some simple statistical analysis procedures to allow
+sensitive determination of whether the desired thermodynamic ensemble
+is properly sampled.
+
+These procedures use paired simulations to cancel out system dependent
+densities of state and directly test the extent to which the Boltzmann
+distribution associated with the ensemble (usually canonical,
+isobaric−isothermal, or grand canonical) is satisfied.
+
+
+Introduction
+============
+
+Molecular simulations, including both molecular dynamics (MD) and
+Monte Carlo (MC) techniques, are powerful tools used to study the
+properties of complex molecular systems.
+
+When used to specifically study thermodynamics of such systems, rather
+than dynamics, the primary goal of molecular simulation is to generate
+uncorrelated samples from the appropriate ensemble as efficiently as
+possible.
+
+
+Bibliography
+============
+
+.. bibliography:: refs.bib
+ :labelprefix: B
+ :filter: docname in docnames
diff --git a/test/issue62/refs.bib b/test/issue62/refs.bib
new file mode 100644
index 0000000..30cd9a2
--- /dev/null
+++ b/test/issue62/refs.bib
@@ -0,0 +1,128 @@
+ at article{grabitz_relaxation_2002,
+ title = {Relaxation kinetics of lipid membranes and its relation to the heat capacity.},
+ volume = {82},
+ number = {1},
+ journal = {Biophysical Journal},
+ author = {Grabitz, Peter and Ivanova, Vesselka P and Heimburg, Thomas},
+ month = jan,
+ year = {2002},
+ pages = {299--309}
+}
+
+ at article{blume_apparent_1983,
+ title = {Apparent molar heat capacities of phospholipids in aqueous dispersion. Effects of chain length and head group structure},
+ volume = {22},
+ doi = {10.1021/bi00292a027},
+ number = {23},
+ journal = {Biochemistry},
+ author = {Blume, Alfred},
+ month = nov,
+ year = {1983},
+ pages = {5436--5442}
+}
+
+ at article{wustner_atomistic_2014,
+ title = {Atomistic Monte Carlo Simulation of Lipid Membranes},
+ volume = {15},
+ copyright = {http://creativecommons.org/licenses/by/3.0/},
+ doi = {10.3390/ijms15021767},
+ number = {2},
+ journal = {International Journal of Molecular Sciences},
+ author = {Wüstner, Daniel and Sklenar, Heinz},
+ month = jan,
+ year = {2014},
+ pages = {1767--1803}
+}
+
+ at article{fuhrmans_molecular_2012,
+ title = {Molecular View of the Role of Fusion Peptides in Promoting Positive Membrane Curvature},
+ volume = {134},
+ doi = {10.1021/ja207290b},
+ number = {3},
+ journal = {Journal of the American Chemical Society},
+ author = {Fuhrmans, Marc and Marrink, Siewert J.},
+ month = jan,
+ year = {2012},
+ pages = {1543--1552}
+}
+
+ at article{shirts_simple_2013,
+ title = {Simple Quantitative Tests to Validate Sampling from Thermodynamic Ensembles},
+ volume = {9},
+ doi = {10.1021/ct300688p},
+ number = {2},
+ journal = {Journal of Chemical Theory and Computation},
+ author = {Shirts, Michael R.},
+ month = feb,
+ year = {2013},
+ pages = {909--926}
+}
+
+ at article{mcmahon_membrane_2010,
+ title = {Membrane Curvature in Synaptic Vesicle Fusion and Beyond},
+ volume = {140},
+ doi = {10.1016/j.cell.2010.02.017},
+ number = {5},
+ journal = {Cell},
+ author = {{McMahon}, Harvey T. and Kozlov, Michael M. and Martens, Sascha},
+ month = mar,
+ year = {2010},
+ pages = {601--605}
+}
+
+ at article{hu_gaussian_2013,
+ title = {Gaussian curvature elasticity determined from global shape transformations and local stress distributions: a comparative study using the {MARTINI} model},
+ volume = {161},
+ journal = {Faraday discussions},
+ author = {Hu, Mingyang and de Jong, Djurre H and Marrink, Siewert J and Deserno, Markus},
+ year = {2013},
+ pages = {365--382}
+}
+
+ at article{baoukina_molecular_2012,
+ title = {Molecular structure of membrane tethers},
+ volume = {102},
+ doi = {10.1016/j.bpj.2012.03.048},
+ number = {8},
+ journal = {Biophysical journal},
+ author = {Baoukina, Svetlana and Marrink, Siewert J and Tieleman, D Peter},
+ month = apr,
+ year = {2012},
+ pages = {1866--1871}
+}
+
+ at article{risselada_curvature-dependent_2011,
+ title = {Curvature-Dependent Elastic Properties of Liquid-Ordered Domains Result in Inverted Domain Sorting on Uniaxially Compressed Vesicles},
+ volume = {106},
+ doi = {10.1103/PhysRevLett.106.148102},
+ number = {14},
+ journal = {Physical Review Letters},
+ author = {Risselada, H. Jelger and Marrink, Siewert Jan and Müller, Marcus},
+ month = apr,
+ year = {2011},
+ pages = {148102}
+}
+
+ at article{risselada_curvature_2009,
+ title = {Curvature effects on lipid packing and dynamics in liposomes revealed by coarse grained molecular dynamics simulations},
+ volume = {11},
+ doi = {10.1039/b818782g},
+ number = {12},
+ journal = {Physical chemistry chemical physics: {PCCP}},
+ author = {Risselada, H Jelger and Marrink, Siewert J},
+ month = mar,
+ year = {2009},
+ pages = {2056--2067}
+}
+
+ at article{marrink_mechanism_2003,
+ title = {The Mechanism of Vesicle Fusion as Revealed by Molecular Dynamics Simulations},
+ volume = {125},
+ doi = {10.1021/ja036138+},
+ number = {37},
+ journal = {Journal of the American Chemical Society},
+ author = {Marrink, Siewert J. and Mark, Alan E.},
+ month = sep,
+ year = {2003},
+ pages = {11144--11145}
+}
diff --git a/test/issue62/summary.rst b/test/issue62/summary.rst
new file mode 100644
index 0000000..d1a224b
--- /dev/null
+++ b/test/issue62/summary.rst
@@ -0,0 +1,47 @@
+Summary
+#######
+
+Постановка задачи
+*****************
+
+:cite:`mcmahon_membrane_2010`: Рис. 1, C, D, E, F.
+
+
+Утверждение
+***********
+
+Выпуклость/вогнутось в центре круга белков с положительной кривизной —
+это локальный минимум энергии.
+
+
+
+Метод
+*****
+
+Крупно-зернистая молекулярная динамика для симуляции большой
+мембраны. Martini используется для упругих расчётов
+:cite:`hu_gaussian_2013`,
+:cite:`fuhrmans_molecular_2012`,
+:cite:`risselada_curvature-dependent_2011`,
+:cite:`risselada_curvature_2009`,
+:cite:`marrink_mechanism_2003`.
+
+
+Аргумент
+********
+
+
+
+
+Проверка ансамбля
+*****************
+
+Не сделано.
+
+
+Библиография
+************
+
+.. bibliography:: refs.bib
+ :labelprefix: C
+ :filter: docname in docnames and key != "fuhrmans_molecular_2012"
diff --git a/test/issue77/conf.py b/test/issue77/conf.py
new file mode 100644
index 0000000..22ad95d
--- /dev/null
+++ b/test/issue77/conf.py
@@ -0,0 +1,21 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
+
+# create and register pybtex plugins
+
+from pybtex.style.formatting.unsrt import Style as UnsrtStyle
+from pybtex.style.labels.alpha import LabelStyle as AlphaLabelStyle
+from pybtex.plugin import register_plugin
+
+
+class ApaLabelStyle(AlphaLabelStyle):
+ def format_label(self, entry):
+ return "APA"
+
+
+class ApaStyle(UnsrtStyle):
+ default_label_style = 'apa'
+
+
+register_plugin('pybtex.style.labels', 'apa', ApaLabelStyle)
+register_plugin('pybtex.style.formatting', 'apastyle', ApaStyle)
diff --git a/test/issue77/contents.rst b/test/issue77/contents.rst
new file mode 100644
index 0000000..ed3cf21
--- /dev/null
+++ b/test/issue77/contents.rst
@@ -0,0 +1,5 @@
+:cite:`2009:mandel`
+:cite:`2003:evensen`
+
+.. bibliography:: test.bib
+ :style: apastyle
diff --git a/test/issue77/test.bib b/test/issue77/test.bib
new file mode 100644
index 0000000..f77e079
--- /dev/null
+++ b/test/issue77/test.bib
@@ -0,0 +1,27 @@
+ at 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}
+}
+
+ at 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}
+}
diff --git a/test/issue80/conf.py b/test/issue80/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/issue80/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/issue80/contents.rst b/test/issue80/contents.rst
new file mode 100644
index 0000000..cd46d34
--- /dev/null
+++ b/test/issue80/contents.rst
@@ -0,0 +1,15 @@
+Contents
+========
+
+.. toctree::
+
+ doc0
+ doc1
+ doc2
+ doc3
+ doc4
+ doc5
+ doc6
+ doc7
+ doc8
+ doc9
diff --git a/test/issue80/doc0.rst b/test/issue80/doc0.rst
new file mode 100644
index 0000000..9926c87
--- /dev/null
+++ b/test/issue80/doc0.rst
@@ -0,0 +1,2 @@
+doc0
+----
diff --git a/test/issue80/doc1.rst b/test/issue80/doc1.rst
new file mode 100644
index 0000000..0da9d50
--- /dev/null
+++ b/test/issue80/doc1.rst
@@ -0,0 +1,4 @@
+doc1
+----
+
+:cite:`1979-shafer`
diff --git a/test/issue80/doc2.rst b/test/issue80/doc2.rst
new file mode 100644
index 0000000..0cad0c1
--- /dev/null
+++ b/test/issue80/doc2.rst
@@ -0,0 +1,4 @@
+doc2
+----
+
+:cite:`1977-morris`
diff --git a/test/issue80/doc3.rst b/test/issue80/doc3.rst
new file mode 100644
index 0000000..99b8560
--- /dev/null
+++ b/test/issue80/doc3.rst
@@ -0,0 +1,4 @@
+doc3
+----
+
+:cite:`1972-savage`
diff --git a/test/issue80/doc4.rst b/test/issue80/doc4.rst
new file mode 100644
index 0000000..d37145f
--- /dev/null
+++ b/test/issue80/doc4.rst
@@ -0,0 +1,4 @@
+doc4
+----
+
+:cite:`rockafellar-1970`
diff --git a/test/issue80/doc5.rst b/test/issue80/doc5.rst
new file mode 100644
index 0000000..baa9ca2
--- /dev/null
+++ b/test/issue80/doc5.rst
@@ -0,0 +1,4 @@
+doc5
+----
+
+:cite:`1966-arrow`
diff --git a/test/issue80/doc6.rst b/test/issue80/doc6.rst
new file mode 100644
index 0000000..200ee96
--- /dev/null
+++ b/test/issue80/doc6.rst
@@ -0,0 +1,4 @@
+doc6
+----
+
+:cite:`1934-hildebrandt`
diff --git a/test/issue80/doc7.rst b/test/issue80/doc7.rst
new file mode 100644
index 0000000..d5a019a
--- /dev/null
+++ b/test/issue80/doc7.rst
@@ -0,0 +1,4 @@
+doc7
+----
+
+:cite:`1986-genest-zidek-combining-probability-distributions`
diff --git a/test/issue80/doc8.rst b/test/issue80/doc8.rst
new file mode 100644
index 0000000..ec7fff0
--- /dev/null
+++ b/test/issue80/doc8.rst
@@ -0,0 +1,4 @@
+doc8
+----
+
+:cite:`2001-kennedy-calibration`
diff --git a/test/issue80/doc9.rst b/test/issue80/doc9.rst
new file mode 100644
index 0000000..37e7f24
--- /dev/null
+++ b/test/issue80/doc9.rst
@@ -0,0 +1,4 @@
+doc9
+----
+
+.. bibliography:: refs.bib
diff --git a/test/issue80/refs.bib b/test/issue80/refs.bib
new file mode 100644
index 0000000..251e7a1
--- /dev/null
+++ b/test/issue80/refs.bib
@@ -0,0 +1,85 @@
+ at article{1979-shafer,
+ author = {Glenn Shafer},
+ title = {Allocations of Probability},
+ journal = {The Annals of Probability},
+ year = {1979},
+ volume = {7},
+ number = {5},
+ pages = {827--839}
+}
+
+ at article{1977-morris,
+ author = {Peter A. Morris},
+ title = {Combining expert judgments: a {B}ayesian approach},
+ journal = {Management Science},
+ year = {1977},
+ volume = {23},
+ number = {7},
+ pages = {679--693}
+}
+
+ at book{1972-savage,
+ author = {Leonard J. Savage},
+ title = {The Foundations of Statistics},
+ publisher = {Dover},
+ year = {1972},
+ address = {New York}
+}
+
+ at book{rockafellar-1970,
+ author = {R. Tyrrell Rockafellar},
+ title = {Convex Analysis},
+ publisher = {Princeton University Press},
+ year = {1970},
+ address = {Princeton}
+}
+
+ at article{1966-arrow,
+ author = {Arrow, K.},
+ title = {Exposition of the theory of choice under uncertainty},
+ journal = {Synthese},
+ year = {1966},
+ volume = {16},
+ number = {3--4},
+ pages = {253--269}
+}
+
+ at article{1951-ville,
+ author = {Jean Ville and P. K. Newman},
+ title = {The Existence-Conditions of a Total Utility Function },
+ journal = {The Review of Economic Studies},
+ year = {1951},
+ volume = {19},
+ number = {2},
+ pages = {123--128}
+}
+
+ at article{1934-hildebrandt,
+ author = {T. H. Hildebrandt},
+ title = {On Bounded Functional Operations},
+ journal = {Transactions of the American Mathematical Society},
+ year = {1934},
+ volume = {36},
+ number = {4},
+ pages = {868--875}
+}
+
+ at article{1986-genest-zidek-combining-probability-distributions,
+ author = {Christian Genest and James V. Zidek},
+ title = {Combining Probability Distributions: A Critique and an Annotated Bibliography},
+ journal = {Statistical Science},
+ year = {1986},
+ volume = {1},
+ number = {1},
+ pages = {114--148}
+}
+
+ at article{2001-kennedy-calibration,
+ author = {Marc C. Kennedy and Anthony O'Hagan},
+ title = {Bayesian Calibration of Computer Models},
+ journal = {Journal of the Royal Statistical Society, Series B},
+ year = {2001},
+ volume = {63},
+ number = {3},
+ pages = {425--464}
+}
diff --git a/test/latex_refs/conf.py b/test/latex_refs/conf.py
new file mode 100644
index 0000000..95dbf72
--- /dev/null
+++ b/test/latex_refs/conf.py
@@ -0,0 +1,7 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
+latex_documents = [
+ ('contents', 'test.tex',
+ u'Test',
+ u'Mr. Test', 'manual'),
+]
diff --git a/test/latex_refs/contents.rst b/test/latex_refs/contents.rst
new file mode 100644
index 0000000..7fa6ac6
--- /dev/null
+++ b/test/latex_refs/contents.rst
@@ -0,0 +1,7 @@
+Test
+====
+
+:cite:`1657:huygens`
+
+.. bibliography:: test.bib
+ :all:
diff --git a/test/latex_refs/test.bib b/test/latex_refs/test.bib
new file mode 100644
index 0000000..2bcab4a
--- /dev/null
+++ b/test/latex_refs/test.bib
@@ -0,0 +1,10 @@
+ at InCollection{1657:huygens,
+ author = {Christiaan Huygens},
+ title = {De Ratiociniis in Ludo Ale{\ae}},
+ booktitle = {Exercitationum Mathematicarum Libri Quinque: Quibus accedit {C}hristiani {H}ugenii Tractatus de Ratiociniis in Ale{\ae} Ludo},
+ pages = {517--524},
+ publisher = {Ex officina Johannis Elsevirii},
+ year = {1657},
+ editor = {Schooten, Franciscus {\'a}},
+ address = {Lugd. Batav.},
+}
diff --git a/test/list_bullet/conf.py b/test/list_bullet/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/list_bullet/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/list_bullet/contents.rst b/test/list_bullet/contents.rst
new file mode 100644
index 0000000..43d4669
--- /dev/null
+++ b/test/list_bullet/contents.rst
@@ -0,0 +1,3 @@
+.. bibliography:: test.bib
+ :list: bullet
+ :all:
diff --git a/test/list_bullet/test.bib b/test/list_bullet/test.bib
new file mode 100644
index 0000000..e404f01
--- /dev/null
+++ b/test/list_bullet/test.bib
@@ -0,0 +1,16 @@
+ at Misc{test1,
+ author = {Mr. Test Akkerdju},
+ title = {Test 1},
+}
+ at Misc{test2,
+ author = {Mr. Test Bro},
+ title = {Test 2},
+}
+ at Misc{test3,
+ author = {Mr. Test Chap},
+ title = {Test 1},
+}
+ at Misc{test4,
+ author = {Mr. Test Dude},
+ title = {Test 4},
+}
diff --git a/test/list_citation/conf.py b/test/list_citation/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/list_citation/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/list_citation/contents.rst b/test/list_citation/contents.rst
new file mode 100644
index 0000000..4360507
--- /dev/null
+++ b/test/list_citation/contents.rst
@@ -0,0 +1,4 @@
+.. bibliography:: test.bib
+ :style: plain
+ :list: citation
+ :all:
diff --git a/test/list_citation/test.bib b/test/list_citation/test.bib
new file mode 100644
index 0000000..e404f01
--- /dev/null
+++ b/test/list_citation/test.bib
@@ -0,0 +1,16 @@
+ at Misc{test1,
+ author = {Mr. Test Akkerdju},
+ title = {Test 1},
+}
+ at Misc{test2,
+ author = {Mr. Test Bro},
+ title = {Test 2},
+}
+ at Misc{test3,
+ author = {Mr. Test Chap},
+ title = {Test 1},
+}
+ at Misc{test4,
+ author = {Mr. Test Dude},
+ title = {Test 4},
+}
diff --git a/test/list_enumerated/conf.py b/test/list_enumerated/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/list_enumerated/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/list_enumerated/contents.rst b/test/list_enumerated/contents.rst
new file mode 100644
index 0000000..604fa2f
--- /dev/null
+++ b/test/list_enumerated/contents.rst
@@ -0,0 +1,14 @@
+.. bibliography:: test.bib
+ :list: enumerated
+ :all:
+
+.. bibliography:: test2.bib
+ :list: enumerated
+ :start: continue
+ :all:
+
+.. bibliography:: test3.bib
+ :list: enumerated
+ :start: 23
+ :all:
+
diff --git a/test/list_enumerated/test.bib b/test/list_enumerated/test.bib
new file mode 100644
index 0000000..e404f01
--- /dev/null
+++ b/test/list_enumerated/test.bib
@@ -0,0 +1,16 @@
+ at Misc{test1,
+ author = {Mr. Test Akkerdju},
+ title = {Test 1},
+}
+ at Misc{test2,
+ author = {Mr. Test Bro},
+ title = {Test 2},
+}
+ at Misc{test3,
+ author = {Mr. Test Chap},
+ title = {Test 1},
+}
+ at Misc{test4,
+ author = {Mr. Test Dude},
+ title = {Test 4},
+}
diff --git a/test/list_enumerated/test2.bib b/test/list_enumerated/test2.bib
new file mode 100644
index 0000000..216f76b
--- /dev/null
+++ b/test/list_enumerated/test2.bib
@@ -0,0 +1,16 @@
+ at Misc{test5,
+ author = {Mr. Test Eminence},
+ title = {Test 5},
+}
+ at Misc{test6,
+ author = {Mr. Test Frater},
+ title = {Test 6},
+}
+ at Misc{test7,
+ author = {Mr. Test Giggles},
+ title = {Test 7},
+}
+ at Misc{test8,
+ author = {Mr. Test Handy},
+ title = {Test 8},
+}
diff --git a/test/list_enumerated/test3.bib b/test/list_enumerated/test3.bib
new file mode 100644
index 0000000..2d8ed38
--- /dev/null
+++ b/test/list_enumerated/test3.bib
@@ -0,0 +1,16 @@
+ at Misc{test9,
+ author = {Mr. Test Iedereen},
+ title = {Test 9},
+}
+ at Misc{test10,
+ author = {Mr. Test Joke},
+ title = {Test 10},
+}
+ at Misc{test11,
+ author = {Mr. Test Klopgeest},
+ title = {Test 11},
+}
+ at Misc{test12,
+ author = {Mr. Test Laterfanter},
+ title = {Test 12},
+}
diff --git a/test/list_invalid/conf.py b/test/list_invalid/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/list_invalid/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/list_invalid/contents.rst b/test/list_invalid/contents.rst
new file mode 100644
index 0000000..ba36d67
--- /dev/null
+++ b/test/list_invalid/contents.rst
@@ -0,0 +1,2 @@
+.. bibliography:: test.bib
+ :list: thisisintentionallyinvalid
diff --git a/test/list_invalid/test.bib b/test/list_invalid/test.bib
new file mode 100644
index 0000000..e69de29
diff --git a/test/path.py b/test/path.py
new file mode 100644
index 0000000..0b947e3
--- /dev/null
+++ b/test/path.py
@@ -0,0 +1,198 @@
+#!/usr/bin/env python
+# coding: utf-8
+"""
+ path
+ ~~~~
+
+ :copyright: Copyright 2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+import os
+import sys
+import shutil
+from codecs import open
+from six.moves import map
+
+
+FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding()
+
+
+class path(str):
+
+ """
+ Represents a path which behaves like a string.
+ """
+ if sys.version_info < (3, 0):
+ def __new__(cls, s, encoding=FILESYSTEMENCODING, errors='strict'):
+ if isinstance(s, unicode):
+ s = s.encode(encoding, errors=errors)
+ return str.__new__(cls, s)
+ return str.__new__(cls, s)
+
+ @property
+ def parent(self):
+ """
+ The name of the directory the file or directory is in.
+ """
+ return self.__class__(os.path.dirname(self))
+
+ def abspath(self):
+ """
+ Returns the absolute path.
+ """
+ return self.__class__(os.path.abspath(self))
+
+ def isabs(self):
+ """
+ Returns ``True`` if the path is absolute.
+ """
+ return os.path.isabs(self)
+
+ def isdir(self):
+ """
+ Returns ``True`` if the path is a directory.
+ """
+ return os.path.isdir(self)
+
+ def isfile(self):
+ """
+ Returns ``True`` if the path is a file.
+ """
+ return os.path.isfile(self)
+
+ def islink(self):
+ """
+ Returns ``True`` if the path is a symbolic link.
+ """
+ return os.path.islink(self)
+
+ def ismount(self):
+ """
+ Returns ``True`` if the path is a mount point.
+ """
+ return os.path.ismount(self)
+
+ def rmtree(self, ignore_errors=False, onerror=None):
+ """
+ Removes the file or directory and any files or directories it may
+ contain.
+
+ :param ignore_errors:
+ If ``True`` errors are silently ignored, otherwise an exception
+ is raised in case an error occurs.
+
+ :param onerror:
+ A callback which gets called with the arguments `func`, `path` and
+ `exc_info`. `func` is one of :func:`os.listdir`, :func:`os.remove`
+ or :func:`os.rmdir`. `path` is the argument to the function which
+ caused it to fail and `exc_info` is a tuple as returned by
+ :func:`sys.exc_info`.
+ """
+ shutil.rmtree(self, ignore_errors=ignore_errors, onerror=onerror)
+
+ def copytree(self, destination, symlinks=False):
+ """
+ Recursively copy a directory to the given `destination`. If the given
+ `destination` does not exist it will be created.
+
+ :param symlinks:
+ If ``True`` symbolic links in the source tree result in symbolic
+ links in the destination tree otherwise the contents of the files
+ pointed to by the symbolic links are copied.
+ """
+ shutil.copytree(self, destination, symlinks=symlinks)
+
+ def movetree(self, destination):
+ """
+ Recursively move the file or directory to the given `destination`
+ similar to the Unix "mv" command.
+
+ If the `destination` is a file it may be overwritten depending on the
+ :func:`os.rename` semantics.
+ """
+ shutil.move(self, destination)
+
+ move = movetree
+
+ def unlink(self):
+ """
+ Removes a file.
+ """
+ os.unlink(self)
+
+ def write_text(self, text, **kwargs):
+ """
+ Writes the given `text` to the file.
+ """
+ f = open(self, 'w', **kwargs)
+ try:
+ f.write(text)
+ finally:
+ f.close()
+
+ def text(self, **kwargs):
+ """
+ Returns the text in the file.
+ """
+ f = open(self, mode='U', **kwargs)
+ try:
+ return f.read()
+ finally:
+ f.close()
+
+ def bytes(self):
+ """
+ Returns the bytes in the file.
+ """
+ f = open(self, mode='rb')
+ try:
+ return f.read()
+ finally:
+ f.close()
+
+ def write_bytes(self, bytes, append=False):
+ """
+ Writes the given `bytes` to the file.
+
+ :param append:
+ If ``True`` given `bytes` are added at the end of the file.
+ """
+ if append:
+ mode = 'ab'
+ else:
+ mode = 'wb'
+ f = open(self, mode=mode)
+ try:
+ f.write(bytes)
+ finally:
+ f.close()
+
+ def exists(self):
+ """
+ Returns ``True`` if the path exist.
+ """
+ return os.path.exists(self)
+
+ def lexists(self):
+ """
+ Returns ``True`` if the path exists unless it is a broken symbolic
+ link.
+ """
+ return os.path.lexists(self)
+
+ def makedirs(self, mode=0o777):
+ """
+ Recursively create directories.
+ """
+ os.makedirs(self, mode)
+
+ def joinpath(self, *args):
+ """
+ Joins the path with the argument given and returns the result.
+ """
+ return self.__class__(os.path.join(self, *map(self.__class__, args)))
+
+ __div__ = __truediv__ = joinpath
+
+ def __repr__(self):
+ return '%s(%s)' % (self.__class__.__name__, str.__repr__(self))
diff --git a/test/sphinx/Makefile b/test/sphinx/Makefile
new file mode 100644
index 0000000..9c6eac1
--- /dev/null
+++ b/test/sphinx/Makefile
@@ -0,0 +1,130 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Sphinxbibtexextensiontest.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Sphinxbibtexextensiontest.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/Sphinxbibtexextensiontest"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Sphinxbibtexextensiontest"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ make -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/test/sphinx/conf.py b/test/sphinx/conf.py
new file mode 100644
index 0000000..1a3d301
--- /dev/null
+++ b/test/sphinx/conf.py
@@ -0,0 +1,2 @@
+extensions = ['sphinxcontrib.bibtex']
+exclude_patterns = ['_build']
diff --git a/test/sphinx/contents.rst b/test/sphinx/contents.rst
new file mode 100644
index 0000000..f3cd998
--- /dev/null
+++ b/test/sphinx/contents.rst
@@ -0,0 +1,25 @@
+.. Sphinx bibtex extension test documentation master file, created by
+ sphinx-quickstart on Mon Mar 21 14:37:33 2011.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to Sphinx bibtex extension test's documentation!
+========================================================
+
+Citation :cite:`1996:fukuda` :cite:`dreze:2000` to other document.
+Regular citation test [Test01]_ to other document.
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ zbibliography
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/test/sphinx/make.bat b/test/sphinx/make.bat
new file mode 100644
index 0000000..a94891a
--- /dev/null
+++ b/test/sphinx/make.bat
@@ -0,0 +1,170 @@
+ at ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Sphinxbibtexextensiontest.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Sphinxbibtexextensiontest.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+:end
diff --git a/test/sphinx/subfolder/test.bib b/test/sphinx/subfolder/test.bib
new file mode 100644
index 0000000..baaf61e
--- /dev/null
+++ b/test/sphinx/subfolder/test.bib
@@ -0,0 +1,12 @@
+ at TechReport{dreze:2000,
+ author={Dr{\'e}ze, Jacques H. and Rustichini, Aldo},
+ title={State-dependent utility and decision theory},
+ year=2000,
+ month=feb,
+ institution={Universit{\'e} catholique de Louvain, Center for Operations Research and Econometrics (CORE)},
+ type={CORE Discussion Papers},
+ url={http://ideas.repec.org/p/cor/louvco/2000007.html},
+ number={2000007},
+ OPTabstract={},
+ OPTkeywords={}
+}
diff --git a/test/sphinx/test.bib b/test/sphinx/test.bib
new file mode 100644
index 0000000..628e66c
--- /dev/null
+++ b/test/sphinx/test.bib
@@ -0,0 +1,275 @@
+ at InCollection{1657:huygens,
+ author = {Christiaan Huygens},
+ title = {De Ratiociniis in Ludo Ale{\ae}},
+ booktitle = {Exercitationum Mathematicarum Libri Quinque: Quibus accedit {C}hristiani {H}ugenii Tractatus de Ratiociniis in Ale{\ae} Ludo},
+ OPTcrossref = {},
+ OPTkey = {},
+ pages = {517--524},
+ publisher = {Ex officina Johannis Elsevirii},
+ year = {1657},
+ editor = {Schooten, Franciscus {\'a}},
+ OPTvolume = {},
+ OPTnumber = {},
+ OPTseries = {},
+ OPTtype = {},
+ OPTchapter = {},
+ address = {Lugd. Batav.},
+ OPTedition = {},
+ OPTmonth = {},
+ OPTnote = {},
+ OPTannote = {}
+}
+
+ at Book{joyce:1999,
+ author = {Joyce, James},
+ ALTeditor = {},
+ title = {The Foundations of Causal Decision Theory},
+ publisher = {Cambridge University Press},
+ year = {1999},
+ OPTkey = {},
+ OPTvolume = {},
+ OPTnumber = {},
+ OPTseries = {},
+ OPTaddress = {},
+ OPTedition = {},
+ OPTmonth = {},
+ OPTnote = {},
+ OPTannote = {}
+}
+
+ at Unpublished{2011:troffaes:isipta:natext,
+ author = {Matthias C. M. Troffaes and Robert Hable},
+ title = {Robustness of Natural Extension},
+ OPTcrossref = {},
+ OPTkey = {},
+ OPTbooktitle = {},
+ OPTpages = {},
+ year = {2011},
+ OPTeditor = {},
+ OPTvolume = {},
+ OPTnumber = {},
+ OPTseries = {},
+ OPTaddress = {},
+ OPTmonth = {},
+ OPTorganization = {},
+ OPTpublisher = {},
+ note = {Submitted to ISIPTA'11},
+ OPTannote = {}
+}
+
+%@Proceedings{2010:coolen:oberguggenberger:troffaes::jrr,
+% title = {Proceedings of the Institution of Mechanical Engineers, Part O: Journal of Risk and Reliability},
+% year = {2010},
+% OPTkey = {},
+% OPTbooktitle = {},
+% editor = {Frank P. A. Coolen and Michael Oberguggenberger and Matthias C. M. Troffaes},
+% volume = {224},
+% number = {4},
+% OPTseries = {},
+% OPTaddress = {},
+% OPTmonth = {},
+% OPTorganization = {},
+% OPTpublisher = {},
+% note = {Special Issue on Uncertainty in Engineering and Risk Reliability},
+% OPTannote = {}
+%}
+
+ at Article{1996:fukuda,
+ author = {K. Fukuda and A. Prodon},
+ title = {Double description method revisited},
+ journal = {Combinatorics and Computer Science},
+ year = {1996},
+ OPTkey = {},
+ volume = {1120},
+ OPTnumber = {},
+ pages = {91--111},
+ OPTmonth = {},
+ OPTnote = {},
+ OPTannote = {},
+ note={\url{http://www.ifor.math.ethz.ch/~fukuda/cdd_home/}}
+}
+
+ at Misc{2009:defra:animal:health,
+ author = {Defra},
+ title = {Impact assessment of an independent body for animal health in {E}ngland},
+ year = {2009},
+ note = {\url{http://www.defra.gov.uk/corporate/consult/newindependent-body-ah/impact-assessment.pdf}},
+}
+
+ at Misc{test:url,
+ OPTkey = {},
+ author = {Mr. Test},
+ title = {Testing the url command in references},
+ OPThowpublished = {},
+ OPTmonth = {},
+ OPTyear = {},
+ note = {\url{http://www.google.com} and \url{http://www.yahoo.com}},
+ OPTannote = {}
+}
+
+ at MASTERSTHESIS{2000:troffaes:msthesis,
+ AUTHOR = {Matthias C. M. Troffaes},
+ TITLE = {Quantum algorithmes: theoretische aspecten en toepassingen},
+ SCHOOL = {Universiteit Gent},
+ YEAR = {2000},
+ OPTKEY = {},
+ OPTTYPE = {},
+ OPTADDRESS = {Gent},
+ MONTH = {May},
+ OPTNOTE = {},
+ OPTANNOTE = {}
+}
+
+ at PhdThesis{2008:hable:thesis,
+ author = {Robert Hable},
+ title = {Data-Based Decisions under Complex Uncertainty},
+ school = {Ludwig-Maximilians-Universit{\"a}t M{\"u}nchen},
+ year = {2008},
+ OPTkey = {},
+ OPTtype = {},
+ OPTaddress = {},
+ OPTmonth = {},
+ OPTnote = {},
+ OPTannote = {}
+}
+
+ at BOOKLET{Sherwood,
+author="D.A. Sherwood",
+title="Phosphorus Loads Entering Long Pond, A Small Embayment of Lake {O}ntario near {R}ochester, {N}ew {Y}ork",
+howpublished="USGS Fact Sheet 128-99",
+pages=4,
+month="November",
+year=1999,
+}
+
+ at InProceedings{2005:cormack,
+ author = {Cormack, G. V. and Lynam, T. R.},
+ title = {Spam Corpus Creation for TREC},
+ OPTcrossref = {},
+ OPTkey = {},
+ booktitle = {Proceedings of the Second Conference on Email and Anti-Spam},
+ OPTpages = {},
+ year = {2005},
+ OPTeditor = {},
+ OPTvolume = {},
+ OPTnumber = {},
+ OPTseries = {},
+ address = {Palo Alto},
+ month = {Jul},
+ OPTorganization = {},
+ OPTpublisher = {},
+ OPTnote = {},
+ OPTannote = {}
+}
+
+ at MANUAL{RSI,
+author="RSI",
+title="ENVI User's Guide",
+publisher="Reasearch Systems Incorporated",
+organization="Research Systems Incorporated",
+howpublished="PDF File",
+address="Boulder, CO",
+month="September",
+year=2001,
+}
+
+ at InBook{Kristensen83,
+ author = {B. B. Kristensen and Ole L. Madsen and B. M{\o}ller-Pedersen and K. Nygaard},
+ editor = {P. Degano and E. Sandewall},
+ title = {Integrated Interactive Computing Systems},
+ chapter = {Syntax-directed program modularization},
+ publisher = {North-Holland, Amsterdam},
+ year = {1983},
+ pages = {207-219}
+}
+
+ at InCollection{2004:seidenfeld::rubinesque,
+ author = {J. B. Kadane and Mark J. Schervish and Teddy Seidenfeld},
+ title = {A {R}ubinesque theory of decision},
+ booktitle = {A festschrift for {H}erman {R}ubin},
+ OPTcrossref = {},
+ OPTkey = {},
+ pages = {45--55},
+ publisher = {Inst. Math. Statist.},
+ year = {2004},
+ OPTeditor = {},
+ volume = {45},
+ OPTnumber = {},
+ series = {IMS Lecture Notes -- Monograph Series},
+ OPTtype = {},
+ OPTchapter = {},
+ address = {Beachwood, Ohio},
+ OPTedition = {},
+ OPTmonth = {},
+ OPTnote = {},
+ OPTannote = {}
+}
+
+%%% taken from Jason K. Moore's thesis; it is a good complex long entry for testing
+ at ARTICLE{Astrom2005,
+ author = {{\AA}str{\"o}m, Karl J. and Klein, Richard E. and Lennartsson, Anders},
+ title = {Bicycle Dynamics and Control},
+ journal = {IEEE Control Systems Magazine},
+ year = {2005},
+ volume = {25},
+ pages = {26--47},
+ number = {4},
+ month = {August},
+ abstract = {This article analyzes the dynamics of bicycles from the perspective
+ of control. Models of different complexity are presented, starting
+ with simple ones and ending with more realistic models generated
+ from multibody software. We consider models that capture essential
+ behavior such as self-stabilization as well as models that demonstrate
+ difficulties with rear wheel steering. We relate our experiences
+ using bicycles in control education along with suggestions for fun
+ and thought-provoking experiments with proven student attraction.
+ Finally, we describe bicycles and clinical programs designed for
+ children with disabilities.},
+ bib = {bibtex-keys#Astrom2005},
+ bibpr = {private-bibtex-keys#Astrom2005},
+ doi = {10.1109/MCS.2005.1499389},
+ file = {Astrom2005.pdf:Astrom2005.pdf:PDF},
+ keywords = {bicycles, control engineering computing, control engineering education,design,
+ handicapped aids, nonlinear control systems, nonlinear dynamicalsystems,
+ position control, stability bicycle control, bicycle dynamics, clinical
+ programs, computer simulation, control education, disabled children,
+ dynamic behavior, inverted pendulum, modelling, multibody software,
+ nonminimum phase steering behavior, rear wheel steering difficulties,
+ self-stabilization},
+ owner = {moorepants},
+ review = {Shows a steer torque measurement system constructed for the UCSB instrumented
+ bicycle but with little extra information. They use a linear force
+ transducer of some sort mounted on the handlebars.
+
+
+ They first show the point mass model like Karnopp's 2004 model (older
+ ones are referenced in Meijaard2007). They stablize the steer angel
+ to roll angle transfer function with a negative feedback gain which
+ has dependence on the forward velocity.
+
+
+ He adds a basic model of the front fork geometry to the point mass
+ model, giving a relationship between steer torque input and steer
+ angle which is speed dependent. The roll angle to steer angle now
+ has a builtin negative feedback law due to the front fork geometry
+ and if the k2 gain is large enough (with steer torque = 0) the system
+ is stable. He uses this to calculat a critical velocity for stability.
+
+
+ Klein says you should grip the handlebars lightly to take advantage
+ of the bicycle self stability. This corresponds to the differences
+ in the Whipple model and one with arms.
+
+
+ Cites Wier1972 as giving 0.1s and 0.3s of nueromuscular delay in steer
+ torque and upper body lean, respectively.
+
+
+ The gyroscopic effects give rise to derivative feedback.
+
+
+ Claims that riders use variation in forward speed as an additional
+ control variable.},
+ timestamp = {2008.10.16},
+ webpdf = {references-folder/Astrom2005.pdf}
+}
diff --git a/test/sphinx/test2.bib b/test/sphinx/test2.bib
new file mode 100644
index 0000000..aed4e0f
--- /dev/null
+++ b/test/sphinx/test2.bib
@@ -0,0 +1,53 @@
+ at ARTICLE{1979:shafer,
+ AUTHOR = {Glenn Shafer},
+ TITLE = {Allocations of Probability},
+ JOURNAL = {The Annals of Probability},
+ YEAR = {1979},
+ OPTKEY = {},
+ VOLUME = {7},
+ NUMBER = {5},
+ PAGES = {827--839},
+ MONTH = OCT,
+ OPTNOTE = {},
+ OPTANNOTE = {}
+}
+
+ at ARTICLE{1977:morris,
+ AUTHOR = {Peter A. Morris},
+ TITLE = {Combining expert judgments: a {B}ayesian approach},
+ JOURNAL = {Management Science},
+ YEAR = {1977},
+ OPTKEY = {},
+ VOLUME = {23},
+ NUMBER = {7},
+ PAGES = {679--693},
+ MONTH = {March},
+ OPTNOTE = {},
+ OPTANNOTE = {}
+}
+
+ at BOOK{1972:savage,
+ AUTHOR = {Leonard J. Savage},
+ ALTEDITOR = {},
+ TITLE = {The Foundations of Statistics},
+ PUBLISHER = {Dover},
+ YEAR = {1972},
+ OPTKEY = {},
+ OPTVOLUME = {},
+ OPTNUMBER = {},
+ OPTSERIES = {},
+ ADDRESS = {New York},
+ OPTEDITION = {},
+ OPTMONTH = {},
+ NOTE = {Second revised edition},
+ OPTANNOTE = {}
+}
+
+ at BOOK{rockafellar:1970,
+ AUTHOR = {R. Tyrrell Rockafellar},
+ ALTEDITOR = {},
+ TITLE = {Convex Analysis},
+ PUBLISHER = {Princeton University Press},
+ YEAR = {1970},
+ ADDRESS = {Princeton}
+}
diff --git a/test/sphinx/zbibliography.rst b/test/sphinx/zbibliography.rst
new file mode 100644
index 0000000..7cb9e88
--- /dev/null
+++ b/test/sphinx/zbibliography.rst
@@ -0,0 +1,59 @@
+Testing the bibliography directive
+==================================
+
+Text
+----
+
+Huyghens :cite:`1657:huygens` wrote one of the first books on
+probability theory.
+
+Mix with a footnote [#note]_ and a regular citation [Test01]_.
+
+Another citation :cite:`dreze:2000`.
+
+Another reference to footnotes [#note]_ and [#note2]_.
+More regular citations [Test01]_ and [Test02]_.
+
+Extra reference to a footnote [#footnote-walley2004]_.
+
+Extra reference to a citation [Wa04]_.
+
+Another few citations: :cite:`rockafellar:1970,1972:savage`.
+
+More citations:
+
+.. rubric:: References
+
+.. bibliography:: test.bib subfolder/test.bib
+ :all:
+ :labelprefix: A
+
+.. rubric:: References (Cited Test)
+
+.. bibliography:: test2.bib
+ :cited:
+ :labelprefix: B
+
+.. rubric:: References (Not Cited Test)
+
+.. bibliography:: test2.bib
+ :notcited:
+ :labelprefix: C
+
+.. rubric:: Footnotes
+
+.. [#note] A footnote.
+.. [#note2] Another footnote.
+.. [#footnote-walley2004]
+
+ Peter Walley, Renato Pelessoni, and Paolo Vicig. Journal of
+ Statistical Planning and Inference, 126(1):119-151, November 2004.
+
+.. rubric:: Citations
+
+.. [Test01] A regular citation.
+.. [Test02] Another regular citation.
+.. [Wa04]
+
+ Peter Walley, Renato Pelessoni, and Paolo Vicig. Journal of
+ Statistical Planning and Inference, 126(1):119-151, November 2004.
diff --git a/test/test_bibfile_out_of_date.py b/test/test_bibfile_out_of_date.py
new file mode 100644
index 0000000..01f1fb7
--- /dev/null
+++ b/test/test_bibfile_out_of_date.py
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+"""
+ test_bibfile_out_of_date
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Test that updates to the bibfile generate the correct result when
+ Sphinx is run again.
+"""
+
+import os.path
+import shutil
+import re
+import time
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('bibfile_out_of_date').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+ os.remove(srcdir / 'test.bib')
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_encoding(app):
+ shutil.copyfile(
+ os.path.join(srcdir, 'test_old.bib'),
+ os.path.join(srcdir, 'test.bib'))
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ assert re.search(
+ '<p id="bibtex-bibliography-contents-0">'
+ '.*<tr><td class="label">\\[1\\]</td><td>.*Akkerdju.*</td></tr>'
+ '.*<tr><td class="label">\\[2\\]</td><td>.*Bro.*</td></tr>'
+ '.*<tr><td class="label">\\[3\\]</td><td>.*Chap.*</td></tr>'
+ '.*<tr><td class="label">\\[4\\]</td><td>.*Dude.*</td></tr>'
+ '.*</p>',
+ stream.read(), re.MULTILINE | re.DOTALL)
+ # wait to ensure different timestamp
+ time.sleep(0.1)
+ shutil.copyfile(
+ os.path.join(srcdir, 'test_new.bib'),
+ os.path.join(srcdir, 'test.bib'))
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ assert re.search(
+ '<p id="bibtex-bibliography-contents-0">'
+ '.*<tr><td class="label">\\[1\\]</td><td>.*Eminence.*</td></tr>'
+ '.*<tr><td class="label">\\[2\\]</td><td>.*Frater.*</td></tr>'
+ '.*<tr><td class="label">\\[3\\]</td><td>.*Giggles.*</td></tr>'
+ '.*<tr><td class="label">\\[4\\]</td><td>.*Handy.*</td></tr>'
+ '.*</p>',
+ stream.read(), re.MULTILINE | re.DOTALL)
diff --git a/test/test_bibfilenotfound.py b/test/test_bibfilenotfound.py
new file mode 100644
index 0000000..05d977f
--- /dev/null
+++ b/test/test_bibfilenotfound.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+"""
+ test_bibfilenotfound
+ ~~~~~~~~~~~~~~~~~~~~
+
+ Bib file not found check.
+"""
+
+import re
+from six import StringIO
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('bibfilenotfound').abspath()
+warnfile = StringIO()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warning=warnfile)
+def test_bibfilenotfound(app):
+ app.builder.build_all()
+ warnings = warnfile.getvalue()
+ assert re.search('could not open bibtex file .*unknown[.]bib', warnings)
diff --git a/test/test_citationnotfound.py b/test/test_citationnotfound.py
new file mode 100644
index 0000000..58b81ed
--- /dev/null
+++ b/test/test_citationnotfound.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+"""
+ test_citationnotfound
+ ~~~~~~~~~~~~~~~~~~~~~
+
+ Citation not found check.
+"""
+
+import re
+from six import StringIO
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('citationnotfound').abspath()
+warnfile = StringIO()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warning=warnfile)
+def test_citationnotfound(app):
+ app.builder.build_all()
+ warnings = warnfile.getvalue()
+ assert re.search('citation not found: nosuchkey', warnings)
diff --git a/test/test_custom_style.py b/test/test_custom_style.py
new file mode 100644
index 0000000..2876940
--- /dev/null
+++ b/test/test_custom_style.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+"""
+ test_custom_style
+ ~~~~~~~~~~~~~~~~~
+
+ Test a custom style.
+"""
+
+import os.path
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('custom_style').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_custom_style(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ output = stream.read()
+ # the custom style suppresses web links
+ assert not re.search('http://arxiv.org', output)
+ assert not re.search('http://dx.doi.org', output)
diff --git a/test/test_filter.py b/test/test_filter.py
new file mode 100644
index 0000000..7350bca
--- /dev/null
+++ b/test/test_filter.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+"""
+ test_filter
+ ~~~~~~~~~~~
+
+ Test filter option.
+"""
+
+import os.path
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('filter').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_filter(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ output = stream.read()
+ assert re.search('Tralalala', output)
+ assert not re.search('ideetje', output)
+ assert not re.search('Jakkamakka', output)
+ with open(os.path.join(app.outdir, "or.html")) as stream:
+ output = stream.read()
+ assert not re.search('Tralalala', output)
+ assert re.search('ideetje', output)
+ assert re.search('Jakkamakka', output)
+ with open(os.path.join(app.outdir, "noteq.html")) as stream:
+ output = stream.read()
+ assert re.search('Tralalala', output)
+ assert re.search('ideetje', output)
+ assert not re.search('Jakkamakka', output)
+ with open(os.path.join(app.outdir, "lt.html")) as stream:
+ output = stream.read()
+ assert re.search('Tralalala', output)
+ assert not re.search('ideetje', output)
+ assert not re.search('Jakkamakka', output)
+ with open(os.path.join(app.outdir, "lte.html")) as stream:
+ output = stream.read()
+ assert re.search('Tralalala', output)
+ assert not re.search('ideetje', output)
+ assert re.search('Jakkamakka', output)
+ with open(os.path.join(app.outdir, "gt.html")) as stream:
+ output = stream.read()
+ assert not re.search('Tralalala', output)
+ assert re.search('ideetje', output)
+ assert not re.search('Jakkamakka', output)
+ with open(os.path.join(app.outdir, "gte.html")) as stream:
+ output = stream.read()
+ assert not re.search('Tralalala', output)
+ assert re.search('ideetje', output)
+ assert re.search('Jakkamakka', output)
+ with open(os.path.join(app.outdir, "key.html")) as stream:
+ output = stream.read()
+ assert not re.search('Tralalala', output)
+ assert re.search('ideetje', output)
+ assert not re.search('Jakkamakka', output)
+ with open(os.path.join(app.outdir, "false.html")) as stream:
+ output = stream.read()
+ assert not re.search('Tralalala', output)
+ assert not re.search('ideetje', output)
+ assert not re.search('Jakkamakka', output)
+ with open(os.path.join(app.outdir, "title.html")) as stream:
+ output = stream.read()
+ assert not re.search('Tralalala', output)
+ assert not re.search('ideetje', output)
+ assert re.search('Jakkamakka', output)
diff --git a/test/test_filter_fix_author_keyerror.py b/test/test_filter_fix_author_keyerror.py
new file mode 100644
index 0000000..9063276
--- /dev/null
+++ b/test/test_filter_fix_author_keyerror.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+"""
+ test_filter_fix_author_keyerror
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Test for a bug in the filter option.
+"""
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('filter_fix_author_keyerror').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_filter_fix_author_keyerror(app):
+ app.builder.build_all()
diff --git a/test/test_filter_option_clash.py b/test/test_filter_option_clash.py
new file mode 100644
index 0000000..55921dd
--- /dev/null
+++ b/test/test_filter_option_clash.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+"""
+ test_filter_option_clash
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Test filter option clash with all, cited, and notcited.
+"""
+
+from six import StringIO
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('filter_option_clash').abspath()
+warnfile = StringIO()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warning=warnfile)
+def test_filter_option_clash(app):
+ app.builder.build_all()
+ warnings = warnfile.getvalue()
+ assert re.search(':filter: overrides :all:', warnings)
+ assert re.search(':filter: overrides :cited:', warnings)
+ assert re.search(':filter: overrides :notcited:', warnings)
diff --git a/test/test_filter_syntax_error.py b/test/test_filter_syntax_error.py
new file mode 100644
index 0000000..0c640ce
--- /dev/null
+++ b/test/test_filter_syntax_error.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+"""
+ test_filter_syntax_error
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Test response on syntax errors in filter.
+"""
+
+import nose.tools
+from six import StringIO
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('filter_syntax_error').abspath()
+warnfile = StringIO()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warning=warnfile)
+def test_filter_syntax_error(app):
+ app.builder.build_all()
+ warnings = warnfile.getvalue()
+ nose.tools.assert_equal(
+ len(re.findall('syntax error in :filter: expression', warnings)), 9)
diff --git a/test/test_invalid_cite_option.py b/test/test_invalid_cite_option.py
new file mode 100644
index 0000000..536f0d9
--- /dev/null
+++ b/test/test_invalid_cite_option.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+"""
+ test_invalid_cite_option
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Test behaviour when invalid cite option is given.
+"""
+
+import re
+from six import StringIO
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('invalid_cite_option').abspath()
+warnfile = StringIO()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warning=warnfile)
+def test_invalid_cite_option(app):
+ app.builder.build_all()
+ warnings = warnfile.getvalue()
+ assert re.search('unknown option: "thisisintentionallyinvalid"', warnings)
diff --git a/test/test_issue1.py b/test/test_issue1.py
new file mode 100644
index 0000000..c0fe51a
--- /dev/null
+++ b/test/test_issue1.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+"""
+ test_issue1
+ ~~~~~~~~~~~
+
+ Test Tinkerer and check output.
+"""
+
+import nose.tools
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue1').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_tinker(app):
+ app.builder.build_all()
+ nose.tools.assert_equal(
+ app.env.bibtex_cache.get_cited_docnames(u"2011:BabikerIPv6"),
+ {u"2012/07/24/hello_world_"})
+ nose.tools.assert_equal(
+ app.env.bibtex_cache.get_label_from_key(u"2011:BabikerIPv6"), u"BNC11")
diff --git a/test/test_issue14.py b/test/test_issue14.py
new file mode 100644
index 0000000..1dbf440
--- /dev/null
+++ b/test/test_issue14.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+"""
+ test_issue14
+ ~~~~~~~~~~~~
+
+ Test duplicate label issue.
+"""
+
+from six import StringIO
+import os.path
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue14').abspath()
+warnfile = StringIO()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warning=warnfile)
+def test_duplicate_label(app):
+ app.builder.build_all()
+ warnings = warnfile.getvalue()
+ assert re.search(
+ 'duplicate label for keys (Test and Test2)|(Test2 and Test)',
+ warnings)
+ with open(os.path.join(app.outdir, "doc1.html")) as stream:
+ assert re.search('<td class="label">\\[1\\]</td>', stream.read())
+ with open(os.path.join(app.outdir, "doc2.html")) as stream:
+ assert re.search('<td class="label">\\[1\\]</td>', stream.read())
diff --git a/test/test_issue14_2.py b/test/test_issue14_2.py
new file mode 100644
index 0000000..8d1eb40
--- /dev/null
+++ b/test/test_issue14_2.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+"""
+ test_issue14_2
+ ~~~~~~~~~~~~~~
+
+ Test labelprefix option.
+"""
+
+import os.path
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue14_2').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_label_prefix(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "doc1.html")) as stream:
+ assert re.search('<td class="label">\\[A1\\]</td>', stream.read())
+ with open(os.path.join(app.outdir, "doc2.html")) as stream:
+ assert re.search('<td class="label">\\[B1\\]</td>', stream.read())
diff --git a/test/test_issue15.py b/test/test_issue15.py
new file mode 100644
index 0000000..6f80832
--- /dev/null
+++ b/test/test_issue15.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+"""
+ test_issue15
+ ~~~~~~~~~~~~
+
+ Test order of bibliography entries when using an unsorted style.
+"""
+
+from six import StringIO
+import os.path
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue15').abspath()
+warnfile = StringIO()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_duplicate_label(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ assert re.search(
+ '<tr>.*Test 1.*</tr>.*<tr>.*Test 2.*</tr>',
+ stream.read(), re.DOTALL)
diff --git a/test/test_issue17.py b/test/test_issue17.py
new file mode 100644
index 0000000..9a64cd7
--- /dev/null
+++ b/test/test_issue17.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+"""
+ test_issue17
+ ~~~~~~~~~~~~
+
+ Test that sphinx [source] links do not generate a warning.
+"""
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue17').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_sphinx_source_no_warning(app):
+ app.builder.build_all()
diff --git a/test/test_issue2.py b/test/test_issue2.py
new file mode 100644
index 0000000..675bb3a
--- /dev/null
+++ b/test/test_issue2.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+"""
+ test_issue2
+ ~~~~~~~~~~~
+
+ Test mixing of ``:cite:`` and ``[]_``.
+"""
+
+import nose.tools
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue2').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_mixing_citation_styles(app):
+ app.builder.build_all()
+ nose.tools.assert_equal(
+ app.env.bibtex_cache.get_cited_docnames(u"Test"), {u"adoc1"})
+ nose.tools.assert_equal(
+ app.env.bibtex_cache.get_label_from_key(u"Test"), u"1")
diff --git a/test/test_issue4.py b/test/test_issue4.py
new file mode 100644
index 0000000..60cf279
--- /dev/null
+++ b/test/test_issue4.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+"""
+ test_issue4
+ ~~~~~~~~~~~
+
+ Test the ``:encoding:`` option.
+"""
+
+import os.path
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue4').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_encoding(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ assert re.search("Tést☺", stream.read())
diff --git a/test/test_issue61.py b/test/test_issue61.py
new file mode 100644
index 0000000..1e57313
--- /dev/null
+++ b/test/test_issue61.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+"""
+ test_issue61
+ ~~~~~~~~~~~~
+
+ Test multiple keys in a single cite.
+"""
+
+import os
+import re
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue61').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_multiple_keys(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ code = stream.read()
+ assert re.search('class="reference internal" href="#testone"', code)
+ assert re.search('class="reference internal" href="#testtwo"', code)
diff --git a/test/test_issue62.py b/test/test_issue62.py
new file mode 100644
index 0000000..897f30f
--- /dev/null
+++ b/test/test_issue62.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+"""
+ test_issue62
+ ~~~~~~~~~~~~
+
+ Test local bibliographies.
+"""
+
+import os
+import re
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue62').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+def extract_references(code):
+ return frozenset(re.findall(
+ '<a class="reference internal" href="([^"]+)"', code))
+
+
+def extract_citations(code):
+ return frozenset(re.findall(
+ '<table class="docutils citation" frame="void" id="([^"]+)"', code))
+
+
+def check_code(code, refs, cites, otherrefs, othercites):
+ code_refs = extract_references(code)
+ code_cites = extract_citations(code)
+ # use <= here because refs contains all internal references, not
+ # just citation references
+ assert refs <= code_refs
+ assert cites == code_cites
+ assert not(otherrefs & code_refs)
+ assert not(othercites & code_cites)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_local_bibliographies(app):
+ doc1_refs = frozenset([
+ '#wustner-atomistic-2014',
+ '#fuhrmans-molecular-2012',
+ '#blume-apparent-1983',
+ '#grabitz-relaxation-2002',
+ ])
+ doc1_cites = frozenset([
+ 'blume-apparent-1983',
+ 'wustner-atomistic-2014',
+ 'fuhrmans-molecular-2012',
+ 'grabitz-relaxation-2002'
+ ])
+ doc2_refs = frozenset([
+ '#shirts-simple-2013'
+ ])
+ doc2_cites = frozenset([
+ 'shirts-simple-2013'
+ ])
+ sum_refs = frozenset([
+ "#mcmahon-membrane-2010",
+ "#hu-gaussian-2013",
+ "doc1.html#fuhrmans-molecular-2012",
+ "#risselada-curvature-dependent-2011",
+ "#risselada-curvature-2009",
+ "#marrink-mechanism-2003",
+ ])
+ sum_cites = frozenset([
+ 'hu-gaussian-2013',
+ 'marrink-mechanism-2003',
+ 'risselada-curvature-2009',
+ 'risselada-curvature-dependent-2011',
+ 'mcmahon-membrane-2010',
+ ])
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "doc1.html")) as stream:
+ check_code(stream.read(), doc1_refs, doc1_cites,
+ doc2_refs | sum_refs, doc2_cites | sum_cites)
+ with open(os.path.join(app.outdir, "doc2.html")) as stream:
+ check_code(stream.read(), doc2_refs, doc2_cites,
+ doc1_refs | sum_refs, doc1_cites | sum_cites)
+ with open(os.path.join(app.outdir, "summary.html")) as stream:
+ check_code(stream.read(), sum_refs, sum_cites,
+ doc1_refs | doc2_refs, doc1_cites | doc2_cites)
diff --git a/test/test_issue77.py b/test/test_issue77.py
new file mode 100644
index 0000000..ff86f87
--- /dev/null
+++ b/test/test_issue77.py
@@ -0,0 +1,26 @@
+"""
+ test_issue77
+ ~~~~~~~~~~~~
+
+ Test label style.
+"""
+
+import os.path
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue77').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_issue77(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ output = stream.read()
+ assert len(re.findall('\\[APAa\\]', output)) == 2
+ assert len(re.findall('\\[APAb\\]', output)) == 2
diff --git a/test/test_issue80_parallel.py b/test/test_issue80_parallel.py
new file mode 100644
index 0000000..db368cd
--- /dev/null
+++ b/test/test_issue80_parallel.py
@@ -0,0 +1,27 @@
+"""
+ test_issue80
+ ~~~~~~~~~~~~
+
+ Test parallel build.
+"""
+
+import re
+from six import StringIO
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue80').abspath()
+warnfile = StringIO()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warning=warnfile, parallel=8)
+def test_issue80_parallel(app):
+ app.builder.build_all()
+ warnings = warnfile.getvalue()
+ assert re.search(
+ 'the sphinxcontrib.bibtex extension is not safe for parallel '
+ 'reading, doing serial read', warnings)
diff --git a/test/test_issue80_serial.py b/test/test_issue80_serial.py
new file mode 100644
index 0000000..ad8aec0
--- /dev/null
+++ b/test/test_issue80_serial.py
@@ -0,0 +1,19 @@
+"""
+ test_issue80
+ ~~~~~~~~~~~~
+
+ Test parallel build.
+"""
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('issue80').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True, parallel=0)
+def test_issue80_serial(app):
+ app.builder.build_all()
diff --git a/test/test_latex_refs.py b/test/test_latex_refs.py
new file mode 100644
index 0000000..0c322e9
--- /dev/null
+++ b/test/test_latex_refs.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+"""
+ test_latex_refs
+ ~~~~~~~~~~~~~~~
+
+ Check that LaTeX backend produces correct references.
+"""
+
+import os
+import re
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('latex_refs').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True, buildername='latex')
+def test_latex_refs(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "test.tex")) as stream:
+ code = stream.read()
+ assert re.search('\\hyperref\[contents:huygens\]', code)
+ assert re.search('\\label{contents:huygens}', code)
diff --git a/test/test_list_bullet.py b/test/test_list_bullet.py
new file mode 100644
index 0000000..5747409
--- /dev/null
+++ b/test/test_list_bullet.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+"""
+ test_list_bullet
+ ~~~~~~~~~~~~~~~~
+
+ Test the ``:list: bullet`` option.
+"""
+
+import os.path
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('list_bullet').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_list_bullet(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ assert re.search(
+ '<ul .* id="bibtex-bibliography-contents-0">'
+ '.*<li>.*Akkerdju.*</li>'
+ '.*<li>.*Bro.*</li>'
+ '.*<li>.*Chap.*</li>'
+ '.*<li>.*Dude.*</li>'
+ '.*</ul>',
+ stream.read(), re.MULTILINE | re.DOTALL)
diff --git a/test/test_list_citation.py b/test/test_list_citation.py
new file mode 100644
index 0000000..3cf89fe
--- /dev/null
+++ b/test/test_list_citation.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+"""
+ test_list_citation
+ ~~~~~~~~~~~~~~~~~~
+
+ Test the ``:list: citation`` option.
+"""
+
+import os.path
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('list_citation').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_list_citation(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ assert re.search(
+ '<p id="bibtex-bibliography-contents-0">'
+ '.*<tr><td class="label">\\[1\\]</td><td>.*Akkerdju.*</td></tr>'
+ '.*<tr><td class="label">\\[2\\]</td><td>.*Bro.*</td></tr>'
+ '.*<tr><td class="label">\\[3\\]</td><td>.*Chap.*</td></tr>'
+ '.*<tr><td class="label">\\[4\\]</td><td>.*Dude.*</td></tr>'
+ '.*</p>',
+ stream.read(), re.MULTILINE | re.DOTALL)
diff --git a/test/test_list_enumerated.py b/test/test_list_enumerated.py
new file mode 100644
index 0000000..fa557d2
--- /dev/null
+++ b/test/test_list_enumerated.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+"""
+ test_list_enumerated
+ ~~~~~~~~~~~~~~~~~~~~
+
+ Test the ``:list: enumerated`` option.
+"""
+
+import os.path
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('list_enumerated').abspath()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warningiserror=True)
+def test_list_enumerated(app):
+ app.builder.build_all()
+ with open(os.path.join(app.outdir, "contents.html")) as stream:
+ assert re.search(
+ '<ol .*id="bibtex-bibliography-contents-0".* start="1".*>'
+ '.*<li>.*Akkerdju.*</li>'
+ '.*<li>.*Bro.*</li>'
+ '.*<li>.*Chap.*</li>'
+ '.*<li>.*Dude.*</li>'
+ '.*</ol>'
+ '.*<ol .*id="bibtex-bibliography-contents-1".* start="5".*>'
+ '.*<li>.*Eminence.*</li>'
+ '.*<li>.*Frater.*</li>'
+ '.*<li>.*Giggles.*</li>'
+ '.*<li>.*Handy.*</li>'
+ '.*</ol>'
+ '.*<ol .*id="bibtex-bibliography-contents-2".* start="23".*>'
+ '.*<li>.*Iedereen.*</li>'
+ '.*<li>.*Joke.*</li>'
+ '.*<li>.*Klopgeest.*</li>'
+ '.*<li>.*Laterfanter.*</li>'
+ '.*</ol>',
+ stream.read(), re.MULTILINE | re.DOTALL)
diff --git a/test/test_list_invalid.py b/test/test_list_invalid.py
new file mode 100644
index 0000000..cb63499
--- /dev/null
+++ b/test/test_list_invalid.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+"""
+ test_list_invalid
+ ~~~~~~~~~~~~~~~~~
+
+ Test invalid ``:list:`` option.
+"""
+
+from six import StringIO
+import re
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('list_invalid').abspath()
+warnfile = StringIO()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warning=warnfile)
+def test_list_invalid(app):
+ app.builder.build_all()
+ warnings = warnfile.getvalue()
+ assert re.search(
+ "unknown bibliography list type 'thisisintentionallyinvalid'",
+ warnings)
diff --git a/test/test_sphinx.py b/test/test_sphinx.py
new file mode 100644
index 0000000..1d0ed1c
--- /dev/null
+++ b/test/test_sphinx.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+"""
+ test_sphinx
+ ~~~~~~~~~~~
+
+ General Sphinx test and check output.
+"""
+
+import re
+from six import StringIO
+
+from util import path, with_app
+
+srcdir = path(__file__).parent.joinpath('sphinx').abspath()
+warnfile = StringIO()
+
+
+def teardown_module():
+ (srcdir / '_build').rmtree(True)
+
+
+ at with_app(srcdir=srcdir, warning=warnfile)
+def test_sphinx(app):
+ app.builder.build_all()
+ warnings = warnfile.getvalue()
+ assert re.search(u'could not relabel citation \\[Test01\\]', warnings)
+ assert re.search(u'could not relabel citation \\[Test02\\]', warnings)
+ assert re.search(u'could not relabel citation \\[Wa04\\]', warnings)
+ assert re.search(
+ u'could not relabel citation reference \\[Test01\\]',
+ warnings)
+ assert re.search(
+ u'could not relabel citation reference \\[Test02\\]',
+ warnings)
+ assert re.search(
+ u'could not relabel citation reference \\[Wa04\\]',
+ warnings)
diff --git a/test/util.py b/test/util.py
new file mode 100644
index 0000000..2196d62
--- /dev/null
+++ b/test/util.py
@@ -0,0 +1,251 @@
+# -*- coding: utf-8 -*-
+"""
+ Sphinx test suite utilities
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import sys
+import tempfile
+import shutil
+import re
+from codecs import open
+from six import StringIO
+from six.moves import map
+
+try:
+ from functools import wraps
+except ImportError:
+ # functools is new in 2.4
+ wraps = lambda f: (lambda w: w)
+
+from sphinx import application
+from sphinx.ext.autodoc import AutoDirective
+
+from path import path
+
+from nose import tools, SkipTest
+
+
+__all__ = [
+ 'test_root', 'raises', 'raises_msg',
+ 'skip_if', 'skip_unless', 'skip_unless_importable', 'Struct',
+ 'ListOutput', 'TestApp', 'with_app', 'gen_with_app',
+ 'path', 'with_tempdir', 'write_file',
+ 'sprint', 'remove_unicode_literals',
+]
+
+
+test_root = path(__file__).parent.joinpath('root').abspath()
+
+
+def _excstr(exc):
+ if isinstance(exc, tuple):
+ return str(tuple(map(_excstr, exc)))
+ return exc.__name__
+
+
+def raises(exc, func, *args, **kwds):
+ """
+ Raise :exc:`AssertionError` if ``func(*args, **kwds)`` does not
+ raise *exc*.
+ """
+ try:
+ func(*args, **kwds)
+ except exc:
+ pass
+ else:
+ raise AssertionError('%s did not raise %s' %
+ (func.__name__, _excstr(exc)))
+
+
+def raises_msg(exc, msg, func, *args, **kwds):
+ """
+ Raise :exc:`AssertionError` if ``func(*args, **kwds)`` does not
+ raise *exc*, and check if the message contains *msg*.
+ """
+ try:
+ func(*args, **kwds)
+ except exc as err:
+ assert msg in str(err), "\"%s\" not in \"%s\"" % (msg, err)
+ else:
+ raise AssertionError('%s did not raise %s' %
+ (func.__name__, _excstr(exc)))
+
+
+def skip_if(condition, msg=None):
+ """Decorator to skip test if condition is true."""
+ def deco(test):
+ @tools.make_decorator(test)
+ def skipper(*args, **kwds):
+ if condition:
+ raise SkipTest(msg or 'conditional skip')
+ return test(*args, **kwds)
+ return skipper
+ return deco
+
+
+def skip_unless(condition, msg=None):
+ """Decorator to skip test if condition is false."""
+ return skip_if(not condition, msg)
+
+
+def skip_unless_importable(module, msg=None):
+ """Decorator to skip test if module is not importable."""
+ try:
+ __import__(module)
+ except ImportError:
+ return skip_if(True, msg)
+ else:
+ return skip_if(False, msg)
+
+
+class Struct(object):
+
+ def __init__(self, **kwds):
+ self.__dict__.update(kwds)
+
+
+class ListOutput(object):
+
+ """
+ File-like object that collects written text in a list.
+ """
+
+ def __init__(self, name):
+ self.name = name
+ self.content = []
+
+ def reset(self):
+ del self.content[:]
+
+ def write(self, text):
+ self.content.append(text)
+
+
+class TestApp(application.Sphinx):
+
+ """
+ A subclass of :class:`Sphinx` that runs on the test root, with some
+ better default values for the initialization parameters.
+ """
+
+ def __init__(self, srcdir=None, confdir=None, outdir=None, doctreedir=None,
+ buildername='html', confoverrides=None,
+ status=None, warning=None, freshenv=None,
+ warningiserror=None, tags=None,
+ confname='conf.py', cleanenv=False, verbosity=0, parallel=0):
+
+ application.CONFIG_FILENAME = confname
+
+ self.cleanup_trees = [test_root / 'generated']
+
+ if srcdir is None:
+ srcdir = test_root
+ if srcdir == '(temp)':
+ tempdir = path(tempfile.mkdtemp())
+ self.cleanup_trees.append(tempdir)
+ temproot = tempdir / 'root'
+ test_root.copytree(temproot)
+ srcdir = temproot
+ else:
+ srcdir = path(srcdir)
+ self.builddir = srcdir.joinpath('_build')
+ if confdir is None:
+ confdir = srcdir
+ if outdir is None:
+ outdir = srcdir.joinpath(self.builddir, buildername)
+ if not outdir.isdir():
+ outdir.makedirs()
+ self.cleanup_trees.insert(0, outdir)
+ if doctreedir is None:
+ doctreedir = srcdir.joinpath(srcdir, self.builddir, 'doctrees')
+ if cleanenv:
+ self.cleanup_trees.insert(0, doctreedir)
+ if confoverrides is None:
+ confoverrides = {}
+ if status is None:
+ status = StringIO()
+ if warning is None:
+ warning = ListOutput('stderr')
+ if freshenv is None:
+ freshenv = False
+ if warningiserror is None:
+ warningiserror = False
+
+ application.Sphinx.__init__(self, srcdir, confdir, outdir, doctreedir,
+ buildername, confoverrides, status,
+ warning,
+ freshenv, warningiserror, tags,
+ verbosity, parallel)
+
+ def cleanup(self, doctrees=False):
+ AutoDirective._registry.clear()
+ for tree in self.cleanup_trees:
+ shutil.rmtree(tree, True)
+
+
+def with_app(*args, **kwargs):
+ """
+ Make a TestApp with args and kwargs, pass it to the test and clean up
+ properly.
+ """
+ def generator(func):
+ @wraps(func)
+ def deco(*args2, **kwargs2):
+ app = TestApp(*args, **kwargs)
+ func(app, *args2, **kwargs2)
+ # don't execute cleanup if test failed
+ app.cleanup()
+ return deco
+ return generator
+
+
+def gen_with_app(*args, **kwargs):
+ """
+ Decorate a test generator to pass a TestApp as the first argument to the
+ test generator when it's executed.
+ """
+ def generator(func):
+ @wraps(func)
+ def deco(*args2, **kwargs2):
+ app = TestApp(*args, **kwargs)
+ for item in func(app, *args2, **kwargs2):
+ yield item
+ # don't execute cleanup if test failed
+ app.cleanup()
+ return deco
+ return generator
+
+
+def with_tempdir(func):
+ def new_func(*args, **kwds):
+ tempdir = path(tempfile.mkdtemp())
+ func(tempdir, *args, **kwds)
+ tempdir.rmtree()
+ new_func.__name__ = func.__name__
+ return new_func
+
+
+def write_file(name, contents, encoding=None):
+ if encoding is None:
+ mode = 'wb'
+ if isinstance(contents, unicode):
+ contents = contents.encode('ascii')
+ else:
+ mode = 'w'
+ f = open(str(name), mode, encoding=encoding)
+ f.write(contents)
+ f.close()
+
+
+def sprint(*args):
+ sys.stderr.write(' '.join(map(str, args)) + '\n')
+
+_unicode_literals_re = re.compile(r'u(".*?")|u(\'.*?\')')
+
+
+def remove_unicode_literals(s):
+ return _unicode_literals_re.sub(lambda x: x.group(1) or x.group(2), s)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/sphinxcontrib-bibtex.git
More information about the debian-med-commit
mailing list