summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2009-01-13 23:59:01 +0100
committerGeorg Brandl <georg@python.org>2009-01-13 23:59:01 +0100
commit2d740f6f61c6a783fc0c270188393e30997ddb25 (patch)
tree959f93834256617ea84f2144baa4bf5cb8d18dee
parentc8095115faac2bf326c856f531691bfe0661b613 (diff)
parent778631271c3ee71d0e54e6405db1a951f4de4e09 (diff)
downloadsphinx-2d740f6f61c6a783fc0c270188393e30997ddb25.tar.gz
merge with 0.5
-rw-r--r--.hgignore2
-rw-r--r--AUTHORS1
-rw-r--r--CHANGES96
-rw-r--r--EXAMPLES5
-rw-r--r--LICENSE90
-rw-r--r--MANIFEST.in1
-rw-r--r--babel.cfg6
-rw-r--r--doc/Makefile24
-rw-r--r--doc/builders.rst8
-rw-r--r--doc/concepts.rst15
-rw-r--r--doc/conf.py2
-rw-r--r--doc/config.rst31
-rw-r--r--doc/ext/appapi.rst9
-rw-r--r--doc/ext/autodoc.rst18
-rw-r--r--doc/ext/builderapi.rst8
-rw-r--r--doc/ext/doctest.rst8
-rw-r--r--doc/glossary.rst2
-rw-r--r--doc/intro.rst8
-rw-r--r--doc/markup/code.rst27
-rw-r--r--doc/markup/desc.rst6
-rw-r--r--doc/markup/inline.rst48
-rw-r--r--doc/markup/para.rst21
-rw-r--r--doc/sphinx-build.196
-rw-r--r--doc/sphinx-quickstart.117
-rw-r--r--doc/templating.rst8
-rw-r--r--setup.py2
-rw-r--r--sphinx/__init__.py13
-rw-r--r--sphinx/_jinja.py113
-rw-r--r--sphinx/addnodes.py18
-rw-r--r--sphinx/application.py31
-rw-r--r--sphinx/builder.py1281
-rw-r--r--sphinx/builders/__init__.py346
-rw-r--r--sphinx/builders/changes.py137
-rw-r--r--sphinx/builders/html.py633
-rw-r--r--sphinx/builders/htmlhelp.py246
-rw-r--r--sphinx/builders/latex.py186
-rw-r--r--sphinx/builders/linkcheck.py (renamed from sphinx/linkcheck.py)6
-rw-r--r--sphinx/builders/qthelp.py261
-rw-r--r--sphinx/builders/text.py68
-rw-r--r--sphinx/config.py20
-rw-r--r--sphinx/directives/code.py77
-rw-r--r--sphinx/directives/desc.py57
-rw-r--r--sphinx/directives/other.py42
-rw-r--r--sphinx/environment.py93
-rw-r--r--sphinx/ext/autodoc.py377
-rw-r--r--sphinx/ext/coverage.py2
-rw-r--r--sphinx/ext/doctest.py14
-rw-r--r--sphinx/ext/intersphinx.py2
-rw-r--r--sphinx/highlighting.py30
-rw-r--r--sphinx/htmlhelp.py220
-rw-r--r--sphinx/jinja2glue.py86
-rw-r--r--sphinx/locale/cs/LC_MESSAGES/sphinx.js2
-rw-r--r--sphinx/locale/cs/LC_MESSAGES/sphinx.mobin7500 -> 9018 bytes
-rw-r--r--sphinx/locale/cs/LC_MESSAGES/sphinx.po136
-rw-r--r--sphinx/locale/de/LC_MESSAGES/sphinx.po244
-rw-r--r--sphinx/locale/es/LC_MESSAGES/sphinx.po249
-rw-r--r--sphinx/locale/fr/LC_MESSAGES/sphinx.po244
-rw-r--r--sphinx/locale/it/LC_MESSAGES/sphinx.js1
-rw-r--r--sphinx/locale/it/LC_MESSAGES/sphinx.mobin0 -> 8415 bytes
-rw-r--r--sphinx/locale/it/LC_MESSAGES/sphinx.po612
-rw-r--r--sphinx/locale/ja/LC_MESSAGES/sphinx.po240
-rw-r--r--sphinx/locale/nl/LC_MESSAGES/sphinx.po244
-rw-r--r--sphinx/locale/pl/LC_MESSAGES/sphinx.po242
-rw-r--r--sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po243
-rw-r--r--sphinx/locale/sl/LC_MESSAGES/sphinx.po242
-rw-r--r--sphinx/locale/sphinx.pot199
-rw-r--r--sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po238
-rw-r--r--sphinx/pycode/Grammar.txt155
-rw-r--r--sphinx/pycode/__init__.py306
-rw-r--r--sphinx/pycode/nodes.py202
-rw-r--r--sphinx/pycode/pgen2/__init__.py4
-rw-r--r--sphinx/pycode/pgen2/driver.py145
-rw-r--r--sphinx/pycode/pgen2/grammar.py171
-rw-r--r--sphinx/pycode/pgen2/literals.py96
-rw-r--r--sphinx/pycode/pgen2/parse.c3261
-rw-r--r--sphinx/pycode/pgen2/parse.py201
-rw-r--r--sphinx/pycode/pgen2/parse.pyx158
-rw-r--r--sphinx/pycode/pgen2/pgen.py384
-rwxr-xr-xsphinx/pycode/pgen2/token.py82
-rw-r--r--sphinx/pycode/pgen2/tokenize.py410
-rw-r--r--sphinx/quickstart.py158
-rw-r--r--sphinx/roles.py11
-rw-r--r--sphinx/templates/changes/versionchanges.html2
-rw-r--r--sphinx/templates/layout.html71
-rw-r--r--sphinx/templates/modindex.html24
-rw-r--r--sphinx/templates/page.html8
-rw-r--r--sphinx/templates/search.html7
-rw-r--r--sphinx/texinputs/sphinx.sty29
-rw-r--r--sphinx/util/__init__.py80
-rw-r--r--sphinx/util/compat.py2
-rw-r--r--sphinx/util/docstrings.py56
-rw-r--r--sphinx/util/jsdump.py2
-rw-r--r--sphinx/writers/__init__.py10
-rw-r--r--sphinx/writers/html.py (renamed from sphinx/htmlwriter.py)34
-rw-r--r--sphinx/writers/latex.py (renamed from sphinx/latexwriter.py)56
-rw-r--r--sphinx/writers/text.py (renamed from sphinx/textwriter.py)24
-rw-r--r--tests/root/includes.txt30
-rw-r--r--tests/root/literal.inc9
-rw-r--r--tests/root/markup.txt10
-rw-r--r--tests/test_autodoc.py127
-rw-r--r--tests/test_build.py42
-rw-r--r--tests/test_config.py4
-rw-r--r--tests/test_env.py9
-rw-r--r--tests/test_highlighting.py68
-rw-r--r--tests/test_markup.py6
-rw-r--r--tests/test_quickstart.py22
-rw-r--r--tests/util.py2
107 files changed, 11214 insertions, 3318 deletions
diff --git a/.hgignore b/.hgignore
index a6b6e37a..99fc8d87 100644
--- a/.hgignore
+++ b/.hgignore
@@ -1,7 +1,9 @@
.*\.pyc
.*\.egg
+.*\.so
build/
dist/
+sphinx/pycode/Grammar.*pickle
Sphinx.egg-info/
doc/_build/
TAGS
diff --git a/AUTHORS b/AUTHORS
index 72a2469e..6750dad9 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -12,6 +12,7 @@ Other contributors, listed alphabetically, are:
* Dave Kuhlman -- original LaTeX writer
* Thomas Lamb -- linkcheck builder
* Benjamin Peterson -- unittests
+* Antonio Valentino -- qthelp builder
* Pauli Virtanen -- autodoc improvements
* Sebastian Wiesner -- image handling, distutils support
diff --git a/CHANGES b/CHANGES
index 88d91b7a..47cfa672 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,99 @@
+Release 0.6 (in development)
+============================
+
+New features added
+------------------
+
+* Incompatible changes:
+
+ - Templating now requires the Jinja2 library, which is an enhanced
+ version of the old Jinja1 engine. Since the syntax and semantic
+ is largely the same, very few fixes should be necessary in
+ custom templates.
+
+ - The ``autodoc_skip_member`` event now also gets to decide
+ whether to skip members whose name starts with underscores.
+ Previously, these members were always automatically skipped.
+ Therefore, if you handle this event, add something like this
+ to your event handler to restore the old behavior::
+
+ if name.startswith('_'):
+ return True
+
+* Markup:
+
+ - Due to popular demand, added a ``:doc:`` role which directly
+ links to another document without the need of creating a
+ label to which a ``:ref:`` could link to.
+
+ - #4: Added a ``:download:`` role that marks a non-document file
+ for inclusion into the HTML output and links to it.
+
+ - The ``literalinclude`` directive now supports several more
+ options, to include only parts of a file.
+
+ - The ``toctree`` directive now supports a ``:hidden:`` flag,
+ which will prevent links from being generated in place of
+ the directive -- this allows you to define your document
+ structure, but place the links yourself.
+
+ - #52: There is now a ``hlist`` directive, creating a compact
+ list by placing distributing items into multiple columns.
+
+ - #77: If a description environment with info field list only
+ contains one ``:param:`` entry, no bullet list is generated.
+
+ - #6: Don't generate redundant ``<ul>`` for top-level TOC tree
+ items, which leads to a visual separation of TOC entries.
+
+ - #23: Added a ``classmethod`` directive along with ``method``
+ and ``staticmethod``.
+
+* Configuration:
+
+ - The new ``html_add_permalinks`` config value can be used to
+ switch off the generated "paragraph sign" permalinks for each
+ heading and definition environment.
+
+ - The new ``html_show_sourcelink`` config value can be used to
+ switch off the links to the reST sources in the sidebar.
+
+ - The default value for ``htmlhelp_basename`` is now the project
+ title, cleaned up as a filename.
+
+* Builders:
+
+ - New builder for Qt help collections, by Antonio Valentino.
+
+ - The new ``html_link_suffix`` config value can be used to select
+ the suffix of generated links between HTML files.
+
+* New translations:
+
+ - Italian by Sandro Dentella.
+
+* Extensions and API:
+
+ - Autodoc now handles documented attributes.
+
+ - Autodoc now handles inner classes and their methods.
+
+ - There is now a ``Sphinx.add_lexer()`` method to be able to use
+ custom Pygments lexers easily.
+
+* Other changes:
+
+ - Config overrides for single dict keys can now be given on the
+ command line.
+
+ - There is now a ``doctest_global_setup`` config value that can
+ be used to give setup code for all doctests in the documentation.
+
+ - Source links in HTML are now generated with ``rel="nofollow"``.
+
+ - Quickstart can now generate a Windows ``make.bat`` file.
+
+
Release 0.5.2 (in development)
==============================
diff --git a/EXAMPLES b/EXAMPLES
index 1ab76433..d3ac299c 100644
--- a/EXAMPLES
+++ b/EXAMPLES
@@ -18,12 +18,15 @@ included, please mail to `the Google group
* Grok: http://grok.zope.org/doc/current/
* IFM: http://fluffybunny.memebot.com/ifm-docs/index.html
* Jinja: http://jinja.pocoo.org/2/documentation/
+* MapServer: http://mapserver.osgeo.org/
* Matplotlib: http://matplotlib.sourceforge.net/
* Mayavi: http://code.enthought.com/projects/mayavi/docs/development/html/mayavi
* Mixin.com: http://dev.mixin.com/
+* mpmath: http://mpmath.googlecode.com/svn/trunk/doc/build/index.html
* NetworkX: http://networkx.lanl.gov/
* NumPy: http://docs.scipy.org/doc/numpy/reference/
* ObjectListView: http://objectlistview.sourceforge.net/python
+* OpenLayers: http://docs.openlayers.org/
* Paste: http://pythonpaste.org/script/
* Paver: http://www.blueskyonmars.com/projects/paver/
* Py on Windows: http://timgolden.me.uk/python-on-windows/
@@ -39,6 +42,6 @@ included, please mail to `the Google group
* SymPy: http://docs.sympy.org/
* tinyTiM: http://tinytim.sourceforge.net/docs/2.0/
* TurboGears: http://turbogears.org/2.0/docs/
+* WFront: http://discorporate.us/projects/WFront/
* Zope 3: e.g. http://docs.carduner.net/z3c-tutorial/
-* mpmath: http://mpmath.googlecode.com/svn/trunk/doc/build/index.html
* zc.async: http://packages.python.org/zc.async/1.5.0/
diff --git a/LICENSE b/LICENSE
index 6128bb42..fb2049a8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,9 +1,9 @@
-Copyright (c) 2007-2009 by the respective authors (see AUTHORS file).
-All rights reserved.
-
License for Sphinx
==================
+Copyright (c) 2007-2009 by the Sphinx team (see AUTHORS file).
+All rights reserved.
+
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
@@ -31,6 +31,64 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Licenses for incorporated software
==================================
+The pgen2 package, included in this distribution under the name
+sphinx.pycode.pgen2, is available in the Python 2.6 distribution under
+the PSF license agreement for Python:
+
+----------------------------------------------------------------------
+Copyright © 2001-2008 Python Software Foundation; All Rights Reserved.
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+ ("PSF"), and the Individual or Organization ("Licensee") accessing
+ and otherwise using Python 2.6 software in source or binary form
+ and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF
+ hereby grants Licensee a nonexclusive, royalty-free, world-wide
+ license to reproduce, analyze, test, perform and/or display
+ publicly, prepare derivative works, distribute, and otherwise use
+ Python 2.6 alone or in any derivative version, provided, however,
+ that PSF's License Agreement and PSF's notice of copyright, i.e.,
+ "Copyright © 2001-2008 Python Software Foundation; All Rights
+ Reserved" are retained in Python 2.6 alone or in any derivative
+ version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+ or incorporates Python 2.6 or any part thereof, and wants to make
+ the derivative work available to others as provided herein, then
+ Licensee hereby agrees to include in any such work a brief summary
+ of the changes made to Python 2.6.
+
+4. PSF is making Python 2.6 available to Licensee on an "AS IS" basis.
+ PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY
+ WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY
+ REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY
+ PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.6 WILL NOT INFRINGE
+ ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+ 2.6 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+ AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON
+ 2.6, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY
+ THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+ breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+ relationship of agency, partnership, or joint venture between PSF
+ and Licensee. This License Agreement does not grant permission to
+ use PSF trademarks or trade name in a trademark sense to endorse or
+ promote products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python 2.6, Licensee
+ agrees to be bound by the terms and conditions of this License
+ Agreement.
+----------------------------------------------------------------------
+
The included smartypants module, included as sphinx.util.smartypants,
is available under the following license:
@@ -133,3 +191,29 @@ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------------------------------------
+
+The included JQuery JavaScript library is available under the MIT
+license:
+
+----------------------------------------------------------------------
+Copyright (c) 2008 John Resig, http://jquery.com/
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+----------------------------------------------------------------------
diff --git a/MANIFEST.in b/MANIFEST.in
index d87a881e..715748e8 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -17,6 +17,7 @@ recursive-include sphinx/static *
recursive-include sphinx/locale *
recursive-include tests *
recursive-include utils *
+include sphinx/pycode/Grammar.txt
recursive-include doc *
prune doc/_build
diff --git a/babel.cfg b/babel.cfg
index 5f5188b1..e53a462d 100644
--- a/babel.cfg
+++ b/babel.cfg
@@ -1,6 +1,4 @@
-[extractors]
-jinja = sphinx._jinja.babel_extract
[python: **.py]
-[jinja: **/templates/**.html]
-[jinja: **/templates/**.xml]
+[jinja2: **/templates/**.html]
+[jinja2: **/templates/**.xml]
[javascript: **.js]
diff --git a/doc/Makefile b/doc/Makefile
index cb5fc645..6da1654b 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -11,12 +11,12 @@ PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) \
$(SPHINXOPTS) .
-.PHONY: help clean html web htmlhelp latex changes linkcheck
+.PHONY: help clean html pickle htmlhelp qthelp latex changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
- @echo " web to make files usable by Sphinx.web"
+ @echo " pickle to make pickle files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview over all changed/added/deprecated items"
@@ -31,13 +31,15 @@ html:
@echo
@echo "Build finished. The HTML pages are in _build/html."
+text:
+ mkdir -p _build/text _build/doctrees
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) _build/text
+ @echo
+ @echo "Build finished."
+
pickle:
mkdir -p _build/pickle _build/doctrees
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
- @echo
- @echo "Build finished; now you can run"
- @echo " python -m sphinx.web _build/pickle"
- @echo "to start the server."
htmlhelp:
mkdir -p _build/htmlhelp _build/doctrees
@@ -46,6 +48,16 @@ htmlhelp:
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in _build/htmlhelp."
+qthelp:
+ mkdir -p _build/qthelp _build/doctrees
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp
+ @echo
+ @echo "Build finished; now you can run qcollectiongenerator with the" \
+ ".qhcp project file in build/qthelp."
+ @echo "# qcollectiongenerator _build/qthelp/Sphinx.qhcp"
+ @echo "To view the help collection:"
+ @echo "# assistant -collectionFile _build/qthelp/Sphinx.qhc"
+
latex:
mkdir -p _build/latex _build/doctrees
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
diff --git a/doc/builders.rst b/doc/builders.rst
index 508ab3c5..dd07a96a 100644
--- a/doc/builders.rst
+++ b/doc/builders.rst
@@ -3,7 +3,7 @@
Available builders
==================
-.. module:: sphinx.builder
+.. module:: sphinx.builders
:synopsis: Available built-in builder classes.
These are the built-in Sphinx builders. More builders can be added by
@@ -13,6 +13,7 @@ The builder's "name" must be given to the **-b** command-line option of
:program:`sphinx-build` to select a builder.
+.. module:: sphinx.builders.html
.. class:: StandaloneHTMLBuilder
This is the standard HTML builder. Its output is a directory with HTML
@@ -30,6 +31,7 @@ The builder's "name" must be given to the **-b** command-line option of
Its name is ``htmlhelp``.
+.. module:: sphinx.builders.latex
.. class:: LaTeXBuilder
This builder produces a bunch of LaTeX files in the output directory. You
@@ -50,6 +52,7 @@ The builder's "name" must be given to the **-b** command-line option of
Its name is ``latex``.
+.. module:: sphinx.builders.text
.. class:: TextBuilder
This builder produces a text file for each reST file -- this is almost the
@@ -60,6 +63,7 @@ The builder's "name" must be given to the **-b** command-line option of
.. versionadded:: 0.4
+.. currentmodule:: sphinx.builders.html
.. class:: SerializingHTMLBuilder
This builder uses a module that implements the Python serialization API
@@ -135,6 +139,7 @@ The builder's "name" must be given to the **-b** command-line option of
.. versionadded:: 0.5
+.. module:: sphinx.builders.changes
.. class:: ChangesBuilder
This builder produces an HTML overview of all :dir:`versionadded`,
@@ -144,6 +149,7 @@ The builder's "name" must be given to the **-b** command-line option of
Its name is ``changes``.
+.. module:: sphinx.builders.linkcheck
.. class:: CheckExternalLinksBuilder
This builder scans all documents for external links, tries to open them with
diff --git a/doc/concepts.rst b/doc/concepts.rst
index ca7aaf7c..379888ff 100644
--- a/doc/concepts.rst
+++ b/doc/concepts.rst
@@ -85,6 +85,18 @@ tables of contents. The ``toctree`` directive is the central element.
This includes first all documents whose names start with ``intro``, then all
documents in the ``recipe`` folder, then all remaining documents (except the
one containing the directive, of course.) [#]_
+
+ You can also give a "hidden" option to the directive, like this::
+
+ .. toctree::
+ :hidden:
+
+ doc_1
+ doc_2
+
+ This will still notify Sphinx of the document hierarchy, but not insert links
+ into the document at the location of the directive -- this makes sense if you
+ intend to insert these links yourself, in a different style.
In the end, all documents in the :term:`source directory` (or subdirectories)
must occur in some ``toctree`` directive; Sphinx will emit a warning if it
@@ -100,6 +112,9 @@ tables of contents. The ``toctree`` directive is the central element.
.. versionchanged:: 0.3
Added "globbing" option.
+ .. versionchanged:: 0.6
+ Added "hidden" option.
+
Special names
-------------
diff --git a/doc/conf.py b/doc/conf.py
index 89247821..709d6f75 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -36,7 +36,7 @@ master_doc = 'contents'
# General substitutions.
project = 'Sphinx'
-copyright = '2008, Georg Brandl'
+copyright = '2007-2009, Georg Brandl'
# The default replacements for |version| and |release|, also used in various
# other places throughout the built documents.
diff --git a/doc/config.rst b/doc/config.rst
index e6af9aae..dd25cf22 100644
--- a/doc/config.rst
+++ b/doc/config.rst
@@ -22,8 +22,8 @@ Important points to note:
* The term "fully-qualified name" refers to a string that names an importable
Python object inside a module; for example, the FQN
- ``"sphinx.builder.Builder"`` means the ``Builder`` class in the
- ``sphinx.builder`` module.
+ ``"sphinx.builders.Builder"`` means the ``Builder`` class in the
+ ``sphinx.builders`` module.
* Remember that document names use ``/`` as the path separator and don't contain
the file name extension.
@@ -205,6 +205,7 @@ Project information
* ``en`` -- English
* ``es`` -- Spanish
* ``fr`` -- French
+ * ``it`` -- Italian
* ``nl`` -- Dutch
* ``pl`` -- Polish
* ``pt_BR`` -- Brazilian Portuguese
@@ -332,6 +333,15 @@ that use Sphinx' HTMLWriter class.
If true, *SmartyPants* will be used to convert quotes and dashes to
typographically correct entities. Default: ``True``.
+.. confval:: html_add_permalinks
+
+ If true, Sphinx will add "permalinks" for each heading and description
+ environment as paragraph signs that become visible when the mouse hovers over
+ them. Default: ``True``.
+
+ .. versionadded:: 0.6
+ Previously, this was always activated.
+
.. confval:: html_sidebars
Custom sidebar templates, must be a dictionary that maps document names to
@@ -399,6 +409,13 @@ that use Sphinx' HTMLWriter class.
will only display the titles of matching documents, and no excerpt from
the matching contents.
+.. confval:: html_show_sourcelink
+
+ If true (and :confval:`html_copy_source` is true as well), links to the
+ reST sources will be added to the sidebar. The default is ``True``.
+
+ .. versionadded:: 0.6
+
.. confval:: html_use_opensearch
If nonempty, an `OpenSearch <http://opensearch.org>` description file will be
@@ -415,10 +432,18 @@ that use Sphinx' HTMLWriter class.
.. versionadded:: 0.4
+.. confval:: html_link_suffix
+
+ Suffix for generated links to HTML files. The default is whatever
+ :confval:`html_file_suffix` is set to; it can be set differently (e.g. to
+ support different web server setups).
+
+ .. versionadded:: 0.6
+
.. confval:: html_translator_class
A string with the fully-qualified name of a HTML Translator class, that is, a
- subclass of Sphinx' :class:`~sphinx.htmlwriter.HTMLTranslator`, that is used
+ subclass of Sphinx' :class:`~sphinx.writers.html.HTMLTranslator`, that is used
to translate document trees to HTML. Default is ``None`` (use the builtin
translator).
diff --git a/doc/ext/appapi.rst b/doc/ext/appapi.rst
index fcc29e38..3dd5282b 100644
--- a/doc/ext/appapi.rst
+++ b/doc/ext/appapi.rst
@@ -13,7 +13,7 @@ the following public API:
.. method:: Sphinx.add_builder(builder)
Register a new builder. *builder* must be a class that inherits from
- :class:`~sphinx.builder.Builder`.
+ :class:`~sphinx.builders.Builder`.
.. method:: Sphinx.add_config_value(name, default, rebuild_env)
@@ -167,6 +167,13 @@ the following public API:
:confval:`the docs for the config value <html_static_path>`.
.. versionadded:: 0.5
+
+.. method:: Sphinx.add_lexer(alias, lexer)
+
+ Use *lexer*, which must be an instance of a Pygments lexer class, to
+ highlight code blocks with the given language *alias*.
+
+ .. versionadded:: 0.6
.. method:: Sphinx.connect(event, callback)
diff --git a/doc/ext/autodoc.rst b/doc/ext/autodoc.rst
index 993f971a..e0766938 100644
--- a/doc/ext/autodoc.rst
+++ b/doc/ext/autodoc.rst
@@ -135,12 +135,30 @@ directive.
.. directive:: autofunction
+ autodata
automethod
autoattribute
These work exactly like :dir:`autoclass` etc., but do not offer the options
used for automatic member documentation.
+ For module data members and class attributes, documentation can either be put
+ into a special-formatted comment *before* the attribute definition, or in a
+ docstring *after* the definition. This means that in the following class
+ definition, both attributes can be autodocumented::
+
+ class Foo:
+ """Docstring for class Foo."""
+
+ #: Doc comment for attribute Foo.bar.
+ bar = 1
+
+ baz = 2
+ """Docstring for attribute Foo.baz."""
+
+ .. versionchanged:: 0.6
+ :dir:`autodata` and :dir:`autoattribute` can now extract docstrings.
+
.. note::
If you document decorated functions or methods, keep in mind that autodoc
diff --git a/doc/ext/builderapi.rst b/doc/ext/builderapi.rst
index adc41016..5c671f2d 100644
--- a/doc/ext/builderapi.rst
+++ b/doc/ext/builderapi.rst
@@ -5,7 +5,7 @@ Writing new builders
.. todo:: Expand this.
-.. currentmodule:: sphinx.builder
+.. currentmodule:: sphinx.builders
.. class:: Builder
@@ -20,7 +20,7 @@ Writing new builders
.. automethod:: build_update
.. automethod:: build
- These methods must be overridden in concrete builder classes:
+ These methods can be overridden in concrete builder classes:
.. automethod:: init
.. automethod:: get_outdated_docs
@@ -28,3 +28,7 @@ Writing new builders
.. automethod:: prepare_writing
.. automethod:: write_doc
.. automethod:: finish
+
+ Useful helpers:
+
+ .. automethod:: init_templates
diff --git a/doc/ext/doctest.rst b/doc/ext/doctest.rst
index 9de6ba9e..7117f6a9 100644
--- a/doc/ext/doctest.rst
+++ b/doc/ext/doctest.rst
@@ -149,6 +149,14 @@ There are also these config values for customizing the doctest extension:
A list of directories that will be added to :data:`sys.path` when the doctest
builder is used. (Make sure it contains absolute paths.)
+.. confval:: doctest_global_setup
+
+ Python code that is treated like it were put in a ``testsetup`` directive for
+ *every* file that is tested, and for every group. You can use this to
+ e.g. import modules you will always need in your doctests.
+
+ .. versionadded:: 0.6
+
.. confval:: doctest_test_doctest_blocks
If this is a nonempty string (the default is ``'default'``), standard reST
diff --git a/doc/glossary.rst b/doc/glossary.rst
index 6a80ad36..7ec787ff 100644
--- a/doc/glossary.rst
+++ b/doc/glossary.rst
@@ -6,7 +6,7 @@ Glossary
.. glossary::
builder
- A class (inheriting from :class:`~sphinx.builder.Builder`) that takes
+ A class (inheriting from :class:`~sphinx.builders.Builder`) that takes
parsed documents and performs an action on them. Normally, builders
translate the documents to an output format, but it is also possible to
use the builder builders that e.g. check for broken links in the
diff --git a/doc/intro.rst b/doc/intro.rst
index 47e016b3..7ce9d1fa 100644
--- a/doc/intro.rst
+++ b/doc/intro.rst
@@ -111,8 +111,12 @@ The :program:`sphinx-build` script has several more options:
.. versionadded:: 0.5
**-D** *setting=value*
- Override a configuration value set in the :file:`conf.py` file. (The value
- must be a string value.)
+ Override a configuration value set in the :file:`conf.py` file. The value
+ must be a string or dictionary value. For the latter, supply the setting
+ name and key like this: ``-D latex_elements.docclass=scrartcl``.
+
+ .. versionchanged:: 0.6
+ The value can now be a dictionary value.
**-A** *name=value*
Make the *name* assigned to *value* in the HTML templates.
diff --git a/doc/markup/code.rst b/doc/markup/code.rst
index 299ab0bc..0bf8343b 100644
--- a/doc/markup/code.rst
+++ b/doc/markup/code.rst
@@ -113,8 +113,35 @@ Includes
.. literalinclude:: example.py
:encoding: latin-1
+ The directive also supports including only parts of the file. If it is a
+ Python module, you can select a class, function or method to include using
+ the ``pyobject`` option::
+
+ .. literalinclude:: example.py
+ :pyobject: Timer.start
+
+ This would only include the code lines belonging to the ``start()`` method in
+ the ``Timer`` class within the file.
+
+ Alternately, you can specify exactly which lines to include by giving a
+ ``lines`` option::
+
+ .. literalinclude:: example.py
+ :lines: 1,3,5-10,20-
+
+ This includes the lines 1, 3, 5 to 10 and lines 20 to the last line.
+
+ Another way to control which part of the file is included is to use the
+ ``start-after`` and ``end-before`` options (or only one of them). If
+ ``start-after`` is given as a string option, only lines that follow the first
+ line containing that string are included. If ``end-before`` is given as a
+ string option, only lines that precede the first lines containing that string
+ are included.
+
.. versionadded:: 0.4.3
The ``encoding`` option.
+ .. versionadded:: 0.6
+ The ``pyobject``, ``lines``, ``start-after`` and ``end-before`` options.
.. rubric:: Footnotes
diff --git a/doc/markup/desc.rst b/doc/markup/desc.rst
index 892cdc4a..67605c77 100644
--- a/doc/markup/desc.rst
+++ b/doc/markup/desc.rst
@@ -205,6 +205,12 @@ The directives are:
.. versionadded:: 0.4
+.. directive:: .. classmethod:: name(signature)
+
+ Like :dir:`method`, but indicates that the method is a class method.
+
+ .. versionadded:: 0.6
+
.. _signatures:
diff --git a/doc/markup/inline.rst b/doc/markup/inline.rst
index 5dbd638e..9f8a01a5 100644
--- a/doc/markup/inline.rst
+++ b/doc/markup/inline.rst
@@ -224,7 +224,50 @@ to labels:
Using :role:`ref` is advised over standard reStructuredText links to sections
(like ```Section title`_``) because it works across files, when section headings
are changed, and for all builders that support cross-references.
-
+
+
+Cross-referencing documents
+---------------------------
+
+.. versionadded:: 0.6
+
+There is also a way to directly link to documents:
+
+.. role:: doc
+
+ Link to the specified document; the document name can be specified in
+ absolute or relative fashion. For example, if the reference
+ ``:doc:`parrot``` occurs in the document ``sketches/index``, then the link
+ refers to ``sketches/parrot``. If the reference is ``:doc:`/people``` or
+ ``:doc:`../people```, the link refers to ``people``.
+
+ If no explicit link text is given (like usual: ``:doc:`Monty Python members
+ </people>```), the link caption will be the title of the given document.
+
+
+Referencing downloadable files
+------------------------------
+
+.. versionadded:: 0.6
+
+.. role:: download
+
+ This role lets you link to files within your source tree that are not reST
+ documents that can be viewed, but files that can be downloaded.
+
+ When you use this role, the referenced file is automatically marked for
+ inclusion in the output when building (obviously, for HTML output only).
+ All downloadable files are put into the ``_downloads`` subdirectory of the
+ output directory; duplicate filenames are handled.
+
+ An example::
+
+ See :download:`this example script <../example.py>`.
+
+ The given filename is relative to the directory the current source file is
+ contained in. The ``../example.py`` file will be copied to the output
+ directory, and a suitable link generated to it.
+
Other semantic markup
---------------------
@@ -330,7 +373,7 @@ in a different style:
curly braces to indicate a "variable" part, as in ``:file:``.
If you don't need the "variable part" indication, use the standard
- ````code```` instead.
+ ````code```` instead.
The following roles generate external links:
@@ -351,6 +394,7 @@ The following roles generate external links:
Note that there are no special roles for including hyperlinks as you can use
the standard reST markup for that purpose.
+
.. _default-substitutions:
Substitutions
diff --git a/doc/markup/para.rst b/doc/markup/para.rst
index c60eb258..b071e46c 100644
--- a/doc/markup/para.rst
+++ b/doc/markup/para.rst
@@ -100,6 +100,27 @@ units as well as normal text:
.. centered:: LICENSE AGREEMENT
+.. directive:: hlist
+
+ This directive must contain a bullet list. It will transform it into a more
+ compact list by either distributing more than one item horizontally, or
+ reducing spacing between items, depending on the builder.
+
+ For builders that support the horizontal distribution, there is a ``columns``
+ option that specifies the number of columns; it defaults to 2. Example::
+
+ .. hlist::
+ :columns: 3
+
+ * A list of
+ * short items
+ * that should be
+ * displayed
+ * horizontally
+
+ .. versionadded:: 0.6
+
+
Table-of-contents markup
------------------------
diff --git a/doc/sphinx-build.1 b/doc/sphinx-build.1
new file mode 100644
index 00000000..16f8bd34
--- /dev/null
+++ b/doc/sphinx-build.1
@@ -0,0 +1,96 @@
+.TH sphinx-build 1 "Jan 2009" "Sphinx 0.6" "User Commands"
+.SH NAME
+sphinx-build \- Sphinx documentation generator tool
+.SH SYNOPSIS
+.B sphinx-build
+[\fIoptions\fR] <\fIsourcedir\fR> <\fIoutdir\fR> [\fIfilenames\fR...]
+.SH DESCRIPTION
+sphinx-build generates documentation from the files in <sourcedir> and places it
+in the <outdir>.
+
+sphinx-build looks for <sourcedir>/conf.py for the configuration settings.
+.B sphinx-quickstart(1)
+may be used to generate template files, including conf.py.
+
+sphinx-build can create documentation in different formats. A format is
+selected by specifying the builder name on the command line; it defaults to
+HTML. Builders can also perform other tasks related to documentation
+processing.
+
+By default, everything that is outdated is built. Output only for selected
+files can be built by specifying individual filenames.
+
+List of available builders:
+.TP
+\fBhtml\fR
+HTML files generation. This is default builder.
+.TP
+\fBhtmlhelp\fR
+Generates files for CHM generation.
+.TP
+\fBqthelp\fR
+Generates files for Qt help collection generation.
+.TP
+\fBlatex\fR
+Generates a LaTeX version of the documentation.
+.TP
+\fBtext\fR
+Generates a plain-text version of the documentation.
+.TP
+\fBchanges\fR
+Generates HTML files listing changed/added/deprecated items for the
+current version.
+.TP
+\fBlinkcheck\fR
+Checks the integrity of all external links in the documentation.
+.TP
+\fBpickle / json\fR
+Generates serialized HTML files in the selected format.
+
+.SH OPTIONS
+.TP
+\fB-b\fR <builder>
+Builder to use; defaults to html. See the full list of builders above.
+.TP
+\fB-a\fR
+Generates output for all files; without this option only output for
+new and changed files is generated.
+.TP
+\fB-E\fR
+Ignores cached files, forces to re-read all source files from disk.
+.TP
+\fB-c\fR <path>
+Locates the conf.py file in the specified path instead of <sourcedir>.
+.TP
+\fB-C\fR
+Specifies that no conf.py file at all is to be used. Configuration can
+only be set with the -D option.
+.TP
+\fB-D\fR <setting>=<value>
+Overrides a setting from the configuration file.
+.TP
+\fB-d\fR <path>
+Path to cached files; defaults to <outdir>/.doctrees.
+.TP
+\fB-A\fR <name>=<value>
+Passes a value into the HTML templates (only for html builders).
+.TP
+\fB-N\fR
+Prevents colored output.
+.TP
+\fB-q\fR
+Quiet operation, just prints warnings and errors on stderr.
+.TP
+\fB-Q\fR
+Very quiet operation, doesn't print anything except for errors.
+.TP
+\fB-P\fR
+Runs Pdb on exception.
+.SH "SEE ALSO"
+.BR sphinx-quickstart(1)
+.SH AUTHOR
+Georg Brandl <georg@python.org>, Armin Ronacher <armin.ronacher@active-4.com> et
+al.
+.PP
+This manual page was initially written by Mikhail Gusarov
+<dottedmag@dottedmag.net>, for the Debian project.
diff --git a/doc/sphinx-quickstart.1 b/doc/sphinx-quickstart.1
new file mode 100644
index 00000000..93b0a4a5
--- /dev/null
+++ b/doc/sphinx-quickstart.1
@@ -0,0 +1,17 @@
+.TH sphinx-quickstart 1 "Jan 2009" "Sphinx 0.6" "User Commands"
+.SH NAME
+sphinx-quickstart \- Sphinx documentation template generator
+.SH SYNOPSIS
+.B sphinx-quickstart
+.SH DESCRIPTION
+sphinx-quickstart is an interactive tool that asks some questions about your
+project and then generates a complete documentation directory and sample
+Makefile to be used with \fBsphinx-build(1)\fR.
+.SH "SEE ALSO"
+.BR sphinx-build(1)
+.SH AUTHOR
+Georg Brandl <georg@python.org>, Armin Ronacher <armin.ronacher@active-4.com> et
+al.
+.PP
+This manual page was initially written by Mikhail Gusarov
+<dottedmag@dottedmag.net> for the Debian project.
diff --git a/doc/templating.rst b/doc/templating.rst
index 61a8a72b..ff4bdd51 100644
--- a/doc/templating.rst
+++ b/doc/templating.rst
@@ -19,10 +19,10 @@ No. You have several other options:
configuration value accordingly.
* You can :ref:`write a custom builder <writing-builders>` that derives from
- :class:`~sphinx.builder.StandaloneHTMLBuilder` and calls your template engine
+ :class:`~sphinx.builders.StandaloneHTMLBuilder` and calls your template engine
of choice.
-* You can use the :class:`~sphinx.builder.PickleHTMLBuilder` that produces
+* You can use the :class:`~sphinx.builders.PickleHTMLBuilder` that produces
pickle files with the page contents, and postprocess them using a custom tool,
or use them in your Web application.
@@ -135,6 +135,10 @@ The following blocks exist in the ``layout`` template:
`sidebarrel`
The relation links (previous, next document) within the sidebar.
+`sidebarsourcelink`
+ The "Show source" link within the sidebar (normally only shown if this is
+ enabled by :confval:`html_show_sourcelink`).
+
`sidebarsearch`
The search box within the sidebar. Override this if you want to place some
content at the bottom of the sidebar.
diff --git a/setup.py b/setup.py
index e747e1b1..37cdd1e8 100644
--- a/setup.py
+++ b/setup.py
@@ -36,7 +36,7 @@ are already present, work fine and can be seen "in action" in the Python docs:
and inclusion of appropriately formatted docstrings.
'''
-requires = ['Pygments>=0.8', 'Jinja>=1.1', 'docutils>=0.4']
+requires = ['Pygments>=0.8', 'Jinja2>=2.0', 'docutils>=0.4']
if sys.version_info < (2, 4):
print 'ERROR: Sphinx requires at least Python 2.4 to run.'
diff --git a/sphinx/__init__.py b/sphinx/__init__.py
index 1dccf1c0..e0d8813f 100644
--- a/sphinx/__init__.py
+++ b/sphinx/__init__.py
@@ -10,10 +10,13 @@
"""
import sys
+from os import path
__revision__ = '$Revision$'
-__version__ = '0.5.1+'
-__released__ = '0.5.1'
+__version__ = '0.6'
+__released__ = '0.6 (hg)'
+
+package_dir = path.abspath(path.dirname(__file__))
def main(argv=sys.argv):
@@ -28,17 +31,23 @@ def main(argv=sys.argv):
errstr = str(err)
if errstr.lower().startswith('no module named'):
whichmod = errstr[16:]
+ hint = ''
if whichmod.startswith('docutils'):
whichmod = 'Docutils library'
elif whichmod.startswith('jinja'):
whichmod = 'Jinja library'
elif whichmod == 'roman':
whichmod = 'roman module (which is distributed with Docutils)'
+ hint = ('This can happen if you upgraded docutils using\n'
+ 'easy_install without uninstalling the old version'
+ 'first.')
else:
whichmod += ' module'
print >>sys.stderr, \
'Error: The %s cannot be found. Did you install Sphinx '\
'and its dependencies correctly?' % whichmod
+ if hint:
+ print >> sys.stderr, hint
return 1
raise
return cmdline.main(argv)
diff --git a/sphinx/_jinja.py b/sphinx/_jinja.py
deleted file mode 100644
index 3adf0de8..00000000
--- a/sphinx/_jinja.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- sphinx._jinja
- ~~~~~~~~~~~~~
-
- Jinja glue.
-
- :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
- :license: BSD, see LICENSE for details.
-"""
-
-import codecs
-from os import path
-
-from sphinx.util import mtimes_of_files
-from sphinx.application import TemplateBridge
-
-from jinja import Environment
-from jinja.loaders import BaseLoader
-from jinja.exceptions import TemplateNotFound
-
-
-def babel_extract(fileobj, keywords, comment_tags, options):
- """
- Simple extractor to get some basic Babel support.
- """
- env = Environment()
- for lineno, sg, pl in env.get_translations_for_string(fileobj.read()):
- yield lineno, None, (sg, pl), ''
-
-
-class SphinxFileSystemLoader(BaseLoader):
- """
- A loader that loads templates either relative to one of a list of given
- paths, or from an absolute path.
- """
-
- def __init__(self, basepath, extpaths):
- self.basepath = path.abspath(basepath)
- self.extpaths = map(path.abspath, extpaths)
- self.searchpaths = self.extpaths + [self.basepath]
-
- def get_source(self, environment, name, parent):
- name = name.replace('/', path.sep)
- if name.startswith('!'):
- name = name[1:]
- if not path.exists(path.join(self.basepath, name)):
- raise TemplateNotFound(name)
- filename = path.join(self.basepath, name)
- elif path.isabs(name):
- if not path.exists(name):
- raise TemplateNotFound(name)
- filename = name
- else:
- for searchpath in self.searchpaths:
- if path.exists(path.join(searchpath, name)):
- filename = path.join(searchpath, name)
- break
- else:
- raise TemplateNotFound(name)
- f = codecs.open(filename, 'r', environment.template_charset)
- try:
- return f.read()
- finally:
- f.close()
-
-
-class TranslatorEnvironment(Environment):
- class _Translator(object):
- def __init__(self, translator):
- self.trans = translator
-
- def gettext(self, string):
- return self.trans.ugettext(string)
-
- def ngettext(self, singular, plural, n):
- return self.trans.ungettext(singular, plural, n)
-
- def __init__(self, *args, **kwargs):
- self.translator = kwargs['translator']
- del kwargs['translator']
- super(TranslatorEnvironment, self).__init__(*args, **kwargs)
-
- def get_translator(self, context):
- return TranslatorEnvironment._Translator(self.translator)
-
-
-class BuiltinTemplates(TemplateBridge):
- def init(self, builder):
- self.templates = {}
- base_templates_path = path.join(path.dirname(__file__), 'templates')
- ext_templates_path = [path.join(builder.confdir, dir)
- for dir in builder.config.templates_path]
- self.templates_path = [base_templates_path] + ext_templates_path
- loader = SphinxFileSystemLoader(base_templates_path, ext_templates_path)
- if builder.translator is not None:
- self.jinja_env = TranslatorEnvironment(loader=loader,
- friendly_traceback=False, translator=builder.translator)
- else:
- self.jinja_env = Environment(loader=loader,
- # disable traceback, more likely that something
- # in the application is broken than in the templates
- friendly_traceback=False)
-
- def newest_template_mtime(self):
- return max(mtimes_of_files(self.templates_path, '.html'))
-
- def render(self, template, context):
- if template in self.templates:
- return self.templates[template].render(context)
- templateobj = self.templates[template] = \
- self.jinja_env.get_template(template)
- return templateobj.render(context)
diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py
index 6ea47d31..a4af584c 100644
--- a/sphinx/addnodes.py
+++ b/sphinx/addnodes.py
@@ -23,8 +23,12 @@ class desc(nodes.Admonition, nodes.Element): pass
class desc_addname(nodes.Part, nodes.Inline, nodes.TextElement): pass
# compatibility alias
desc_classname = desc_addname
-# return type (C); object type, e.g. -> annotation (Python)
+# return type (C); object type
class desc_type(nodes.Part, nodes.Inline, nodes.TextElement): pass
+# -> annotation (Python)
+class desc_returns(desc_type):
+ def astext(self):
+ return ' -> ' + nodes.TextElement.astext(self)
# main name of object
class desc_name(nodes.Part, nodes.Inline, nodes.TextElement): pass
# argument list
@@ -64,9 +68,16 @@ class pending_xref(nodes.Element): pass
# compact paragraph -- never makes a <p>
class compact_paragraph(nodes.paragraph): pass
+# reference to a file to download
+class download_reference(nodes.reference): pass
+
# for the ACKS list
class acks(nodes.Element): pass
+# for horizontal lists
+class hlist(nodes.Element): pass
+class hlistcol(nodes.Element): pass
+
# sets the highlighting language for literal blocks
class highlightlang(nodes.Element): pass
@@ -90,8 +101,9 @@ class meta(nodes.Special, nodes.PreBibliographic, nodes.Element): pass
# make them known to docutils. this is needed, because the HTML writer
# will choke at some point if these are not added
-nodes._add_node_class_names("""index desc desc_content desc_signature desc_type
- desc_addname desc_name desc_parameterlist desc_parameter desc_optional
+nodes._add_node_class_names("""index desc desc_content desc_signature
+ desc_type desc_returns desc_addname desc_name desc_parameterlist
+ desc_parameter desc_optional download_reference hlist hlistcol
centered versionmodified seealso productionlist production toctree
pending_xref compact_paragraph highlightlang literal_emphasis
glossary acks module start_of_file tabular_col_spec meta""".split())
diff --git a/sphinx/application.py b/sphinx/application.py
index ecc2037a..1ad7823f 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -7,7 +7,6 @@
Gracefully adapted from the TextPress system by Armin.
-
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@@ -22,7 +21,7 @@ from docutils.parsers.rst import directives, roles
import sphinx
from sphinx.roles import xfileref_role, innernodetypes
from sphinx.config import Config
-from sphinx.builder import builtin_builders, StandaloneHTMLBuilder
+from sphinx.builders import BUILTIN_BUILDERS
from sphinx.directives import desc_directive, target_directive, additional_xref_types
from sphinx.environment import SphinxStandaloneReader
from sphinx.util.console import bold
@@ -77,7 +76,7 @@ class Sphinx(object):
confoverrides, status, warning=sys.stderr, freshenv=False):
self.next_listener_id = 0
self._listeners = {}
- self.builderclasses = builtin_builders.copy()
+ self.builderclasses = BUILTIN_BUILDERS.copy()
self.builder = None
self.srcdir = srcdir
@@ -125,6 +124,11 @@ class Sphinx(object):
buildername)))
builderclass = self.builderclasses[buildername]
+ if isinstance(builderclass, tuple):
+ # builtin builder
+ mod, cls = builderclass
+ builderclass = getattr(
+ __import__('sphinx.builders.' + mod, None, None, [cls]), cls)
self.builder = builderclass(self, freshenv=freshenv)
self.emit('builder-inited')
@@ -227,8 +231,12 @@ class Sphinx(object):
if not hasattr(builder, 'name'):
raise ExtensionError('Builder class %s has no "name" attribute' % builder)
if builder.name in self.builderclasses:
- raise ExtensionError('Builder %r already exists (in module %s)' % (
- builder.name, self.builderclasses[builder.name].__module__))
+ if isinstance(self.builderclasses[builder.name], tuple):
+ raise ExtensionError('Builder %r is a builtin builder' %
+ builder.name)
+ else:
+ raise ExtensionError('Builder %r already exists (in module %s)' % (
+ builder.name, self.builderclasses[builder.name].__module__))
self.builderclasses[builder.name] = builder
def add_config_value(self, name, default, rebuild_env):
@@ -250,11 +258,11 @@ class Sphinx(object):
raise ExtensionError('Value for key %r must be a (visit, depart) '
'function tuple' % key)
if key == 'html':
- from sphinx.htmlwriter import HTMLTranslator as translator
+ from sphinx.writers.html import HTMLTranslator as translator
elif key == 'latex':
- from sphinx.latexwriter import LaTeXTranslator as translator
+ from sphinx.writers.latex import LaTeXTranslator as translator
elif key == 'text':
- from sphinx.textwriter import TextTranslator as translator
+ from sphinx.writers.text import TextTranslator as translator
else:
# ignore invalid keys for compatibility
continue
@@ -291,9 +299,16 @@ class Sphinx(object):
SphinxStandaloneReader.transforms.append(transform)
def add_javascript(self, filename):
+ from sphinx.builders.html import StandaloneHTMLBuilder
StandaloneHTMLBuilder.script_files.append(
posixpath.join('_static', filename))
+ def add_lexer(self, alias, lexer):
+ from sphinx.highlighting import lexers
+ if lexers is None:
+ return
+ lexers[alias] = lexer
+
class TemplateBridge(object):
"""
diff --git a/sphinx/builder.py b/sphinx/builder.py
index 7b45f973..13c56e18 100644
--- a/sphinx/builder.py
+++ b/sphinx/builder.py
@@ -3,1275 +3,26 @@
sphinx.builder
~~~~~~~~~~~~~~
- Builder classes for different output formats.
+ .. warning::
+
+ This module is only kept for API compatibility; new code should
+ import these classes directly from the sphinx.builders package.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
-import os
-import time
-import codecs
-import shutil
-import gettext
-import cPickle as pickle
-from os import path
-from cgi import escape
-
-from docutils import nodes
-from docutils.io import StringOutput, FileOutput, DocTreeInput
-from docutils.core import publish_parts
-from docutils.utils import new_document
-from docutils.frontend import OptionParser
-from docutils.readers.doctree import Reader as DoctreeReader
-
-from sphinx import addnodes, locale, __version__
-from sphinx.util import movefile, ensuredir, relative_uri, SEP, os_path, texescape, \
- ustrftime
-from sphinx.htmlhelp import build_hhx
-from sphinx.htmlwriter import HTMLWriter, HTMLTranslator, SmartyPantsHTMLTranslator
-from sphinx.textwriter import TextWriter
-from sphinx.latexwriter import LaTeXWriter
-from sphinx.environment import BuildEnvironment, NoUri
-from sphinx.highlighting import PygmentsBridge
-from sphinx.util.console import bold, purple, darkgreen
-from sphinx.search import js_index
-
-try:
- import json
-except ImportError:
- try:
- import simplejson as json
- except ImportError:
- json = None
-
-# side effect: registers roles and directives
-from sphinx import roles
-from sphinx import directives
-
-ENV_PICKLE_FILENAME = 'environment.pickle'
-LAST_BUILD_FILENAME = 'last_build'
-INVENTORY_FILENAME = 'objects.inv'
-
-
-class Builder(object):
- """
- Builds target formats from the reST sources.
- """
-
- # builder's name, for the -b command line options
- name = ''
-
- def __init__(self, app, env=None, freshenv=False):
- self.srcdir = app.srcdir
- self.confdir = app.confdir
- self.outdir = app.outdir
- self.doctreedir = app.doctreedir
- if not path.isdir(self.doctreedir):
- os.makedirs(self.doctreedir)
-
- self.app = app
- self.warn = app.warn
- self.info = app.info
- self.config = app.config
-
- self.load_i18n()
-
- # images that need to be copied over (source -> dest)
- self.images = {}
-
- # if None, this is set in load_env()
- self.env = env
- self.freshenv = freshenv
-
- self.init()
- self.load_env()
-
- # helper methods
-
- def init(self):
- """Load necessary templates and perform initialization."""
- raise NotImplementedError
-
- def init_templates(self):
- # Call this from init() if you need templates.
- if self.config.template_bridge:
- self.templates = self.app.import_object(
- self.config.template_bridge, 'template_bridge setting')()
- else:
- from sphinx._jinja import BuiltinTemplates
- self.templates = BuiltinTemplates()
- self.templates.init(self)
-
- def get_target_uri(self, docname, typ=None):
- """
- Return the target URI for a document name (typ can be used to qualify
- the link characteristic for individual builders).
- """
- raise NotImplementedError
-
- def get_relative_uri(self, from_, to, typ=None):
- """
- Return a relative URI between two source filenames. May raise environment.NoUri
- if there's no way to return a sensible URI.
- """
- return relative_uri(self.get_target_uri(from_),
- self.get_target_uri(to, typ))
-
- def get_outdated_docs(self):
- """
- Return an iterable of output files that are outdated, or a string describing
- what an update build will build.
- """
- raise NotImplementedError
-
- def status_iterator(self, iterable, summary, colorfunc=darkgreen):
- l = -1
- for item in iterable:
- if l == -1:
- self.info(bold(summary), nonl=1)
- l = 0
- self.info(colorfunc(item) + ' ', nonl=1)
- yield item
- if l == 0:
- self.info()
-
- supported_image_types = []
-
- def post_process_images(self, doctree):
- """
- Pick the best candidate for all image URIs.
- """
- for node in doctree.traverse(nodes.image):
- if '?' in node['candidates']:
- # don't rewrite nonlocal image URIs
- continue
- if '*' not in node['candidates']:
- for imgtype in self.supported_image_types:
- candidate = node['candidates'].get(imgtype, None)
- if candidate:
- break
- else:
- self.warn('%s:%s: no matching candidate for image URI %r' %
- (node.source, getattr(node, 'lineno', ''), node['uri']))
- continue
- node['uri'] = candidate
- else:
- candidate = node['uri']
- if candidate not in self.env.images:
- # non-existing URI; let it alone
- continue
- self.images[candidate] = self.env.images[candidate][1]
-
- # build methods
-
- def load_i18n(self):
- """
- Load translated strings from the configured localedirs if
- enabled in the configuration.
- """
- self.translator = None
- if self.config.language is not None:
- self.info(bold('loading translations [%s]... ' % self.config.language),
- nonl=True)
- locale_dirs = [path.join(path.dirname(__file__), 'locale')] + \
- [path.join(self.srcdir, x) for x in self.config.locale_dirs]
- for dir_ in locale_dirs:
- try:
- trans = gettext.translation('sphinx', localedir=dir_,
- languages=[self.config.language])
- if self.translator is None:
- self.translator = trans
- else:
- self.translator._catalog.update(trans.catalog)
- except Exception:
- # Language couldn't be found in the specified path
- pass
- if self.translator is not None:
- self.info('done')
- else:
- self.info('locale not available')
- if self.translator is None:
- self.translator = gettext.NullTranslations()
- self.translator.install(unicode=True)
- locale.init() # translate common labels
-
- def load_env(self):
- """Set up the build environment."""
- if self.env:
- return
- if not self.freshenv:
- try:
- self.info(bold('loading pickled environment... '), nonl=True)
- self.env = BuildEnvironment.frompickle(self.config,
- path.join(self.doctreedir, ENV_PICKLE_FILENAME))
- self.info('done')
- except Exception, err:
- if type(err) is IOError and err.errno == 2:
- self.info('not found')
- else:
- self.info('failed: %s' % err)
- self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config)
- self.env.find_files(self.config)
- else:
- self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config)
- self.env.find_files(self.config)
- self.env.set_warnfunc(self.warn)
-
- def build_all(self):
- """Build all source files."""
- self.build(None, summary='all source files', method='all')
-
- def build_specific(self, filenames):
- """Only rebuild as much as needed for changes in the source_filenames."""
- # bring the filenames to the canonical format, that is,
- # relative to the source directory and without source_suffix.
- dirlen = len(self.srcdir) + 1
- to_write = []
- suffix = self.config.source_suffix
- for filename in filenames:
- filename = path.abspath(filename)[dirlen:]
- if filename.endswith(suffix):
- filename = filename[:-len(suffix)]
- filename = filename.replace(os.path.sep, SEP)
- to_write.append(filename)
- self.build(to_write, method='specific',
- summary='%d source files given on command '
- 'line' % len(to_write))
-
- def build_update(self):
- """Only rebuild files changed or added since last build."""
- to_build = self.get_outdated_docs()
- if isinstance(to_build, str):
- self.build(['__all__'], to_build)
- else:
- to_build = list(to_build)
- self.build(to_build,
- summary='targets for %d source files that are '
- 'out of date' % len(to_build))
-
- def build(self, docnames, summary=None, method='update'):
- if summary:
- self.info(bold('building [%s]: ' % self.name), nonl=1)
- self.info(summary)
-
- updated_docnames = []
- # while reading, collect all warnings from docutils
- warnings = []
- self.env.set_warnfunc(warnings.append)
- self.info(bold('updating environment: '), nonl=1)
- iterator = self.env.update(self.config, self.srcdir, self.doctreedir, self.app)
- # the first item in the iterator is a summary message
- self.info(iterator.next())
- for docname in self.status_iterator(iterator, 'reading sources... ', purple):
- updated_docnames.append(docname)
- # nothing further to do, the environment has already done the reading
- for warning in warnings:
- if warning.strip():
- self.warn(warning)
- self.env.set_warnfunc(self.warn)
-
- if updated_docnames:
- # save the environment
- self.info(bold('pickling environment... '), nonl=True)
- self.env.topickle(path.join(self.doctreedir, ENV_PICKLE_FILENAME))
- self.info('done')
-
- # global actions
- self.info(bold('checking consistency... '), nonl=True)
- self.env.check_consistency()
- self.info('done')
- else:
- if method == 'update' and not docnames:
- self.info(bold('no targets are out of date.'))
- return
-
- # another indirection to support methods which don't build files
- # individually
- self.write(docnames, updated_docnames, method)
-
- # finish (write static files etc.)
- self.finish()
- status = self.app.statuscode == 0 and 'succeeded' or 'finished with problems'
- if self.app._warncount:
- self.info(bold('build %s, %s warning%s.' %
- (status, self.app._warncount,
- self.app._warncount != 1 and 's' or '')))
- else:
- self.info(bold('build %s.' % status))
-
- def write(self, build_docnames, updated_docnames, method='update'):
- if build_docnames is None or build_docnames == ['__all__']:
- # build_all
- build_docnames = self.env.found_docs
- if method == 'update':
- # build updated ones as well
- docnames = set(build_docnames) | set(updated_docnames)
- else:
- docnames = set(build_docnames)
-
- # add all toctree-containing files that may have changed
- for docname in list(docnames):
- for tocdocname in self.env.files_to_rebuild.get(docname, []):
- docnames.add(tocdocname)
- docnames.add(self.config.master_doc)
-
- self.info(bold('preparing documents... '), nonl=True)
- self.prepare_writing(docnames)
- self.info('done')
-
- # write target files
- warnings = []
- self.env.set_warnfunc(warnings.append)
- for docname in self.status_iterator(sorted(docnames),
- 'writing output... ', darkgreen):
- doctree = self.env.get_and_resolve_doctree(docname, self)
- self.write_doc(docname, doctree)
- for warning in warnings:
- if warning.strip():
- self.warn(warning)
- self.env.set_warnfunc(self.warn)
-
- def prepare_writing(self, docnames):
- raise NotImplementedError
-
- def write_doc(self, docname, doctree):
- raise NotImplementedError
-
- def finish(self):
- raise NotImplementedError
-
-
-class StandaloneHTMLBuilder(Builder):
- """
- Builds standalone HTML docs.
- """
- name = 'html'
- copysource = True
- out_suffix = '.html'
- indexer_format = js_index
- supported_image_types = ['image/svg+xml', 'image/png', 'image/gif',
- 'image/jpeg']
- searchindex_filename = 'searchindex.js'
- add_header_links = True
- add_definition_links = True
-
- # This is a class attribute because it is mutated by Sphinx.add_javascript.
- script_files = ['_static/jquery.js', '_static/doctools.js']
-
- def init(self):
- """Load templates."""
- self.init_templates()
- self.init_translator_class()
- if self.config.html_file_suffix:
- self.out_suffix = self.config.html_file_suffix
-
- if self.config.language is not None:
- jsfile = path.join(path.dirname(__file__), 'locale', self.config.language,
- 'LC_MESSAGES', 'sphinx.js')
- if path.isfile(jsfile):
- self.script_files.append('_static/translations.js')
-
- def init_translator_class(self):
- if self.config.html_translator_class:
- self.translator_class = self.app.import_object(
- self.config.html_translator_class, 'html_translator_class setting')
- elif self.config.html_use_smartypants:
- self.translator_class = SmartyPantsHTMLTranslator
- else:
- self.translator_class = HTMLTranslator
-
- def render_partial(self, node):
- """Utility: Render a lone doctree node."""
- doc = new_document('<partial node>')
- doc.append(node)
- return publish_parts(
- doc,
- source_class=DocTreeInput,
- reader=DoctreeReader(),
- writer=HTMLWriter(self),
- settings_overrides={'output_encoding': 'unicode'}
- )
-
- def prepare_writing(self, docnames):
- from sphinx.search import IndexBuilder
-
- self.indexer = IndexBuilder(self.env)
- self.load_indexer(docnames)
- self.docwriter = HTMLWriter(self)
- self.docsettings = OptionParser(
- defaults=self.env.settings,
- components=(self.docwriter,)).get_default_values()
-
- # format the "last updated on" string, only once is enough since it
- # typically doesn't include the time of day
- lufmt = self.config.html_last_updated_fmt
- if lufmt is not None:
- self.last_updated = ustrftime(lufmt or _('%b %d, %Y'))
- else:
- self.last_updated = None
-
- logo = self.config.html_logo and \
- path.basename(self.config.html_logo) or ''
-
- favicon = self.config.html_favicon and \
- path.basename(self.config.html_favicon) or ''
- if favicon and os.path.splitext(favicon)[1] != '.ico':
- self.warn('html_favicon is not an .ico file')
-
- if not isinstance(self.config.html_use_opensearch, basestring):
- self.warn('html_use_opensearch config value must now be a string')
-
- self.relations = self.env.collect_relations()
-
- rellinks = []
- if self.config.html_use_index:
- rellinks.append(('genindex', _('General Index'), 'I', _('index')))
- if self.config.html_use_modindex and self.env.modules:
- rellinks.append(('modindex', _('Global Module Index'), 'M', _('modules')))
-
- self.globalcontext = dict(
- project = self.config.project,
- release = self.config.release,
- version = self.config.version,
- last_updated = self.last_updated,
- copyright = self.config.copyright,
- master_doc = self.config.master_doc,
- style = self.config.html_style,
- use_opensearch = self.config.html_use_opensearch,
- docstitle = self.config.html_title,
- shorttitle = self.config.html_short_title,
- show_sphinx = self.config.html_show_sphinx,
- has_source = self.config.html_copy_source,
- file_suffix = self.out_suffix,
- script_files = self.script_files,
- sphinx_version = __version__,
- rellinks = rellinks,
- builder = self.name,
- parents = [],
- logo = logo,
- favicon = favicon,
- )
- self.globalcontext.update(self.config.html_context)
-
- def get_doc_context(self, docname, body, metatags):
- """Collect items for the template context of a page."""
- # find out relations
- prev = next = None
- parents = []
- rellinks = self.globalcontext['rellinks'][:]
- related = self.relations.get(docname)
- titles = self.env.titles
- if related and related[2]:
- try:
- next = {'link': self.get_relative_uri(docname, related[2]),
- 'title': self.render_partial(titles[related[2]])['title']}
- rellinks.append((related[2], next['title'], 'N', _('next')))
- except KeyError:
- next = None
- if related and related[1]:
- try:
- prev = {'link': self.get_relative_uri(docname, related[1]),
- 'title': self.render_partial(titles[related[1]])['title']}
- rellinks.append((related[1], prev['title'], 'P', _('previous')))
- except KeyError:
- # the relation is (somehow) not in the TOC tree, handle that gracefully
- prev = None
- while related and related[0]:
- try:
- parents.append(
- {'link': self.get_relative_uri(docname, related[0]),
- 'title': self.render_partial(titles[related[0]])['title']})
- except KeyError:
- pass
- related = self.relations.get(related[0])
- if parents:
- parents.pop() # remove link to the master file; we have a generic
- # "back to index" link already
- parents.reverse()
-
- # title rendered as HTML
- title = titles.get(docname)
- title = title and self.render_partial(title)['title'] or ''
- # the name for the copied source
- sourcename = self.config.html_copy_source and docname + '.txt' or ''
-
- # metadata for the document
- meta = self.env.metadata.get(docname)
-
- return dict(
- parents = parents,
- prev = prev,
- next = next,
- title = title,
- meta = meta,
- body = body,
- metatags = metatags,
- rellinks = rellinks,
- sourcename = sourcename,
- toc = self.render_partial(self.env.get_toc_for(docname))['fragment'],
- # only display a TOC if there's more than one item to show
- display_toc = (self.env.toc_num_entries[docname] > 1),
- )
-
- def write_doc(self, docname, doctree):
- self.post_process_images(doctree)
- destination = StringOutput(encoding='utf-8')
- doctree.settings = self.docsettings
-
- self.imgpath = relative_uri(self.get_target_uri(docname), '_images')
- self.docwriter.write(doctree, destination)
- self.docwriter.assemble_parts()
- body = self.docwriter.parts['fragment']
- metatags = self.docwriter.clean_meta
-
- ctx = self.get_doc_context(docname, body, metatags)
- self.index_page(docname, doctree, ctx.get('title', ''))
- self.handle_page(docname, ctx, event_arg=doctree)
-
- def finish(self):
- self.info(bold('writing additional files...'), nonl=1)
-
- # the global general index
-
- if self.config.html_use_index:
- # the total count of lines for each index letter, used to distribute
- # the entries into two columns
- genindex = self.env.create_index(self)
- indexcounts = []
- for _, entries in genindex:
- indexcounts.append(sum(1 + len(subitems)
- for _, (_, subitems) in entries))
-
- genindexcontext = dict(
- genindexentries = genindex,
- genindexcounts = indexcounts,
- split_index = self.config.html_split_index,
- )
- self.info(' genindex', nonl=1)
-
- if self.config.html_split_index:
- self.handle_page('genindex', genindexcontext, 'genindex-split.html')
- self.handle_page('genindex-all', genindexcontext, 'genindex.html')
- for (key, entries), count in zip(genindex, indexcounts):
- ctx = {'key': key, 'entries': entries, 'count': count,
- 'genindexentries': genindex}
- self.handle_page('genindex-' + key, ctx, 'genindex-single.html')
- else:
- self.handle_page('genindex', genindexcontext, 'genindex.html')
-
- # the global module index
-
- if self.config.html_use_modindex and self.env.modules:
- # the sorted list of all modules, for the global module index
- modules = sorted(((mn, (self.get_relative_uri('modindex', fn) +
- '#module-' + mn, sy, pl, dep))
- for (mn, (fn, sy, pl, dep)) in
- self.env.modules.iteritems()),
- key=lambda x: x[0].lower())
- # collect all platforms
- platforms = set()
- # sort out collapsable modules
- modindexentries = []
- letters = []
- pmn = ''
- num_toplevels = 0
- num_collapsables = 0
- cg = 0 # collapse group
- fl = '' # first letter
- for mn, (fn, sy, pl, dep) in modules:
- pl = pl and pl.split(', ') or []
- platforms.update(pl)
- if fl != mn[0].lower() and mn[0] != '_':
- # heading
- modindexentries.append(['', False, 0, False,
- mn[0].upper(), '', [], False])
- letters.append(mn[0].upper())
- tn = mn.split('.')[0]
- if tn != mn:
- # submodule
- if pmn == tn:
- # first submodule - make parent collapsable
- modindexentries[-1][1] = True
- num_collapsables += 1
- elif not pmn.startswith(tn):
- # submodule without parent in list, add dummy entry
- cg += 1
- modindexentries.append([tn, True, cg, False, '', '', [], False])
- else:
- num_toplevels += 1
- cg += 1
- modindexentries.append([mn, False, cg, (tn != mn), fn, sy, pl, dep])
- pmn = mn
- fl = mn[0].lower()
- platforms = sorted(platforms)
-
- # apply heuristics when to collapse modindex at page load:
- # only collapse if number of toplevel modules is larger than
- # number of submodules
- collapse = len(modules) - num_toplevels < num_toplevels
-
- modindexcontext = dict(
- modindexentries = modindexentries,
- platforms = platforms,
- letters = letters,
- collapse_modindex = collapse,
- )
- self.info(' modindex', nonl=1)
- self.handle_page('modindex', modindexcontext, 'modindex.html')
-
- # the search page
- if self.name != 'htmlhelp':
- self.info(' search', nonl=1)
- self.handle_page('search', {}, 'search.html')
-
- # additional pages from conf.py
- for pagename, template in self.config.html_additional_pages.items():
- self.info(' '+pagename, nonl=1)
- self.handle_page(pagename, {}, template)
-
- if self.config.html_use_opensearch and self.name != 'htmlhelp':
- self.info(' opensearch', nonl=1)
- fn = path.join(self.outdir, '_static', 'opensearch.xml')
- self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn)
-
- self.info()
-
- # copy image files
- if self.images:
- self.info(bold('copying images...'), nonl=True)
- ensuredir(path.join(self.outdir, '_images'))
- for src, dest in self.images.iteritems():
- self.info(' '+src, nonl=1)
- shutil.copyfile(path.join(self.srcdir, src),
- path.join(self.outdir, '_images', dest))
- self.info()
-
- # copy static files
- self.info(bold('copying static files... '), nonl=True)
- ensuredir(path.join(self.outdir, '_static'))
- # first, create pygments style file
- f = open(path.join(self.outdir, '_static', 'pygments.css'), 'w')
- f.write(PygmentsBridge('html', self.config.pygments_style).get_stylesheet())
- f.close()
- # then, copy translations JavaScript file
- if self.config.language is not None:
- jsfile = path.join(path.dirname(__file__), 'locale', self.config.language,
- 'LC_MESSAGES', 'sphinx.js')
- if path.isfile(jsfile):
- shutil.copyfile(jsfile, path.join(self.outdir, '_static',
- 'translations.js'))
- # then, copy over all user-supplied static files
- staticdirnames = [path.join(path.dirname(__file__), 'static')] + \
- [path.join(self.confdir, spath)
- for spath in self.config.html_static_path]
- for staticdirname in staticdirnames:
- for filename in os.listdir(staticdirname):
- if filename.startswith('.'):
- continue
- fullname = path.join(staticdirname, filename)
- targetname = path.join(self.outdir, '_static', filename)
- if path.isfile(fullname):
- shutil.copyfile(fullname, targetname)
- elif path.isdir(fullname):
- if filename in self.config.exclude_dirnames:
- continue
- if path.exists(targetname):
- shutil.rmtree(targetname)
- shutil.copytree(fullname, targetname)
- # last, copy logo file (handled differently)
- if self.config.html_logo:
- logobase = path.basename(self.config.html_logo)
- shutil.copyfile(path.join(self.confdir, self.config.html_logo),
- path.join(self.outdir, '_static', logobase))
- self.info('done')
-
- # dump the search index
- self.handle_finish()
-
- def get_outdated_docs(self):
- if self.templates:
- template_mtime = self.templates.newest_template_mtime()
- else:
- template_mtime = 0
- for docname in self.env.found_docs:
- if docname not in self.env.all_docs:
- yield docname
- continue
- targetname = self.env.doc2path(docname, self.outdir, self.out_suffix)
- try:
- targetmtime = path.getmtime(targetname)
- except Exception:
- targetmtime = 0
- try:
- srcmtime = max(path.getmtime(self.env.doc2path(docname)),
- template_mtime)
- if srcmtime > targetmtime:
- yield docname
- except EnvironmentError:
- # source doesn't exist anymore
- pass
-
- def load_indexer(self, docnames):
- keep = set(self.env.all_docs) - set(docnames)
- try:
- f = open(path.join(self.outdir, self.searchindex_filename), 'rb')
- try:
- self.indexer.load(f, self.indexer_format)
- finally:
- f.close()
- except (IOError, OSError, ValueError):
- if keep:
- self.warn("search index couldn't be loaded, but not all documents "
- "will be built: the index will be incomplete.")
- # delete all entries for files that will be rebuilt
- self.indexer.prune(keep)
-
- def index_page(self, pagename, doctree, title):
- # only index pages with title
- if self.indexer is not None and title:
- self.indexer.feed(pagename, title, doctree)
-
- # --------- these are overwritten by the serialization builder
-
- def get_target_uri(self, docname, typ=None):
- return docname + self.out_suffix
-
- def handle_page(self, pagename, addctx, templatename='page.html',
- outfilename=None, event_arg=None):
- ctx = self.globalcontext.copy()
- # current_page_name is backwards compatibility
- ctx['pagename'] = ctx['current_page_name'] = pagename
-
- def pathto(otheruri, resource=False,
- baseuri=self.get_target_uri(pagename)):
- if not resource:
- otheruri = self.get_target_uri(otheruri)
- return relative_uri(baseuri, otheruri)
- ctx['pathto'] = pathto
- ctx['hasdoc'] = lambda name: name in self.env.all_docs
- ctx['customsidebar'] = self.config.html_sidebars.get(pagename)
- ctx.update(addctx)
-
- self.app.emit('html-page-context', pagename, templatename, ctx, event_arg)
-
- output = self.templates.render(templatename, ctx)
- if not outfilename:
- outfilename = path.join(self.outdir, os_path(pagename) + self.out_suffix)
- ensuredir(path.dirname(outfilename)) # normally different from self.outdir
- try:
- f = codecs.open(outfilename, 'w', 'utf-8')
- try:
- f.write(output)
- finally:
- f.close()
- except (IOError, OSError), err:
- self.warn("Error writing file %s: %s" % (outfilename, err))
- if self.copysource and ctx.get('sourcename'):
- # copy the source file for the "show source" link
- source_name = path.join(self.outdir, '_sources', os_path(ctx['sourcename']))
- ensuredir(path.dirname(source_name))
- shutil.copyfile(self.env.doc2path(pagename), source_name)
-
- def handle_finish(self):
- self.info(bold('dumping search index... '), nonl=True)
- self.indexer.prune(self.env.all_docs)
- searchindexfn = path.join(self.outdir, self.searchindex_filename)
- # first write to a temporary file, so that if dumping fails, the existing
- # index won't be overwritten
- f = open(searchindexfn + '.tmp', 'wb')
- try:
- self.indexer.dump(f, self.indexer_format)
- finally:
- f.close()
- movefile(searchindexfn + '.tmp', searchindexfn)
- self.info('done')
-
- self.info(bold('dumping object inventory... '), nonl=True)
- f = open(path.join(self.outdir, INVENTORY_FILENAME), 'w')
- try:
- f.write('# Sphinx inventory version 1\n')
- f.write('# Project: %s\n' % self.config.project.encode('utf-8'))
- f.write('# Version: %s\n' % self.config.version)
- for modname, info in self.env.modules.iteritems():
- f.write('%s mod %s\n' % (modname, self.get_target_uri(info[0])))
- for refname, (docname, desctype) in self.env.descrefs.iteritems():
- f.write('%s %s %s\n' % (refname, desctype, self.get_target_uri(docname)))
- finally:
- f.close()
- self.info('done')
-
-
-class SerializingHTMLBuilder(StandaloneHTMLBuilder):
- """
- An abstract builder that serializes the HTML generated.
- """
- #: the serializing implementation to use. Set this to a module that
- #: implements a `dump`, `load`, `dumps` and `loads` functions
- #: (pickle, simplejson etc.)
- implementation = None
-
- #: the filename for the global context file
- globalcontext_filename = None
-
- supported_image_types = ('image/svg+xml', 'image/png', 'image/gif',
- 'image/jpeg')
-
- def init(self):
- self.init_translator_class()
- self.templates = None # no template bridge necessary
-
- def get_target_uri(self, docname, typ=None):
- if docname == 'index':
- return ''
- if docname.endswith(SEP + 'index'):
- return docname[:-5] # up to sep
- return docname + SEP
-
- def handle_page(self, pagename, ctx, templatename='page.html',
- outfilename=None, event_arg=None):
- ctx['current_page_name'] = pagename
- sidebarfile = self.config.html_sidebars.get(pagename)
- if sidebarfile:
- ctx['customsidebar'] = sidebarfile
-
- if not outfilename:
- outfilename = path.join(self.outdir, os_path(pagename) + self.out_suffix)
-
- self.app.emit('html-page-context', pagename, templatename, ctx, event_arg)
-
- ensuredir(path.dirname(outfilename))
- f = open(outfilename, 'wb')
- try:
- self.implementation.dump(ctx, f, 2)
- finally:
- f.close()
-
- # if there is a source file, copy the source file for the
- # "show source" link
- if ctx.get('sourcename'):
- source_name = path.join(self.outdir, '_sources',
- os_path(ctx['sourcename']))
- ensuredir(path.dirname(source_name))
- shutil.copyfile(self.env.doc2path(pagename), source_name)
-
- def handle_finish(self):
- # dump the global context
- outfilename = path.join(self.outdir, self.globalcontext_filename)
- f = open(outfilename, 'wb')
- try:
- self.implementation.dump(self.globalcontext, f, 2)
- finally:
- f.close()
-
- # super here to dump the search index
- StandaloneHTMLBuilder.handle_finish(self)
-
- # copy the environment file from the doctree dir to the output dir
- # as needed by the web app
- shutil.copyfile(path.join(self.doctreedir, ENV_PICKLE_FILENAME),
- path.join(self.outdir, ENV_PICKLE_FILENAME))
-
- # touch 'last build' file, used by the web application to determine
- # when to reload its environment and clear the cache
- open(path.join(self.outdir, LAST_BUILD_FILENAME), 'w').close()
-
-
-class PickleHTMLBuilder(SerializingHTMLBuilder):
- """
- A Builder that dumps the generated HTML into pickle files.
- """
- implementation = pickle
- indexer_format = pickle
- name = 'pickle'
- out_suffix = '.fpickle'
- globalcontext_filename = 'globalcontext.pickle'
- searchindex_filename = 'searchindex.pickle'
-
-
-class JSONHTMLBuilder(SerializingHTMLBuilder):
- """
- A builder that dumps the generated HTML into JSON files.
- """
- implementation = json
- indexer_format = json
- name = 'json'
- out_suffix = '.fjson'
- globalcontext_filename = 'globalcontext.json'
- searchindex_filename = 'searchindex.json'
-
- def init(self):
- if json is None:
- from sphinx.application import SphinxError
- raise SphinxError('The module simplejson (or json in Python >= 2.6) '
- 'is not available. The JSONHTMLBuilder builder '
- 'will not work.')
- SerializingHTMLBuilder.init(self)
-
-
-class HTMLHelpBuilder(StandaloneHTMLBuilder):
- """
- Builder that also outputs Windows HTML help project, contents and index files.
- Adapted from the original Doc/tools/prechm.py.
- """
- name = 'htmlhelp'
-
- # don't copy the reST source
- copysource = False
- supported_image_types = ['image/png', 'image/gif', 'image/jpeg']
-
- # don't add links
- add_header_links = False
- add_definition_links = False
-
- def init(self):
- StandaloneHTMLBuilder.init(self)
- # the output files for HTML help must be .html only
- self.out_suffix = '.html'
-
- def handle_finish(self):
- build_hhx(self, self.outdir, self.config.htmlhelp_basename)
-
-
-class LaTeXBuilder(Builder):
- """
- Builds LaTeX output to create PDF.
- """
- name = 'latex'
- supported_image_types = ['application/pdf', 'image/png', 'image/gif',
- 'image/jpeg']
-
- def init(self):
- self.docnames = []
- self.document_data = []
- texescape.init()
-
- def get_outdated_docs(self):
- return 'all documents' # for now
-
- def get_target_uri(self, docname, typ=None):
- if typ == 'token':
- # token references are always inside production lists and must be
- # replaced by \token{} in LaTeX
- return '@token'
- if docname not in self.docnames:
- raise NoUri
- else:
- return ''
-
- def init_document_data(self):
- preliminary_document_data = map(list, self.config.latex_documents)
- if not preliminary_document_data:
- self.warn('No "latex_documents" config value found; no documents '
- 'will be written.')
- return
- # assign subdirs to titles
- self.titles = []
- for entry in preliminary_document_data:
- docname = entry[0]
- if docname not in self.env.all_docs:
- self.warn('"latex_documents" config value references unknown '
- 'document %s' % docname)
- continue
- self.document_data.append(entry)
- if docname.endswith(SEP+'index'):
- docname = docname[:-5]
- self.titles.append((docname, entry[2]))
-
- def write(self, *ignored):
- # first, assemble the "appendix" docs that are in every PDF
- appendices = []
- for fname in self.config.latex_appendices:
- appendices.append(self.env.get_doctree(fname))
-
- docwriter = LaTeXWriter(self)
- docsettings = OptionParser(
- defaults=self.env.settings,
- components=(docwriter,)).get_default_values()
-
- self.init_document_data()
-
- for entry in self.document_data:
- docname, targetname, title, author, docclass = entry[:5]
- toctree_only = False
- if len(entry) > 5:
- toctree_only = entry[5]
- destination = FileOutput(
- destination_path=path.join(self.outdir, targetname),
- encoding='utf-8')
- self.info("processing " + targetname + "... ", nonl=1)
- doctree = self.assemble_doctree(docname, toctree_only,
- appendices=(docclass == 'manual') and appendices or [])
- self.post_process_images(doctree)
- self.info("writing... ", nonl=1)
- doctree.settings = docsettings
- doctree.settings.author = author
- doctree.settings.title = title
- doctree.settings.docname = docname
- doctree.settings.docclass = docclass
- docwriter.write(doctree, destination)
- self.info("done")
-
- def assemble_doctree(self, indexfile, toctree_only, appendices):
- self.docnames = set([indexfile] + appendices)
- self.info(darkgreen(indexfile) + " ", nonl=1)
- def process_tree(docname, tree):
- tree = tree.deepcopy()
- for toctreenode in tree.traverse(addnodes.toctree):
- newnodes = []
- includefiles = map(str, toctreenode['includefiles'])
- for includefile in includefiles:
- try:
- self.info(darkgreen(includefile) + " ", nonl=1)
- subtree = process_tree(includefile,
- self.env.get_doctree(includefile))
- self.docnames.add(includefile)
- except Exception:
- self.warn('%s: toctree contains ref to nonexisting file %r' %
- (docname, includefile))
- else:
- sof = addnodes.start_of_file()
- sof.children = subtree.children
- newnodes.append(sof)
- toctreenode.parent.replace(toctreenode, newnodes)
- return tree
- tree = self.env.get_doctree(indexfile)
- if toctree_only:
- # extract toctree nodes from the tree and put them in a fresh document
- new_tree = new_document('<latex output>')
- new_sect = nodes.section()
- new_sect += nodes.title(u'<Set title in conf.py>', u'<Set title in conf.py>')
- new_tree += new_sect
- for node in tree.traverse(addnodes.toctree):
- new_sect += node
- tree = new_tree
- largetree = process_tree(indexfile, tree)
- largetree.extend(appendices)
- self.info()
- self.info("resolving references...")
- self.env.resolve_references(largetree, indexfile, self)
- # resolve :ref:s to distant tex files -- we can't add a cross-reference,
- # but append the document name
- for pendingnode in largetree.traverse(addnodes.pending_xref):
- docname = pendingnode['refdocname']
- sectname = pendingnode['refsectname']
- newnodes = [nodes.emphasis(sectname, sectname)]
- for subdir, title in self.titles:
- if docname.startswith(subdir):
- newnodes.append(nodes.Text(_(' (in '), _(' (in ')))
- newnodes.append(nodes.emphasis(title, title))
- newnodes.append(nodes.Text(')', ')'))
- break
- else:
- pass
- pendingnode.replace_self(newnodes)
- return largetree
-
- def finish(self):
- # copy image files
- if self.images:
- self.info(bold('copying images...'), nonl=1)
- for src, dest in self.images.iteritems():
- self.info(' '+src, nonl=1)
- shutil.copyfile(path.join(self.srcdir, src),
- path.join(self.outdir, dest))
- self.info()
-
- # the logo is handled differently
- if self.config.latex_logo:
- logobase = path.basename(self.config.latex_logo)
- shutil.copyfile(path.join(self.confdir, self.config.latex_logo),
- path.join(self.outdir, logobase))
-
- self.info(bold('copying TeX support files... '), nonl=True)
- staticdirname = path.join(path.dirname(__file__), 'texinputs')
- for filename in os.listdir(staticdirname):
- if not filename.startswith('.'):
- shutil.copyfile(path.join(staticdirname, filename),
- path.join(self.outdir, filename))
- self.info('done')
-
-
-class ChangesBuilder(Builder):
- """
- Write a summary with all versionadded/changed directives.
- """
- name = 'changes'
-
- def init(self):
- self.init_templates()
-
- def get_outdated_docs(self):
- return self.outdir
-
- typemap = {
- 'versionadded': 'added',
- 'versionchanged': 'changed',
- 'deprecated': 'deprecated',
- }
-
- def write(self, *ignored):
- version = self.config.version
- libchanges = {}
- apichanges = []
- otherchanges = {}
- if version not in self.env.versionchanges:
- self.info(bold('no changes in this version.'))
- return
- self.info(bold('writing summary file...'))
- for type, docname, lineno, module, descname, content in \
- self.env.versionchanges[version]:
- ttext = self.typemap[type]
- context = content.replace('\n', ' ')
- if descname and docname.startswith('c-api'):
- if not descname:
- continue
- if context:
- entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext, context)
- else:
- entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
- apichanges.append((entry, docname, lineno))
- elif descname or module:
- if not module:
- module = _('Builtins')
- if not descname:
- descname = _('Module level')
- if context:
- entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext, context)
- else:
- entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
- libchanges.setdefault(module, []).append((entry, docname, lineno))
- else:
- if not context:
- continue
- entry = '<i>%s:</i> %s' % (ttext.capitalize(), context)
- title = self.env.titles[docname].astext()
- otherchanges.setdefault((docname, title), []).append(
- (entry, docname, lineno))
-
- ctx = {
- 'project': self.config.project,
- 'version': version,
- 'docstitle': self.config.html_title,
- 'shorttitle': self.config.html_short_title,
- 'libchanges': sorted(libchanges.iteritems()),
- 'apichanges': sorted(apichanges),
- 'otherchanges': sorted(otherchanges.iteritems()),
- 'show_sphinx': self.config.html_show_sphinx,
- }
- f = open(path.join(self.outdir, 'index.html'), 'w')
- try:
- f.write(self.templates.render('changes/frameset.html', ctx))
- finally:
- f.close()
- f = open(path.join(self.outdir, 'changes.html'), 'w')
- try:
- f.write(self.templates.render('changes/versionchanges.html', ctx))
- finally:
- f.close()
-
- hltext = ['.. versionadded:: %s' % version,
- '.. versionchanged:: %s' % version,
- '.. deprecated:: %s' % version]
-
- def hl(no, line):
- line = '<a name="L%s"> </a>' % no + escape(line)
- for x in hltext:
- if x in line:
- line = '<span class="hl">%s</span>' % line
- break
- return line
-
- self.info(bold('copying source files...'))
- for docname in self.env.all_docs:
- f = open(self.env.doc2path(docname))
- lines = f.readlines()
- targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html'
- ensuredir(path.dirname(targetfn))
- f = codecs.open(targetfn, 'w', 'utf8')
- try:
- text = ''.join(hl(i+1, line) for (i, line) in enumerate(lines))
- ctx = {'filename': self.env.doc2path(docname, None), 'text': text}
- f.write(self.templates.render('changes/rstsource.html', ctx))
- finally:
- f.close()
- shutil.copyfile(path.join(path.dirname(__file__), 'static', 'default.css'),
- path.join(self.outdir, 'default.css'))
-
- def hl(self, text, version):
- text = escape(text)
- for directive in ['versionchanged', 'versionadded', 'deprecated']:
- text = text.replace('.. %s:: %s' % (directive, version),
- '<b>.. %s:: %s</b>' % (directive, version))
- return text
-
- def finish(self):
- pass
-
-
-class TextBuilder(Builder):
- name = 'text'
- out_suffix = '.txt'
-
- def init(self):
- pass
-
- def get_outdated_docs(self):
- for docname in self.env.found_docs:
- if docname not in self.env.all_docs:
- yield docname
- continue
- targetname = self.env.doc2path(docname, self.outdir, self.out_suffix)
- try:
- targetmtime = path.getmtime(targetname)
- except Exception:
- targetmtime = 0
- try:
- srcmtime = path.getmtime(self.env.doc2path(docname))
- if srcmtime > targetmtime:
- yield docname
- except EnvironmentError:
- # source doesn't exist anymore
- pass
-
- def get_target_uri(self, docname, typ=None):
- return ''
-
- def prepare_writing(self, docnames):
- self.writer = TextWriter(self)
-
- def write_doc(self, docname, doctree):
- destination = StringOutput(encoding='utf-8')
- self.writer.write(doctree, destination)
- outfilename = path.join(self.outdir, os_path(docname) + self.out_suffix)
- ensuredir(path.dirname(outfilename)) # normally different from self.outdir
- try:
- f = codecs.open(outfilename, 'w', 'utf-8')
- try:
- f.write(self.writer.output)
- finally:
- f.close()
- except (IOError, OSError), err:
- self.warn("Error writing file %s: %s" % (outfilename, err))
-
- def finish(self):
- pass
-
-
-# compatibility alias
-WebHTMLBuilder = PickleHTMLBuilder
-
+import warnings
-from sphinx.linkcheck import CheckExternalLinksBuilder
+from sphinx.builders import Builder
+from sphinx.builders.text import TextBuilder
+from sphinx.builders.html import StandaloneHTMLBuilder, WebHTMLBuilder, \
+ PickleHTMLBuilder, JSONHTMLBuilder
+from sphinx.builders.latex import LaTeXBuilder
+from sphinx.builders.changes import ChangesBuilder
+from sphinx.builders.htmlhelp import HTMLHelpBuilder
+from sphinx.builders.linkcheck import CheckExternalLinksBuilder
-builtin_builders = {
- 'html': StandaloneHTMLBuilder,
- 'pickle': PickleHTMLBuilder,
- 'json': JSONHTMLBuilder,
- 'web': PickleHTMLBuilder,
- 'htmlhelp': HTMLHelpBuilder,
- 'latex': LaTeXBuilder,
- 'text': TextBuilder,
- 'changes': ChangesBuilder,
- 'linkcheck': CheckExternalLinksBuilder,
-}
+warnings.warn('The sphinx.builder module is deprecated; please import '
+ 'builders from the respective sphinx.builders submodules.',
+ DeprecationWarning, stacklevel=2)
diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py
new file mode 100644
index 00000000..8847b6dc
--- /dev/null
+++ b/sphinx/builders/__init__.py
@@ -0,0 +1,346 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.builders
+ ~~~~~~~~~~~~~~~
+
+ Builder superclass for all builders.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import os
+import gettext
+from os import path
+
+from docutils import nodes
+
+from sphinx import package_dir, locale
+from sphinx.util import SEP, relative_uri
+from sphinx.environment import BuildEnvironment
+from sphinx.util.console import bold, purple, darkgreen
+
+# side effect: registers roles and directives
+from sphinx import roles
+from sphinx import directives
+
+
+ENV_PICKLE_FILENAME = 'environment.pickle'
+
+
+class Builder(object):
+ """
+ Builds target formats from the reST sources.
+ """
+
+ # builder's name, for the -b command line options
+ name = ''
+
+ def __init__(self, app, env=None, freshenv=False):
+ self.srcdir = app.srcdir
+ self.confdir = app.confdir
+ self.outdir = app.outdir
+ self.doctreedir = app.doctreedir
+ if not path.isdir(self.doctreedir):
+ os.makedirs(self.doctreedir)
+
+ self.app = app
+ self.warn = app.warn
+ self.info = app.info
+ self.config = app.config
+
+ self.load_i18n()
+
+ # images that need to be copied over (source -> dest)
+ self.images = {}
+
+ # if None, this is set in load_env()
+ self.env = env
+ self.freshenv = freshenv
+
+ self.init()
+ self.load_env()
+
+ # helper methods
+
+ def init(self):
+ """
+ Load necessary templates and perform initialization. The default
+ implementation does nothing.
+ """
+ pass
+
+ def init_templates(self):
+ """
+ Initialize the template system.
+
+ Call this method from init() if you need templates in your builder.
+ """
+ if self.config.template_bridge:
+ self.templates = self.app.import_object(
+ self.config.template_bridge, 'template_bridge setting')()
+ else:
+ from sphinx.jinja2glue import BuiltinTemplates
+ self.templates = BuiltinTemplates()
+ self.templates.init(self)
+
+ def get_target_uri(self, docname, typ=None):
+ """
+ Return the target URI for a document name (*typ* can be used to qualify
+ the link characteristic for individual builders).
+ """
+ raise NotImplementedError
+
+ def get_relative_uri(self, from_, to, typ=None):
+ """
+ Return a relative URI between two source filenames. May raise environment.NoUri
+ if there's no way to return a sensible URI.
+ """
+ return relative_uri(self.get_target_uri(from_),
+ self.get_target_uri(to, typ))
+
+ def get_outdated_docs(self):
+ """
+ Return an iterable of output files that are outdated, or a string describing
+ what an update build will build.
+
+ If the builder does not output individual files corresponding to source files,
+ return a string here. If it does, return an iterable of those files that need
+ to be written.
+ """
+ raise NotImplementedError
+
+ def status_iterator(self, iterable, summary, colorfunc=darkgreen):
+ l = -1
+ for item in iterable:
+ if l == -1:
+ self.info(bold(summary), nonl=1)
+ l = 0
+ self.info(colorfunc(item) + ' ', nonl=1)
+ yield item
+ if l == 0:
+ self.info()
+
+ supported_image_types = []
+
+ def post_process_images(self, doctree):
+ """
+ Pick the best candidate for all image URIs.
+ """
+ for node in doctree.traverse(nodes.image):
+ if '?' in node['candidates']:
+ # don't rewrite nonlocal image URIs
+ continue
+ if '*' not in node['candidates']:
+ for imgtype in self.supported_image_types:
+ candidate = node['candidates'].get(imgtype, None)
+ if candidate:
+ break
+ else:
+ self.warn('%s:%s: no matching candidate for image URI %r' %
+ (node.source, getattr(node, 'lineno', ''), node['uri']))
+ continue
+ node['uri'] = candidate
+ else:
+ candidate = node['uri']
+ if candidate not in self.env.images:
+ # non-existing URI; let it alone
+ continue
+ self.images[candidate] = self.env.images[candidate][1]
+
+ # build methods
+
+ def load_i18n(self):
+ """
+ Load translated strings from the configured localedirs if
+ enabled in the configuration.
+ """
+ self.translator = None
+ if self.config.language is not None:
+ self.info(bold('loading translations [%s]... ' % self.config.language),
+ nonl=True)
+ locale_dirs = [path.join(package_dir, 'locale')] + \
+ [path.join(self.srcdir, x) for x in self.config.locale_dirs]
+ for dir_ in locale_dirs:
+ try:
+ trans = gettext.translation('sphinx', localedir=dir_,
+ languages=[self.config.language])
+ if self.translator is None:
+ self.translator = trans
+ else:
+ self.translator._catalog.update(trans.catalog)
+ except Exception:
+ # Language couldn't be found in the specified path
+ pass
+ if self.translator is not None:
+ self.info('done')
+ else:
+ self.info('locale not available')
+ if self.translator is None:
+ self.translator = gettext.NullTranslations()
+ self.translator.install(unicode=True)
+ locale.init() # translate common labels
+
+ def load_env(self):
+ """Set up the build environment."""
+ if self.env:
+ return
+ if not self.freshenv:
+ try:
+ self.info(bold('loading pickled environment... '), nonl=True)
+ self.env = BuildEnvironment.frompickle(self.config,
+ path.join(self.doctreedir, ENV_PICKLE_FILENAME))
+ self.info('done')
+ except Exception, err:
+ if type(err) is IOError and err.errno == 2:
+ self.info('not found')
+ else:
+ self.info('failed: %s' % err)
+ self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config)
+ self.env.find_files(self.config)
+ else:
+ self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config)
+ self.env.find_files(self.config)
+ self.env.set_warnfunc(self.warn)
+
+ def build_all(self):
+ """Build all source files."""
+ self.build(None, summary='all source files', method='all')
+
+ def build_specific(self, filenames):
+ """Only rebuild as much as needed for changes in the *filenames*."""
+ # bring the filenames to the canonical format, that is,
+ # relative to the source directory and without source_suffix.
+ dirlen = len(self.srcdir) + 1
+ to_write = []
+ suffix = self.config.source_suffix
+ for filename in filenames:
+ filename = path.abspath(filename)[dirlen:]
+ if filename.endswith(suffix):
+ filename = filename[:-len(suffix)]
+ filename = filename.replace(os.path.sep, SEP)
+ to_write.append(filename)
+ self.build(to_write, method='specific',
+ summary='%d source files given on command '
+ 'line' % len(to_write))
+
+ def build_update(self):
+ """Only rebuild what was changed or added since last build."""
+ to_build = self.get_outdated_docs()
+ if isinstance(to_build, str):
+ self.build(['__all__'], to_build)
+ else:
+ to_build = list(to_build)
+ self.build(to_build,
+ summary='targets for %d source files that are '
+ 'out of date' % len(to_build))
+
+ def build(self, docnames, summary=None, method='update'):
+ """
+ Main build method. First updates the environment, and then calls :meth:`write`.
+ """
+ if summary:
+ self.info(bold('building [%s]: ' % self.name), nonl=1)
+ self.info(summary)
+
+ updated_docnames = []
+ # while reading, collect all warnings from docutils
+ warnings = []
+ self.env.set_warnfunc(warnings.append)
+ self.info(bold('updating environment: '), nonl=1)
+ iterator = self.env.update(self.config, self.srcdir, self.doctreedir, self.app)
+ # the first item in the iterator is a summary message
+ self.info(iterator.next())
+ for docname in self.status_iterator(iterator, 'reading sources... ', purple):
+ updated_docnames.append(docname)
+ # nothing further to do, the environment has already done the reading
+ for warning in warnings:
+ if warning.strip():
+ self.warn(warning)
+ self.env.set_warnfunc(self.warn)
+
+ if updated_docnames:
+ # save the environment
+ self.info(bold('pickling environment... '), nonl=True)
+ self.env.topickle(path.join(self.doctreedir, ENV_PICKLE_FILENAME))
+ self.info('done')
+
+ # global actions
+ self.info(bold('checking consistency... '), nonl=True)
+ self.env.check_consistency()
+ self.info('done')
+ else:
+ if method == 'update' and not docnames:
+ self.info(bold('no targets are out of date.'))
+ return
+
+ # another indirection to support builders that don't build files individually
+ self.write(docnames, updated_docnames, method)
+
+ # finish (write static files etc.)
+ self.finish()
+ status = self.app.statuscode == 0 and 'succeeded' or 'finished with problems'
+ if self.app._warncount:
+ self.info(bold('build %s, %s warning%s.' %
+ (status, self.app._warncount,
+ self.app._warncount != 1 and 's' or '')))
+ else:
+ self.info(bold('build %s.' % status))
+
+ def write(self, build_docnames, updated_docnames, method='update'):
+ if build_docnames is None or build_docnames == ['__all__']:
+ # build_all
+ build_docnames = self.env.found_docs
+ if method == 'update':
+ # build updated ones as well
+ docnames = set(build_docnames) | set(updated_docnames)
+ else:
+ docnames = set(build_docnames)
+
+ # add all toctree-containing files that may have changed
+ for docname in list(docnames):
+ for tocdocname in self.env.files_to_rebuild.get(docname, []):
+ docnames.add(tocdocname)
+ docnames.add(self.config.master_doc)
+
+ self.info(bold('preparing documents... '), nonl=True)
+ self.prepare_writing(docnames)
+ self.info('done')
+
+ # write target files
+ warnings = []
+ self.env.set_warnfunc(warnings.append)
+ for docname in self.status_iterator(sorted(docnames),
+ 'writing output... ', darkgreen):
+ doctree = self.env.get_and_resolve_doctree(docname, self)
+ self.write_doc(docname, doctree)
+ for warning in warnings:
+ if warning.strip():
+ self.warn(warning)
+ self.env.set_warnfunc(self.warn)
+
+ def prepare_writing(self, docnames):
+ raise NotImplementedError
+
+ def write_doc(self, docname, doctree):
+ raise NotImplementedError
+
+ def finish(self):
+ """
+ Finish the building process. The default implementation does nothing.
+ """
+ pass
+
+
+BUILTIN_BUILDERS = {
+ 'html': ('html', 'StandaloneHTMLBuilder'),
+ 'pickle': ('html', 'PickleHTMLBuilder'),
+ 'json': ('html', 'JSONHTMLBuilder'),
+ 'web': ('html', 'PickleHTMLBuilder'),
+ 'htmlhelp': ('htmlhelp', 'HTMLHelpBuilder'),
+ 'qthelp': ('qthelp', 'QtHelpBuilder'),
+ 'latex': ('latex', 'LaTeXBuilder'),
+ 'text': ('text', 'TextBuilder'),
+ 'changes': ('changes', 'ChangesBuilder'),
+ 'linkcheck': ('linkcheck', 'CheckExternalLinksBuilder'),
+}
diff --git a/sphinx/builders/changes.py b/sphinx/builders/changes.py
new file mode 100644
index 00000000..8770d49b
--- /dev/null
+++ b/sphinx/builders/changes.py
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.builders.changes
+ ~~~~~~~~~~~~~~~~~~~~~~~
+
+ Changelog builder.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import codecs
+import shutil
+from os import path
+from cgi import escape
+
+from sphinx import package_dir
+from sphinx.util import ensuredir, os_path
+from sphinx.builders import Builder
+from sphinx.util.console import bold
+
+
+class ChangesBuilder(Builder):
+ """
+ Write a summary with all versionadded/changed directives.
+ """
+ name = 'changes'
+
+ def init(self):
+ self.init_templates()
+
+ def get_outdated_docs(self):
+ return self.outdir
+
+ typemap = {
+ 'versionadded': 'added',
+ 'versionchanged': 'changed',
+ 'deprecated': 'deprecated',
+ }
+
+ def write(self, *ignored):
+ version = self.config.version
+ libchanges = {}
+ apichanges = []
+ otherchanges = {}
+ if version not in self.env.versionchanges:
+ self.info(bold('no changes in this version.'))
+ return
+ self.info(bold('writing summary file...'))
+ for type, docname, lineno, module, descname, content in \
+ self.env.versionchanges[version]:
+ ttext = self.typemap[type]
+ context = content.replace('\n', ' ')
+ if descname and docname.startswith('c-api'):
+ if not descname:
+ continue
+ if context:
+ entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext, context)
+ else:
+ entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
+ apichanges.append((entry, docname, lineno))
+ elif descname or module:
+ if not module:
+ module = _('Builtins')
+ if not descname:
+ descname = _('Module level')
+ if context:
+ entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext, context)
+ else:
+ entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
+ libchanges.setdefault(module, []).append((entry, docname, lineno))
+ else:
+ if not context:
+ continue
+ entry = '<i>%s:</i> %s' % (ttext.capitalize(), context)
+ title = self.env.titles[docname].astext()
+ otherchanges.setdefault((docname, title), []).append(
+ (entry, docname, lineno))
+
+ ctx = {
+ 'project': self.config.project,
+ 'version': version,
+ 'docstitle': self.config.html_title,
+ 'shorttitle': self.config.html_short_title,
+ 'libchanges': sorted(libchanges.iteritems()),
+ 'apichanges': sorted(apichanges),
+ 'otherchanges': sorted(otherchanges.iteritems()),
+ 'show_sphinx': self.config.html_show_sphinx,
+ }
+ f = codecs.open(path.join(self.outdir, 'index.html'), 'w', 'utf8')
+ try:
+ f.write(self.templates.render('changes/frameset.html', ctx))
+ finally:
+ f.close()
+ f = codecs.open(path.join(self.outdir, 'changes.html'), 'w', 'utf8')
+ try:
+ f.write(self.templates.render('changes/versionchanges.html', ctx))
+ finally:
+ f.close()
+
+ hltext = ['.. versionadded:: %s' % version,
+ '.. versionchanged:: %s' % version,
+ '.. deprecated:: %s' % version]
+
+ def hl(no, line):
+ line = '<a name="L%s"> </a>' % no + escape(line)
+ for x in hltext:
+ if x in line:
+ line = '<span class="hl">%s</span>' % line
+ break
+ return line
+
+ self.info(bold('copying source files...'))
+ for docname in self.env.all_docs:
+ f = codecs.open(self.env.doc2path(docname), 'r', 'latin1')
+ lines = f.readlines()
+ targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html'
+ ensuredir(path.dirname(targetfn))
+ f = codecs.open(targetfn, 'w', 'latin1')
+ try:
+ text = ''.join(hl(i+1, line) for (i, line) in enumerate(lines))
+ ctx = {'filename': self.env.doc2path(docname, None), 'text': text}
+ f.write(self.templates.render('changes/rstsource.html', ctx))
+ finally:
+ f.close()
+ shutil.copyfile(path.join(package_dir, 'static', 'default.css'),
+ path.join(self.outdir, 'default.css'))
+
+ def hl(self, text, version):
+ text = escape(text)
+ for directive in ['versionchanged', 'versionadded', 'deprecated']:
+ text = text.replace('.. %s:: %s' % (directive, version),
+ '<b>.. %s:: %s</b>' % (directive, version))
+ return text
+
+ def finish(self):
+ pass
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
new file mode 100644
index 00000000..fa802613
--- /dev/null
+++ b/sphinx/builders/html.py
@@ -0,0 +1,633 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.builders.html
+ ~~~~~~~~~~~~~~~~~~~~
+
+ Several HTML builders.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import os
+import codecs
+import shutil
+import cPickle as pickle
+from os import path
+
+from docutils.io import DocTreeInput, StringOutput
+from docutils.core import publish_parts
+from docutils.utils import new_document
+from docutils.frontend import OptionParser
+from docutils.readers.doctree import Reader as DoctreeReader
+
+from sphinx import package_dir, __version__
+from sphinx.util import SEP, os_path, relative_uri, ensuredir, \
+ movefile, ustrftime
+from sphinx.search import js_index
+from sphinx.builders import Builder, ENV_PICKLE_FILENAME
+from sphinx.highlighting import PygmentsBridge
+from sphinx.util.console import bold
+from sphinx.writers.html import HTMLWriter, HTMLTranslator, SmartyPantsHTMLTranslator
+
+try:
+ import json
+except ImportError:
+ try:
+ import simplejson as json
+ except ImportError:
+ json = None
+
+#: the filename for the inventory of objects
+INVENTORY_FILENAME = 'objects.inv'
+#: the filename for the "last build" file (for serializing builders)
+LAST_BUILD_FILENAME = 'last_build'
+
+
+class StandaloneHTMLBuilder(Builder):
+ """
+ Builds standalone HTML docs.
+ """
+ name = 'html'
+ copysource = True
+ out_suffix = '.html'
+ link_suffix = '.html' # defaults to matching out_suffix
+ indexer_format = js_index
+ supported_image_types = ['image/svg+xml', 'image/png', 'image/gif',
+ 'image/jpeg']
+ searchindex_filename = 'searchindex.js'
+ add_permalinks = True
+ embedded = False # for things like HTML help or Qt help: suppresses sidebar
+
+ # This is a class attribute because it is mutated by Sphinx.add_javascript.
+ script_files = ['_static/jquery.js', '_static/doctools.js']
+
+ def init(self):
+ """Load templates."""
+ self.init_templates()
+ self.init_translator_class()
+ if self.config.html_file_suffix:
+ self.out_suffix = self.config.html_file_suffix
+
+ if self.config.html_link_suffix is not None:
+ self.link_suffix = self.config.html_link_suffix
+ else:
+ self.link_suffix = self.out_suffix
+
+ if self.config.language is not None:
+ jsfile = path.join(package_dir, 'locale', self.config.language,
+ 'LC_MESSAGES', 'sphinx.js')
+ if path.isfile(jsfile):
+ self.script_files.append('_static/translations.js')
+
+ def init_translator_class(self):
+ if self.config.html_translator_class:
+ self.translator_class = self.app.import_object(
+ self.config.html_translator_class, 'html_translator_class setting')
+ elif self.config.html_use_smartypants:
+ self.translator_class = SmartyPantsHTMLTranslator
+ else:
+ self.translator_class = HTMLTranslator
+
+ def render_partial(self, node):
+ """Utility: Render a lone doctree node."""
+ doc = new_document('<partial node>')
+ doc.append(node)
+ return publish_parts(
+ doc,
+ source_class=DocTreeInput,
+ reader=DoctreeReader(),
+ writer=HTMLWriter(self),
+ settings_overrides={'output_encoding': 'unicode'}
+ )
+
+ def prepare_writing(self, docnames):
+ from sphinx.search import IndexBuilder
+
+ self.indexer = IndexBuilder(self.env)
+ self.load_indexer(docnames)
+ self.docwriter = HTMLWriter(self)
+ self.docsettings = OptionParser(
+ defaults=self.env.settings,
+ components=(self.docwriter,)).get_default_values()
+
+ # format the "last updated on" string, only once is enough since it
+ # typically doesn't include the time of day
+ lufmt = self.config.html_last_updated_fmt
+ if lufmt is not None:
+ self.last_updated = ustrftime(lufmt or _('%b %d, %Y'))
+ else:
+ self.last_updated = None
+
+ logo = self.config.html_logo and \
+ path.basename(self.config.html_logo) or ''
+
+ favicon = self.config.html_favicon and \
+ path.basename(self.config.html_favicon) or ''
+ if favicon and os.path.splitext(favicon)[1] != '.ico':
+ self.warn('html_favicon is not an .ico file')
+
+ if not isinstance(self.config.html_use_opensearch, basestring):
+ self.warn('html_use_opensearch config value must now be a string')
+
+ self.relations = self.env.collect_relations()
+
+ rellinks = []
+ if self.config.html_use_index:
+ rellinks.append(('genindex', _('General Index'), 'I', _('index')))
+ if self.config.html_use_modindex and self.env.modules:
+ rellinks.append(('modindex', _('Global Module Index'), 'M', _('modules')))
+
+ self.globalcontext = dict(
+ embedded = self.embedded,
+ project = self.config.project,
+ release = self.config.release,
+ version = self.config.version,
+ last_updated = self.last_updated,
+ copyright = self.config.copyright,
+ master_doc = self.config.master_doc,
+ style = self.config.html_style,
+ use_opensearch = self.config.html_use_opensearch,
+ docstitle = self.config.html_title,
+ shorttitle = self.config.html_short_title,
+ show_sphinx = self.config.html_show_sphinx,
+ has_source = self.config.html_copy_source,
+ show_source = self.config.html_show_sourcelink,
+ file_suffix = self.out_suffix,
+ script_files = self.script_files,
+ sphinx_version = __version__,
+ rellinks = rellinks,
+ builder = self.name,
+ parents = [],
+ logo = logo,
+ favicon = favicon,
+ )
+ self.globalcontext.update(self.config.html_context)
+
+ def get_doc_context(self, docname, body, metatags):
+ """Collect items for the template context of a page."""
+ # find out relations
+ prev = next = None
+ parents = []
+ rellinks = self.globalcontext['rellinks'][:]
+ related = self.relations.get(docname)
+ titles = self.env.titles
+ if related and related[2]:
+ try:
+ next = {'link': self.get_relative_uri(docname, related[2]),
+ 'title': self.render_partial(titles[related[2]])['title']}
+ rellinks.append((related[2], next['title'], 'N', _('next')))
+ except KeyError:
+ next = None
+ if related and related[1]:
+ try:
+ prev = {'link': self.get_relative_uri(docname, related[1]),
+ 'title': self.render_partial(titles[related[1]])['title']}
+ rellinks.append((related[1], prev['title'], 'P', _('previous')))
+ except KeyError:
+ # the relation is (somehow) not in the TOC tree, handle that gracefully
+ prev = None
+ while related and related[0]:
+ try:
+ parents.append(
+ {'link': self.get_relative_uri(docname, related[0]),
+ 'title': self.render_partial(titles[related[0]])['title']})
+ except KeyError:
+ pass
+ related = self.relations.get(related[0])
+ if parents:
+ parents.pop() # remove link to the master file; we have a generic
+ # "back to index" link already
+ parents.reverse()
+
+ # title rendered as HTML
+ title = titles.get(docname)
+ title = title and self.render_partial(title)['title'] or ''
+ # the name for the copied source
+ sourcename = self.config.html_copy_source and docname + '.txt' or ''
+
+ # metadata for the document
+ meta = self.env.metadata.get(docname)
+
+ return dict(
+ parents = parents,
+ prev = prev,
+ next = next,
+ title = title,
+ meta = meta,
+ body = body,
+ metatags = metatags,
+ rellinks = rellinks,
+ sourcename = sourcename,
+ toc = self.render_partial(self.env.get_toc_for(docname))['fragment'],
+ # only display a TOC if there's more than one item to show
+ display_toc = (self.env.toc_num_entries[docname] > 1),
+ )
+
+ def write_doc(self, docname, doctree):
+ self.post_process_images(doctree)
+ destination = StringOutput(encoding='utf-8')
+ doctree.settings = self.docsettings
+
+ self.imgpath = relative_uri(self.get_target_uri(docname), '_images')
+ self.dlpath = relative_uri(self.get_target_uri(docname), '_downloads')
+ self.docwriter.write(doctree, destination)
+ self.docwriter.assemble_parts()
+ body = self.docwriter.parts['fragment']
+ metatags = self.docwriter.clean_meta
+
+ ctx = self.get_doc_context(docname, body, metatags)
+ self.index_page(docname, doctree, ctx.get('title', ''))
+ self.handle_page(docname, ctx, event_arg=doctree)
+
+ def finish(self):
+ self.info(bold('writing additional files...'), nonl=1)
+
+ # the global general index
+
+ if self.config.html_use_index:
+ # the total count of lines for each index letter, used to distribute
+ # the entries into two columns
+ genindex = self.env.create_index(self)
+ indexcounts = []
+ for _, entries in genindex:
+ indexcounts.append(sum(1 + len(subitems)
+ for _, (_, subitems) in entries))
+
+ genindexcontext = dict(
+ genindexentries = genindex,
+ genindexcounts = indexcounts,
+ split_index = self.config.html_split_index,
+ )
+ self.info(' genindex', nonl=1)
+
+ if self.config.html_split_index:
+ self.handle_page('genindex', genindexcontext, 'genindex-split.html')
+ self.handle_page('genindex-all', genindexcontext, 'genindex.html')
+ for (key, entries), count in zip(genindex, indexcounts):
+ ctx = {'key': key, 'entries': entries, 'count': count,
+ 'genindexentries': genindex}
+ self.handle_page('genindex-' + key, ctx, 'genindex-single.html')
+ else:
+ self.handle_page('genindex', genindexcontext, 'genindex.html')
+
+ # the global module index
+
+ if self.config.html_use_modindex and self.env.modules:
+ # the sorted list of all modules, for the global module index
+ modules = sorted(((mn, (self.get_relative_uri('modindex', fn) +
+ '#module-' + mn, sy, pl, dep))
+ for (mn, (fn, sy, pl, dep)) in
+ self.env.modules.iteritems()),
+ key=lambda x: x[0].lower())
+ # collect all platforms
+ platforms = set()
+ # sort out collapsable modules
+ modindexentries = []
+ letters = []
+ pmn = ''
+ num_toplevels = 0
+ num_collapsables = 0
+ cg = 0 # collapse group
+ fl = '' # first letter
+ for mn, (fn, sy, pl, dep) in modules:
+ pl = pl and pl.split(', ') or []
+ platforms.update(pl)
+ if fl != mn[0].lower() and mn[0] != '_':
+ # heading
+ modindexentries.append(['', False, 0, False,
+ mn[0].upper(), '', [], False])
+ letters.append(mn[0].upper())
+ tn = mn.split('.')[0]
+ if tn != mn:
+ # submodule
+ if pmn == tn:
+ # first submodule - make parent collapsable
+ modindexentries[-1][1] = True
+ num_collapsables += 1
+ elif not pmn.startswith(tn):
+ # submodule without parent in list, add dummy entry
+ cg += 1
+ modindexentries.append([tn, True, cg, False, '', '', [], False])
+ else:
+ num_toplevels += 1
+ cg += 1
+ modindexentries.append([mn, False, cg, (tn != mn), fn, sy, pl, dep])
+ pmn = mn
+ fl = mn[0].lower()
+ platforms = sorted(platforms)
+
+ # apply heuristics when to collapse modindex at page load:
+ # only collapse if number of toplevel modules is larger than
+ # number of submodules
+ collapse = len(modules) - num_toplevels < num_toplevels
+
+ modindexcontext = dict(
+ modindexentries = modindexentries,
+ platforms = platforms,
+ letters = letters,
+ collapse_modindex = collapse,
+ )
+ self.info(' modindex', nonl=1)
+ self.handle_page('modindex', modindexcontext, 'modindex.html')
+
+ # the search page
+ if self.name != 'htmlhelp':
+ self.info(' search', nonl=1)
+ self.handle_page('search', {}, 'search.html')
+
+ # additional pages from conf.py
+ for pagename, template in self.config.html_additional_pages.items():
+ self.info(' '+pagename, nonl=1)
+ self.handle_page(pagename, {}, template)
+
+ if self.config.html_use_opensearch and self.name != 'htmlhelp':
+ self.info(' opensearch', nonl=1)
+ fn = path.join(self.outdir, '_static', 'opensearch.xml')
+ self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn)
+
+ self.info()
+
+ # copy image files
+ if self.images:
+ self.info(bold('copying images...'), nonl=True)
+ ensuredir(path.join(self.outdir, '_images'))
+ for src, dest in self.images.iteritems():
+ self.info(' '+src, nonl=1)
+ shutil.copyfile(path.join(self.srcdir, src),
+ path.join(self.outdir, '_images', dest))
+ self.info()
+
+ # copy downloadable files
+ if self.env.dlfiles:
+ self.info(bold('copying downloadable files...'), nonl=True)
+ ensuredir(path.join(self.outdir, '_downloads'))
+ for src, (_, dest) in self.env.dlfiles.iteritems():
+ self.info(' '+src, nonl=1)
+ shutil.copyfile(path.join(self.srcdir, src),
+ path.join(self.outdir, '_downloads', dest))
+ self.info()
+
+ # copy static files
+ self.info(bold('copying static files... '), nonl=True)
+ ensuredir(path.join(self.outdir, '_static'))
+ # first, create pygments style file
+ f = open(path.join(self.outdir, '_static', 'pygments.css'), 'w')
+ f.write(PygmentsBridge('html', self.config.pygments_style).get_stylesheet())
+ f.close()
+ # then, copy translations JavaScript file
+ if self.config.language is not None:
+ jsfile = path.join(package_dir, 'locale', self.config.language,
+ 'LC_MESSAGES', 'sphinx.js')
+ if path.isfile(jsfile):
+ shutil.copyfile(jsfile, path.join(self.outdir, '_static',
+ 'translations.js'))
+ # then, copy over all user-supplied static files
+ staticdirnames = [path.join(package_dir, 'static')] + \
+ [path.join(self.confdir, spath)
+ for spath in self.config.html_static_path]
+ for staticdirname in staticdirnames:
+ for filename in os.listdir(staticdirname):
+ if filename.startswith('.'):
+ continue
+ fullname = path.join(staticdirname, filename)
+ targetname = path.join(self.outdir, '_static', filename)
+ if path.isfile(fullname):
+ shutil.copyfile(fullname, targetname)
+ elif path.isdir(fullname):
+ if filename in self.config.exclude_dirnames:
+ continue
+ if path.exists(targetname):
+ shutil.rmtree(targetname)
+ shutil.copytree(fullname, targetname)
+ # last, copy logo file (handled differently)
+ if self.config.html_logo:
+ logobase = path.basename(self.config.html_logo)
+ shutil.copyfile(path.join(self.confdir, self.config.html_logo),
+ path.join(self.outdir, '_static', logobase))
+ self.info('done')
+
+ # dump the search index
+ self.handle_finish()
+
+ def get_outdated_docs(self):
+ if self.templates:
+ template_mtime = self.templates.newest_template_mtime()
+ else:
+ template_mtime = 0
+ for docname in self.env.found_docs:
+ if docname not in self.env.all_docs:
+ yield docname
+ continue
+ targetname = self.env.doc2path(docname, self.outdir, self.out_suffix)
+ try:
+ targetmtime = path.getmtime(targetname)
+ except Exception:
+ targetmtime = 0
+ try:
+ srcmtime = max(path.getmtime(self.env.doc2path(docname)),
+ template_mtime)
+ if srcmtime > targetmtime:
+ yield docname
+ except EnvironmentError:
+ # source doesn't exist anymore
+ pass
+
+ def load_indexer(self, docnames):
+ keep = set(self.env.all_docs) - set(docnames)
+ try:
+ f = open(path.join(self.outdir, self.searchindex_filename), 'rb')
+ try:
+ self.indexer.load(f, self.indexer_format)
+ finally:
+ f.close()
+ except (IOError, OSError, ValueError):
+ if keep:
+ self.warn("search index couldn't be loaded, but not all documents "
+ "will be built: the index will be incomplete.")
+ # delete all entries for files that will be rebuilt
+ self.indexer.prune(keep)
+
+ def index_page(self, pagename, doctree, title):
+ # only index pages with title
+ if self.indexer is not None and title:
+ self.indexer.feed(pagename, title, doctree)
+
+ # --------- these are overwritten by the serialization builder
+
+ def get_target_uri(self, docname, typ=None):
+ return docname + self.link_suffix
+
+ def handle_page(self, pagename, addctx, templatename='page.html',
+ outfilename=None, event_arg=None):
+ ctx = self.globalcontext.copy()
+ # current_page_name is backwards compatibility
+ ctx['pagename'] = ctx['current_page_name'] = pagename
+
+ def pathto(otheruri, resource=False,
+ baseuri=self.get_target_uri(pagename)):
+ if not resource:
+ otheruri = self.get_target_uri(otheruri)
+ return relative_uri(baseuri, otheruri)
+ ctx['pathto'] = pathto
+ ctx['hasdoc'] = lambda name: name in self.env.all_docs
+ ctx['customsidebar'] = self.config.html_sidebars.get(pagename)
+ ctx.update(addctx)
+
+ self.app.emit('html-page-context', pagename, templatename, ctx, event_arg)
+
+ output = self.templates.render(templatename, ctx)
+ if not outfilename:
+ outfilename = path.join(self.outdir, os_path(pagename) + self.out_suffix)
+ ensuredir(path.dirname(outfilename)) # normally different from self.outdir
+ try:
+ f = codecs.open(outfilename, 'w', 'utf-8')
+ try:
+ f.write(output)
+ finally:
+ f.close()
+ except (IOError, OSError), err:
+ self.warn("Error writing file %s: %s" % (outfilename, err))
+ if self.copysource and ctx.get('sourcename'):
+ # copy the source file for the "show source" link
+ source_name = path.join(self.outdir, '_sources', os_path(ctx['sourcename']))
+ ensuredir(path.dirname(source_name))
+ shutil.copyfile(self.env.doc2path(pagename), source_name)
+
+ def handle_finish(self):
+ self.info(bold('dumping search index... '), nonl=True)
+ self.indexer.prune(self.env.all_docs)
+ searchindexfn = path.join(self.outdir, self.searchindex_filename)
+ # first write to a temporary file, so that if dumping fails, the existing
+ # index won't be overwritten
+ f = open(searchindexfn + '.tmp', 'wb')
+ try:
+ self.indexer.dump(f, self.indexer_format)
+ finally:
+ f.close()
+ movefile(searchindexfn + '.tmp', searchindexfn)
+ self.info('done')
+
+ self.info(bold('dumping object inventory... '), nonl=True)
+ f = open(path.join(self.outdir, INVENTORY_FILENAME), 'w')
+ try:
+ f.write('# Sphinx inventory version 1\n')
+ f.write('# Project: %s\n' % self.config.project.encode('utf-8'))
+ f.write('# Version: %s\n' % self.config.version)
+ for modname, info in self.env.modules.iteritems():
+ f.write('%s mod %s\n' % (modname, self.get_target_uri(info[0])))
+ for refname, (docname, desctype) in self.env.descrefs.iteritems():
+ f.write('%s %s %s\n' % (refname, desctype, self.get_target_uri(docname)))
+ finally:
+ f.close()
+ self.info('done')
+
+
+class SerializingHTMLBuilder(StandaloneHTMLBuilder):
+ """
+ An abstract builder that serializes the HTML generated.
+ """
+ #: the serializing implementation to use. Set this to a module that
+ #: implements a `dump`, `load`, `dumps` and `loads` functions
+ #: (pickle, simplejson etc.)
+ implementation = None
+
+ #: the filename for the global context file
+ globalcontext_filename = None
+
+ supported_image_types = ('image/svg+xml', 'image/png', 'image/gif',
+ 'image/jpeg')
+
+ def init(self):
+ self.init_translator_class()
+ self.templates = None # no template bridge necessary
+
+ def get_target_uri(self, docname, typ=None):
+ if docname == 'index':
+ return ''
+ if docname.endswith(SEP + 'index'):
+ return docname[:-5] # up to sep
+ return docname + SEP
+
+ def handle_page(self, pagename, ctx, templatename='page.html',
+ outfilename=None, event_arg=None):
+ ctx['current_page_name'] = pagename
+ sidebarfile = self.config.html_sidebars.get(pagename)
+ if sidebarfile:
+ ctx['customsidebar'] = sidebarfile
+
+ if not outfilename:
+ outfilename = path.join(self.outdir, os_path(pagename) + self.out_suffix)
+
+ self.app.emit('html-page-context', pagename, templatename, ctx, event_arg)
+
+ ensuredir(path.dirname(outfilename))
+ f = open(outfilename, 'wb')
+ try:
+ self.implementation.dump(ctx, f, 2)
+ finally:
+ f.close()
+
+ # if there is a source file, copy the source file for the
+ # "show source" link
+ if ctx.get('sourcename'):
+ source_name = path.join(self.outdir, '_sources',
+ os_path(ctx['sourcename']))
+ ensuredir(path.dirname(source_name))
+ shutil.copyfile(self.env.doc2path(pagename), source_name)
+
+ def handle_finish(self):
+ # dump the global context
+ outfilename = path.join(self.outdir, self.globalcontext_filename)
+ f = open(outfilename, 'wb')
+ try:
+ self.implementation.dump(self.globalcontext, f, 2)
+ finally:
+ f.close()
+
+ # super here to dump the search index
+ StandaloneHTMLBuilder.handle_finish(self)
+
+ # copy the environment file from the doctree dir to the output dir
+ # as needed by the web app
+ shutil.copyfile(path.join(self.doctreedir, ENV_PICKLE_FILENAME),
+ path.join(self.outdir, ENV_PICKLE_FILENAME))
+
+ # touch 'last build' file, used by the web application to determine
+ # when to reload its environment and clear the cache
+ open(path.join(self.outdir, LAST_BUILD_FILENAME), 'w').close()
+
+
+class PickleHTMLBuilder(SerializingHTMLBuilder):
+ """
+ A Builder that dumps the generated HTML into pickle files.
+ """
+ implementation = pickle
+ indexer_format = pickle
+ name = 'pickle'
+ out_suffix = '.fpickle'
+ globalcontext_filename = 'globalcontext.pickle'
+ searchindex_filename = 'searchindex.pickle'
+
+# compatibility alias
+WebHTMLBuilder = PickleHTMLBuilder
+
+
+class JSONHTMLBuilder(SerializingHTMLBuilder):
+ """
+ A builder that dumps the generated HTML into JSON files.
+ """
+ implementation = json
+ indexer_format = json
+ name = 'json'
+ out_suffix = '.fjson'
+ globalcontext_filename = 'globalcontext.json'
+ searchindex_filename = 'searchindex.json'
+
+ def init(self):
+ if json is None:
+ from sphinx.application import SphinxError
+ raise SphinxError('The module simplejson (or json in Python >= 2.6) '
+ 'is not available. The JSONHTMLBuilder builder '
+ 'will not work.')
+ SerializingHTMLBuilder.init(self)
diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py
new file mode 100644
index 00000000..9baaa235
--- /dev/null
+++ b/sphinx/builders/htmlhelp.py
@@ -0,0 +1,246 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.builders.htmlhelp
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Build HTML help support files.
+ Parts adapted from Python's Doc/tools/prechm.py.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import os
+import cgi
+from os import path
+
+from docutils import nodes
+
+from sphinx import addnodes
+from sphinx.builders.html import StandaloneHTMLBuilder
+
+
+# Project file (*.hhp) template. 'outname' is the file basename (like
+# the pythlp in pythlp.hhp); 'version' is the doc version number (like
+# the 2.2 in Python 2.2).
+# The magical numbers in the long line under [WINDOWS] set most of the
+# user-visible features (visible buttons, tabs, etc).
+# About 0x10384e: This defines the buttons in the help viewer. The
+# following defns are taken from htmlhelp.h. Not all possibilities
+# actually work, and not all those that work are available from the Help
+# Workshop GUI. In particular, the Zoom/Font button works and is not
+# available from the GUI. The ones we're using are marked with 'x':
+#
+# 0x000002 Hide/Show x
+# 0x000004 Back x
+# 0x000008 Forward x
+# 0x000010 Stop
+# 0x000020 Refresh
+# 0x000040 Home x
+# 0x000080 Forward
+# 0x000100 Back
+# 0x000200 Notes
+# 0x000400 Contents
+# 0x000800 Locate x
+# 0x001000 Options x
+# 0x002000 Print x
+# 0x004000 Index
+# 0x008000 Search
+# 0x010000 History
+# 0x020000 Favorites
+# 0x040000 Jump 1
+# 0x080000 Jump 2
+# 0x100000 Zoom/Font x
+# 0x200000 TOC Next
+# 0x400000 TOC Prev
+
+project_template = '''\
+[OPTIONS]
+Binary TOC=Yes
+Binary Index=No
+Compiled file=%(outname)s.chm
+Contents file=%(outname)s.hhc
+Default Window=%(outname)s
+Default topic=index.html
+Display compile progress=No
+Full text search stop list file=%(outname)s.stp
+Full-text search=Yes
+Index file=%(outname)s.hhk
+Language=0x409
+Title=%(title)s
+
+[WINDOWS]
+%(outname)s="%(title)s","%(outname)s.hhc","%(outname)s.hhk",\
+"index.html","index.html",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0
+
+[FILES]
+'''
+
+contents_header = '''\
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<OBJECT type="text/site properties">
+ <param name="Window Styles" value="0x801227">
+ <param name="ImageType" value="Folder">
+</OBJECT>
+<UL>
+'''
+
+contents_footer = '''\
+</UL></BODY></HTML>
+'''
+
+object_sitemap = '''\
+<OBJECT type="text/sitemap">
+ <param name="Name" value="%s">
+ <param name="Local" value="%s">
+</OBJECT>
+'''
+
+# List of words the full text search facility shouldn't index. This
+# becomes file outname.stp. Note that this list must be pretty small!
+# Different versions of the MS docs claim the file has a maximum size of
+# 256 or 512 bytes (including \r\n at the end of each line).
+# Note that "and", "or", "not" and "near" are operators in the search
+# language, so no point indexing them even if we wanted to.
+stopwords = """
+a and are as at
+be but by
+for
+if in into is it
+near no not
+of on or
+such
+that the their then there these they this to
+was will with
+""".split()
+
+
+class HTMLHelpBuilder(StandaloneHTMLBuilder):
+ """
+ Builder that also outputs Windows HTML help project, contents and index files.
+ Adapted from the original Doc/tools/prechm.py.
+ """
+ name = 'htmlhelp'
+
+ # don't copy the reST source
+ copysource = False
+ supported_image_types = ['image/png', 'image/gif', 'image/jpeg']
+
+ # don't add links
+ add_permalinks = False
+ # don't add sidebar etc.
+ embedded = True
+
+ def init(self):
+ StandaloneHTMLBuilder.init(self)
+ # the output files for HTML help must be .html only
+ self.out_suffix = '.html'
+
+ def handle_finish(self):
+ self.build_hhx(self.outdir, self.config.htmlhelp_basename)
+
+ def build_hhx(self, outdir, outname):
+ self.info('dumping stopword list...')
+ f = open(path.join(outdir, outname+'.stp'), 'w')
+ try:
+ for word in sorted(stopwords):
+ print >>f, word
+ finally:
+ f.close()
+
+ self.info('writing project file...')
+ f = open(path.join(outdir, outname+'.hhp'), 'w')
+ try:
+ f.write(project_template % {'outname': outname,
+ 'title': self.config.html_title,
+ 'version': self.config.version,
+ 'project': self.config.project})
+ if not outdir.endswith(os.sep):
+ outdir += os.sep
+ olen = len(outdir)
+ for root, dirs, files in os.walk(outdir):
+ staticdir = (root == path.join(outdir, '_static'))
+ for fn in files:
+ if (staticdir and not fn.endswith('.js')) or fn.endswith('.html'):
+ print >>f, path.join(root, fn)[olen:].replace(os.sep, '\\')
+ finally:
+ f.close()
+
+ self.info('writing TOC file...')
+ f = open(path.join(outdir, outname+'.hhc'), 'w')
+ try:
+ f.write(contents_header)
+ # special books
+ f.write('<LI> ' + object_sitemap % (self.config.html_short_title,
+ 'index.html'))
+ if self.config.html_use_modindex:
+ f.write('<LI> ' + object_sitemap % (_('Global Module Index'),
+ 'modindex.html'))
+ # the TOC
+ tocdoc = self.env.get_and_resolve_doctree(self.config.master_doc, self,
+ prune_toctrees=False)
+ def write_toc(node, ullevel=0):
+ if isinstance(node, nodes.list_item):
+ f.write('<LI> ')
+ for subnode in node:
+ write_toc(subnode, ullevel)
+ elif isinstance(node, nodes.reference):
+ link = node['refuri']
+ title = cgi.escape(node.astext()).replace('"','&quot;')
+ item = object_sitemap % (title, link)
+ f.write(item.encode('ascii', 'xmlcharrefreplace'))
+ elif isinstance(node, nodes.bullet_list):
+ if ullevel != 0:
+ f.write('<UL>\n')
+ for subnode in node:
+ write_toc(subnode, ullevel+1)
+ if ullevel != 0:
+ f.write('</UL>\n')
+ elif isinstance(node, addnodes.compact_paragraph):
+ for subnode in node:
+ write_toc(subnode, ullevel)
+ istoctree = lambda node: isinstance(node, addnodes.compact_paragraph) and \
+ node.has_key('toctree')
+ for node in tocdoc.traverse(istoctree):
+ write_toc(node)
+ f.write(contents_footer)
+ finally:
+ f.close()
+
+ self.info('writing index file...')
+ index = self.env.create_index(self)
+ f = open(path.join(outdir, outname+'.hhk'), 'w')
+ try:
+ f.write('<UL>\n')
+ def write_index(title, refs, subitems):
+ def write_param(name, value):
+ item = ' <param name="%s" value="%s">\n' % (name, value)
+ f.write(item.encode('ascii', 'xmlcharrefreplace'))
+ title = cgi.escape(title)
+ f.write('<LI> <OBJECT type="text/sitemap">\n')
+ write_param('Keyword', title)
+ if len(refs) == 0:
+ write_param('See Also', title)
+ elif len(refs) == 1:
+ write_param('Local', refs[0])
+ else:
+ for i, ref in enumerate(refs):
+ write_param('Name', '[%d] %s' % (i, ref)) # XXX: better title?
+ write_param('Local', ref)
+ f.write('</OBJECT>\n')
+ if subitems:
+ f.write('<UL> ')
+ for subitem in subitems:
+ write_index(subitem[0], subitem[1], [])
+ f.write('</UL>')
+ for (key, group) in index:
+ for title, (refs, subitems) in group:
+ write_index(title, refs, subitems)
+ f.write('</UL>\n')
+ finally:
+ f.close()
diff --git a/sphinx/builders/latex.py b/sphinx/builders/latex.py
new file mode 100644
index 00000000..3b7b0c19
--- /dev/null
+++ b/sphinx/builders/latex.py
@@ -0,0 +1,186 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.builders.latex
+ ~~~~~~~~~~~~~~~~~~~~~
+
+ LaTeX builder.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import os
+import shutil
+from os import path
+
+from docutils import nodes
+from docutils.io import FileOutput
+from docutils.utils import new_document
+from docutils.frontend import OptionParser
+
+from sphinx import package_dir, addnodes
+from sphinx.util import SEP, texescape
+from sphinx.builders import Builder
+from sphinx.environment import NoUri
+from sphinx.util.console import bold, darkgreen
+from sphinx.writers.latex import LaTeXWriter
+
+
+class LaTeXBuilder(Builder):
+ """
+ Builds LaTeX output to create PDF.
+ """
+ name = 'latex'
+ supported_image_types = ['application/pdf', 'image/png', 'image/gif',
+ 'image/jpeg']
+
+ def init(self):
+ self.docnames = []
+ self.document_data = []
+ texescape.init()
+
+ def get_outdated_docs(self):
+ return 'all documents' # for now
+
+ def get_target_uri(self, docname, typ=None):
+ if typ == 'token':
+ # token references are always inside production lists and must be
+ # replaced by \token{} in LaTeX
+ return '@token'
+ if docname not in self.docnames:
+ raise NoUri
+ else:
+ return '%' + docname
+
+ def init_document_data(self):
+ preliminary_document_data = map(list, self.config.latex_documents)
+ if not preliminary_document_data:
+ self.warn('No "latex_documents" config value found; no documents '
+ 'will be written.')
+ return
+ # assign subdirs to titles
+ self.titles = []
+ for entry in preliminary_document_data:
+ docname = entry[0]
+ if docname not in self.env.all_docs:
+ self.warn('"latex_documents" config value references unknown '
+ 'document %s' % docname)
+ continue
+ self.document_data.append(entry)
+ if docname.endswith(SEP+'index'):
+ docname = docname[:-5]
+ self.titles.append((docname, entry[2]))
+
+ def write(self, *ignored):
+ # first, assemble the "appendix" docs that are in every PDF
+ appendices = []
+ for fname in self.config.latex_appendices:
+ appendices.append(self.env.get_doctree(fname))
+
+ docwriter = LaTeXWriter(self)
+ docsettings = OptionParser(
+ defaults=self.env.settings,
+ components=(docwriter,)).get_default_values()
+
+ self.init_document_data()
+
+ for entry in self.document_data:
+ docname, targetname, title, author, docclass = entry[:5]
+ toctree_only = False
+ if len(entry) > 5:
+ toctree_only = entry[5]
+ destination = FileOutput(
+ destination_path=path.join(self.outdir, targetname),
+ encoding='utf-8')
+ self.info("processing " + targetname + "... ", nonl=1)
+ doctree = self.assemble_doctree(docname, toctree_only,
+ appendices=(docclass == 'manual') and appendices or [])
+ self.post_process_images(doctree)
+ self.info("writing... ", nonl=1)
+ doctree.settings = docsettings
+ doctree.settings.author = author
+ doctree.settings.title = title
+ doctree.settings.docname = docname
+ doctree.settings.docclass = docclass
+ docwriter.write(doctree, destination)
+ self.info("done")
+
+ def assemble_doctree(self, indexfile, toctree_only, appendices):
+ self.docnames = set([indexfile] + appendices)
+ self.info(darkgreen(indexfile) + " ", nonl=1)
+ def process_tree(docname, tree):
+ tree = tree.deepcopy()
+ for toctreenode in tree.traverse(addnodes.toctree):
+ newnodes = []
+ includefiles = map(str, toctreenode['includefiles'])
+ for includefile in includefiles:
+ try:
+ self.info(darkgreen(includefile) + " ", nonl=1)
+ subtree = process_tree(includefile,
+ self.env.get_doctree(includefile))
+ self.docnames.add(includefile)
+ except Exception:
+ self.warn('%s: toctree contains ref to nonexisting file %r' %
+ (docname, includefile))
+ else:
+ sof = addnodes.start_of_file(docname=includefile)
+ sof.children = subtree.children
+ newnodes.append(sof)
+ toctreenode.parent.replace(toctreenode, newnodes)
+ return tree
+ tree = self.env.get_doctree(indexfile)
+ tree['docname'] = indexfile
+ if toctree_only:
+ # extract toctree nodes from the tree and put them in a fresh document
+ new_tree = new_document('<latex output>')
+ new_sect = nodes.section()
+ new_sect += nodes.title(u'<Set title in conf.py>', u'<Set title in conf.py>')
+ new_tree += new_sect
+ for node in tree.traverse(addnodes.toctree):
+ new_sect += node
+ tree = new_tree
+ largetree = process_tree(indexfile, tree)
+ largetree.extend(appendices)
+ self.info()
+ self.info("resolving references...")
+ self.env.resolve_references(largetree, indexfile, self)
+ # resolve :ref:s to distant tex files -- we can't add a cross-reference,
+ # but append the document name
+ for pendingnode in largetree.traverse(addnodes.pending_xref):
+ docname = pendingnode['refdocname']
+ sectname = pendingnode['refsectname']
+ newnodes = [nodes.emphasis(sectname, sectname)]
+ for subdir, title in self.titles:
+ if docname.startswith(subdir):
+ newnodes.append(nodes.Text(_(' (in '), _(' (in ')))
+ newnodes.append(nodes.emphasis(title, title))
+ newnodes.append(nodes.Text(')', ')'))
+ break
+ else:
+ pass
+ pendingnode.replace_self(newnodes)
+ return largetree
+
+ def finish(self):
+ # copy image files
+ if self.images:
+ self.info(bold('copying images...'), nonl=1)
+ for src, dest in self.images.iteritems():
+ self.info(' '+src, nonl=1)
+ shutil.copyfile(path.join(self.srcdir, src),
+ path.join(self.outdir, dest))
+ self.info()
+
+ # the logo is handled differently
+ if self.config.latex_logo:
+ logobase = path.basename(self.config.latex_logo)
+ shutil.copyfile(path.join(self.confdir, self.config.latex_logo),
+ path.join(self.outdir, logobase))
+
+ self.info(bold('copying TeX support files... '), nonl=True)
+ staticdirname = path.join(package_dir, 'texinputs')
+ for filename in os.listdir(staticdirname):
+ if not filename.startswith('.'):
+ shutil.copyfile(path.join(staticdirname, filename),
+ path.join(self.outdir, filename))
+ self.info('done')
diff --git a/sphinx/linkcheck.py b/sphinx/builders/linkcheck.py
index a4e876e2..5fcda231 100644
--- a/sphinx/linkcheck.py
+++ b/sphinx/builders/linkcheck.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
- sphinx.linkcheck
- ~~~~~~~~~~~~~~~~
+ sphinx.builders.linkcheck
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
The CheckExternalLinksBuilder class.
@@ -15,7 +15,7 @@ from urllib2 import build_opener, HTTPError
from docutils import nodes
-from sphinx.builder import Builder
+from sphinx.builders import Builder
from sphinx.util.console import purple, red, darkgreen
# create an opener that will simulate a browser user-agent
diff --git a/sphinx/builders/qthelp.py b/sphinx/builders/qthelp.py
new file mode 100644
index 00000000..855b340e
--- /dev/null
+++ b/sphinx/builders/qthelp.py
@@ -0,0 +1,261 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.builders.qthelp
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ Build input files for the Qt collection generator.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import os
+import re
+import cgi
+from os import path
+
+from docutils import nodes
+
+from sphinx import addnodes
+from sphinx.builders.html import StandaloneHTMLBuilder
+
+_idpattern = re.compile('(?P<title>.+) (\((?P<id>[\w\.]+)( (?P<descr>\w+))?\))$')
+
+
+# Qt Help Collection Project (.qhcp).
+# Is the input file for the help collection generator.
+# It contains references to compressed help files which should be
+# included in the collection.
+# It may contain various other information for customizing Qt Assistant.
+collection_template = '''\
+<?xml version="1.0" encoding="utf-8" ?>
+<QHelpCollectionProject version="1.0">
+ <docFiles>
+ <generate>
+ <file>
+ <input>%(outname)s.qhp</input>
+ <output>%(outname)s.qch</output>
+ </file>
+ </generate>
+ <register>
+ <file>%(outname)s.qch</file>
+ </register>
+ </docFiles>
+</QHelpCollectionProject>
+'''
+
+# Qt Help Project (.qhp)
+# This is the input file for the help generator.
+# It contains the table of contents, indices and references to the
+# actual documentation files (*.html).
+# In addition it defines a unique namespace for the documentation.
+project_template = '''\
+<?xml version="1.0" encoding="UTF-8"?>
+<QtHelpProject version="1.0">
+ <namespace>%(outname)s.org.%(outname)s.%(nversion)s</namespace>
+ <virtualFolder>doc</virtualFolder>
+ <customFilter name="%(project)s %(version)s">
+ <filterAttribute>%(outname)s</filterAttribute>
+ <filterAttribute>%(version)s</filterAttribute>
+ </customFilter>
+ <filterSection>
+ <filterAttribute>%(outname)s</filterAttribute>
+ <filterAttribute>%(version)s</filterAttribute>
+ <toc>
+ <section title="%(title)s" ref="%(masterdoc)s.html">
+%(sections)s
+ </section>
+ </toc>
+ <keywords>
+%(keywords)s
+ </keywords>
+ <files>
+%(files)s
+ </files>
+ </filterSection>
+</QtHelpProject>
+'''
+
+section_template = '<section title="%(title)s" ref="%(ref)s"/>'
+file_template = ' '*12 + '<file>%(filename)s</file>'
+
+
+class QtHelpBuilder(StandaloneHTMLBuilder):
+ """
+ Builder that also outputs Qt help project, contents and index files.
+ """
+ name = 'qthelp'
+
+ # don't copy the reST source
+ copysource = False
+ supported_image_types = ['image/svg+xml', 'image/png', 'image/gif',
+ 'image/jpeg']
+
+ # don't add links
+ add_permalinks = False
+ # don't add sidebar etc.
+ embedded = True
+
+ def init(self):
+ StandaloneHTMLBuilder.init(self)
+ # the output files for HTML help must be .html only
+ self.out_suffix = '.html'
+ #self.config.html_style = 'traditional.css'
+
+ def handle_finish(self):
+ self.build_qhcp(self.outdir, self.config.qthelp_basename)
+ self.build_qhp(self.outdir, self.config.qthelp_basename)
+
+ def build_qhcp(self, outdir, outname):
+ self.info('writing collection project file...')
+ f = open(path.join(outdir, outname+'.qhcp'), 'w')
+ try:
+ f.write(collection_template % {'outname': outname})
+ finally:
+ f.close()
+
+ def build_qhp(self, outdir, outname):
+ self.info('writing project file...')
+
+ # sections
+ tocdoc = self.env.get_and_resolve_doctree(self.config.master_doc, self,
+ prune_toctrees=False)
+ istoctree = lambda node: (
+ isinstance(node, addnodes.compact_paragraph)
+ and node.has_key('toctree'))
+ sections = []
+ for node in tocdoc.traverse(istoctree):
+ sections.extend(self.write_toc(node))
+
+ if self.config.html_use_modindex:
+ item = section_template % {'title': _('Global Module Index'),
+ 'ref': 'modindex.html'}
+ sections.append(' '*4*4 + item)
+ sections = '\n'.join(sections)
+
+ # keywords
+ keywords = []
+ index = self.env.create_index(self)
+ for (key, group) in index:
+ for title, (refs, subitems) in group:
+ keywords.extend(self.build_keywords(title, refs, subitems))
+ keywords = '\n'.join(keywords)
+
+ # files
+ if not outdir.endswith(os.sep):
+ outdir += os.sep
+ olen = len(outdir)
+ projectfiles = []
+ for root, dirs, files in os.walk(outdir):
+ staticdir = (root == path.join(outdir, '_static'))
+ for fn in files:
+ if (staticdir and not fn.endswith('.js')) or fn.endswith('.html'):
+ filename = path.join(root, fn)[olen:]
+ #filename = filename.replace(os.sep, '\\') # XXX
+ projectfiles.append(file_template % {'filename': filename})
+ projectfiles = '\n'.join(projectfiles)
+
+ # write the project file
+ f = open(path.join(outdir, outname+'.qhp'), 'w')
+ try:
+ nversion = self.config.version.replace('.', '_')
+ nversion = nversion.replace(' ', '_')
+ f.write(project_template % {'outname': outname,
+ 'title': self.config.html_title,
+ 'version': self.config.version,
+ 'project': self.config.project,
+ 'nversion': nversion,
+ 'masterdoc': self.config.master_doc,
+ 'sections': sections,
+ 'keywords': keywords,
+ 'files': projectfiles})
+ finally:
+ f.close()
+
+ def isdocnode(self, node):
+ if not isinstance(node, nodes.list_item):
+ return False
+ if len(node.children) != 2:
+ return False
+ if not isinstance(node.children[0], addnodes.compact_paragraph):
+ return False
+ if not isinstance(node.children[0][0], nodes.reference):
+ return False
+ if not isinstance(node.children[1], nodes.bullet_list):
+ return False
+ return True
+
+ def write_toc(self, node, indentlevel=4):
+ parts = []
+ if self.isdocnode(node):
+ refnode = node.children[0][0]
+ link = refnode['refuri']
+ title = cgi.escape(refnode.astext()).replace('"','&quot;')
+ item = '<section title="%(title)s" ref="%(ref)s">' % {
+ 'title': title,
+ 'ref': link}
+ parts.append(' '*4*indentlevel + item)
+ for subnode in node.children[1]:
+ parts.extend(self.write_toc(subnode, indentlevel+1))
+ parts.append(' '*4*indentlevel + '</section>')
+ elif isinstance(node, nodes.list_item):
+ for subnode in node:
+ parts.extend(self.write_toc(subnode, indentlevel))
+ elif isinstance(node, nodes.reference):
+ link = node['refuri']
+ title = cgi.escape(node.astext()).replace('"','&quot;')
+ item = section_template % {'title': title, 'ref': link}
+ item = ' '*4*indentlevel + item.encode('ascii', 'xmlcharrefreplace')
+ parts.append(item.encode('ascii', 'xmlcharrefreplace'))
+ elif isinstance(node, nodes.bullet_list):
+ for subnode in node:
+ parts.extend(self.write_toc(subnode, indentlevel))
+ elif isinstance(node, addnodes.compact_paragraph):
+ for subnode in node:
+ parts.extend(self.write_toc(subnode, indentlevel))
+
+ return parts
+
+ def keyword_item(self, name, ref):
+ matchobj = _idpattern.match(name)
+ if matchobj:
+ groupdict = matchobj.groupdict()
+ shortname = groupdict['title']
+ id = groupdict.get('id')
+# descr = groupdict.get('descr')
+ if shortname.endswith('()'):
+ shortname = shortname[:-2]
+ id = '%s.%s' % (id, shortname)
+ else:
+ id = descr = None
+
+ if id:
+ item = ' '*12 + '<keyword name="%s" id="%s" ref="%s"/>' % (
+ name, id, ref)
+ else:
+ item = ' '*12 + '<keyword name="%s" ref="%s"/>' % (name, ref)
+ item.encode('ascii', 'xmlcharrefreplace')
+ return item
+
+ def build_keywords(self, title, refs, subitems):
+ keywords = []
+
+ title = cgi.escape(title)
+# if len(refs) == 0: # XXX
+# write_param('See Also', title)
+ if len(refs) == 1:
+ keywords.append(self.keyword_item(title, refs[0]))
+ elif len(refs) > 1:
+ for i, ref in enumerate(refs): # XXX
+# item = (' '*12 +
+# '<keyword name="%s [%d]" ref="%s"/>' % (
+# title, i, ref))
+# item.encode('ascii', 'xmlcharrefreplace')
+# keywords.append(item)
+ keywords.append(self.keyword_item(title, ref))
+
+ if subitems:
+ for subitem in subitems:
+ keywords.extend(self.build_keywords(subitem[0], subitem[1], []))
+
+ return keywords
diff --git a/sphinx/builders/text.py b/sphinx/builders/text.py
new file mode 100644
index 00000000..aaafedb4
--- /dev/null
+++ b/sphinx/builders/text.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.builders.text
+ ~~~~~~~~~~~~~~~~~~~~
+
+ Plain-text Sphinx builder.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import codecs
+from os import path
+
+from docutils.io import StringOutput
+
+from sphinx.util import ensuredir, os_path
+from sphinx.builders import Builder
+from sphinx.writers.text import TextWriter
+
+
+class TextBuilder(Builder):
+ name = 'text'
+ out_suffix = '.txt'
+
+ def init(self):
+ pass
+
+ def get_outdated_docs(self):
+ for docname in self.env.found_docs:
+ if docname not in self.env.all_docs:
+ yield docname
+ continue
+ targetname = self.env.doc2path(docname, self.outdir, self.out_suffix)
+ try:
+ targetmtime = path.getmtime(targetname)
+ except Exception:
+ targetmtime = 0
+ try:
+ srcmtime = path.getmtime(self.env.doc2path(docname))
+ if srcmtime > targetmtime:
+ yield docname
+ except EnvironmentError:
+ # source doesn't exist anymore
+ pass
+
+ def get_target_uri(self, docname, typ=None):
+ return ''
+
+ def prepare_writing(self, docnames):
+ self.writer = TextWriter(self)
+
+ def write_doc(self, docname, doctree):
+ destination = StringOutput(encoding='utf-8')
+ self.writer.write(doctree, destination)
+ outfilename = path.join(self.outdir, os_path(docname) + self.out_suffix)
+ ensuredir(path.dirname(outfilename)) # normally different from self.outdir
+ try:
+ f = codecs.open(outfilename, 'w', 'utf-8')
+ try:
+ f.write(self.writer.output)
+ finally:
+ f.close()
+ except (IOError, OSError), err:
+ self.warn("Error writing file %s: %s" % (outfilename, err))
+
+ def finish(self):
+ pass
diff --git a/sphinx/config.py b/sphinx/config.py
index a9c7ae95..e1eb8ec8 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -6,12 +6,14 @@
Build configuration file handling.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
- :license: BSD license.
+ :license: BSD, see LICENSE for details.
"""
import os
from os import path
+from sphinx.util import make_filename
+
class Config(object):
"""Configuration file abstraction."""
@@ -65,16 +67,22 @@ class Config(object):
html_sidebars = ({}, False),
html_additional_pages = ({}, False),
html_use_modindex = (True, False),
+ html_add_permalinks = (True, False),
html_use_index = (True, False),
html_split_index = (False, False),
html_copy_source = (True, False),
+ html_show_sourcelink = (True, False),
html_use_opensearch = ('', False),
html_file_suffix = (None, False),
+ html_link_suffix = (None, False),
html_show_sphinx = (True, False),
html_context = ({}, False),
# HTML help only options
- htmlhelp_basename = ('pydoc', False),
+ htmlhelp_basename = (lambda self: make_filename(self.project), False),
+
+ # Qt help only options
+ qthelp_basename = (lambda self: make_filename(self.project), False),
# LaTeX options
latex_documents = ([], False),
@@ -111,6 +119,12 @@ class Config(object):
def init_values(self):
config = self._raw_config
+ for valname, value in self.overrides.iteritems():
+ if '.' in valname:
+ realvalname, key = valname.split('.', 1)
+ config.setdefault(realvalname, {})[key] = value
+ else:
+ config[valname] = value
config.update(self.overrides)
for name in config:
if name in self.values:
@@ -123,7 +137,7 @@ class Config(object):
if name not in self.values:
raise AttributeError('No such config value: %s' % name)
default = self.values[name][0]
- if callable(default):
+ if hasattr(default, '__call__'):
return default(self)
return default
diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py
index 5a438886..74ac8e7f 100644
--- a/sphinx/directives/code.py
+++ b/sphinx/directives/code.py
@@ -15,6 +15,7 @@ from docutils import nodes
from docutils.parsers.rst import directives
from sphinx import addnodes
+from sphinx.util import parselinenos
# ------ highlight directive --------------------------------------------------------
@@ -68,32 +69,78 @@ def literalinclude_directive(name, arguments, options, content, lineno,
lineno - state_machine.input_offset - 1)))
fn = path.normpath(path.join(source_dir, rel_fn))
+ if 'pyobject' in options and 'lines' in options:
+ return [state.document.reporter.warning(
+ 'Cannot use both "pyobject" and "lines" options', line=lineno)]
+
encoding = options.get('encoding', env.config.source_encoding)
try:
f = codecs.open(fn, 'r', encoding)
- text = f.read()
+ lines = f.readlines()
f.close()
except (IOError, OSError):
- retnode = state.document.reporter.warning(
- 'Include file %r not found or reading it failed' % arguments[0], line=lineno)
+ return [state.document.reporter.warning(
+ 'Include file %r not found or reading it failed' % arguments[0],
+ line=lineno)]
except UnicodeError:
- retnode = state.document.reporter.warning(
+ return [state.document.reporter.warning(
'Encoding %r used for reading included file %r seems to '
'be wrong, try giving an :encoding: option' %
- (encoding, arguments[0]))
- else:
- retnode = nodes.literal_block(text, text, source=fn)
- retnode.line = 1
- if options.get('language', ''):
- retnode['language'] = options['language']
- if 'linenos' in options:
- retnode['linenos'] = True
- state.document.settings.env.note_dependency(rel_fn)
+ (encoding, arguments[0]))]
+
+ objectname = options.get('pyobject')
+ if objectname is not None:
+ from sphinx.pycode import ModuleAnalyzer
+ analyzer = ModuleAnalyzer.for_file(fn, '')
+ tags = analyzer.find_tags()
+ if objectname not in tags:
+ return [state.document.reporter.warning(
+ 'Object named %r not found in include file %r' %
+ (objectname, arguments[0]), line=lineno)]
+ else:
+ lines = lines[tags[objectname][1] - 1 : tags[objectname][2] - 1]
+
+ linespec = options.get('lines')
+ if linespec is not None:
+ try:
+ linelist = parselinenos(linespec, len(lines))
+ except ValueError, err:
+ return [state.document.reporter.warning(str(err), line=lineno)]
+ lines = [lines[i] for i in linelist]
+
+ startafter = options.get('start-after')
+ endbefore = options.get('end-before')
+ if startafter is not None or endbefore is not None:
+ use = not startafter
+ res = []
+ for line in lines:
+ if not use and startafter in line:
+ use = True
+ elif use and endbefore in line:
+ use = False
+ break
+ elif use:
+ res.append(line)
+ lines = res
+
+ text = ''.join(lines)
+ retnode = nodes.literal_block(text, text, source=fn)
+ retnode.line = 1
+ if options.get('language', ''):
+ retnode['language'] = options['language']
+ if 'linenos' in options:
+ retnode['linenos'] = True
+ state.document.settings.env.note_dependency(rel_fn)
return [retnode]
literalinclude_directive.options = {'linenos': directives.flag,
- 'language': directives.unchanged,
- 'encoding': directives.encoding}
+ 'language': directives.unchanged_required,
+ 'encoding': directives.encoding,
+ 'pyobject': directives.unchanged_required,
+ 'lines': directives.unchanged_required,
+ 'start-after': directives.unchanged_required,
+ 'end-before': directives.unchanged_required,
+ }
literalinclude_directive.content = 0
literalinclude_directive.arguments = (1, 0, 0)
directives.register_directive('literalinclude', literalinclude_directive)
diff --git a/sphinx/directives/desc.py b/sphinx/directives/desc.py
index fc6cb4f6..3ffe048b 100644
--- a/sphinx/directives/desc.py
+++ b/sphinx/directives/desc.py
@@ -58,6 +58,18 @@ def desc_index_text(desctype, module, name, add_modules):
return _('%s() (%s.%s static method)') % (methname, module, clsname)
else:
return _('%s() (%s static method)') % (methname, clsname)
+ elif desctype == 'classmethod':
+ try:
+ clsname, methname = name.rsplit('.', 1)
+ except ValueError:
+ if module:
+ return '%s() (in module %s)' % (name, module)
+ else:
+ return '%s()' % name
+ if module:
+ return '%s() (%s.%s class method)' % (methname, module, clsname)
+ else:
+ return '%s() (%s class method)' % (methname, clsname)
elif desctype == 'attribute':
try:
clsname, attrname = name.rsplit('.', 1)
@@ -137,7 +149,8 @@ def handle_doc_fields(node, env):
for child in node.children:
if not isinstance(child, nodes.field_list):
continue
- params = None
+ params = []
+ pfield = None
param_nodes = {}
param_types = {}
new_list = nodes.field_list()
@@ -152,11 +165,8 @@ def handle_doc_fields(node, env):
children = fbody.children
if typdesc == '%param':
if not params:
+ # add the field that later gets all the parameters
pfield = nodes.field()
- pfield += nodes.field_name('', _('Parameters'))
- pfield += nodes.field_body()
- params = nodes.bullet_list()
- pfield[1] += params
new_list += pfield
dlitem = nodes.list_item()
dlpar = nodes.paragraph()
@@ -165,7 +175,7 @@ def handle_doc_fields(node, env):
dlpar += children
param_nodes[obj] = dlpar
dlitem += dlpar
- params += dlitem
+ params.append(dlitem)
elif typdesc == '%type':
typenodes = fbody.children
if _is_only_paragraph(fbody):
@@ -198,6 +208,17 @@ def handle_doc_fields(node, env):
typ = fnametext.capitalize()
fname[0] = nodes.Text(typ)
new_list += field
+ if params:
+ if len(params) == 1:
+ pfield += nodes.field_name('', _('Parameter'))
+ pfield += nodes.field_body()
+ pfield[1] += params[0][0]
+ else:
+ pfield += nodes.field_name('', _('Parameters'))
+ pfield += nodes.field_body()
+ pfield[1] += nodes.bullet_list()
+ pfield[1][0].extend(params)
+
for param, type in param_types.iteritems():
if param in param_nodes:
param_nodes[param][1:1] = type
@@ -209,8 +230,9 @@ def handle_doc_fields(node, env):
py_sig_re = re.compile(
r'''^ ([\w.]*\.)? # class name(s)
(\w+) \s* # thing name
- (?: \((.*)\) # optional arguments
- (\s* -> \s* .*)? )? $ # optional return annotation
+ (?: \((.*)\) # optional: arguments
+ (?:\s* -> \s* (.*))? # return annotation
+ )? $ # and nothing more
''', re.VERBOSE)
py_paramlist_re = re.compile(r'([\[\],])') # split at '[', ']' and ','
@@ -229,9 +251,6 @@ def parse_py_signature(signode, sig, desctype, module, env):
raise ValueError
classname, name, arglist, retann = m.groups()
- if retann:
- retann = u' \N{RIGHTWARDS ARROW} ' + retann.strip()[2:]
-
if env.currclass:
add_module = False
if classname and classname.startswith(env.currclass):
@@ -251,6 +270,8 @@ def parse_py_signature(signode, sig, desctype, module, env):
if desctype == 'staticmethod':
signode += addnodes.desc_annotation('static ', 'static ')
+ elif desctype == 'classmethod':
+ signode += addnodes.desc_annotation('classmethod ', 'classmethod ')
if classname:
signode += addnodes.desc_addname(classname, classname)
@@ -263,11 +284,11 @@ def parse_py_signature(signode, sig, desctype, module, env):
signode += addnodes.desc_name(name, name)
if not arglist:
- if desctype in ('function', 'method', 'staticmethod'):
+ if desctype in ('function', 'method', 'staticmethod', 'classmethod'):
# for callables, add an empty parameter list
signode += addnodes.desc_parameterlist()
if retann:
- signode += addnodes.desc_type(retann, retann)
+ signode += addnodes.desc_returns(retann, retann)
return fullname, classname
signode += addnodes.desc_parameterlist()
@@ -290,7 +311,7 @@ def parse_py_signature(signode, sig, desctype, module, env):
if len(stack) != 1:
raise ValueError
if retann:
- signode += addnodes.desc_type(retann, retann)
+ signode += addnodes.desc_returns(retann, retann)
return fullname, classname
@@ -426,7 +447,8 @@ def desc_directive(desctype, arguments, options, content, lineno,
node.append(signode)
try:
if desctype in ('function', 'data', 'class', 'exception',
- 'method', 'staticmethod', 'attribute'):
+ 'method', 'staticmethod', 'classmethod',
+ 'attribute'):
name, clsname = parse_py_signature(signode, sig, desctype, module, env)
elif desctype in ('cfunction', 'cmember', 'cmacro', 'ctype', 'cvar'):
name = parse_c_signature(signode, sig, desctype)
@@ -503,8 +525,8 @@ def desc_directive(desctype, arguments, options, content, lineno,
if desctype in ('class', 'exception') and names:
env.currclass = names[0]
clsname_set = True
- elif desctype in ('method', 'staticmethod', 'attribute') and \
- clsname and not env.currclass:
+ elif desctype in ('method', 'staticmethod', 'classmethod',
+ 'attribute') and clsname and not env.currclass:
env.currclass = clsname.strip('.')
clsname_set = True
# needed for association of version{added,changed} directives
@@ -529,6 +551,7 @@ desctypes = [
'data',
'class',
'method',
+ 'classmethod',
'staticmethod',
'attribute',
'exception',
diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py
index f92683a3..cbf548be 100644
--- a/sphinx/directives/other.py
+++ b/sphinx/directives/other.py
@@ -8,14 +8,13 @@
"""
import re
-import posixpath
from docutils import nodes
from docutils.parsers.rst import directives
from sphinx import addnodes
from sphinx.locale import pairindextypes
-from sphinx.util import patfilter, ws_re, caption_ref_re
+from sphinx.util import patfilter, ws_re, caption_ref_re, docname_join
from sphinx.util.compat import make_admonition
@@ -25,11 +24,9 @@ def toctree_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
env = state.document.settings.env
suffix = env.config.source_suffix
- dirname = posixpath.dirname(env.docname)
glob = 'glob' in options
ret = []
- subnode = addnodes.toctree()
includefiles = []
includetitles = {}
all_docnames = env.found_docs.copy()
@@ -50,14 +47,14 @@ def toctree_directive(name, arguments, options, content, lineno,
if docname.endswith(suffix):
docname = docname[:-len(suffix)]
# absolutize filenames
- docname = posixpath.normpath(posixpath.join(dirname, docname))
+ docname = docname_join(env.docname, docname)
if docname not in env.found_docs:
ret.append(state.document.reporter.warning(
'toctree references unknown document %r' % docname, line=lineno))
else:
includefiles.append(docname)
else:
- patname = posixpath.normpath(posixpath.join(dirname, entry))
+ patname = docname_join(env.docname, entry)
docnames = sorted(patfilter(all_docnames, patname))
for docname in docnames:
all_docnames.remove(docname) # don't include it again
@@ -66,15 +63,18 @@ def toctree_directive(name, arguments, options, content, lineno,
ret.append(state.document.reporter.warning(
'toctree glob pattern %r didn\'t match any documents' % entry,
line=lineno))
+ subnode = addnodes.toctree()
subnode['includefiles'] = includefiles
subnode['includetitles'] = includetitles
subnode['maxdepth'] = options.get('maxdepth', -1)
subnode['glob'] = glob
+ subnode['hidden'] = 'hidden' in options
ret.append(subnode)
return ret
toctree_directive.content = 1
-toctree_directive.options = {'maxdepth': int, 'glob': directives.flag}
+toctree_directive.options = {'maxdepth': int, 'glob': directives.flag,
+ 'hidden': directives.flag}
directives.register_directive('toctree', toctree_directive)
@@ -383,6 +383,34 @@ acks_directive.arguments = (0, 0, 0)
directives.register_directive('acks', acks_directive)
+def hlist_directive(name, arguments, options, content, lineno,
+ content_offset, block_text, state, state_machine):
+ ncolumns = options.get('columns', 2)
+ node = nodes.paragraph()
+ state.nested_parse(content, content_offset, node)
+ if len(node.children) != 1 or not isinstance(node.children[0], nodes.bullet_list):
+ return [state.document.reporter.warning('.. hlist content is not a list',
+ line=lineno)]
+ fulllist = node.children[0]
+ # create a hlist node where the items are distributed
+ npercol, nmore = divmod(len(fulllist), ncolumns)
+ index = 0
+ newnode = addnodes.hlist()
+ for column in range(ncolumns):
+ endindex = index + (column < nmore and (npercol+1) or npercol)
+ col = addnodes.hlistcol()
+ col += nodes.bullet_list()
+ col[0] += fulllist.children[index:endindex]
+ index = endindex
+ newnode += col
+ return [newnode]
+
+hlist_directive.content = 1
+hlist_directive.arguments = (0, 0, 0)
+hlist_directive.options = {'columns': int}
+directives.register_directive('hlist', hlist_directive)
+
+
def tabularcolumns_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
# support giving explicit tabulary column definition to latex
diff --git a/sphinx/environment.py b/sphinx/environment.py
index a0270d33..18c3ffe3 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -15,6 +15,7 @@ import time
import heapq
import types
import imghdr
+import string
import difflib
import cPickle as pickle
from os import path
@@ -42,7 +43,8 @@ from docutils.transforms import Transform
from docutils.transforms.parts import ContentsFilter
from sphinx import addnodes
-from sphinx.util import movefile, get_matching_docs, SEP, ustrftime
+from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \
+ docname_join, FilenameUniqDict
from sphinx.directives import additional_xref_types
default_settings = {
@@ -57,7 +59,7 @@ default_settings = {
# This is increased every time an environment attribute is added
# or changed to properly invalidate pickle files.
-ENV_VERSION = 26
+ENV_VERSION = 27
default_substitutions = set([
@@ -279,7 +281,8 @@ class BuildEnvironment:
# (type, string, target, aliasname)
self.versionchanges = {} # version -> list of
# (type, docname, lineno, module, descname, content)
- self.images = {} # absolute path -> (docnames, unique filename)
+ self.images = FilenameUniqDict() # absolute path -> (docnames, unique filename)
+ self.dlfiles = FilenameUniqDict() # absolute path -> (docnames, unique filename)
# These are set while parsing a file
self.docname = None # current document name
@@ -291,9 +294,12 @@ class BuildEnvironment:
self.gloss_entries = set() # existing definition labels
# Some magically present labels
- self.labels['genindex'] = ('genindex', '', _('Index'))
- self.labels['modindex'] = ('modindex', '', _('Module Index'))
- self.labels['search'] = ('search', '', _('Search Page'))
+ def add_magic_label(name, description):
+ self.labels[name] = (name, '', description)
+ self.anonlabels[name] = (name, '')
+ add_magic_label('genindex', _('Index'))
+ add_magic_label('modindex', _('Module Index'))
+ add_magic_label('search', _('Search Page'))
def set_warnfunc(self, func):
self._warnfunc = func
@@ -320,6 +326,8 @@ class BuildEnvironment:
self.filemodules.pop(docname, None)
self.indexentries.pop(docname, None)
self.glob_toctrees.discard(docname)
+ self.images.purge_doc(docname)
+ self.dlfiles.purge_doc(docname)
for subfn, fnset in self.files_to_rebuild.items():
fnset.discard(docname)
@@ -343,10 +351,6 @@ class BuildEnvironment:
for version, changes in self.versionchanges.items():
new = [change for change in changes if change[1] != docname]
changes[:] = new
- for fullpath, (docs, _) in self.images.items():
- docs.discard(docname)
- if not docs:
- del self.images[fullpath]
def doc2path(self, docname, base=True, suffix=None):
"""
@@ -483,12 +487,6 @@ class BuildEnvironment:
self.doc2path(config.master_doc))
self.app = None
-
- # remove all non-existing images from inventory
- for imgsrc in self.images.keys():
- if not os.access(path.join(self.srcdir, imgsrc), os.R_OK):
- del self.images[imgsrc]
-
if app:
app.emit('env-updated', self)
@@ -543,10 +541,11 @@ class BuildEnvironment:
doctree = pub.document
except UnicodeError, err:
from sphinx.application import SphinxError
- raise SphinxError(err.message)
+ raise SphinxError(str(err))
self.filter_messages(doctree)
self.process_dependencies(docname, doctree)
self.process_images(docname, doctree)
+ self.process_downloads(docname, doctree)
self.process_metadata(docname, doctree)
self.create_title_from(docname, doctree)
self.note_labels_from(docname, doctree)
@@ -611,11 +610,25 @@ class BuildEnvironment:
dep = path.join(docdir, dep)
self.dependencies.setdefault(docname, set()).add(dep)
+ def process_downloads(self, docname, doctree):
+ """
+ Process downloadable file paths.
+ """
+ docdir = path.dirname(self.doc2path(docname, base=None))
+ for node in doctree.traverse(addnodes.download_reference):
+ filepath = path.normpath(path.join(docdir, node['reftarget']))
+ self.dependencies.setdefault(docname, set()).add(filepath)
+ if not os.access(path.join(self.srcdir, filepath), os.R_OK):
+ self.warn(docname, 'Download file not readable: %s' % filepath,
+ getattr(node, 'line', None))
+ continue
+ uniquename = self.dlfiles.add_file(docname, filepath)
+ node['filename'] = uniquename
+
def process_images(self, docname, doctree):
"""
Process and rewrite image URIs.
"""
- existing_names = set(v[1] for v in self.images.itervalues())
docdir = path.dirname(self.doc2path(docname, base=None))
for node in doctree.traverse(nodes.image):
# Map the mimetype to the corresponding image. The writer may
@@ -659,17 +672,8 @@ class BuildEnvironment:
if not os.access(path.join(self.srcdir, imgpath), os.R_OK):
self.warn(docname, 'Image file not readable: %s' % imgpath,
node.line)
- if imgpath in self.images:
- self.images[imgpath][0].add(docname)
continue
- uniquename = path.basename(imgpath)
- base, ext = path.splitext(uniquename)
- i = 0
- while uniquename in existing_names:
- i += 1
- uniquename = '%s%s%s' % (base, i, ext)
- self.images[imgpath] = (set([docname]), uniquename)
- existing_names.add(uniquename)
+ self.images.add_file(docname, imgpath)
def process_metadata(self, docname, doctree):
"""
@@ -905,6 +909,8 @@ class BuildEnvironment:
If *titles_only* is True, only toplevel document titles will be in the
resulting tree.
"""
+ if toctree.get('hidden', False):
+ return None
def _walk_depth(node, depth, maxdepth, titleoverrides):
"""Utility: Cut a TOC at a specified depth."""
@@ -918,7 +924,7 @@ class BuildEnvironment:
else:
_walk_depth(subnode, depth+1, maxdepth, titleoverrides)
- def _entries_from_toctree(toctreenode, separate=False):
+ def _entries_from_toctree(toctreenode, separate=False, subtree=False):
"""Return TOC entries for a toctree node."""
includefiles = map(str, toctreenode['includefiles'])
@@ -948,7 +954,7 @@ class BuildEnvironment:
# resolve all sub-toctrees
for toctreenode in toc.traverse(addnodes.toctree):
i = toctreenode.parent.index(toctreenode) + 1
- for item in _entries_from_toctree(toctreenode):
+ for item in _entries_from_toctree(toctreenode, subtree=True):
toctreenode.parent.insert(i, item)
i += 1
toctreenode.parent.remove(toctreenode)
@@ -956,12 +962,19 @@ class BuildEnvironment:
entries.append(toc)
else:
entries.extend(toc.children)
+ if not subtree and not separate:
+ ret = nodes.bullet_list()
+ ret += entries
+ return [ret]
return entries
maxdepth = maxdepth or toctree.get('maxdepth', -1)
titleoverrides = toctree.get('includetitles', {})
- tocentries = _entries_from_toctree(toctree, separate=True)
+ # NOTE: previously, this was separate=True, but that leads to artificial
+ # separation when two or more toctree entries form a logical unit, so
+ # separating mode is no longer used -- it's kept here for history's sake
+ tocentries = _entries_from_toctree(toctree, separate=False)
if not tocentries:
return None
@@ -1030,6 +1043,24 @@ class BuildEnvironment:
if labelid:
newnode['refuri'] += '#' + labelid
newnode.append(innernode)
+ elif typ == 'doc':
+ # directly reference to document by source name; can be absolute
+ # or relative
+ docname = docname_join(fromdocname, target)
+ if docname not in self.all_docs:
+ newnode = doctree.reporter.system_message(
+ 2, 'unknown document: %s' % docname)
+ else:
+ if node['refcaption']:
+ # reference with explicit title
+ caption = node.astext()
+ else:
+ caption = self.titles[docname].astext()
+ innernode = nodes.emphasis(caption, caption)
+ newnode = nodes.reference('', '')
+ newnode['refuri'] = builder.get_relative_uri(
+ fromdocname, docname)
+ newnode.append(innernode)
elif typ == 'keyword':
# keywords are referenced by named labels
docname, labelid, _ = self.labels.get(target, ('','',''))
diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py
index ee45a312..d0512f2b 100644
--- a/sphinx/ext/autodoc.py
+++ b/sphinx/ext/autodoc.py
@@ -13,40 +13,51 @@
import re
import sys
-import types
import inspect
import linecache
-from types import FunctionType, BuiltinMethodType, MethodType
+from types import FunctionType, BuiltinFunctionType, MethodType, ClassType
from docutils import nodes
from docutils.parsers.rst import directives
from docutils.statemachine import ViewList
-from sphinx.util import rpartition, nested_parse_with_titles
-from sphinx.directives.desc import py_sig_re
+from sphinx.util import rpartition, nested_parse_with_titles, force_decode
+from sphinx.pycode import ModuleAnalyzer, PycodeError
+from sphinx.util.docstrings import prepare_docstring
+clstypes = (type, ClassType)
try:
base_exception = BaseException
except NameError:
base_exception = Exception
-_charset_re = re.compile(r'coding[:=]\s*([-\w.]+)')
-_module_charsets = {}
+
+py_ext_sig_re = re.compile(
+ r'''^ ([\w.]+::)? # explicit module name
+ ([\w.]+\.)? # module and/or class name(s)
+ (\w+) \s* # thing name
+ (?: \((.*)\) # optional: arguments
+ (?:\s* -> \s* (.*))? # return annotation
+ )? $ # and nothing more
+ ''', re.VERBOSE)
class Options(object):
pass
-def is_static_method(obj):
- """Check if the object given is a static method."""
- if isinstance(obj, (FunctionType, classmethod)):
- return True
- elif isinstance(obj, BuiltinMethodType):
- return obj.__self__ is not None
- elif isinstance(obj, MethodType):
- return obj.im_self is not None
- return False
+def get_method_type(obj):
+ """
+ Return the method type for an object: method, staticmethod or classmethod.
+ """
+ if isinstance(obj, classmethod) or \
+ (isinstance(obj, MethodType) and obj.im_self is not None):
+ return 'classmethod'
+ elif isinstance(obj, FunctionType) or \
+ (isinstance(obj, BuiltinFunctionType) and obj.__self__ is not None):
+ return 'staticmethod'
+ else:
+ return 'method'
class AutodocReporter(object):
@@ -155,61 +166,11 @@ def between(marker, what=None, keepempty=False):
def isdescriptor(x):
"""Check if the object is some kind of descriptor."""
for item in '__get__', '__set__', '__delete__':
- if callable(getattr(x, item, None)):
+ if hasattr(getattr(x, item, None), '__call__'):
return True
return False
-def prepare_docstring(s):
- """
- Convert a docstring into lines of parseable reST. Return it as a list of
- lines usable for inserting into a docutils ViewList (used as argument
- of nested_parse().) An empty line is added to act as a separator between
- this docstring and following content.
- """
- lines = s.expandtabs().splitlines()
- # Find minimum indentation of any non-blank lines after first line.
- margin = sys.maxint
- for line in lines[1:]:
- content = len(line.lstrip())
- if content:
- indent = len(line) - content
- margin = min(margin, indent)
- # Remove indentation.
- if lines:
- lines[0] = lines[0].lstrip()
- if margin < sys.maxint:
- for i in range(1, len(lines)): lines[i] = lines[i][margin:]
- # Remove any leading blank lines.
- while lines and not lines[0]:
- lines.pop(0)
- # make sure there is an empty line at the end
- if lines and lines[-1]:
- lines.append('')
- return lines
-
-
-def get_module_charset(module):
- """Return the charset of the given module (cached in _module_charsets)."""
- if module in _module_charsets:
- return _module_charsets[module]
- try:
- filename = __import__(module, None, None, ['foo']).__file__
- except (ImportError, AttributeError):
- return None
- if filename[-4:].lower() in ('.pyc', '.pyo'):
- filename = filename[:-1]
- for line in [linecache.getline(filename, x) for x in (1, 2)]:
- match = _charset_re.search(line)
- if match is not None:
- charset = match.group(1)
- break
- else:
- charset = 'ascii'
- _module_charsets[module] = charset
- return charset
-
-
class RstGenerator(object):
def __init__(self, options, document, lineno):
self.options = options
@@ -223,15 +184,19 @@ class RstGenerator(object):
def warn(self, msg):
self.warnings.append(self.reporter.warning(msg, line=self.lineno))
- def get_doc(self, what, name, obj):
- """Format and yield lines of the docstring(s) for the object."""
+ def get_doc(self, what, obj, encoding=None):
+ """Decode and return lines of the docstring(s) for the object."""
docstrings = []
+
+ # add the regular docstring if present
if getattr(obj, '__doc__', None):
docstrings.append(obj.__doc__)
- # skip some lines in module docstrings if configured
+
+ # skip some lines in module docstrings if configured (deprecated!)
if what == 'module' and self.env.config.automodule_skip_lines and docstrings:
docstrings[0] = '\n'.join(docstrings[0].splitlines()
[self.env.config.automodule_skip_lines:])
+
# for classes, what the "docstring" is can be controlled via an option
if what in ('class', 'exception'):
content = self.env.config.autoclass_content
@@ -247,24 +212,13 @@ class RstGenerator(object):
docstrings.append(initdocstring)
# the default is only the class docstring
- # decode the docstrings using the module's source encoding
- charset = None
- module = getattr(obj, '__module__', None)
- if module is not None:
- charset = get_module_charset(module)
+ # make sure we have Unicode docstrings, then sanitize and split into lines
+ return [prepare_docstring(force_decode(docstring, encoding))
+ for docstring in docstrings]
- for docstring in docstrings:
- if isinstance(docstring, str):
- if charset:
- docstring = docstring.decode(charset)
- else:
- try:
- # try decoding with utf-8, should only work for real UTF-8
- docstring = docstring.decode('utf-8')
- except UnicodeError:
- # last resort -- can't fail
- docstring = docstring.decode('latin1')
- docstringlines = prepare_docstring(docstring)
+ def process_doc(self, docstrings, what, name, obj):
+ """Let the user process the docstrings."""
+ for docstringlines in docstrings:
if self.env.app:
# let extensions preprocess docstrings
self.env.app.emit('autodoc-process-docstring',
@@ -282,61 +236,71 @@ class RstGenerator(object):
# first, parse the definition -- auto directives for classes and functions
# can contain a signature which is then used instead of an autogenerated one
try:
- path, base, args, retann = py_sig_re.match(name).groups()
+ mod, path, base, args, retann = py_ext_sig_re.match(name).groups()
except:
self.warn('invalid signature for auto%s (%r)' % (what, name))
- return
- # fullname is the fully qualified name, base the name after the last dot
- fullname = (path or '') + base
+ return None, [], None, None
+
+ # support explicit module and class name separation via ::
+ if mod is not None:
+ mod = mod[:-2]
+ parents = path and path.rstrip('.').split('.') or []
+ else:
+ parents = []
if what == 'module':
+ if mod is not None:
+ self.warn('"::" in automodule name doesn\'t make sense')
if args or retann:
self.warn('ignoring signature arguments and return annotation '
- 'for automodule %s' % fullname)
- return fullname, fullname, [], None, None
+ 'for automodule %s' % name)
+ return (path or '') + base, [], None, None
- elif what in ('class', 'exception', 'function'):
- if path:
- mod = path.rstrip('.')
- else:
- mod = None
- # if documenting a toplevel object without explicit module, it can
- # be contained in another auto directive ...
- if hasattr(self.env, 'autodoc_current_module'):
+ elif what in ('exception', 'function', 'class', 'data'):
+ if mod is None:
+ if path:
+ mod = path.rstrip('.')
+ else:
+ # if documenting a toplevel object without explicit module, it can
+ # be contained in another auto directive ...
+ if hasattr(self.env, 'autodoc_current_module'):
+ mod = self.env.autodoc_current_module
+ # ... or in the scope of a module directive
+ if not mod:
+ mod = self.env.currmodule
+ return mod, parents + [base], args, retann
+
+ else:
+ if mod is None:
+ if path:
+ mod_cls = path.rstrip('.')
+ else:
+ mod_cls = None
+ # if documenting a class-level object without path, there must be a
+ # current class, either from a parent auto directive ...
+ if hasattr(self.env, 'autodoc_current_class'):
+ mod_cls = self.env.autodoc_current_class
+ # ... or from a class directive
+ if mod_cls is None:
+ mod_cls = self.env.currclass
+ # ... if still None, there's no way to know
+ if mod_cls is None:
+ return None, [], None, None
+ mod, cls = rpartition(mod_cls, '.')
+ parents = [cls]
+ # if the module name is still missing, get it like above
+ if not mod and hasattr(self.env, 'autodoc_current_module'):
mod = self.env.autodoc_current_module
- # ... or in the scope of a module directive
if not mod:
mod = self.env.currmodule
- return fullname, mod, [base], args, retann
-
- else:
- if path:
- mod_cls = path.rstrip('.')
- else:
- mod_cls = None
- # if documenting a class-level object without path, there must be a
- # current class, either from a parent auto directive ...
- if hasattr(self.env, 'autodoc_current_class'):
- mod_cls = self.env.autodoc_current_class
- # ... or from a class directive
- if mod_cls is None:
- mod_cls = self.env.currclass
- # ... if still None, there's no way to know
- if mod_cls is None:
- return fullname, None, [], args, retann
- mod, cls = rpartition(mod_cls, '.')
- # if the module name is still missing, get it like above
- if not mod and hasattr(self.env, 'autodoc_current_module'):
- mod = self.env.autodoc_current_module
- if not mod:
- mod = self.env.currmodule
- return fullname, mod, [cls, base], args, retann
+ return mod, parents + [base], args, retann
def format_signature(self, what, name, obj, args, retann):
"""
Return the signature of the object, formatted for display.
"""
- if what not in ('class', 'method', 'function'):
+ if what not in ('class', 'method', 'staticmethod', 'classmethod',
+ 'function'):
return ''
err = None
@@ -361,7 +325,8 @@ class RstGenerator(object):
getargs = False
if getargs:
argspec = inspect.getargspec(obj)
- if what in ('class', 'method') and argspec[0] and \
+ if what in ('class', 'method', 'staticmethod',
+ 'classmethod') and argspec[0] and \
argspec[0][0] in ('cls', 'self'):
del argspec[0][0]
args = inspect.formatargspec(*argspec)
@@ -375,38 +340,35 @@ class RstGenerator(object):
args, retann = result
if args is not None:
- return '%s%s' % (args, retann or '')
+ return '%s%s' % (args, retann and (' -> %s' % retann) or '')
elif err:
# re-raise the error for perusal of the handler in generate()
raise RuntimeError(err)
else:
return ''
- def generate(self, what, name, members, add_content, indent=u'', check_module=False):
+ def generate(self, what, name, members, add_content, indent=u'', check_module=False,
+ no_docstring=False):
"""
Generate reST for the object in self.result.
"""
- fullname, mod, objpath, args, retann = self.resolve_name(what, name)
+ mod, objpath, args, retann = self.resolve_name(what, name)
if not mod:
# need a module to import
self.warn('don\'t know which module to import for autodocumenting %r '
'(try placing a "module" or "currentmodule" directive in the '
- 'document, or giving an explicit module name)' % fullname)
+ 'document, or giving an explicit module name)' % name)
return
+ # fully-qualified name
+ fullname = mod + (objpath and '.' + '.'.join(objpath) or '')
# the name to put into the generated directive -- doesn't contain the module
name_in_directive = '.'.join(objpath) or mod
# now, import the module and get object to document
try:
- todoc = module = __import__(mod, None, None, ['foo'])
- if hasattr(module, '__file__') and module.__file__:
- modfile = module.__file__
- if modfile[-4:].lower() in ('.pyc', '.pyo'):
- modfile = modfile[:-1]
- self.filename_set.add(modfile)
- else:
- modfile = None # e.g. for builtin and C modules
+ __import__(mod)
+ todoc = module = sys.modules[mod]
for part in objpath:
todoc = getattr(todoc, part)
except (ImportError, AttributeError), err:
@@ -415,28 +377,41 @@ class RstGenerator(object):
(what, str(fullname), err))
return
+ # try to also get a source code analyzer for attribute docs
+ try:
+ analyzer = ModuleAnalyzer.for_module(mod)
+ # parse right now, to get PycodeErrors on parsing
+ analyzer.parse()
+ except PycodeError, err:
+ # no source file -- e.g. for builtin and C modules
+ analyzer = None
+ else:
+ self.filename_set.add(analyzer.srcname)
+
# check __module__ of object if wanted (for members not given explicitly)
if check_module:
if hasattr(todoc, '__module__'):
if todoc.__module__ != mod:
return
+ # make sure that the result starts with an empty line. This is
+ # necessary for some situations where another directive preprocesses
+ # reST and no starting newline is present
+ self.result.append(u'', '')
+
# format the object's signature, if any
try:
- sig = self.format_signature(what, name, todoc, args, retann)
+ sig = self.format_signature(what, fullname, todoc, args, retann)
except Exception, err:
self.warn('error while formatting signature for %s: %s' %
(fullname, err))
sig = ''
- # make sure that the result starts with an empty line. This is
- # necessary for some situations where another directive preprocesses
- # reST and no starting newline is present
- self.result.append(u'', '')
-
# now, create the directive header
- directive = (what == 'method' and is_static_method(todoc)) \
- and 'staticmethod' or what
+ if what == 'method':
+ directive = get_method_type(todoc)
+ else:
+ directive = what
self.result.append(indent + u'.. %s:: %s%s' %
(directive, name_in_directive, sig), '<autodoc>')
if what == 'module':
@@ -457,13 +432,14 @@ class RstGenerator(object):
self.result.append(indent + u' :noindex:', '<autodoc>')
self.result.append(u'', '<autodoc>')
+ # add inheritance info, if wanted
if self.options.show_inheritance and what in ('class', 'exception'):
if len(todoc.__bases__):
bases = [b.__module__ == '__builtin__' and
u':class:`%s`' % b.__name__ or
u':class:`%s.%s`' % (b.__module__, b.__name__)
for b in todoc.__bases__]
- self.result.append(indent + u' Bases: %s' % ', '.join(bases),
+ self.result.append(indent + _(u' Bases: %s') % ', '.join(bases),
'<autodoc>')
self.result.append(u'', '<autodoc>')
@@ -471,22 +447,38 @@ class RstGenerator(object):
if what != 'module':
indent += u' '
- if modfile:
- sourcename = '%s:docstring of %s' % (modfile, fullname)
+ # add content from attribute documentation
+ if analyzer:
+ sourcename = '%s:docstring of %s' % (analyzer.srcname, fullname)
+ attr_docs = analyzer.find_attr_docs()
+ if what in ('data', 'attribute'):
+ key = ('.'.join(objpath[:-1]), objpath[-1])
+ if key in attr_docs:
+ no_docstring = True
+ docstrings = [attr_docs[key]]
+ for i, line in enumerate(self.process_doc(docstrings, what,
+ fullname, todoc)):
+ self.result.append(indent + line, sourcename, i)
else:
sourcename = 'docstring of %s' % fullname
+ attr_docs = {}
# add content from docstrings
- for i, line in enumerate(self.get_doc(what, fullname, todoc)):
- self.result.append(indent + line, sourcename, i)
-
- # add source content, if present
+ if not no_docstring:
+ encoding = analyzer and analyzer.encoding
+ docstrings = self.get_doc(what, todoc, encoding)
+ for i, line in enumerate(self.process_doc(docstrings, what,
+ fullname, todoc)):
+ self.result.append(indent + line, sourcename, i)
+
+ # add additional content (e.g. from document), if present
if add_content:
for line, src in zip(add_content.data, add_content.items):
self.result.append(indent + line, src[0], src[1])
# document members?
- if not members or what in ('function', 'method', 'attribute'):
+ if not members or what in ('function', 'method', 'staticmethod',
+ 'classmethod', 'data', 'attribute'):
return
# set current namespace for finding members
@@ -494,10 +486,10 @@ class RstGenerator(object):
if objpath:
self.env.autodoc_current_class = objpath[0]
- # add members, if possible
- _all = members == ['__all__']
+ # look for members to include
+ want_all_members = members == ['__all__']
members_check_module = False
- if _all:
+ if want_all_members:
# unqualified :members: given
if what == 'module':
if hasattr(todoc, '__all__'):
@@ -525,14 +517,29 @@ class RstGenerator(object):
all_members = sorted(todoc.__dict__.iteritems())
else:
all_members = [(mname, getattr(todoc, mname)) for mname in members]
+
+ # search for members in source code too
+ namespace = '.'.join(objpath) # will be empty for modules
+
for (membername, member) in all_members:
- # ignore members whose name starts with _ by default
- if _all and membername.startswith('_'):
- continue
+ # if isattr is True, the member is documented as an attribute
+ isattr = False
+ # if content is not None, no extra content from docstrings will be added
+ content = None
+
+ if want_all_members and membername.startswith('_'):
+ # ignore members whose name starts with _ by default
+ skip = True
+ else:
+ if (namespace, membername) in attr_docs:
+ # keep documented attributes
+ skip = False
+ isattr = True
+ else:
+ # ignore undocumented members if :undoc-members: is not given
+ doc = getattr(member, '__doc__', None)
+ skip = not self.options.undoc_members and not doc
- # ignore undocumented members if :undoc-members: is not given
- doc = getattr(member, '__doc__', None)
- skip = not self.options.undoc_members and not doc
# give the user a chance to decide whether this member should be skipped
if self.env.app:
# let extensions preprocess docstrings
@@ -543,30 +550,48 @@ class RstGenerator(object):
if skip:
continue
+ # determine member type
if what == 'module':
- if isinstance(member, (types.FunctionType,
- types.BuiltinFunctionType)):
+ if isinstance(member, (FunctionType, BuiltinFunctionType)):
memberwhat = 'function'
- elif isinstance(member, types.ClassType) or \
- isinstance(member, type):
- if issubclass(member, base_exception):
+ elif isattr:
+ memberwhat = 'attribute'
+ elif isinstance(member, clstypes):
+ if member.__name__ != membername:
+ # assume it's aliased
+ memberwhat = 'data'
+ content = ViewList([_('alias of :class:`%s`') % member.__name__],
+ source='')
+ elif issubclass(member, base_exception):
memberwhat = 'exception'
else:
memberwhat = 'class'
else:
- # XXX: todo -- attribute docs
continue
else:
- if callable(member):
+ if inspect.isroutine(member):
memberwhat = 'method'
+ elif isattr:
+ memberwhat = 'attribute'
+ elif isinstance(member, clstypes):
+ if member.__name__ != membername:
+ # assume it's aliased
+ memberwhat = 'attribute'
+ content = ViewList([_('alias of :class:`%s`') % member.__name__],
+ source='')
+ else:
+ memberwhat = 'class'
elif isdescriptor(member):
memberwhat = 'attribute'
else:
- # XXX: todo -- attribute docs
continue
- full_membername = fullname + '.' + membername
- self.generate(memberwhat, full_membername, ['__all__'], None, indent,
- check_module=members_check_module)
+
+ # give explicitly separated module name, so that members of inner classes
+ # can be documented
+ full_membername = mod + '::' + '.'.join(objpath + [membername])
+ self.generate(memberwhat, full_membername, ['__all__'],
+ add_content=content, no_docstring=bool(content),
+ indent=indent, check_module=members_check_module)
self.env.autodoc_current_module = None
self.env.autodoc_current_class = None
@@ -641,6 +666,8 @@ def setup(app):
1, (1, 0, 1), **cls_options)
app.add_directive('autoexception', autoclass_directive,
1, (1, 0, 1), **cls_options)
+ app.add_directive('autodata', auto_directive, 1, (1, 0, 1),
+ noindex=directives.flag)
app.add_directive('autofunction', auto_directive, 1, (1, 0, 1),
noindex=directives.flag)
app.add_directive('automethod', auto_directive, 1, (1, 0, 1),
diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py
index c26a1cfd..a3dc5889 100644
--- a/sphinx/ext/coverage.py
+++ b/sphinx/ext/coverage.py
@@ -16,7 +16,7 @@ import inspect
import cPickle as pickle
from os import path
-from sphinx.builder import Builder
+from sphinx.builders import Builder
# utility
diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py
index 3a44c3f7..d6697f98 100644
--- a/sphinx/ext/doctest.py
+++ b/sphinx/ext/doctest.py
@@ -22,7 +22,7 @@ doctest = __import__('doctest')
from docutils import nodes
from docutils.parsers.rst import directives
-from sphinx.builder import Builder
+from sphinx.builders import Builder
from sphinx.util.console import bold
blankline_re = re.compile(r'^\s*<BLANKLINE>', re.MULTILINE)
@@ -99,9 +99,12 @@ class TestGroup(object):
self.setup = []
self.tests = []
- def add_code(self, code):
+ def add_code(self, code, prepend=False):
if code.type == 'testsetup':
- self.setup.append(code)
+ if prepend:
+ self.setup.insert(0, code)
+ else:
+ self.setup.append(code)
elif code.type == 'doctest':
self.tests.append([code])
elif code.type == 'testcode':
@@ -258,6 +261,10 @@ Doctest summary
for code in add_to_all_groups:
for group in groups.itervalues():
group.add_code(code)
+ if self.config.doctest_global_setup:
+ code = TestCode(self.config.doctest_global_setup, 'testsetup', lineno=0)
+ for group in groups.itervalues():
+ group.add_code(code, prepend=True)
if not groups:
return
@@ -335,3 +342,4 @@ def setup(app):
# this config value adds to sys.path
app.add_config_value('doctest_path', [], False)
app.add_config_value('doctest_test_doctest_blocks', 'default', False)
+ app.add_config_value('doctest_global_setup', '', False)
diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py
index 4938c041..5340a55e 100644
--- a/sphinx/ext/intersphinx.py
+++ b/sphinx/ext/intersphinx.py
@@ -31,7 +31,7 @@ from os import path
from docutils import nodes
-from sphinx.builder import INVENTORY_FILENAME
+from sphinx.builders.html import INVENTORY_FILENAME
def fetch_inventory(app, uri, inv):
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index fe82b0bc..c818af30 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -30,6 +30,8 @@ try:
from pygments.token import Generic, Comment, Number
except ImportError:
pygments = None
+ lexers = None
+ HtmlFormatter = LatexFormatter = None
else:
class SphinxStyle(Style):
"""
@@ -81,6 +83,11 @@ if sys.version_info < (2, 5):
class PygmentsBridge(object):
+ # Set these attributes if you want to have different Pygments formatters
+ # than the default ones.
+ html_formatter = HtmlFormatter
+ latex_formatter = LatexFormatter
+
def __init__(self, dest='html', stylename='sphinx'):
self.dest = dest
if not pygments:
@@ -89,14 +96,17 @@ class PygmentsBridge(object):
style = SphinxStyle
elif '.' in stylename:
module, stylename = stylename.rsplit('.', 1)
- style = getattr(__import__(module, None, None, ['']), stylename)
+ style = getattr(__import__(module, None, None, ['__name__']), stylename)
else:
style = get_style_by_name(stylename)
- self.hfmter = {False: HtmlFormatter(style=style),
- True: HtmlFormatter(style=style, linenos=True)}
- self.lfmter = {False: LatexFormatter(style=style, commandprefix='PYG'),
- True: LatexFormatter(style=style, linenos=True,
- commandprefix='PYG')}
+ if dest == 'html':
+ self.fmter = {False: self.html_formatter(style=style),
+ True: self.html_formatter(style=style, linenos=True)}
+ else:
+ self.fmter = {False: self.latex_formatter(style=style,
+ commandprefix='PYG'),
+ True: self.latex_formatter(style=style, linenos=True,
+ commandprefix='PYG')}
def unhighlighted(self, source):
if self.dest == 'html':
@@ -170,9 +180,9 @@ class PygmentsBridge(object):
lexer.add_filter('raiseonerror')
try:
if self.dest == 'html':
- return highlight(source, lexer, self.hfmter[bool(linenos)])
+ return highlight(source, lexer, self.fmter[bool(linenos)])
else:
- hlsource = highlight(source, lexer, self.lfmter[bool(linenos)])
+ hlsource = highlight(source, lexer, self.fmter[bool(linenos)])
return hlsource.translate(tex_hl_escape_map)
except ErrorToken:
# this is most probably not the selected language,
@@ -186,9 +196,9 @@ class PygmentsBridge(object):
# no HTML styles needed
return ''
if self.dest == 'html':
- return self.hfmter[0].get_style_defs()
+ return self.fmter[0].get_style_defs()
else:
- styledefs = self.lfmter[0].get_style_defs()
+ styledefs = self.fmter[0].get_style_defs()
# workaround for Pygments < 0.12
if styledefs.startswith('\\newcommand\\at{@}'):
styledefs += _LATEX_STYLES
diff --git a/sphinx/htmlhelp.py b/sphinx/htmlhelp.py
deleted file mode 100644
index 84ef31d9..00000000
--- a/sphinx/htmlhelp.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- sphinx.htmlhelp
- ~~~~~~~~~~~~~~~
-
- Build HTML help support files.
- Adapted from the original Doc/tools/prechm.py.
-
- :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
- :license: BSD, see LICENSE for details.
-"""
-
-import os
-import cgi
-from os import path
-
-from docutils import nodes
-
-from sphinx import addnodes
-
-# Project file (*.hhp) template. 'outname' is the file basename (like
-# the pythlp in pythlp.hhp); 'version' is the doc version number (like
-# the 2.2 in Python 2.2).
-# The magical numbers in the long line under [WINDOWS] set most of the
-# user-visible features (visible buttons, tabs, etc).
-# About 0x10384e: This defines the buttons in the help viewer. The
-# following defns are taken from htmlhelp.h. Not all possibilities
-# actually work, and not all those that work are available from the Help
-# Workshop GUI. In particular, the Zoom/Font button works and is not
-# available from the GUI. The ones we're using are marked with 'x':
-#
-# 0x000002 Hide/Show x
-# 0x000004 Back x
-# 0x000008 Forward x
-# 0x000010 Stop
-# 0x000020 Refresh
-# 0x000040 Home x
-# 0x000080 Forward
-# 0x000100 Back
-# 0x000200 Notes
-# 0x000400 Contents
-# 0x000800 Locate x
-# 0x001000 Options x
-# 0x002000 Print x
-# 0x004000 Index
-# 0x008000 Search
-# 0x010000 History
-# 0x020000 Favorites
-# 0x040000 Jump 1
-# 0x080000 Jump 2
-# 0x100000 Zoom/Font x
-# 0x200000 TOC Next
-# 0x400000 TOC Prev
-
-project_template = '''\
-[OPTIONS]
-Binary TOC=Yes
-Binary Index=No
-Compiled file=%(outname)s.chm
-Contents file=%(outname)s.hhc
-Default Window=%(outname)s
-Default topic=index.html
-Display compile progress=No
-Full text search stop list file=%(outname)s.stp
-Full-text search=Yes
-Index file=%(outname)s.hhk
-Language=0x409
-Title=%(title)s
-
-[WINDOWS]
-%(outname)s="%(title)s","%(outname)s.hhc","%(outname)s.hhk",\
-"index.html","index.html",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0
-
-[FILES]
-'''
-
-contents_header = '''\
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<HTML>
-<HEAD>
-<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
-<!-- Sitemap 1.0 -->
-</HEAD><BODY>
-<OBJECT type="text/site properties">
- <param name="Window Styles" value="0x801227">
- <param name="ImageType" value="Folder">
-</OBJECT>
-<UL>
-'''
-
-contents_footer = '''\
-</UL></BODY></HTML>
-'''
-
-object_sitemap = '''\
-<OBJECT type="text/sitemap">
- <param name="Name" value="%s">
- <param name="Local" value="%s">
-</OBJECT>
-'''
-
-# List of words the full text search facility shouldn't index. This
-# becomes file outname.stp. Note that this list must be pretty small!
-# Different versions of the MS docs claim the file has a maximum size of
-# 256 or 512 bytes (including \r\n at the end of each line).
-# Note that "and", "or", "not" and "near" are operators in the search
-# language, so no point indexing them even if we wanted to.
-stopwords = """
-a and are as at
-be but by
-for
-if in into is it
-near no not
-of on or
-such
-that the their then there these they this to
-was will with
-""".split()
-
-
-def build_hhx(builder, outdir, outname):
- builder.info('dumping stopword list...')
- f = open(path.join(outdir, outname+'.stp'), 'w')
- try:
- for word in sorted(stopwords):
- print >>f, word
- finally:
- f.close()
-
- builder.info('writing project file...')
- f = open(path.join(outdir, outname+'.hhp'), 'w')
- try:
- f.write(project_template % {'outname': outname,
- 'title': builder.config.html_title,
- 'version': builder.config.version,
- 'project': builder.config.project})
- if not outdir.endswith(os.sep):
- outdir += os.sep
- olen = len(outdir)
- for root, dirs, files in os.walk(outdir):
- staticdir = (root == path.join(outdir, '_static'))
- for fn in files:
- if (staticdir and not fn.endswith('.js')) or fn.endswith('.html'):
- print >>f, path.join(root, fn)[olen:].replace(os.sep, '\\')
- finally:
- f.close()
-
- builder.info('writing TOC file...')
- f = open(path.join(outdir, outname+'.hhc'), 'w')
- try:
- f.write(contents_header)
- # special books
- f.write('<LI> ' + object_sitemap % (builder.config.html_short_title,
- 'index.html'))
- if builder.config.html_use_modindex:
- f.write('<LI> ' + object_sitemap % (_('Global Module Index'),
- 'modindex.html'))
- # the TOC
- tocdoc = builder.env.get_and_resolve_doctree(builder.config.master_doc, builder,
- prune_toctrees=False)
- def write_toc(node, ullevel=0):
- if isinstance(node, nodes.list_item):
- f.write('<LI> ')
- for subnode in node:
- write_toc(subnode, ullevel)
- elif isinstance(node, nodes.reference):
- link = node['refuri']
- title = cgi.escape(node.astext()).replace('"','&quot;')
- item = object_sitemap % (title, link)
- f.write(item.encode('ascii', 'xmlcharrefreplace'))
- elif isinstance(node, nodes.bullet_list):
- if ullevel != 0:
- f.write('<UL>\n')
- for subnode in node:
- write_toc(subnode, ullevel+1)
- if ullevel != 0:
- f.write('</UL>\n')
- elif isinstance(node, addnodes.compact_paragraph):
- for subnode in node:
- write_toc(subnode, ullevel)
- istoctree = lambda node: isinstance(node, addnodes.compact_paragraph) and \
- node.has_key('toctree')
- for node in tocdoc.traverse(istoctree):
- write_toc(node)
- f.write(contents_footer)
- finally:
- f.close()
-
- builder.info('writing index file...')
- index = builder.env.create_index(builder)
- f = open(path.join(outdir, outname+'.hhk'), 'w')
- try:
- f.write('<UL>\n')
- def write_index(title, refs, subitems):
- def write_param(name, value):
- item = ' <param name="%s" value="%s">\n' % (name, value)
- f.write(item.encode('ascii', 'xmlcharrefreplace'))
- title = cgi.escape(title)
- f.write('<LI> <OBJECT type="text/sitemap">\n')
- write_param('Keyword', title)
- if len(refs) == 0:
- write_param('See Also', title)
- elif len(refs) == 1:
- write_param('Local', refs[0])
- else:
- for i, ref in enumerate(refs):
- write_param('Name', '[%d] %s' % (i, ref)) # XXX: better title?
- write_param('Local', ref)
- f.write('</OBJECT>\n')
- if subitems:
- f.write('<UL> ')
- for subitem in subitems:
- write_index(subitem[0], subitem[1], [])
- f.write('</UL>')
- for (key, group) in index:
- for title, (refs, subitems) in group:
- write_index(title, refs, subitems)
- f.write('</UL>\n')
- finally:
- f.close()
diff --git a/sphinx/jinja2glue.py b/sphinx/jinja2glue.py
new file mode 100644
index 00000000..0c7c5d72
--- /dev/null
+++ b/sphinx/jinja2glue.py
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.jinja2glue
+ ~~~~~~~~~~~~~~~~~
+
+ Glue code for the jinja2 templating engine.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import codecs
+from os import path
+
+import jinja2
+
+from sphinx.util import mtimes_of_files
+from sphinx.application import TemplateBridge
+
+
+class SphinxLoader(jinja2.BaseLoader):
+ """
+ A jinja2 reimplementation of `sphinx._jinja.SphinxFileSystemLoader`.
+ """
+
+ def __init__(self, basepath, extpaths, encoding='utf-8'):
+ """
+ Create a new loader for sphinx.
+
+ *extpaths* is a list of directories, which provide additional templates
+ to sphinx.
+
+ *encoding* is used to decode the templates into unicode strings.
+ Defaults to utf-8.
+
+ If *basepath* is set, this path is used to load sphinx core templates.
+ If False, these templates are loaded from the sphinx package.
+ """
+ self.core_loader = jinja2.FileSystemLoader(basepath)
+ self.all_loaders = jinja2.ChoiceLoader(
+ [jinja2.FileSystemLoader(extpath) for extpath in extpaths] +
+ [self.core_loader])
+
+ def get_source(self, environment, template):
+ # exclamation mark forces loading from core
+ if template.startswith('!'):
+ return self.core_loader.get_source(environment, template[1:])
+ # check if the template is probably an absolute path
+ fs_path = template.replace('/', path.sep)
+ if path.isabs(fs_path):
+ if not path.exists(fs_path):
+ raise jinja2.TemplateNotFound(template)
+ f = codecs.open(fs_path, 'r', self.encoding)
+ try:
+ mtime = path.getmtime(path)
+ return (f.read(), fs_path,
+ lambda: mtime == path.getmtime(path))
+ finally:
+ f.close()
+ # finally try to load from custom templates
+ return self.all_loaders.get_source(environment, template)
+
+
+class BuiltinTemplates(TemplateBridge):
+ """
+ Interfaces the rendering environment of jinja2 for use in sphinx.
+ """
+
+ def init(self, builder):
+ base_templates_path = path.join(path.dirname(__file__), 'templates')
+ ext_templates_path = [path.join(builder.confdir, dir)
+ for dir in builder.config.templates_path]
+ self.templates_path = [base_templates_path] + ext_templates_path
+ loader = SphinxLoader(base_templates_path, ext_templates_path)
+ use_i18n = builder.translator is not None
+ extensions = use_i18n and ['jinja2.ext.i18n'] or []
+ self.environment = jinja2.Environment(loader=loader,
+ extensions=extensions)
+ if use_i18n:
+ self.environment.install_gettext_translations(builder.translator)
+
+ def render(self, template, context):
+ return self.environment.get_template(template).render(context)
+
+ def newest_template_mtime(self):
+ return max(mtimes_of_files(self.templates_path, '.html'))
diff --git a/sphinx/locale/cs/LC_MESSAGES/sphinx.js b/sphinx/locale/cs/LC_MESSAGES/sphinx.js
index 4b814e4f..0684899d 100644
--- a/sphinx/locale/cs/LC_MESSAGES/sphinx.js
+++ b/sphinx/locale/cs/LC_MESSAGES/sphinx.js
@@ -1 +1 @@
-Documentation.addTranslations({"locale": "cs", "plural_expr": "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)", "messages": {"module, in ": "modul", "Preparing search...": "", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "", "Search finished, found %s page(s) matching the search query.": "", ", in ": "", "Permalink to this headline": "Trval\u00fd odkaz na tento nadpis", "Searching": "hledej", "Permalink to this definition": "Trval\u00fd odkaz na tuto definici", "Hide Search Matches": "", "Search Results": "V\u00fdsledky hled\u00e1n\u00ed"}}); \ No newline at end of file
+Documentation.addTranslations({"locale": "cs", "plural_expr": "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)", "messages": {"module, in ": "modul, v", "Preparing search...": "Připravuji hledání...", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "Nenalezli jsme žádný dokument. Ujistěte se prosím, že všechna slova jsou správně.", "Search finished, found %s page(s) matching the search query.": "Vyhledávání skončilo, nalezeno %s stran.", ", in ": ", v", "Permalink to this headline": "Trvalý odkaz na tento nadpis", "Searching": "Hledám", "Permalink to this definition": "Trvalý odkaz na tuto definici", "Hide Search Matches": "Skrýt výsledky hledání", "Search Results": "Výsledky hledání"}});
diff --git a/sphinx/locale/cs/LC_MESSAGES/sphinx.mo b/sphinx/locale/cs/LC_MESSAGES/sphinx.mo
index c50de3db..fd97a57e 100644
--- a/sphinx/locale/cs/LC_MESSAGES/sphinx.mo
+++ b/sphinx/locale/cs/LC_MESSAGES/sphinx.mo
Binary files differ
diff --git a/sphinx/locale/cs/LC_MESSAGES/sphinx.po b/sphinx/locale/cs/LC_MESSAGES/sphinx.po
index b6936022..0d11dded 100644
--- a/sphinx/locale/cs/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/cs/LC_MESSAGES/sphinx.po
@@ -7,23 +7,25 @@ msgid ""
msgstr ""
"Project-Id-Version: Sphinx 0.5\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2008-08-10 11:43+0000\n"
-"PO-Revision-Date: 2008-11-27 18:40+0100\n"
+"POT-Creation-Date: 2008-11-27 18:39+0100\n"
+"PO-Revision-Date: 2008-12-25 05:59+0100\n"
"Last-Translator: Pavel Kosina <pavel.kosina@gmail.com>\n"
"Language-Team: Pavel Kosina <pavel.kosina@gmail.com>\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
-"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
"Generated-By: Babel 0.9.4\n"
+"X-Poedit-Language: Czech\n"
+"X-Poedit-Country: CZECH REPUBLIC\n"
#: sphinx/builder.py:408
#, python-format
msgid "%b %d, %Y"
msgstr "%d.%m.%Y"
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
+#: sphinx/builder.py:427
+#: sphinx/templates/defindex.html:21
msgid "General Index"
msgstr "Rejstřík indexů"
@@ -31,11 +33,13 @@ msgstr "Rejstřík indexů"
msgid "index"
msgstr "index"
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
+#: sphinx/builder.py:429
+#: sphinx/htmlhelp.py:156
+#: sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2
#: sphinx/templates/modindex.html:13
msgid "Global Module Index"
-msgstr "Rejstřík modulů"
+msgstr "Celkový rejstřík modulů"
#: sphinx/builder.py:429
msgid "modules"
@@ -51,45 +55,51 @@ msgstr "předchozí"
#: sphinx/builder.py:1054
msgid " (in "
-msgstr ""
+msgstr "(v"
#: sphinx/builder.py:1129
msgid "Builtins"
-msgstr "Vestavěné funkce"
+msgstr "Vestavěné funkce "
#: sphinx/builder.py:1131
msgid "Module level"
msgstr "Úroveň modulů"
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/environment.py:102
+#: sphinx/latexwriter.py:169
#, python-format
msgid "%B %d, %Y"
msgstr "%d.%m.%Y"
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
+#: sphinx/environment.py:291
+#: sphinx/latexwriter.py:175
#: sphinx/templates/genindex-single.html:2
#: sphinx/templates/genindex-split.html:2
-#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
-#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
+#: sphinx/templates/genindex-split.html:5
+#: sphinx/templates/genindex.html:2
+#: sphinx/templates/genindex.html:5
+#: sphinx/templates/genindex.html:48
#: sphinx/templates/layout.html:130
msgid "Index"
msgstr "Index"
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
-#, fuzzy
+#: sphinx/environment.py:292
+#: sphinx/latexwriter.py:174
msgid "Module Index"
-msgstr "Rejstřík modulů"
+msgstr "Rejstřík modulů "
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
-#, fuzzy
+#: sphinx/environment.py:293
+#: sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Vyhledávací stránka"
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
+#: sphinx/htmlwriter.py:79
+#: sphinx/static/doctools.js:145
msgid "Permalink to this definition"
msgstr "Trvalý odkaz na tuto definici"
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
+#: sphinx/htmlwriter.py:399
+#: sphinx/static/doctools.js:139
msgid "Permalink to this headline"
msgstr "Trvalý odkaz na tento nadpis"
@@ -97,7 +107,8 @@ msgstr "Trvalý odkaz na tento nadpis"
msgid "Release"
msgstr "Vydání"
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
+#: sphinx/roles.py:53
+#: sphinx/directives/desc.py:537
#, python-format
msgid "environment variable; %s"
msgstr "promměná prostředí, %s"
@@ -121,7 +132,8 @@ msgstr "[obrázek]"
msgid "%s() (built-in function)"
msgstr "%s() (vestavěná funkce)"
-#: sphinx/directives/desc.py:26 sphinx/directives/desc.py:42
+#: sphinx/directives/desc.py:26
+#: sphinx/directives/desc.py:42
#: sphinx/directives/desc.py:54
#, python-format
msgid "%s() (in module %s)"
@@ -132,15 +144,16 @@ msgstr "%s() (v modulu %s)"
msgid "%s (built-in variable)"
msgstr "%s() (vestavěná proměnná)"
-#: sphinx/directives/desc.py:30 sphinx/directives/desc.py:66
+#: sphinx/directives/desc.py:30
+#: sphinx/directives/desc.py:66
#, python-format
msgid "%s (in module %s)"
msgstr "%s() (v modulu %s)"
#: sphinx/directives/desc.py:33
-#, fuzzy, python-format
+#, python-format
msgid "%s (built-in class)"
-msgstr "%s() (vestavěná proměnná)"
+msgstr "%s () (vestavěná proměnná)"
#: sphinx/directives/desc.py:34
#, python-format
@@ -223,9 +236,9 @@ msgid "Parameters"
msgstr "Parametry"
#: sphinx/directives/desc.py:423
-#, fuzzy, python-format
+#, python-format
msgid "%scommand line option; %s"
-msgstr "%sparametry příkazového řádku; %s"
+msgstr "%s parametry příkazového řádku; %s"
#: sphinx/directives/other.py:101
msgid "Platforms: "
@@ -254,16 +267,16 @@ msgstr "Viz také"
#: sphinx/ext/todo.py:31
msgid "Todo"
-msgstr ""
+msgstr "Todo"
#: sphinx/ext/todo.py:75
#, python-format
msgid "(The original entry is located in %s, line %d and can be found "
-msgstr ""
+msgstr "(Původní záznam je v %s, řádka %d a lze jej nalézt"
#: sphinx/ext/todo.py:81
msgid "here"
-msgstr ""
+msgstr "zde"
#: sphinx/locale/__init__.py:15
msgid "Attention"
@@ -350,40 +363,37 @@ msgstr "vestavěná funkce"
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
-msgstr ""
+msgstr "Skrýt výsledky vyhledávání"
#: sphinx/static/searchtools.js:274
-#, fuzzy
msgid "Searching"
-msgstr "hledej"
+msgstr "Hledám"
#: sphinx/static/searchtools.js:279
msgid "Preparing search..."
-msgstr ""
+msgstr "Připravuji vyhledávání...."
#: sphinx/static/searchtools.js:338
-#, fuzzy
msgid "module, in "
-msgstr "modul"
+msgstr "modul, v"
#: sphinx/static/searchtools.js:347
msgid ", in "
-msgstr ""
+msgstr ", v"
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:447
+#: sphinx/templates/search.html:18
msgid "Search Results"
msgstr "Výsledky hledání"
#: sphinx/static/searchtools.js:449
-msgid ""
-"Your search did not match any documents. Please make sure that all words "
-"are spelled correctly and that you've selected enough categories."
-msgstr ""
+msgid "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
+msgstr "Nenalezli jsme žádný dokument. Ujistěte se prosím, že všechna slova jsou správně a že jste vybral dostatek kategorií."
#: sphinx/static/searchtools.js:451
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
-msgstr ""
+msgstr "Vyhledávání skončilo, nalezeno %s stran."
#: sphinx/templates/defindex.html:2
msgid "Overview"
@@ -420,7 +430,8 @@ msgstr "Index &ndash; %(key)s"
#: sphinx/templates/genindex-single.html:44
#: sphinx/templates/genindex-split.html:14
-#: sphinx/templates/genindex-split.html:27 sphinx/templates/genindex.html:54
+#: sphinx/templates/genindex-split.html:27
+#: sphinx/templates/genindex.html:54
msgid "Full index on one page"
msgstr "Plný index na jedné stránce"
@@ -464,7 +475,8 @@ msgstr "Tato stránka"
msgid "Suggest Change"
msgstr "Návrh změnu"
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:60
+#: sphinx/templates/layout.html:62
msgid "Show Source"
msgstr "Ukázat zdroj"
@@ -493,7 +505,8 @@ msgstr "Hledání uvnitř %(docstitle)s"
msgid "About these documents"
msgstr "O těchto dokumentech"
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:131
+#: sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Hledání"
@@ -515,16 +528,12 @@ msgstr "&copy; Copyright %(copyright)s."
#: sphinx/templates/layout.html:183
#, python-format
msgid "Last updated on %(last_updated)s."
-msgstr "Naposledy aktualizováno dne %(last_updated)s."
+msgstr "Aktualizováno dne %(last_updated)s."
#: sphinx/templates/layout.html:186
#, python-format
-msgid ""
-"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
-"%(sphinx_version)s."
-msgstr ""
-"Vytvořeno pomocí <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
-"%(sphinx_version)s."
+msgid "Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> %(sphinx_version)s."
+msgstr "Vytvořeno pomocí <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> %(sphinx_version)s."
#: sphinx/templates/modindex.html:15
msgid "Most popular modules:"
@@ -544,27 +553,18 @@ msgid "Search %(docstitle)s"
msgstr "Prohledat %(docstitle)s"
#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-"<strong>Poznámka:</strong> Stránka, kterou hledáte, "
-"neexistuje.<br>Snažili jsme se najít nové umístění této stránky, ale "
-"nepovedlo se."
+msgid "<strong>Note:</strong> You requested an out-of-date URL from this server. We've tried to redirect you to the new location of this page, but it may not be the right one."
+msgstr "<strong>Poznámka:</strong> Stránka, kterou hledáte, neexistuje.<br>Snažili jsme se najít nové umístění této stránky, ale nepovedlo se."
#: sphinx/templates/search.html:7
-#, fuzzy
msgid ""
"From here you can search these documents. Enter your search\n"
" words into the box below and click \"search\". Note that the search\n"
" function will automatically search for all of the words. Pages\n"
" containing fewer words won't appear in the result list."
msgstr ""
-"Toto je vyhledávací stránka. Zadejte klíčová slova do pole níže a "
-"klikněte na \"hledej\". \n"
-"Prohledávání funkcí hledá automaticky všechna slova. Stránky obsahující"
-" slov méně, nebudou nalezeny."
+"Toto je vyhledávací stránka. Zadejte klíčová slova a klikněte na \"hledej\". \n"
+"Vyhledávání hledá automaticky všechna slova. Nebudou tedy nalezeny stránky, obsahující méně slov."
#: sphinx/templates/search.html:14
msgid "search"
diff --git a/sphinx/locale/de/LC_MESSAGES/sphinx.po b/sphinx/locale/de/LC_MESSAGES/sphinx.po
index 5fdd4a96..2fac78d9 100644
--- a/sphinx/locale/de/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/de/LC_MESSAGES/sphinx.po
@@ -7,93 +7,37 @@ msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2008-08-07 21:40+0200\n"
-"PO-Revision-Date: 2008-11-27 18:40+0100\n"
+"PO-Revision-Date: 2008-12-28 23:40+0100\n"
"Last-Translator: Horst Gutmann <zerok@zerokspot.com>\n"
"Language-Team: de <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.4\n"
+"Generated-By: Babel 0.9.3\n"
-#: sphinx/builder.py:408
-#, python-format
-msgid "%b %d, %Y"
-msgstr "%d. %m. %Y"
-
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
-msgid "General Index"
-msgstr "Allgemeiner Index"
-
-#: sphinx/builder.py:427
-msgid "index"
-msgstr "Index"
-
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
-#: sphinx/templates/modindex.html:13
-msgid "Global Module Index"
-msgstr "Globaler Modulindex"
-
-#: sphinx/builder.py:429
-msgid "modules"
-msgstr "Module"
-
-#: sphinx/builder.py:466
-msgid "next"
-msgstr "weiter"
-
-#: sphinx/builder.py:473
-msgid "previous"
-msgstr "zurück"
-
-#: sphinx/builder.py:1054
-msgid " (in "
-msgstr ""
-
-#: sphinx/builder.py:1129
-msgid "Builtins"
-msgstr "Builtins"
-
-#: sphinx/builder.py:1131
-msgid "Module level"
-msgstr "Modulebene"
-
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%d. %m. %Y"
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
-#: sphinx/templates/genindex-single.html:2
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
#: sphinx/templates/genindex-split.html:2
#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
-#: sphinx/templates/layout.html:130
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Stichwortverzeichnis"
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Modulindex"
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Suche"
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
-msgid "Permalink to this definition"
-msgstr "Permalink zu dieser Definition"
-
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
-msgid "Permalink to this headline"
-msgstr "Permalink zu dieser Überschrift"
-
-#: sphinx/latexwriter.py:172
-msgid "Release"
-msgstr "Release"
-
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
#, python-format
msgid "environment variable; %s"
msgstr "Umgebungsvariable; %s"
@@ -103,14 +47,48 @@ msgstr "Umgebungsvariable; %s"
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
-#: sphinx/textwriter.py:166
+#: sphinx/builders/changes.py:64
+msgid "Builtins"
+msgstr "Builtins"
+
+#: sphinx/builders/changes.py:66
+msgid "Module level"
+msgstr "Modulebene"
+
+#: sphinx/builders/html.py:115
#, python-format
-msgid "Platform: %s"
-msgstr "Plattform: %s"
+msgid "%b %d, %Y"
+msgstr "%d. %m. %Y"
-#: sphinx/textwriter.py:422
-msgid "[image]"
-msgstr "[Bild]"
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
+msgstr "Allgemeiner Index"
+
+#: sphinx/builders/html.py:134
+msgid "index"
+msgstr "Index"
+
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
+msgstr "Globaler Modulindex"
+
+#: sphinx/builders/html.py:136
+msgid "modules"
+msgstr "Module"
+
+#: sphinx/builders/html.py:175
+msgid "next"
+msgstr "weiter"
+
+#: sphinx/builders/html.py:182
+msgid "previous"
+msgstr "zurück"
+
+#: sphinx/builders/latex.py:155
+msgid " (in "
+msgstr ""
#: sphinx/directives/desc.py:25
#, python-format
@@ -214,11 +192,16 @@ msgstr "Rückgabe"
msgid "Return type"
msgstr "Rückgabetyp"
-#: sphinx/directives/desc.py:143
+#: sphinx/directives/desc.py:201
+#, fuzzy
+msgid "Parameter"
+msgstr "Parameter"
+
+#: sphinx/directives/desc.py:205
msgid "Parameters"
msgstr "Parameter"
-#: sphinx/directives/desc.py:423
+#: sphinx/directives/desc.py:450
#, python-format
msgid "%scommand line option; %s"
msgstr "%sKommandozeilenoption; %s"
@@ -244,10 +227,15 @@ msgstr "Autor des Moduls: "
msgid "Author: "
msgstr "Autor: "
-#: sphinx/directives/other.py:246
+#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Siehe auch"
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr ""
@@ -344,6 +332,14 @@ msgstr "Statement"
msgid "built-in function"
msgstr "eingebaute Funktion"
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr "Permalink zu dieser Überschrift"
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr "Permalink zu dieser Definition"
+
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
msgstr "Suchergebnisse ausblenden"
@@ -364,11 +360,11 @@ msgstr "Modul, in "
msgid ", in "
msgstr ""
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
msgid "Search Results"
msgstr "Suchergebnisse"
-#: sphinx/static/searchtools.js:449
+#: sphinx/static/searchtools.js:455
msgid ""
"Your search did not match any documents. Please make sure that all words "
"are spelled correctly and that you've selected enough categories."
@@ -376,7 +372,7 @@ msgstr ""
"Es wurden keine Dokumente gefunden. Haben Sie alle Suchworte richtig "
"geschrieben und genügend Kategorien ausgewählt?"
-#: sphinx/static/searchtools.js:451
+#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr "Suche beendet, %s Seite(n) mit Ergebnissen wurden gefunden."
@@ -452,68 +448,61 @@ msgstr "Nächstes Thema"
msgid "next chapter"
msgstr "nächstes Kapitel"
-#: sphinx/templates/layout.html:55
+#: sphinx/templates/layout.html:56
msgid "This Page"
msgstr "Diese Seite"
-#: sphinx/templates/layout.html:59
-msgid "Suggest Change"
-msgstr "Änderung vorschlagen"
-
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:58
msgid "Show Source"
msgstr "Quelltext anzeigen"
-#: sphinx/templates/layout.html:71
+#: sphinx/templates/layout.html:67
msgid "Quick search"
msgstr "Schnellsuche"
-#: sphinx/templates/layout.html:71
-msgid "Keyword search"
-msgstr "Stichwortsuche"
-
-#: sphinx/templates/layout.html:73
+#: sphinx/templates/layout.html:69
msgid "Go"
msgstr "Los"
-#: sphinx/templates/layout.html:78
-msgid "Enter a module, class or function name."
+#: sphinx/templates/layout.html:73
+#, fuzzy
+msgid "Enter search terms or a module, class or function name."
msgstr "Gib einen Modul-, Klassen- oder Funktionsnamen an."
-#: sphinx/templates/layout.html:119
+#: sphinx/templates/layout.html:106
#, python-format
msgid "Search within %(docstitle)s"
msgstr "Suche in %(docstitle)s"
-#: sphinx/templates/layout.html:128
+#: sphinx/templates/layout.html:115
msgid "About these documents"
msgstr "Über diese Dokumentation"
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Suche"
-#: sphinx/templates/layout.html:133
+#: sphinx/templates/layout.html:120
msgid "Copyright"
msgstr "Copyright"
-#: sphinx/templates/layout.html:178
+#: sphinx/templates/layout.html:165
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
-#: sphinx/templates/layout.html:180
+#: sphinx/templates/layout.html:167
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Copyright %(copyright)s."
-#: sphinx/templates/layout.html:183
+#: sphinx/templates/layout.html:170
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr "Zuletzt aktualisiert am %(last_updated)s."
-#: sphinx/templates/layout.html:186
+#: sphinx/templates/layout.html:173
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
@@ -522,15 +511,7 @@ msgstr ""
"Mit <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> %(sphinx_version)s "
"erstellt."
-#: sphinx/templates/modindex.html:15
-msgid "Most popular modules:"
-msgstr "Beliebteste Module:"
-
-#: sphinx/templates/modindex.html:24
-msgid "Show modules only available on these platforms"
-msgstr "Zeige nur Module, die auf diesen Plattformen verfügbar sind"
-
-#: sphinx/templates/modindex.html:56
+#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "Veraltet"
@@ -539,16 +520,6 @@ msgstr "Veraltet"
msgid "Search %(docstitle)s"
msgstr "Suche in %(docstitle)s"
-#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-"<strong>Anmerkung:</strong> Du hast eine nicht länger gültige URL von "
-"diesem Server angefragt. Wir haben versucht dich auf die neue Adresse "
-"dieser Seite umzuleiten, aber dies muss nicht die richtige Seite sein."
-
#: sphinx/templates/search.html:7
#, fuzzy
msgid ""
@@ -599,3 +570,42 @@ msgstr "C API-Änderungen"
msgid "Other changes"
msgstr "Andere Änderungen"
+#: sphinx/writers/latex.py:173
+msgid "Release"
+msgstr "Release"
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr "Plattform: %s"
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr "[Bild]"
+
+#~ msgid "Suggest Change"
+#~ msgstr "Änderung vorschlagen"
+
+#~ msgid "Keyword search"
+#~ msgstr "Stichwortsuche"
+
+#~ msgid "Most popular modules:"
+#~ msgstr "Beliebteste Module:"
+
+#~ msgid "Show modules only available on these platforms"
+#~ msgstr "Zeige nur Module, die auf diesen Plattformen verfügbar sind"
+
+#~ msgid ""
+#~ "<strong>Note:</strong> You requested an "
+#~ "out-of-date URL from this server. "
+#~ "We've tried to redirect you to the"
+#~ " new location of this page, but "
+#~ "it may not be the right one."
+#~ msgstr ""
+#~ "<strong>Anmerkung:</strong> Du hast eine nicht"
+#~ " länger gültige URL von diesem Server"
+#~ " angefragt. Wir haben versucht dich "
+#~ "auf die neue Adresse dieser Seite "
+#~ "umzuleiten, aber dies muss nicht die "
+#~ "richtige Seite sein."
+
diff --git a/sphinx/locale/es/LC_MESSAGES/sphinx.po b/sphinx/locale/es/LC_MESSAGES/sphinx.po
index 288e0090..f50a34cc 100644
--- a/sphinx/locale/es/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/es/LC_MESSAGES/sphinx.po
@@ -8,96 +8,37 @@ msgstr ""
"Project-Id-Version: Sphinx 0.5\n"
"Report-Msgid-Bugs-To: guillem@torroja.dmt.upm.es\n"
"POT-Creation-Date: 2008-09-11 23:58+0200\n"
-"PO-Revision-Date: 2008-11-27 18:40+0100\n"
+"PO-Revision-Date: 2008-12-28 23:40+0100\n"
"Last-Translator: Guillem Borrell <guillem@torroja.dmt.upm.es>\n"
"Language-Team: es <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.4\n"
+"Generated-By: Babel 0.9.3\n"
-#: sphinx/builder.py:408
-#, python-format
-msgid "%b %d, %Y"
-msgstr "%d %b, %Y"
-
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
-msgid "General Index"
-msgstr "Índice General"
-
-#: sphinx/builder.py:427
-msgid "index"
-msgstr "índice"
-
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
-#: sphinx/templates/modindex.html:13
-msgid "Global Module Index"
-msgstr "Índice Global de Módulos"
-
-#: sphinx/builder.py:429
-msgid "modules"
-msgstr "módulos"
-
-#: sphinx/builder.py:466
-msgid "next"
-msgstr "siguiente"
-
-#: sphinx/builder.py:473
-msgid "previous"
-msgstr "anterior"
-
-#: sphinx/builder.py:1054
-msgid " (in "
-msgstr ""
-
-#: sphinx/builder.py:1129
-#, fuzzy
-msgid "Builtins"
-msgstr "Funciones de base"
-
-#: sphinx/builder.py:1131
-#, fuzzy
-msgid "Module level"
-msgstr "Módulos"
-
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
#, fuzzy, python-format
msgid "%B %d, %Y"
msgstr "%d de %B de %Y"
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
-#: sphinx/templates/genindex-single.html:2
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
#: sphinx/templates/genindex-split.html:2
#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
-#: sphinx/templates/layout.html:130
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Índice"
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Índice de Módulos"
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Página de Búsqueda"
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
-msgid "Permalink to this definition"
-msgstr "Enlazar permanentemente con esta definición"
-
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
-msgid "Permalink to this headline"
-msgstr "Enlazar permanentemente con este título"
-
-#: sphinx/latexwriter.py:172
-#, fuzzy
-msgid "Release"
-msgstr "Versión"
-
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
#, python-format
msgid "environment variable; %s"
msgstr "variables de entorno; %s"
@@ -107,14 +48,50 @@ msgstr "variables de entorno; %s"
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
-#: sphinx/textwriter.py:166
+#: sphinx/builders/changes.py:64
+#, fuzzy
+msgid "Builtins"
+msgstr "Funciones de base"
+
+#: sphinx/builders/changes.py:66
+#, fuzzy
+msgid "Module level"
+msgstr "Módulos"
+
+#: sphinx/builders/html.py:115
#, python-format
-msgid "Platform: %s"
-msgstr "Plataforma: %s"
+msgid "%b %d, %Y"
+msgstr "%d %b, %Y"
-#: sphinx/textwriter.py:422
-msgid "[image]"
-msgstr "[imagen]"
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
+msgstr "Índice General"
+
+#: sphinx/builders/html.py:134
+msgid "index"
+msgstr "índice"
+
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
+msgstr "Índice Global de Módulos"
+
+#: sphinx/builders/html.py:136
+msgid "modules"
+msgstr "módulos"
+
+#: sphinx/builders/html.py:175
+msgid "next"
+msgstr "siguiente"
+
+#: sphinx/builders/html.py:182
+msgid "previous"
+msgstr "anterior"
+
+#: sphinx/builders/latex.py:155
+msgid " (in "
+msgstr ""
#: sphinx/directives/desc.py:25
#, fuzzy, python-format
@@ -219,11 +196,16 @@ msgstr "Devuelve"
msgid "Return type"
msgstr "Tipo del argumento devuelto"
-#: sphinx/directives/desc.py:143
+#: sphinx/directives/desc.py:201
+#, fuzzy
+msgid "Parameter"
+msgstr "Parámetros"
+
+#: sphinx/directives/desc.py:205
msgid "Parameters"
msgstr "Parámetros"
-#: sphinx/directives/desc.py:423
+#: sphinx/directives/desc.py:450
#, fuzzy, python-format
msgid "%scommand line option; %s"
msgstr "%sOpciones en línea de comandos; %s"
@@ -249,10 +231,15 @@ msgstr "Autor del módulo"
msgid "Author: "
msgstr "Autor:"
-#: sphinx/directives/other.py:246
+#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Ver también"
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr ""
@@ -350,6 +337,14 @@ msgstr "sentencia"
msgid "built-in function"
msgstr "función de base"
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr "Enlazar permanentemente con este título"
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr "Enlazar permanentemente con esta definición"
+
#: sphinx/static/doctools.js:174
#, fuzzy
msgid "Hide Search Matches"
@@ -372,11 +367,11 @@ msgstr "módulo"
msgid ", in "
msgstr ""
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
msgid "Search Results"
msgstr "Resultados de la búsqueda"
-#: sphinx/static/searchtools.js:449
+#: sphinx/static/searchtools.js:455
msgid ""
"Your search did not match any documents. Please make sure that all words "
"are spelled correctly and that you've selected enough categories."
@@ -385,7 +380,7 @@ msgstr ""
"todas las palabras correctamente y que ha seleccionado suficientes "
"categorías"
-#: sphinx/static/searchtools.js:451
+#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr ""
@@ -463,68 +458,61 @@ msgstr "Próximo tema"
msgid "next chapter"
msgstr "Próximo capítulo"
-#: sphinx/templates/layout.html:55
+#: sphinx/templates/layout.html:56
msgid "This Page"
msgstr "Esta página"
-#: sphinx/templates/layout.html:59
-msgid "Suggest Change"
-msgstr "Sugerir una modificación"
-
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:58
msgid "Show Source"
msgstr "Enseñar el código"
-#: sphinx/templates/layout.html:71
+#: sphinx/templates/layout.html:67
msgid "Quick search"
msgstr "Búsqueda rápida"
-#: sphinx/templates/layout.html:71
-msgid "Keyword search"
-msgstr "Búsqueda por palabras clave"
-
-#: sphinx/templates/layout.html:73
+#: sphinx/templates/layout.html:69
msgid "Go"
msgstr "Ir a"
-#: sphinx/templates/layout.html:78
-msgid "Enter a module, class or function name."
+#: sphinx/templates/layout.html:73
+#, fuzzy
+msgid "Enter search terms or a module, class or function name."
msgstr "Introducir en nombre de un módulo, clase o función"
-#: sphinx/templates/layout.html:119
+#: sphinx/templates/layout.html:106
#, python-format
msgid "Search within %(docstitle)s"
msgstr "Buscar en %(docstitle)s"
-#: sphinx/templates/layout.html:128
+#: sphinx/templates/layout.html:115
msgid "About these documents"
msgstr "Sobre este documento"
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Búsqueda"
-#: sphinx/templates/layout.html:133
+#: sphinx/templates/layout.html:120
msgid "Copyright"
msgstr "Copyright"
-#: sphinx/templates/layout.html:178
+#: sphinx/templates/layout.html:165
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr "&copy; <a href=\\\"%(path)s\\\">Copyright</a> %(copyright)s."
-#: sphinx/templates/layout.html:180
+#: sphinx/templates/layout.html:167
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Copyright %(copyright)s."
-#: sphinx/templates/layout.html:183
+#: sphinx/templates/layout.html:170
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr "Actualizado por última vez en %(last_updated)s."
-#: sphinx/templates/layout.html:186
+#: sphinx/templates/layout.html:173
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
@@ -533,15 +521,7 @@ msgstr ""
"Creado con <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s."
-#: sphinx/templates/modindex.html:15
-msgid "Most popular modules:"
-msgstr "Módulos más comunes:"
-
-#: sphinx/templates/modindex.html:24
-msgid "Show modules only available on these platforms"
-msgstr "Mostrar sólo los módulos disponibles en estas plataformas"
-
-#: sphinx/templates/modindex.html:56
+#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "Obsoleto"
@@ -550,16 +530,6 @@ msgstr "Obsoleto"
msgid "Search %(docstitle)s"
msgstr "Buscar en %(docstitle)s"
-#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-"<strong>Nota:</strong> Has solicitado una dirección desactualizada a este"
-" servidor. Hemos intentado redirigirte a la nueva dirección de la misma "
-"página pero puede no ser la correcta."
-
#: sphinx/templates/search.html:7
#, fuzzy
msgid ""
@@ -609,3 +579,42 @@ msgstr "Cambios en la API C"
msgid "Other changes"
msgstr "Otros cambios"
+#: sphinx/writers/latex.py:173
+#, fuzzy
+msgid "Release"
+msgstr "Versión"
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr "Plataforma: %s"
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr "[imagen]"
+
+#~ msgid "Suggest Change"
+#~ msgstr "Sugerir una modificación"
+
+#~ msgid "Keyword search"
+#~ msgstr "Búsqueda por palabras clave"
+
+#~ msgid "Most popular modules:"
+#~ msgstr "Módulos más comunes:"
+
+#~ msgid "Show modules only available on these platforms"
+#~ msgstr "Mostrar sólo los módulos disponibles en estas plataformas"
+
+#~ msgid ""
+#~ "<strong>Note:</strong> You requested an "
+#~ "out-of-date URL from this server. "
+#~ "We've tried to redirect you to the"
+#~ " new location of this page, but "
+#~ "it may not be the right one."
+#~ msgstr ""
+#~ "<strong>Nota:</strong> Has solicitado una "
+#~ "dirección desactualizada a este servidor. "
+#~ "Hemos intentado redirigirte a la nueva"
+#~ " dirección de la misma página pero"
+#~ " puede no ser la correcta."
+
diff --git a/sphinx/locale/fr/LC_MESSAGES/sphinx.po b/sphinx/locale/fr/LC_MESSAGES/sphinx.po
index 0d92cc35..c715e626 100644
--- a/sphinx/locale/fr/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/fr/LC_MESSAGES/sphinx.po
@@ -9,93 +9,37 @@ msgstr ""
"Project-Id-Version: Sphinx 0.5\n"
"Report-Msgid-Bugs-To: larlet@gmail.com\n"
"POT-Creation-Date: 2008-08-08 12:39+0000\n"
-"PO-Revision-Date: 2008-11-27 18:40+0100\n"
+"PO-Revision-Date: 2008-12-28 23:40+0100\n"
"Last-Translator: Sébastien Douche <sdouche@gmail.com>\n"
"Language-Team: French Translation Team <sphinx-dev@googlegroups.com>\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.4\n"
+"Generated-By: Babel 0.9.3\n"
-#: sphinx/builder.py:408
-#, python-format
-msgid "%b %d, %Y"
-msgstr "%d %b %Y"
-
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
-msgid "General Index"
-msgstr "Index général"
-
-#: sphinx/builder.py:427
-msgid "index"
-msgstr "index"
-
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
-#: sphinx/templates/modindex.html:13
-msgid "Global Module Index"
-msgstr "Index général des modules"
-
-#: sphinx/builder.py:429
-msgid "modules"
-msgstr "modules"
-
-#: sphinx/builder.py:466
-msgid "next"
-msgstr "suivant"
-
-#: sphinx/builder.py:473
-msgid "previous"
-msgstr "précédent"
-
-#: sphinx/builder.py:1054
-msgid " (in "
-msgstr "(dans"
-
-#: sphinx/builder.py:1129
-msgid "Builtins"
-msgstr "Fonctions de base"
-
-#: sphinx/builder.py:1131
-msgid "Module level"
-msgstr "Module"
-
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%d %B %Y"
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
-#: sphinx/templates/genindex-single.html:2
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
#: sphinx/templates/genindex-split.html:2
#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
-#: sphinx/templates/layout.html:130
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Index"
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Index du module"
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Page de recherche"
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
-msgid "Permalink to this definition"
-msgstr "Lien permanent vers cette définition"
-
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
-msgid "Permalink to this headline"
-msgstr "Lien permanent vers ce titre"
-
-#: sphinx/latexwriter.py:172
-msgid "Release"
-msgstr "Version"
-
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
#, python-format
msgid "environment variable; %s"
msgstr "variable d'environnement; %s"
@@ -105,14 +49,48 @@ msgstr "variable d'environnement; %s"
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
-#: sphinx/textwriter.py:166
+#: sphinx/builders/changes.py:64
+msgid "Builtins"
+msgstr "Fonctions de base"
+
+#: sphinx/builders/changes.py:66
+msgid "Module level"
+msgstr "Module"
+
+#: sphinx/builders/html.py:115
#, python-format
-msgid "Platform: %s"
-msgstr "Plateforme : %s"
+msgid "%b %d, %Y"
+msgstr "%d %b %Y"
-#: sphinx/textwriter.py:422
-msgid "[image]"
-msgstr "[image]"
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
+msgstr "Index général"
+
+#: sphinx/builders/html.py:134
+msgid "index"
+msgstr "index"
+
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
+msgstr "Index général des modules"
+
+#: sphinx/builders/html.py:136
+msgid "modules"
+msgstr "modules"
+
+#: sphinx/builders/html.py:175
+msgid "next"
+msgstr "suivant"
+
+#: sphinx/builders/html.py:182
+msgid "previous"
+msgstr "précédent"
+
+#: sphinx/builders/latex.py:155
+msgid " (in "
+msgstr "(dans"
#: sphinx/directives/desc.py:25
#, python-format
@@ -216,11 +194,16 @@ msgstr "Retourne"
msgid "Return type"
msgstr "Type retourné"
-#: sphinx/directives/desc.py:143
+#: sphinx/directives/desc.py:201
+#, fuzzy
+msgid "Parameter"
+msgstr "Paramètres"
+
+#: sphinx/directives/desc.py:205
msgid "Parameters"
msgstr "Paramètres"
-#: sphinx/directives/desc.py:423
+#: sphinx/directives/desc.py:450
#, python-format
msgid "%scommand line option; %s"
msgstr "%soption de ligne de commande; %s"
@@ -246,10 +229,15 @@ msgstr "Auteur du module : "
msgid "Author: "
msgstr "Auteur : "
-#: sphinx/directives/other.py:246
+#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Voir aussi"
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr "A faire"
@@ -346,6 +334,14 @@ msgstr "état"
msgid "built-in function"
msgstr "fonction de base"
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr "Lien permanent vers ce titre"
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr "Lien permanent vers cette définition"
+
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
msgstr "Cacher les résultats de la recherche"
@@ -366,11 +362,11 @@ msgstr "module, dans"
msgid ", in "
msgstr ", dans"
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
msgid "Search Results"
msgstr "Résultats de la recherche"
-#: sphinx/static/searchtools.js:449
+#: sphinx/static/searchtools.js:455
msgid ""
"Your search did not match any documents. Please make sure that all words "
"are spelled correctly and that you've selected enough categories."
@@ -379,7 +375,7 @@ msgstr ""
"des termes de recherche et que vous avez sélectionné suffisamment de "
"catégories."
-#: sphinx/static/searchtools.js:451
+#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr "La recherche est terminée, %s page(s) correspond(ent) à la requête."
@@ -455,68 +451,61 @@ msgstr "Sujet suivant"
msgid "next chapter"
msgstr "Chapitre suivant"
-#: sphinx/templates/layout.html:55
+#: sphinx/templates/layout.html:56
msgid "This Page"
msgstr "Cette page"
-#: sphinx/templates/layout.html:59
-msgid "Suggest Change"
-msgstr "Suggérer une modification"
-
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:58
msgid "Show Source"
msgstr "Montrer la source"
-#: sphinx/templates/layout.html:71
+#: sphinx/templates/layout.html:67
msgid "Quick search"
msgstr "Recherche rapide"
-#: sphinx/templates/layout.html:71
-msgid "Keyword search"
-msgstr "Recherche par mot-clé"
-
-#: sphinx/templates/layout.html:73
+#: sphinx/templates/layout.html:69
msgid "Go"
msgstr "Go"
-#: sphinx/templates/layout.html:78
-msgid "Enter a module, class or function name."
+#: sphinx/templates/layout.html:73
+#, fuzzy
+msgid "Enter search terms or a module, class or function name."
msgstr "Saisissez un nom de module, classe ou fonction."
-#: sphinx/templates/layout.html:119
+#: sphinx/templates/layout.html:106
#, python-format
msgid "Search within %(docstitle)s"
msgstr "Recherchez dans %(docstitle)s"
-#: sphinx/templates/layout.html:128
+#: sphinx/templates/layout.html:115
msgid "About these documents"
msgstr "À propos de ces documents"
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Recherche"
-#: sphinx/templates/layout.html:133
+#: sphinx/templates/layout.html:120
msgid "Copyright"
msgstr "Copyright"
-#: sphinx/templates/layout.html:178
+#: sphinx/templates/layout.html:165
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
-#: sphinx/templates/layout.html:180
+#: sphinx/templates/layout.html:167
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Copyright %(copyright)s."
-#: sphinx/templates/layout.html:183
+#: sphinx/templates/layout.html:170
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr "Mis à jour le %(last_updated)s."
-#: sphinx/templates/layout.html:186
+#: sphinx/templates/layout.html:173
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
@@ -525,15 +514,7 @@ msgstr ""
"Créé avec <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s."
-#: sphinx/templates/modindex.html:15
-msgid "Most popular modules:"
-msgstr "Modules les plus utilisés :"
-
-#: sphinx/templates/modindex.html:24
-msgid "Show modules only available on these platforms"
-msgstr "N'afficher que les modules disponibles sur ces plateformes"
-
-#: sphinx/templates/modindex.html:56
+#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "Obsolète"
@@ -542,16 +523,6 @@ msgstr "Obsolète"
msgid "Search %(docstitle)s"
msgstr "Rechercher %(docstitle)s"
-#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-"<strong>Note :</strong> Vous tentez d'accéder à une ancienne URL de ce "
-"serveur. Nous avons essayé de vous rediriger vers la nouvelle adresse de "
-"cette page, mais ce n'est peut-être pas la bonne."
-
#: sphinx/templates/search.html:7
#, fuzzy
msgid ""
@@ -604,3 +575,42 @@ msgstr "Modifications de l'API C"
msgid "Other changes"
msgstr "Autres modifications"
+#: sphinx/writers/latex.py:173
+msgid "Release"
+msgstr "Version"
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr "Plateforme : %s"
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr "[image]"
+
+#~ msgid "Suggest Change"
+#~ msgstr "Suggérer une modification"
+
+#~ msgid "Keyword search"
+#~ msgstr "Recherche par mot-clé"
+
+#~ msgid "Most popular modules:"
+#~ msgstr "Modules les plus utilisés :"
+
+#~ msgid "Show modules only available on these platforms"
+#~ msgstr "N'afficher que les modules disponibles sur ces plateformes"
+
+#~ msgid ""
+#~ "<strong>Note:</strong> You requested an "
+#~ "out-of-date URL from this server. "
+#~ "We've tried to redirect you to the"
+#~ " new location of this page, but "
+#~ "it may not be the right one."
+#~ msgstr ""
+#~ "<strong>Note :</strong> Vous tentez d'accéder"
+#~ " à une ancienne URL de ce "
+#~ "serveur. Nous avons essayé de vous "
+#~ "rediriger vers la nouvelle adresse de"
+#~ " cette page, mais ce n'est peut-être"
+#~ " pas la bonne."
+
diff --git a/sphinx/locale/it/LC_MESSAGES/sphinx.js b/sphinx/locale/it/LC_MESSAGES/sphinx.js
new file mode 100644
index 00000000..c2c8be7b
--- /dev/null
+++ b/sphinx/locale/it/LC_MESSAGES/sphinx.js
@@ -0,0 +1 @@
+Documentation.addTranslations({"locale": "it", "plural_expr": "(n != 1)", "messages": {"module, in ": "modulo, in", "Preparing search...": "Preparazione della ricerca", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "La tua ricerca non ha trovato alcun risultato. Controlla la corettezzadei termini di ricerca e di avere selezionato un numero sufficiente di categorie", "Search finished, found %s page(s) matching the search query.": "Ricera terminata, trovate %s pagine corrispondenti alla ricerca.", ", in ": ", in ", "Permalink to this headline": "link permanente per questa inestazione", "Searching": "Ricerca in corso", "Permalink to this definition": "link permanente per questa definizione", "Hide Search Matches": "Nascondi i risultati della ricerca", "Search Results": "Risultati della ricerca"}}); \ No newline at end of file
diff --git a/sphinx/locale/it/LC_MESSAGES/sphinx.mo b/sphinx/locale/it/LC_MESSAGES/sphinx.mo
new file mode 100644
index 00000000..7818e876
--- /dev/null
+++ b/sphinx/locale/it/LC_MESSAGES/sphinx.mo
Binary files differ
diff --git a/sphinx/locale/it/LC_MESSAGES/sphinx.po b/sphinx/locale/it/LC_MESSAGES/sphinx.po
new file mode 100644
index 00000000..4545f4a8
--- /dev/null
+++ b/sphinx/locale/it/LC_MESSAGES/sphinx.po
@@ -0,0 +1,612 @@
+# Italian translations for Sphinx.
+# Copyright (C) 2008 ORGANIZATION
+# This file is distributed under the same license as the Sphinx project.
+# Sandro Dentella <sandro@e-den.it>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Sphinx 0.5\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2008-11-27 18:39+0100\n"
+"PO-Revision-Date: 2008-12-28 23:40+0100\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: it <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.3\n"
+
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
+#, python-format
+msgid "%B %d, %Y"
+msgstr "%d %B %Y"
+
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
+#: sphinx/templates/genindex-split.html:2
+#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
+#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
+msgid "Index"
+msgstr "Indice"
+
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
+msgid "Module Index"
+msgstr "Indice dei Moduli"
+
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
+msgid "Search Page"
+msgstr "Cerca"
+
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
+#, python-format
+msgid "environment variable; %s"
+msgstr "variabile dámbiente, %s"
+
+#: sphinx/roles.py:60
+#, python-format
+msgid "Python Enhancement Proposals!PEP %s"
+msgstr "Python Enhancement Proposals!PEP %s"
+
+#: sphinx/builders/changes.py:64
+msgid "Builtins"
+msgstr "Builtin"
+
+#: sphinx/builders/changes.py:66
+msgid "Module level"
+msgstr "Modulo"
+
+#: sphinx/builders/html.py:115
+#, python-format
+msgid "%b %d, %Y"
+msgstr "%d/%b/%Y"
+
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
+msgstr "Indice generale"
+
+#: sphinx/builders/html.py:134
+msgid "index"
+msgstr "indice"
+
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
+msgstr "Indice dei moduli"
+
+#: sphinx/builders/html.py:136
+msgid "modules"
+msgstr "moduli"
+
+#: sphinx/builders/html.py:175
+msgid "next"
+msgstr "successivo"
+
+#: sphinx/builders/html.py:182
+msgid "previous"
+msgstr "precedente"
+
+#: sphinx/builders/latex.py:155
+msgid " (in "
+msgstr " (in "
+
+#: sphinx/directives/desc.py:25
+#, python-format
+msgid "%s() (built-in function)"
+msgstr "%s() (funzione built-in)"
+
+#: sphinx/directives/desc.py:26 sphinx/directives/desc.py:42
+#: sphinx/directives/desc.py:54
+#, python-format
+msgid "%s() (in module %s)"
+msgstr "%s() (nel modulo %s)"
+
+#: sphinx/directives/desc.py:29
+#, python-format
+msgid "%s (built-in variable)"
+msgstr "%s (variabile built-in)"
+
+#: sphinx/directives/desc.py:30 sphinx/directives/desc.py:66
+#, python-format
+msgid "%s (in module %s)"
+msgstr "%s (nel modulo %s)"
+
+#: sphinx/directives/desc.py:33
+#, python-format
+msgid "%s (built-in class)"
+msgstr "%s (classe built-in)"
+
+#: sphinx/directives/desc.py:34
+#, python-format
+msgid "%s (class in %s)"
+msgstr "%s (classe in %s)"
+
+#: sphinx/directives/desc.py:46
+#, python-format
+msgid "%s() (%s.%s method)"
+msgstr "%s() (%s.%s metodo)"
+
+#: sphinx/directives/desc.py:48
+#, python-format
+msgid "%s() (%s method)"
+msgstr "%s() (%s metodo)"
+
+#: sphinx/directives/desc.py:58
+#, python-format
+msgid "%s() (%s.%s static method)"
+msgstr "%s() (%s.%s metodo statico)"
+
+#: sphinx/directives/desc.py:60
+#, python-format
+msgid "%s() (%s static method)"
+msgstr "%s() (%s metodo statico)"
+
+#: sphinx/directives/desc.py:70
+#, python-format
+msgid "%s (%s.%s attribute)"
+msgstr "%s (%s.%s attributo)"
+
+#: sphinx/directives/desc.py:72
+#, python-format
+msgid "%s (%s attribute)"
+msgstr "%s (%s attributo)"
+
+#: sphinx/directives/desc.py:74
+#, python-format
+msgid "%s (C function)"
+msgstr "%s (functione C)"
+
+#: sphinx/directives/desc.py:76
+#, python-format
+msgid "%s (C member)"
+msgstr "%s (membro C )"
+
+#: sphinx/directives/desc.py:78
+#, python-format
+msgid "%s (C macro)"
+msgstr "%s (macro C)"
+
+#: sphinx/directives/desc.py:80
+#, python-format
+msgid "%s (C type)"
+msgstr "%s (tipo C)"
+
+#: sphinx/directives/desc.py:82
+#, python-format
+msgid "%s (C variable)"
+msgstr "%s (variabile C)"
+
+#: sphinx/directives/desc.py:100
+msgid "Raises"
+msgstr "Solleva"
+
+#: sphinx/directives/desc.py:104
+msgid "Variable"
+msgstr "Variabile"
+
+#: sphinx/directives/desc.py:107
+msgid "Returns"
+msgstr "Ritorna"
+
+#: sphinx/directives/desc.py:116
+msgid "Return type"
+msgstr "Tipo di ritorno"
+
+#: sphinx/directives/desc.py:201
+#, fuzzy
+msgid "Parameter"
+msgstr "Parametri"
+
+#: sphinx/directives/desc.py:205
+msgid "Parameters"
+msgstr "Parametri"
+
+#: sphinx/directives/desc.py:450
+#, python-format
+msgid "%scommand line option; %s"
+msgstr "%sopzione di linea di comando; %s"
+
+#: sphinx/directives/other.py:101
+msgid "Platforms: "
+msgstr "Piattaforme:"
+
+#: sphinx/directives/other.py:106
+#, python-format
+msgid "%s (module)"
+msgstr "%s (modulo)"
+
+#: sphinx/directives/other.py:146
+msgid "Section author: "
+msgstr "Autore della sezione"
+
+#: sphinx/directives/other.py:148
+msgid "Module author: "
+msgstr "Autore del modulo"
+
+#: sphinx/directives/other.py:150
+msgid "Author: "
+msgstr "Autore: "
+
+#: sphinx/directives/other.py:249
+msgid "See also"
+msgstr "Vedi anche"
+
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
+#: sphinx/ext/todo.py:31
+msgid "Todo"
+msgstr "Da fare"
+
+#: sphinx/ext/todo.py:75
+#, python-format
+msgid "(The original entry is located in %s, line %d and can be found "
+msgstr "(La riga originale si trova in %s, linea %d e può essere trovata "
+
+#: sphinx/ext/todo.py:81
+msgid "here"
+msgstr "qui"
+
+#: sphinx/locale/__init__.py:15
+msgid "Attention"
+msgstr "Attenzione"
+
+#: sphinx/locale/__init__.py:16
+msgid "Caution"
+msgstr "Attenzione"
+
+#: sphinx/locale/__init__.py:17
+msgid "Danger"
+msgstr "Pericolo"
+
+#: sphinx/locale/__init__.py:18
+msgid "Error"
+msgstr "Errore"
+
+#: sphinx/locale/__init__.py:19
+msgid "Hint"
+msgstr "Consiglio"
+
+#: sphinx/locale/__init__.py:20
+msgid "Important"
+msgstr "Importante"
+
+#: sphinx/locale/__init__.py:21
+msgid "Note"
+msgstr "Nota"
+
+#: sphinx/locale/__init__.py:22
+msgid "See Also"
+msgstr "Vedi anche"
+
+#: sphinx/locale/__init__.py:23
+msgid "Tip"
+msgstr "Suggerimento"
+
+#: sphinx/locale/__init__.py:24
+msgid "Warning"
+msgstr "Avvertimento"
+
+#: sphinx/locale/__init__.py:28
+#, python-format
+msgid "New in version %s"
+msgstr "Nuovo nella versione %s"
+
+#: sphinx/locale/__init__.py:29
+#, python-format
+msgid "Changed in version %s"
+msgstr "Cambiato nella versione %s"
+
+#: sphinx/locale/__init__.py:30
+#, python-format
+msgid "Deprecated since version %s"
+msgstr "Deprecato dalla versione %s"
+
+#: sphinx/locale/__init__.py:34
+msgid "module"
+msgstr "modulo"
+
+#: sphinx/locale/__init__.py:35
+msgid "keyword"
+msgstr "keyword"
+
+#: sphinx/locale/__init__.py:36
+msgid "operator"
+msgstr "operatore"
+
+#: sphinx/locale/__init__.py:37
+msgid "object"
+msgstr "oggetto"
+
+#: sphinx/locale/__init__.py:38
+msgid "exception"
+msgstr "eccezione"
+
+#: sphinx/locale/__init__.py:39
+msgid "statement"
+msgstr "statement"
+
+#: sphinx/locale/__init__.py:40
+msgid "built-in function"
+msgstr "funzione built-in"
+
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr "link permanente per questa inestazione"
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr "link permanente per questa definizione"
+
+#: sphinx/static/doctools.js:174
+msgid "Hide Search Matches"
+msgstr "Nascondi i risultati della ricerca"
+
+#: sphinx/static/searchtools.js:274
+msgid "Searching"
+msgstr "Ricerca in corso"
+
+#: sphinx/static/searchtools.js:279
+msgid "Preparing search..."
+msgstr "Preparazione della ricerca"
+
+#: sphinx/static/searchtools.js:338
+msgid "module, in "
+msgstr "modulo, in"
+
+#: sphinx/static/searchtools.js:347
+msgid ", in "
+msgstr ", in "
+
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
+msgid "Search Results"
+msgstr "Risultati della ricerca"
+
+#: sphinx/static/searchtools.js:455
+msgid ""
+"Your search did not match any documents. Please make sure that all words "
+"are spelled correctly and that you've selected enough categories."
+msgstr ""
+"La tua ricerca non ha trovato alcun risultato. Controlla la corettezzadei"
+" termini di ricerca e di avere selezionato un numero sufficiente di "
+"categorie"
+
+#: sphinx/static/searchtools.js:457
+#, python-format
+msgid "Search finished, found %s page(s) matching the search query."
+msgstr "Ricera terminata, trovate %s pagine corrispondenti alla ricerca."
+
+#: sphinx/templates/defindex.html:2
+msgid "Overview"
+msgstr "Sintesi"
+
+#: sphinx/templates/defindex.html:11
+msgid "Indices and tables:"
+msgstr "Indici e tabelle:"
+
+#: sphinx/templates/defindex.html:14
+msgid "Complete Table of Contents"
+msgstr "Tabella dei contenuti completa"
+
+#: sphinx/templates/defindex.html:15
+msgid "lists all sections and subsections"
+msgstr "elenca l'insieme delle sezioni e sottosezioni"
+
+#: sphinx/templates/defindex.html:17
+msgid "search this documentation"
+msgstr "cerca in questa documentazione"
+
+#: sphinx/templates/defindex.html:20
+msgid "quick access to all modules"
+msgstr "accesso veloce ai moduli"
+
+#: sphinx/templates/defindex.html:22
+msgid "all functions, classes, terms"
+msgstr "tutte le funzioni, classi e moduli"
+
+#: sphinx/templates/genindex-single.html:5
+#, python-format
+msgid "Index &ndash; %(key)s"
+msgstr "Indice &ndash; %(key)s"
+
+#: sphinx/templates/genindex-single.html:44
+#: sphinx/templates/genindex-split.html:14
+#: sphinx/templates/genindex-split.html:27 sphinx/templates/genindex.html:54
+msgid "Full index on one page"
+msgstr "Indice completo in una pagina"
+
+#: sphinx/templates/genindex-split.html:7
+msgid "Index pages by letter"
+msgstr "Indice delle pagine per lettera"
+
+#: sphinx/templates/genindex-split.html:15
+msgid "can be huge"
+msgstr "può essere enorme"
+
+#: sphinx/templates/layout.html:9
+msgid "Navigation"
+msgstr "Navigazione"
+
+#: sphinx/templates/layout.html:40
+msgid "Table Of Contents"
+msgstr "Tablella dei contenuti"
+
+#: sphinx/templates/layout.html:46
+msgid "Previous topic"
+msgstr "Argomento precedente"
+
+#: sphinx/templates/layout.html:47
+msgid "previous chapter"
+msgstr "capitolo precedente"
+
+#: sphinx/templates/layout.html:50
+msgid "Next topic"
+msgstr "Argomento successivo"
+
+#: sphinx/templates/layout.html:51
+msgid "next chapter"
+msgstr "capitolo successivo"
+
+#: sphinx/templates/layout.html:56
+msgid "This Page"
+msgstr "Questa pagina"
+
+#: sphinx/templates/layout.html:58
+msgid "Show Source"
+msgstr "Mostra sorgente"
+
+#: sphinx/templates/layout.html:67
+msgid "Quick search"
+msgstr "Ricerca veloce"
+
+#: sphinx/templates/layout.html:69
+msgid "Go"
+msgstr "Vai"
+
+#: sphinx/templates/layout.html:73
+#, fuzzy
+msgid "Enter search terms or a module, class or function name."
+msgstr "Inserisci un modulo, classe o nome di funzione"
+
+#: sphinx/templates/layout.html:106
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "Cerca in %(docstitle)s"
+
+#: sphinx/templates/layout.html:115
+msgid "About these documents"
+msgstr "A proposito di questi documenti"
+
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
+#: sphinx/templates/search.html:5
+msgid "Search"
+msgstr "Cerca"
+
+#: sphinx/templates/layout.html:120
+msgid "Copyright"
+msgstr "Copyright"
+
+#: sphinx/templates/layout.html:165
+#, python-format
+msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
+msgstr "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
+
+#: sphinx/templates/layout.html:167
+#, python-format
+msgid "&copy; Copyright %(copyright)s."
+msgstr "&copy; Copyright %(copyright)s."
+
+#: sphinx/templates/layout.html:170
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "Ultimo Aggiornamento on %(last_updated)s."
+
+#: sphinx/templates/layout.html:173
+#, python-format
+msgid ""
+"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
+"%(sphinx_version)s."
+msgstr ""
+"Creato con <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
+"%(sphinx_version)s."
+
+#: sphinx/templates/modindex.html:36
+msgid "Deprecated"
+msgstr "Deprecato"
+
+#: sphinx/templates/opensearch.xml:4
+#, python-format
+msgid "Search %(docstitle)s"
+msgstr "Cerca %(docstitle)s"
+
+#: sphinx/templates/search.html:7
+msgid ""
+"From here you can search these documents. Enter your search\n"
+" words into the box below and click \"search\". Note that the search\n"
+" function will automatically search for all of the words. Pages\n"
+" containing fewer words won't appear in the result list."
+msgstr ""
+"Puoi effettuare una ricerca in questi documenti. Immetti le parole chiave"
+" \n"
+" della tua ricerca nel riquadro sottostante \"search\". Nota che la "
+"funzione\n"
+" di ricerca cerca automaticamente per tutte le parole. Le pagine\n"
+" che contendono meno parole non compariranno nei risultati di ricerca."
+
+#: sphinx/templates/search.html:14
+msgid "search"
+msgstr "cerca"
+
+#: sphinx/templates/search.html:20
+msgid "Your search did not match any results."
+msgstr "La tua ricerca non ha ottenuto risultati"
+
+#: sphinx/templates/changes/frameset.html:5
+#: sphinx/templates/changes/versionchanges.html:12
+#, python-format
+msgid "Changes in Version %(version)s &mdash; %(docstitle)s"
+msgstr "Modifiche nella Versione %(version)s &mdash; %(docstitle)s"
+
+#: sphinx/templates/changes/rstsource.html:5
+#, python-format
+msgid "%(filename)s &mdash; %(docstitle)s"
+msgstr "%(filename)s &mdash; %(docstitle)s"
+
+#: sphinx/templates/changes/versionchanges.html:17
+#, python-format
+msgid "Automatically generated list of changes in version %(version)s"
+msgstr "Lista delle modifiche generata automaticamente nella versione %(version)s"
+
+#: sphinx/templates/changes/versionchanges.html:18
+msgid "Library changes"
+msgstr "Modifiche nela libreria"
+
+#: sphinx/templates/changes/versionchanges.html:23
+msgid "C API changes"
+msgstr "Modifche nelle API C"
+
+#: sphinx/templates/changes/versionchanges.html:25
+msgid "Other changes"
+msgstr "Altre modifiche"
+
+#: sphinx/writers/latex.py:173
+#, fuzzy
+msgid "Release"
+msgstr "Release"
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr "Piattaforma: %s"
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr "[immagine]"
+
+#~ msgid "Suggest Change"
+#~ msgstr "Suggerisci una modifica"
+
+#~ msgid "Keyword search"
+#~ msgstr "Ricerca per parola chiave"
+
+#~ msgid "Most popular modules:"
+#~ msgstr "Moduli più utilizzati"
+
+#~ msgid "Show modules only available on these platforms"
+#~ msgstr "Mostra solo i moduli disponibili su questa piattaforma"
+
+#~ msgid ""
+#~ "<strong>Note:</strong> You requested an "
+#~ "out-of-date URL from this server. "
+#~ "We've tried to redirect you to the"
+#~ " new location of this page, but "
+#~ "it may not be the right one."
+#~ msgstr ""
+#~ "<strong>Nota:</strong> Hai chiesto un URL "
+#~ "non più valido. Abbiamo provato a "
+#~ "ridirigerti verso il nuovo indirizzo, ma"
+#~ " potrebbe non essere quello giusto"
+
diff --git a/sphinx/locale/ja/LC_MESSAGES/sphinx.po b/sphinx/locale/ja/LC_MESSAGES/sphinx.po
index 3bec3ae3..a2c65446 100644
--- a/sphinx/locale/ja/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ja/LC_MESSAGES/sphinx.po
@@ -8,93 +8,37 @@ msgstr ""
"Project-Id-Version: Sphinx 0.5\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2008-09-11 23:58+0200\n"
-"PO-Revision-Date: 2008-11-27 18:40+0100\n"
+"PO-Revision-Date: 2008-12-28 23:40+0100\n"
"Last-Translator: Yasushi MASUDA <whosaysni@gmail.com>\n"
"Language-Team: ja <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.4\n"
+"Generated-By: Babel 0.9.3\n"
-#: sphinx/builder.py:408
-#, python-format
-msgid "%b %d, %Y"
-msgstr "%Y 年 %m 月 %d 日"
-
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
-msgid "General Index"
-msgstr "総合索引"
-
-#: sphinx/builder.py:427
-msgid "index"
-msgstr "索引"
-
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
-#: sphinx/templates/modindex.html:13
-msgid "Global Module Index"
-msgstr "モジュール総索引"
-
-#: sphinx/builder.py:429
-msgid "modules"
-msgstr "モジュール"
-
-#: sphinx/builder.py:466
-msgid "next"
-msgstr "次へ"
-
-#: sphinx/builder.py:473
-msgid "previous"
-msgstr "前へ"
-
-#: sphinx/builder.py:1054
-msgid " (in "
-msgstr ""
-
-#: sphinx/builder.py:1129
-msgid "Builtins"
-msgstr "組み込み"
-
-#: sphinx/builder.py:1131
-msgid "Module level"
-msgstr "モジュールレベル"
-
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%Y 年 %m 月 %d 日"
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
-#: sphinx/templates/genindex-single.html:2
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
#: sphinx/templates/genindex-split.html:2
#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
-#: sphinx/templates/layout.html:130
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
msgid "Index"
msgstr "索引"
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "モジュール索引"
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "検索ページ"
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
-msgid "Permalink to this definition"
-msgstr "この定義へのパーマリンク"
-
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
-msgid "Permalink to this headline"
-msgstr "このヘッドラインへのパーマリンク"
-
-#: sphinx/latexwriter.py:172
-msgid "Release"
-msgstr "リリース"
-
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
#, python-format
msgid "environment variable; %s"
msgstr "環境変数; %s"
@@ -104,14 +48,48 @@ msgstr "環境変数; %s"
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
-#: sphinx/textwriter.py:166
+#: sphinx/builders/changes.py:64
+msgid "Builtins"
+msgstr "組み込み"
+
+#: sphinx/builders/changes.py:66
+msgid "Module level"
+msgstr "モジュールレベル"
+
+#: sphinx/builders/html.py:115
#, python-format
-msgid "Platform: %s"
-msgstr "プラットフォーム: %s"
+msgid "%b %d, %Y"
+msgstr "%Y 年 %m 月 %d 日"
-#: sphinx/textwriter.py:422
-msgid "[image]"
-msgstr "[画像]"
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
+msgstr "総合索引"
+
+#: sphinx/builders/html.py:134
+msgid "index"
+msgstr "索引"
+
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
+msgstr "モジュール総索引"
+
+#: sphinx/builders/html.py:136
+msgid "modules"
+msgstr "モジュール"
+
+#: sphinx/builders/html.py:175
+msgid "next"
+msgstr "次へ"
+
+#: sphinx/builders/html.py:182
+msgid "previous"
+msgstr "前へ"
+
+#: sphinx/builders/latex.py:155
+msgid " (in "
+msgstr ""
#: sphinx/directives/desc.py:25
#, python-format
@@ -215,11 +193,16 @@ msgstr "戻り値"
msgid "Return type"
msgstr "戻り値の型"
-#: sphinx/directives/desc.py:143
+#: sphinx/directives/desc.py:201
+#, fuzzy
+msgid "Parameter"
+msgstr "パラメタ"
+
+#: sphinx/directives/desc.py:205
msgid "Parameters"
msgstr "パラメタ"
-#: sphinx/directives/desc.py:423
+#: sphinx/directives/desc.py:450
#, fuzzy, python-format
msgid "%scommand line option; %s"
msgstr "%sコマンドラインオプション; %s"
@@ -245,10 +228,15 @@ msgstr "モジュールの作者: "
msgid "Author: "
msgstr "作者: "
-#: sphinx/directives/other.py:246
+#: sphinx/directives/other.py:249
msgid "See also"
msgstr "参考"
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr ""
@@ -345,6 +333,14 @@ msgstr "文"
msgid "built-in function"
msgstr "組み込み関数"
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr "このヘッドラインへのパーマリンク"
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr "この定義へのパーマリンク"
+
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
msgstr "検索結果を隠す"
@@ -366,17 +362,17 @@ msgstr "モジュール"
msgid ", in "
msgstr ""
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
msgid "Search Results"
msgstr "検索結果"
-#: sphinx/static/searchtools.js:449
+#: sphinx/static/searchtools.js:455
msgid ""
"Your search did not match any documents. Please make sure that all words "
"are spelled correctly and that you've selected enough categories."
msgstr "検索条件に一致するドキュメントはありませんでした。検索したい言葉を正しいつづりで入力しているか確認してください。また、正しいカテゴリの検索を行っているか確認してください。"
-#: sphinx/static/searchtools.js:451
+#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr "検索が終了し、条件に一致するページが %s 個みつかりました。"
@@ -452,68 +448,61 @@ msgstr "次のトピックへ"
msgid "next chapter"
msgstr "次の章へ"
-#: sphinx/templates/layout.html:55
+#: sphinx/templates/layout.html:56
msgid "This Page"
msgstr "このページ"
-#: sphinx/templates/layout.html:59
-msgid "Suggest Change"
-msgstr "変更のサジェスト"
-
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:58
msgid "Show Source"
msgstr "ソースコードを表示"
-#: sphinx/templates/layout.html:71
+#: sphinx/templates/layout.html:67
msgid "Quick search"
msgstr "クイック検索"
-#: sphinx/templates/layout.html:71
-msgid "Keyword search"
-msgstr "キーワード検索"
-
-#: sphinx/templates/layout.html:73
+#: sphinx/templates/layout.html:69
msgid "Go"
msgstr "検索"
-#: sphinx/templates/layout.html:78
-msgid "Enter a module, class or function name."
+#: sphinx/templates/layout.html:73
+#, fuzzy
+msgid "Enter search terms or a module, class or function name."
msgstr "モジュール、クラス、または関数名を入力してください"
-#: sphinx/templates/layout.html:119
+#: sphinx/templates/layout.html:106
#, python-format
msgid "Search within %(docstitle)s"
msgstr "%(docstitle)s 内を検索"
-#: sphinx/templates/layout.html:128
+#: sphinx/templates/layout.html:115
msgid "About these documents"
msgstr "このドキュメントについて"
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "検索"
-#: sphinx/templates/layout.html:133
+#: sphinx/templates/layout.html:120
msgid "Copyright"
msgstr "著作権"
-#: sphinx/templates/layout.html:178
+#: sphinx/templates/layout.html:165
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
-#: sphinx/templates/layout.html:180
+#: sphinx/templates/layout.html:167
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Copyright %(copyright)s."
-#: sphinx/templates/layout.html:183
+#: sphinx/templates/layout.html:170
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr "最終更新: %(last_updated)s"
-#: sphinx/templates/layout.html:186
+#: sphinx/templates/layout.html:173
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
@@ -522,15 +511,7 @@ msgstr ""
"このドキュメントは <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s で生成しました。"
-#: sphinx/templates/modindex.html:15
-msgid "Most popular modules:"
-msgstr "よく参照されているモジュール:"
-
-#: sphinx/templates/modindex.html:24
-msgid "Show modules only available on these platforms"
-msgstr "このプラットフォームで利用可能なモジュールだけを表示する"
-
-#: sphinx/templates/modindex.html:56
+#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "撤廃"
@@ -539,15 +520,6 @@ msgstr "撤廃"
msgid "Search %(docstitle)s"
msgstr "%(docstitle)s 内を検索"
-#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-"<strong>注意:</strong> あなたが表示しようとしているのは古い URL です。このページに対応する新しい URL "
-"へのリダイレクトを試みますが、適切なリダイレクト先でないかもしれないので注意してください。"
-
#: sphinx/templates/search.html:7
#, fuzzy
msgid ""
@@ -593,3 +565,39 @@ msgstr "C API に関する変更"
msgid "Other changes"
msgstr "その多の変更"
+#: sphinx/writers/latex.py:173
+msgid "Release"
+msgstr "リリース"
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr "プラットフォーム: %s"
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr "[画像]"
+
+#~ msgid "Suggest Change"
+#~ msgstr "変更のサジェスト"
+
+#~ msgid "Keyword search"
+#~ msgstr "キーワード検索"
+
+#~ msgid "Most popular modules:"
+#~ msgstr "よく参照されているモジュール:"
+
+#~ msgid "Show modules only available on these platforms"
+#~ msgstr "このプラットフォームで利用可能なモジュールだけを表示する"
+
+#~ msgid ""
+#~ "<strong>Note:</strong> You requested an "
+#~ "out-of-date URL from this server. "
+#~ "We've tried to redirect you to the"
+#~ " new location of this page, but "
+#~ "it may not be the right one."
+#~ msgstr ""
+#~ "<strong>注意:</strong> あなたが表示しようとしているのは古い URL "
+#~ "です。このページに対応する新しい URL "
+#~ "へのリダイレクトを試みますが、適切なリダイレクト先でないかもしれないので注意してください。"
+
diff --git a/sphinx/locale/nl/LC_MESSAGES/sphinx.po b/sphinx/locale/nl/LC_MESSAGES/sphinx.po
index 49b2d192..fe6a4556 100644
--- a/sphinx/locale/nl/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/nl/LC_MESSAGES/sphinx.po
@@ -7,93 +7,37 @@ msgstr ""
"Project-Id-Version: Sphinx 0.5\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2008-09-11 23:58+0200\n"
-"PO-Revision-Date: 2008-11-27 18:40+0100\n"
+"PO-Revision-Date: 2008-12-28 23:40+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: nl <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.4\n"
+"Generated-By: Babel 0.9.3\n"
-#: sphinx/builder.py:408
-#, python-format
-msgid "%b %d, %Y"
-msgstr "%d.%b.%Y"
-
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
-msgid "General Index"
-msgstr "Algemene index"
-
-#: sphinx/builder.py:427
-msgid "index"
-msgstr "Index"
-
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
-#: sphinx/templates/modindex.html:13
-msgid "Global Module Index"
-msgstr "Globale Module-index"
-
-#: sphinx/builder.py:429
-msgid "modules"
-msgstr "modules"
-
-#: sphinx/builder.py:466
-msgid "next"
-msgstr "volgende"
-
-#: sphinx/builder.py:473
-msgid "previous"
-msgstr "vorige"
-
-#: sphinx/builder.py:1054
-msgid " (in "
-msgstr ""
-
-#: sphinx/builder.py:1129
-msgid "Builtins"
-msgstr "Builtins"
-
-#: sphinx/builder.py:1131
-msgid "Module level"
-msgstr "Moduleniveau"
-
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%d. %B %Y"
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
-#: sphinx/templates/genindex-single.html:2
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
#: sphinx/templates/genindex-split.html:2
#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
-#: sphinx/templates/layout.html:130
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Index"
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Module-index"
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Zoekpagina"
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
-msgid "Permalink to this definition"
-msgstr "Permanente link naar deze definitie"
-
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
-msgid "Permalink to this headline"
-msgstr "Permanente link naar deze titel"
-
-#: sphinx/latexwriter.py:172
-msgid "Release"
-msgstr "Release"
-
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
#, python-format
msgid "environment variable; %s"
msgstr "Omgevingsvariabele; %s"
@@ -103,14 +47,48 @@ msgstr "Omgevingsvariabele; %s"
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
-#: sphinx/textwriter.py:166
+#: sphinx/builders/changes.py:64
+msgid "Builtins"
+msgstr "Builtins"
+
+#: sphinx/builders/changes.py:66
+msgid "Module level"
+msgstr "Moduleniveau"
+
+#: sphinx/builders/html.py:115
#, python-format
-msgid "Platform: %s"
-msgstr "Platform: %s"
+msgid "%b %d, %Y"
+msgstr "%d.%b.%Y"
-#: sphinx/textwriter.py:422
-msgid "[image]"
-msgstr "[afbeelding]"
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
+msgstr "Algemene index"
+
+#: sphinx/builders/html.py:134
+msgid "index"
+msgstr "Index"
+
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
+msgstr "Globale Module-index"
+
+#: sphinx/builders/html.py:136
+msgid "modules"
+msgstr "modules"
+
+#: sphinx/builders/html.py:175
+msgid "next"
+msgstr "volgende"
+
+#: sphinx/builders/html.py:182
+msgid "previous"
+msgstr "vorige"
+
+#: sphinx/builders/latex.py:155
+msgid " (in "
+msgstr ""
#: sphinx/directives/desc.py:25
#, python-format
@@ -214,11 +192,16 @@ msgstr "Returns"
msgid "Return type"
msgstr "Return type"
-#: sphinx/directives/desc.py:143
+#: sphinx/directives/desc.py:201
+#, fuzzy
+msgid "Parameter"
+msgstr "Parameters"
+
+#: sphinx/directives/desc.py:205
msgid "Parameters"
msgstr "Parameters"
-#: sphinx/directives/desc.py:423
+#: sphinx/directives/desc.py:450
#, fuzzy, python-format
msgid "%scommand line option; %s"
msgstr "%scommandolijn optie; %s"
@@ -244,10 +227,15 @@ msgstr "Auteur van deze module: "
msgid "Author: "
msgstr "Auteur: "
-#: sphinx/directives/other.py:246
+#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Zie ook"
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr ""
@@ -344,6 +332,14 @@ msgstr "statement"
msgid "built-in function"
msgstr "geïntegreerde functie"
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr "Permanente link naar deze titel"
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr "Permanente link naar deze definitie"
+
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
msgstr "Zoekresultaten verbergen"
@@ -365,11 +361,11 @@ msgstr "module"
msgid ", in "
msgstr ""
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
msgid "Search Results"
msgstr "Zoekresultaten"
-#: sphinx/static/searchtools.js:449
+#: sphinx/static/searchtools.js:455
msgid ""
"Your search did not match any documents. Please make sure that all words "
"are spelled correctly and that you've selected enough categories."
@@ -377,7 +373,7 @@ msgstr ""
"Uw zoekopdracht leverde geen resultaten op. Controleer of alle "
"woordencorrect gespeld zijn en dat u genoeg categoriën hebt geselecteerd."
-#: sphinx/static/searchtools.js:451
+#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr "Zoeken voltooid, %s pagina(s) gevonden."
@@ -453,68 +449,61 @@ msgstr "Volgend onderwerp"
msgid "next chapter"
msgstr "volgend hoofdstuk"
-#: sphinx/templates/layout.html:55
+#: sphinx/templates/layout.html:56
msgid "This Page"
msgstr "Deze Pagina"
-#: sphinx/templates/layout.html:59
-msgid "Suggest Change"
-msgstr "Wijziging Voorstellen"
-
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:58
msgid "Show Source"
msgstr "Broncode weergeven"
-#: sphinx/templates/layout.html:71
+#: sphinx/templates/layout.html:67
msgid "Quick search"
msgstr "Snel zoeken"
-#: sphinx/templates/layout.html:71
-msgid "Keyword search"
-msgstr "Trefwoord opzoeken"
-
-#: sphinx/templates/layout.html:73
+#: sphinx/templates/layout.html:69
msgid "Go"
msgstr "Go"
-#: sphinx/templates/layout.html:78
-msgid "Enter a module, class or function name."
+#: sphinx/templates/layout.html:73
+#, fuzzy
+msgid "Enter search terms or a module, class or function name."
msgstr "Geef de naam van een module, klasse of functie."
-#: sphinx/templates/layout.html:119
+#: sphinx/templates/layout.html:106
#, python-format
msgid "Search within %(docstitle)s"
msgstr "Zoeken in %(docstitle)s"
-#: sphinx/templates/layout.html:128
+#: sphinx/templates/layout.html:115
msgid "About these documents"
msgstr "Over deze documenten"
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Zoeken"
-#: sphinx/templates/layout.html:133
+#: sphinx/templates/layout.html:120
msgid "Copyright"
msgstr "Copyright"
-#: sphinx/templates/layout.html:178
+#: sphinx/templates/layout.html:165
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
-#: sphinx/templates/layout.html:180
+#: sphinx/templates/layout.html:167
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Copyright %(copyright)s."
-#: sphinx/templates/layout.html:183
+#: sphinx/templates/layout.html:170
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr "Laatste aanpassing op %(last_updated)s."
-#: sphinx/templates/layout.html:186
+#: sphinx/templates/layout.html:173
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
@@ -523,15 +512,7 @@ msgstr ""
"Aangemaakt met <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s."
-#: sphinx/templates/modindex.html:15
-msgid "Most popular modules:"
-msgstr "Populairste modules:"
-
-#: sphinx/templates/modindex.html:24
-msgid "Show modules only available on these platforms"
-msgstr "Enkel modules weergeven die op deze platformen beschikbaar zijn"
-
-#: sphinx/templates/modindex.html:56
+#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "Verouderd"
@@ -540,16 +521,6 @@ msgstr "Verouderd"
msgid "Search %(docstitle)s"
msgstr "Zoeken %(docstitle)s"
-#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-"<strong>Opgelet:</strong> U heeft een verouderde URL aangevraagd op deze "
-"server. Wij hebben probeerd u door te verwijzen naar de nieuwe locatie "
-"van deze pagina, maar dat is misschien niet gelukt."
-
#: sphinx/templates/search.html:7
#, fuzzy
msgid ""
@@ -601,3 +572,42 @@ msgstr "Veranderingen in de C-API"
msgid "Other changes"
msgstr "Andere veranderingen"
+#: sphinx/writers/latex.py:173
+msgid "Release"
+msgstr "Release"
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr "Platform: %s"
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr "[afbeelding]"
+
+#~ msgid "Suggest Change"
+#~ msgstr "Wijziging Voorstellen"
+
+#~ msgid "Keyword search"
+#~ msgstr "Trefwoord opzoeken"
+
+#~ msgid "Most popular modules:"
+#~ msgstr "Populairste modules:"
+
+#~ msgid "Show modules only available on these platforms"
+#~ msgstr "Enkel modules weergeven die op deze platformen beschikbaar zijn"
+
+#~ msgid ""
+#~ "<strong>Note:</strong> You requested an "
+#~ "out-of-date URL from this server. "
+#~ "We've tried to redirect you to the"
+#~ " new location of this page, but "
+#~ "it may not be the right one."
+#~ msgstr ""
+#~ "<strong>Opgelet:</strong> U heeft een "
+#~ "verouderde URL aangevraagd op deze "
+#~ "server. Wij hebben probeerd u door "
+#~ "te verwijzen naar de nieuwe locatie "
+#~ "van deze pagina, maar dat is "
+#~ "misschien niet gelukt."
+
diff --git a/sphinx/locale/pl/LC_MESSAGES/sphinx.po b/sphinx/locale/pl/LC_MESSAGES/sphinx.po
index 87f5c4cb..fdd14ca3 100644
--- a/sphinx/locale/pl/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/pl/LC_MESSAGES/sphinx.po
@@ -4,7 +4,7 @@ msgstr ""
"Project-Id-Version: Sphinx 0.5\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2008-08-10 11:43+0000\n"
-"PO-Revision-Date: 2008-11-27 18:40+0100\n"
+"PO-Revision-Date: 2008-12-28 23:40+0100\n"
"Last-Translator: Michał Kandulski <Michal.Kandulski@poczta.onet.pl>\n"
"Language-Team: \n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && "
@@ -12,86 +12,30 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.4\n"
+"Generated-By: Babel 0.9.3\n"
-#: sphinx/builder.py:408
-#, python-format
-msgid "%b %d, %Y"
-msgstr "%b %d %Y"
-
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
-msgid "General Index"
-msgstr "Indeks ogólny"
-
-#: sphinx/builder.py:427
-msgid "index"
-msgstr "indeks"
-
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
-#: sphinx/templates/modindex.html:13
-msgid "Global Module Index"
-msgstr "Indeks modułów"
-
-#: sphinx/builder.py:429
-msgid "modules"
-msgstr "moduły"
-
-#: sphinx/builder.py:466
-msgid "next"
-msgstr "dalej"
-
-#: sphinx/builder.py:473
-msgid "previous"
-msgstr "wstecz"
-
-#: sphinx/builder.py:1054
-msgid " (in "
-msgstr ""
-
-#: sphinx/builder.py:1129
-msgid "Builtins"
-msgstr "Wbudowane"
-
-#: sphinx/builder.py:1131
-msgid "Module level"
-msgstr "Poziom modułu"
-
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%B %d %Y"
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
-#: sphinx/templates/genindex-single.html:2
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
#: sphinx/templates/genindex-split.html:2
#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
-#: sphinx/templates/layout.html:130
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Indeks"
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Indeks modułów"
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Wyszukiwanie"
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
-msgid "Permalink to this definition"
-msgstr "Stały odnośnik do tej definicji"
-
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
-msgid "Permalink to this headline"
-msgstr "Stały odnośnik do tego nagłówka"
-
-#: sphinx/latexwriter.py:172
-msgid "Release"
-msgstr "Wydanie"
-
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
#, python-format
msgid "environment variable; %s"
msgstr "zmienna środowiskowa; %s"
@@ -101,14 +45,48 @@ msgstr "zmienna środowiskowa; %s"
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
-#: sphinx/textwriter.py:166
+#: sphinx/builders/changes.py:64
+msgid "Builtins"
+msgstr "Wbudowane"
+
+#: sphinx/builders/changes.py:66
+msgid "Module level"
+msgstr "Poziom modułu"
+
+#: sphinx/builders/html.py:115
#, python-format
-msgid "Platform: %s"
-msgstr "Platforma: %s"
+msgid "%b %d, %Y"
+msgstr "%b %d %Y"
-#: sphinx/textwriter.py:422
-msgid "[image]"
-msgstr "[obrazek]"
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
+msgstr "Indeks ogólny"
+
+#: sphinx/builders/html.py:134
+msgid "index"
+msgstr "indeks"
+
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
+msgstr "Indeks modułów"
+
+#: sphinx/builders/html.py:136
+msgid "modules"
+msgstr "moduły"
+
+#: sphinx/builders/html.py:175
+msgid "next"
+msgstr "dalej"
+
+#: sphinx/builders/html.py:182
+msgid "previous"
+msgstr "wstecz"
+
+#: sphinx/builders/latex.py:155
+msgid " (in "
+msgstr ""
#: sphinx/directives/desc.py:25
#, python-format
@@ -212,11 +190,16 @@ msgstr "Zwraca"
msgid "Return type"
msgstr "Typ zwracany"
-#: sphinx/directives/desc.py:143
+#: sphinx/directives/desc.py:201
+#, fuzzy
+msgid "Parameter"
+msgstr "Parametry"
+
+#: sphinx/directives/desc.py:205
msgid "Parameters"
msgstr "Parametry"
-#: sphinx/directives/desc.py:423
+#: sphinx/directives/desc.py:450
#, fuzzy, python-format
msgid "%scommand line option; %s"
msgstr "%sopcja linii komend; %s"
@@ -242,10 +225,15 @@ msgstr "Autor modułu: "
msgid "Author: "
msgstr "Autor: "
-#: sphinx/directives/other.py:246
+#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Zobacz także"
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr ""
@@ -342,6 +330,14 @@ msgstr "instrukcja"
msgid "built-in function"
msgstr "funkcja wbudowana"
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr "Stały odnośnik do tego nagłówka"
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr "Stały odnośnik do tej definicji"
+
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
msgstr "Ukryj wyniki wyszukiwania"
@@ -363,11 +359,11 @@ msgstr "moduł"
msgid ", in "
msgstr ""
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
msgid "Search Results"
msgstr "Wyniki wyszukiwania"
-#: sphinx/static/searchtools.js:449
+#: sphinx/static/searchtools.js:455
msgid ""
"Your search did not match any documents. Please make sure that all words "
"are spelled correctly and that you've selected enough categories."
@@ -375,7 +371,7 @@ msgstr ""
"Nie znaleziono żadnych pasujących dokumentów. Upewnij się, że wszystkie "
"słowa są poprawnie wpisane i że wybrałeś wystarczającąliczbę kategorii."
-#: sphinx/static/searchtools.js:451
+#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr "Przeszukiwanie zakończone, znaleziono %s pasujących stron."
@@ -451,68 +447,61 @@ msgstr "Następny temat"
msgid "next chapter"
msgstr "następny rozdział"
-#: sphinx/templates/layout.html:55
+#: sphinx/templates/layout.html:56
msgid "This Page"
msgstr "Ta strona"
-#: sphinx/templates/layout.html:59
-msgid "Suggest Change"
-msgstr "Zasugeruj zmianę"
-
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:58
msgid "Show Source"
msgstr "Pokaż źródło"
-#: sphinx/templates/layout.html:71
+#: sphinx/templates/layout.html:67
msgid "Quick search"
msgstr "Szybkie wyszukiwanie"
-#: sphinx/templates/layout.html:71
-msgid "Keyword search"
-msgstr "Szukanie wg słowa kluczowego"
-
-#: sphinx/templates/layout.html:73
+#: sphinx/templates/layout.html:69
msgid "Go"
msgstr "Szukaj"
-#: sphinx/templates/layout.html:78
-msgid "Enter a module, class or function name."
+#: sphinx/templates/layout.html:73
+#, fuzzy
+msgid "Enter search terms or a module, class or function name."
msgstr "Wprowadź nazwę modułu, klasy lub funkcji."
-#: sphinx/templates/layout.html:119
+#: sphinx/templates/layout.html:106
#, python-format
msgid "Search within %(docstitle)s"
msgstr "Szukaj pośród %(docstitle)s"
-#: sphinx/templates/layout.html:128
+#: sphinx/templates/layout.html:115
msgid "About these documents"
msgstr "O tych dokumentach"
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Szukaj"
-#: sphinx/templates/layout.html:133
+#: sphinx/templates/layout.html:120
msgid "Copyright"
msgstr "Copyright"
-#: sphinx/templates/layout.html:178
+#: sphinx/templates/layout.html:165
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
-#: sphinx/templates/layout.html:180
+#: sphinx/templates/layout.html:167
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Copyright %(copyright)s."
-#: sphinx/templates/layout.html:183
+#: sphinx/templates/layout.html:170
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr "Ostatnia modyfikacja %(last_updated)s."
-#: sphinx/templates/layout.html:186
+#: sphinx/templates/layout.html:173
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
@@ -521,15 +510,7 @@ msgstr ""
"Utworzone przy pomocy <a href=\"http://sphinx.pocoo.org/\">Sphinx</a>'a "
"%(sphinx_version)s."
-#: sphinx/templates/modindex.html:15
-msgid "Most popular modules:"
-msgstr "Najbardziej popularne moduły:"
-
-#: sphinx/templates/modindex.html:24
-msgid "Show modules only available on these platforms"
-msgstr "Pokaż moduły dostępne tylko na tych platformach"
-
-#: sphinx/templates/modindex.html:56
+#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "Niezalecane"
@@ -538,16 +519,6 @@ msgstr "Niezalecane"
msgid "Search %(docstitle)s"
msgstr "Przeszukaj %(docstitle)s"
-#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-"<strong>Uwaga:</strong> Zażądano przedawnionego URL'a z tego serwera. "
-"Nastąpiła próba przekierowania do nowej lokalizacji, ale może ona być "
-"niewłaściwa."
-
#: sphinx/templates/search.html:7
#, fuzzy
msgid ""
@@ -598,3 +569,40 @@ msgstr "Zmiany w C API"
msgid "Other changes"
msgstr "Inne zmiany"
+#: sphinx/writers/latex.py:173
+msgid "Release"
+msgstr "Wydanie"
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr "Platforma: %s"
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr "[obrazek]"
+
+#~ msgid "Suggest Change"
+#~ msgstr "Zasugeruj zmianę"
+
+#~ msgid "Keyword search"
+#~ msgstr "Szukanie wg słowa kluczowego"
+
+#~ msgid "Most popular modules:"
+#~ msgstr "Najbardziej popularne moduły:"
+
+#~ msgid "Show modules only available on these platforms"
+#~ msgstr "Pokaż moduły dostępne tylko na tych platformach"
+
+#~ msgid ""
+#~ "<strong>Note:</strong> You requested an "
+#~ "out-of-date URL from this server. "
+#~ "We've tried to redirect you to the"
+#~ " new location of this page, but "
+#~ "it may not be the right one."
+#~ msgstr ""
+#~ "<strong>Uwaga:</strong> Zażądano przedawnionego "
+#~ "URL'a z tego serwera. Nastąpiła próba"
+#~ " przekierowania do nowej lokalizacji, ale"
+#~ " może ona być niewłaściwa."
+
diff --git a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po
index 021b70aa..d3144c25 100644
--- a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po
@@ -8,93 +8,37 @@ msgstr ""
"Project-Id-Version: Sphinx 0.5\n"
"Report-Msgid-Bugs-To: roger.demetrescu@gmail.com\n"
"POT-Creation-Date: 2008-11-09 19:46+0100\n"
-"PO-Revision-Date: 2008-11-27 18:40+0100\n"
+"PO-Revision-Date: 2008-12-28 23:40+0100\n"
"Last-Translator: Roger Demetrescu <roger.demetrescu@gmail.com>\n"
"Language-Team: pt_BR <roger.demetrescu@gmail.com>\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.4\n"
+"Generated-By: Babel 0.9.3\n"
-#: sphinx/builder.py:408
-#, python-format
-msgid "%b %d, %Y"
-msgstr "%d/%m/%Y"
-
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
-msgid "General Index"
-msgstr "Índice Geral"
-
-#: sphinx/builder.py:427
-msgid "index"
-msgstr "índice"
-
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
-#: sphinx/templates/modindex.html:13
-msgid "Global Module Index"
-msgstr "Índice Global de Módulos"
-
-#: sphinx/builder.py:429
-msgid "modules"
-msgstr "módulos"
-
-#: sphinx/builder.py:466
-msgid "next"
-msgstr "próximo"
-
-#: sphinx/builder.py:473
-msgid "previous"
-msgstr "anterior"
-
-#: sphinx/builder.py:1054
-msgid " (in "
-msgstr " (em "
-
-#: sphinx/builder.py:1129
-msgid "Builtins"
-msgstr "Internos"
-
-#: sphinx/builder.py:1131
-msgid "Module level"
-msgstr "Módulo"
-
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%d/%m/%Y"
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
-#: sphinx/templates/genindex-single.html:2
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
#: sphinx/templates/genindex-split.html:2
#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
-#: sphinx/templates/layout.html:130
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Índice"
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Índice do Módulo"
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Página de Pesquisa"
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
-msgid "Permalink to this definition"
-msgstr "Link permanente para esta definição"
-
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
-msgid "Permalink to this headline"
-msgstr "Link permanente para este título"
-
-#: sphinx/latexwriter.py:172
-msgid "Release"
-msgstr "Versão"
-
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
#, python-format
msgid "environment variable; %s"
msgstr "váriavel de ambiente; %s"
@@ -104,14 +48,48 @@ msgstr "váriavel de ambiente; %s"
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
-#: sphinx/textwriter.py:166
+#: sphinx/builders/changes.py:64
+msgid "Builtins"
+msgstr "Internos"
+
+#: sphinx/builders/changes.py:66
+msgid "Module level"
+msgstr "Módulo"
+
+#: sphinx/builders/html.py:115
#, python-format
-msgid "Platform: %s"
-msgstr "Plataforma: %s"
+msgid "%b %d, %Y"
+msgstr "%d/%m/%Y"
-#: sphinx/textwriter.py:422
-msgid "[image]"
-msgstr "[imagem]"
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
+msgstr "Índice Geral"
+
+#: sphinx/builders/html.py:134
+msgid "index"
+msgstr "índice"
+
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
+msgstr "Índice Global de Módulos"
+
+#: sphinx/builders/html.py:136
+msgid "modules"
+msgstr "módulos"
+
+#: sphinx/builders/html.py:175
+msgid "next"
+msgstr "próximo"
+
+#: sphinx/builders/html.py:182
+msgid "previous"
+msgstr "anterior"
+
+#: sphinx/builders/latex.py:155
+msgid " (in "
+msgstr " (em "
#: sphinx/directives/desc.py:25
#, python-format
@@ -215,11 +193,16 @@ msgstr "Retorna"
msgid "Return type"
msgstr "Tipo de retorno"
-#: sphinx/directives/desc.py:143
+#: sphinx/directives/desc.py:201
+#, fuzzy
+msgid "Parameter"
+msgstr "Parâmetros"
+
+#: sphinx/directives/desc.py:205
msgid "Parameters"
msgstr "Parâmetros"
-#: sphinx/directives/desc.py:423
+#: sphinx/directives/desc.py:450
#, python-format
msgid "%scommand line option; %s"
msgstr "%sopção de linha de comando; %s"
@@ -245,10 +228,15 @@ msgstr "Autor do módulo: "
msgid "Author: "
msgstr "Autor: "
-#: sphinx/directives/other.py:246
+#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Veja também"
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr "Por fazer"
@@ -345,6 +333,14 @@ msgstr "comando"
msgid "built-in function"
msgstr "função interna"
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr "Link permanente para este título"
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr "Link permanente para esta definição"
+
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
msgstr "Esconder Resultados da Pesquisa"
@@ -365,11 +361,11 @@ msgstr "módulo, em "
msgid ", in "
msgstr ", em "
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
msgid "Search Results"
msgstr "Resultados da Pesquisa"
-#: sphinx/static/searchtools.js:449
+#: sphinx/static/searchtools.js:455
msgid ""
"Your search did not match any documents. Please make sure that all words "
"are spelled correctly and that you've selected enough categories."
@@ -378,7 +374,7 @@ msgstr ""
" todas as palavras foram digitadas corretamente e de que você tenha "
"selecionado o mínimo de categorias."
-#: sphinx/static/searchtools.js:451
+#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr ""
@@ -456,68 +452,61 @@ msgstr "Próximo tópico"
msgid "next chapter"
msgstr "próximo capítulo"
-#: sphinx/templates/layout.html:55
+#: sphinx/templates/layout.html:56
msgid "This Page"
msgstr "Esta Página"
-#: sphinx/templates/layout.html:59
-msgid "Suggest Change"
-msgstr "Sugerir Alteração"
-
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:58
msgid "Show Source"
msgstr "Exibir Fonte"
-#: sphinx/templates/layout.html:71
+#: sphinx/templates/layout.html:67
msgid "Quick search"
msgstr "Pesquisa rápida"
-#: sphinx/templates/layout.html:71
-msgid "Keyword search"
-msgstr "Pesquisa de palavras-chave"
-
-#: sphinx/templates/layout.html:73
+#: sphinx/templates/layout.html:69
msgid "Go"
msgstr "Ir"
-#: sphinx/templates/layout.html:78
-msgid "Enter a module, class or function name."
+#: sphinx/templates/layout.html:73
+#, fuzzy
+msgid "Enter search terms or a module, class or function name."
msgstr "Informe o nome de um módulo, classe ou função."
-#: sphinx/templates/layout.html:119
+#: sphinx/templates/layout.html:106
#, python-format
msgid "Search within %(docstitle)s"
msgstr "Pesquisar dentro de %(docstitle)s"
-#: sphinx/templates/layout.html:128
+#: sphinx/templates/layout.html:115
msgid "About these documents"
msgstr "Sobre estes documentos"
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Pesquisar"
-#: sphinx/templates/layout.html:133
+#: sphinx/templates/layout.html:120
msgid "Copyright"
msgstr "Copyright"
-#: sphinx/templates/layout.html:178
+#: sphinx/templates/layout.html:165
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
-#: sphinx/templates/layout.html:180
+#: sphinx/templates/layout.html:167
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Copyright %(copyright)s."
-#: sphinx/templates/layout.html:183
+#: sphinx/templates/layout.html:170
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr "Última atualização em %(last_updated)s."
-#: sphinx/templates/layout.html:186
+#: sphinx/templates/layout.html:173
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
@@ -526,15 +515,7 @@ msgstr ""
"Criado com <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s."
-#: sphinx/templates/modindex.html:15
-msgid "Most popular modules:"
-msgstr "Módulos mais populares:"
-
-#: sphinx/templates/modindex.html:24
-msgid "Show modules only available on these platforms"
-msgstr "Exibir somente módulos disponíveis nestas plataformas"
-
-#: sphinx/templates/modindex.html:56
+#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "Obsoleto"
@@ -543,16 +524,6 @@ msgstr "Obsoleto"
msgid "Search %(docstitle)s"
msgstr "Pesquisar em %(docstitle)s"
-#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-"<strong>Nota:</strong> Você requisitou uma URL desatualizada deste "
-"servidor. Tentamos redirecioná-lo para um novo endereço desta página, "
-"porém é possível que o mesmo não seja o correto."
-
#: sphinx/templates/search.html:7
#, fuzzy
msgid ""
@@ -604,3 +575,41 @@ msgstr "Alterações na API C"
msgid "Other changes"
msgstr "Outras alterações"
+#: sphinx/writers/latex.py:173
+msgid "Release"
+msgstr "Versão"
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr "Plataforma: %s"
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr "[imagem]"
+
+#~ msgid "Suggest Change"
+#~ msgstr "Sugerir Alteração"
+
+#~ msgid "Keyword search"
+#~ msgstr "Pesquisa de palavras-chave"
+
+#~ msgid "Most popular modules:"
+#~ msgstr "Módulos mais populares:"
+
+#~ msgid "Show modules only available on these platforms"
+#~ msgstr "Exibir somente módulos disponíveis nestas plataformas"
+
+#~ msgid ""
+#~ "<strong>Note:</strong> You requested an "
+#~ "out-of-date URL from this server. "
+#~ "We've tried to redirect you to the"
+#~ " new location of this page, but "
+#~ "it may not be the right one."
+#~ msgstr ""
+#~ "<strong>Nota:</strong> Você requisitou uma URL"
+#~ " desatualizada deste servidor. Tentamos "
+#~ "redirecioná-lo para um novo endereço "
+#~ "desta página, porém é possível que "
+#~ "o mesmo não seja o correto."
+
diff --git a/sphinx/locale/sl/LC_MESSAGES/sphinx.po b/sphinx/locale/sl/LC_MESSAGES/sphinx.po
index 0c6bbab3..b08c75c9 100644
--- a/sphinx/locale/sl/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/sl/LC_MESSAGES/sphinx.po
@@ -4,93 +4,37 @@ msgstr ""
"Project-Id-Version: Sphinx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2008-09-11 23:58+0200\n"
-"PO-Revision-Date: 2008-11-27 18:40+0100\n"
+"PO-Revision-Date: 2008-12-28 23:40+0100\n"
"Last-Translator: Rok Garbas <rok.garbas@gmail.com>\n"
"Language-Team: Rok Garbas <rok.garbas@gmail.com>\n"
"Plural-Forms: nplurals=1; plural=0\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.4\n"
+"Generated-By: Babel 0.9.3\n"
-#: sphinx/builder.py:408
-#, python-format
-msgid "%b %d, %Y"
-msgstr "%d %b, %Y"
-
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
-msgid "General Index"
-msgstr "Splošni abecedni seznam"
-
-#: sphinx/builder.py:427
-msgid "index"
-msgstr "abecedni seznam"
-
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
-#: sphinx/templates/modindex.html:13
-msgid "Global Module Index"
-msgstr "Splošen Seznam Modulov"
-
-#: sphinx/builder.py:429
-msgid "modules"
-msgstr "Moduli"
-
-#: sphinx/builder.py:466
-msgid "next"
-msgstr "naprej"
-
-#: sphinx/builder.py:473
-msgid "previous"
-msgstr "nazaj"
-
-#: sphinx/builder.py:1054
-msgid " (in "
-msgstr "(v "
-
-#: sphinx/builder.py:1129
-msgid "Builtins"
-msgstr "Vgrajeni deli"
-
-#: sphinx/builder.py:1131
-msgid "Module level"
-msgstr "Nivo modula"
-
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%d %B, %Y"
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
-#: sphinx/templates/genindex-single.html:2
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
#: sphinx/templates/genindex-split.html:2
#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
-#: sphinx/templates/layout.html:130
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Abecedni seznam"
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Seznam modulov"
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Iskalna stran"
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
-msgid "Permalink to this definition"
-msgstr "Povezava na to definicijo"
-
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
-msgid "Permalink to this headline"
-msgstr "Povezava na naslov"
-
-#: sphinx/latexwriter.py:172
-msgid "Release"
-msgstr "Izdaja"
-
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
#, python-format
msgid "environment variable; %s"
msgstr "globalna spremenljivka; %s"
@@ -100,14 +44,48 @@ msgstr "globalna spremenljivka; %s"
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
-#: sphinx/textwriter.py:166
+#: sphinx/builders/changes.py:64
+msgid "Builtins"
+msgstr "Vgrajeni deli"
+
+#: sphinx/builders/changes.py:66
+msgid "Module level"
+msgstr "Nivo modula"
+
+#: sphinx/builders/html.py:115
#, python-format
-msgid "Platform: %s"
-msgstr "Platforma: %s"
+msgid "%b %d, %Y"
+msgstr "%d %b, %Y"
-#: sphinx/textwriter.py:422
-msgid "[image]"
-msgstr "[slika]"
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
+msgstr "Splošni abecedni seznam"
+
+#: sphinx/builders/html.py:134
+msgid "index"
+msgstr "abecedni seznam"
+
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
+msgstr "Splošen Seznam Modulov"
+
+#: sphinx/builders/html.py:136
+msgid "modules"
+msgstr "Moduli"
+
+#: sphinx/builders/html.py:175
+msgid "next"
+msgstr "naprej"
+
+#: sphinx/builders/html.py:182
+msgid "previous"
+msgstr "nazaj"
+
+#: sphinx/builders/latex.py:155
+msgid " (in "
+msgstr "(v "
#: sphinx/directives/desc.py:25
#, python-format
@@ -211,11 +189,16 @@ msgstr "Vrne"
msgid "Return type"
msgstr "Vrne tip"
-#: sphinx/directives/desc.py:143
+#: sphinx/directives/desc.py:201
+#, fuzzy
+msgid "Parameter"
+msgstr "Parametri"
+
+#: sphinx/directives/desc.py:205
msgid "Parameters"
msgstr "Parametri"
-#: sphinx/directives/desc.py:423
+#: sphinx/directives/desc.py:450
#, python-format
msgid "%scommand line option; %s"
msgstr "%sopcija komandne linije; %s"
@@ -241,10 +224,15 @@ msgstr "Avtor modula:"
msgid "Author: "
msgstr "Avtor:"
-#: sphinx/directives/other.py:246
+#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Poglej tudi"
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr "Naredi"
@@ -341,6 +329,14 @@ msgstr "izjava"
msgid "built-in function"
msgstr "vgrajene funkcije"
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr "Povezava na naslov"
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr "Povezava na to definicijo"
+
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
msgstr "Skrij Resultate Iskanja"
@@ -361,11 +357,11 @@ msgstr "modul, v "
msgid ", in "
msgstr ", v "
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
msgid "Search Results"
msgstr "Rezultati Iskanja"
-#: sphinx/static/searchtools.js:449
+#: sphinx/static/searchtools.js:455
msgid ""
"Your search did not match any documents. Please make sure that all words "
"are spelled correctly and that you've selected enough categories."
@@ -373,7 +369,7 @@ msgstr ""
"Za vaše iskanje ni rezultatov. Prosimo preglejte ali so vse besede "
"pravilno črkovane in ali ste izbrali dovolj kategorij."
-#: sphinx/static/searchtools.js:451
+#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr "Iskanje končano, najdeno %s strani, ki ustrezajo iskalnemu nizu."
@@ -449,68 +445,61 @@ msgstr "Naslednja tema"
msgid "next chapter"
msgstr "naslednje poglavje"
-#: sphinx/templates/layout.html:55
+#: sphinx/templates/layout.html:56
msgid "This Page"
msgstr "Ta stran"
-#: sphinx/templates/layout.html:59
-msgid "Suggest Change"
-msgstr "Predlagaj spremembo"
-
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:58
msgid "Show Source"
msgstr "Prikaži izvorno kodo"
-#: sphinx/templates/layout.html:71
+#: sphinx/templates/layout.html:67
msgid "Quick search"
msgstr "Hitro iskanje"
-#: sphinx/templates/layout.html:71
-msgid "Keyword search"
-msgstr "Iskanje po ključniih besedah"
-
-#: sphinx/templates/layout.html:73
+#: sphinx/templates/layout.html:69
msgid "Go"
msgstr "Potrdi"
-#: sphinx/templates/layout.html:78
-msgid "Enter a module, class or function name."
+#: sphinx/templates/layout.html:73
+#, fuzzy
+msgid "Enter search terms or a module, class or function name."
msgstr "Vnesi ime mudla, razreda ali funkcije."
-#: sphinx/templates/layout.html:119
+#: sphinx/templates/layout.html:106
#, python-format
msgid "Search within %(docstitle)s"
msgstr "Išči med %(docstitle)s"
-#: sphinx/templates/layout.html:128
+#: sphinx/templates/layout.html:115
msgid "About these documents"
msgstr "O teh dokumentih"
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Išči"
-#: sphinx/templates/layout.html:133
+#: sphinx/templates/layout.html:120
msgid "Copyright"
msgstr "Vse pravice pridržane"
-#: sphinx/templates/layout.html:178
+#: sphinx/templates/layout.html:165
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr "&copy; <a href=\"%(path)s\">Vse pravice pridržane</a> %(copyright)s."
-#: sphinx/templates/layout.html:180
+#: sphinx/templates/layout.html:167
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Vse pravice pridržane %(copyright)s."
-#: sphinx/templates/layout.html:183
+#: sphinx/templates/layout.html:170
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr "Zadnjič posodobljeno na %(last_updated)s."
-#: sphinx/templates/layout.html:186
+#: sphinx/templates/layout.html:173
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
@@ -519,15 +508,7 @@ msgstr ""
"Narejeno s <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s."
-#: sphinx/templates/modindex.html:15
-msgid "Most popular modules:"
-msgstr "Najbolj popularni moduli:"
-
-#: sphinx/templates/modindex.html:24
-msgid "Show modules only available on these platforms"
-msgstr "Prikaži module na razpolago na platformah"
-
-#: sphinx/templates/modindex.html:56
+#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "Zastarelo"
@@ -536,16 +517,6 @@ msgstr "Zastarelo"
msgid "Search %(docstitle)s"
msgstr "Išči %(docstitle)s"
-#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-"<strong>Opomba:</strong> Vaš zahtevek za URL s tega streznika je "
-"zastaral. Poskušali smo vas preusmeriti na novo lokacijo, vendar utegne "
-"biti napačna."
-
#: sphinx/templates/search.html:7
#, fuzzy
msgid ""
@@ -595,3 +566,40 @@ msgstr "C API spremembe"
msgid "Other changes"
msgstr "Ostale spremembe"
+#: sphinx/writers/latex.py:173
+msgid "Release"
+msgstr "Izdaja"
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr "Platforma: %s"
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr "[slika]"
+
+#~ msgid "Suggest Change"
+#~ msgstr "Predlagaj spremembo"
+
+#~ msgid "Keyword search"
+#~ msgstr "Iskanje po ključniih besedah"
+
+#~ msgid "Most popular modules:"
+#~ msgstr "Najbolj popularni moduli:"
+
+#~ msgid "Show modules only available on these platforms"
+#~ msgstr "Prikaži module na razpolago na platformah"
+
+#~ msgid ""
+#~ "<strong>Note:</strong> You requested an "
+#~ "out-of-date URL from this server. "
+#~ "We've tried to redirect you to the"
+#~ " new location of this page, but "
+#~ "it may not be the right one."
+#~ msgstr ""
+#~ "<strong>Opomba:</strong> Vaš zahtevek za URL"
+#~ " s tega streznika je zastaral. "
+#~ "Poskušali smo vas preusmeriti na novo"
+#~ " lokacijo, vendar utegne biti napačna."
+
diff --git a/sphinx/locale/sphinx.pot b/sphinx/locale/sphinx.pot
index ad78625f..bcaee360 100644
--- a/sphinx/locale/sphinx.pot
+++ b/sphinx/locale/sphinx.pot
@@ -6,111 +6,89 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: Sphinx 0.5\n"
+"Project-Id-Version: Sphinx 0.6\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2008-11-27 18:39+0100\n"
+"POT-Creation-Date: 2008-12-28 23:40+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.4\n"
+"Generated-By: Babel 0.9.3\n"
-#: sphinx/builder.py:408
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
#, python-format
-msgid "%b %d, %Y"
-msgstr ""
-
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
-msgid "General Index"
-msgstr ""
-
-#: sphinx/builder.py:427
-msgid "index"
+msgid "%B %d, %Y"
msgstr ""
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
-#: sphinx/templates/modindex.html:13
-msgid "Global Module Index"
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
+#: sphinx/templates/genindex-split.html:2
+#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
+#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
+msgid "Index"
msgstr ""
-#: sphinx/builder.py:429
-msgid "modules"
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
+msgid "Module Index"
msgstr ""
-#: sphinx/builder.py:466
-msgid "next"
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
+msgid "Search Page"
msgstr ""
-#: sphinx/builder.py:473
-msgid "previous"
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
+#, python-format
+msgid "environment variable; %s"
msgstr ""
-#: sphinx/builder.py:1054
-msgid " (in "
+#: sphinx/roles.py:60
+#, python-format
+msgid "Python Enhancement Proposals!PEP %s"
msgstr ""
-#: sphinx/builder.py:1129
+#: sphinx/builders/changes.py:64
msgid "Builtins"
msgstr ""
-#: sphinx/builder.py:1131
+#: sphinx/builders/changes.py:66
msgid "Module level"
msgstr ""
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/builders/html.py:115
#, python-format
-msgid "%B %d, %Y"
-msgstr ""
-
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
-#: sphinx/templates/genindex-single.html:2
-#: sphinx/templates/genindex-split.html:2
-#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
-#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
-#: sphinx/templates/layout.html:130
-msgid "Index"
-msgstr ""
-
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
-msgid "Module Index"
-msgstr ""
-
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
-msgid "Search Page"
+msgid "%b %d, %Y"
msgstr ""
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
-msgid "Permalink to this definition"
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
msgstr ""
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
-msgid "Permalink to this headline"
+#: sphinx/builders/html.py:134
+msgid "index"
msgstr ""
-#: sphinx/latexwriter.py:172
-msgid "Release"
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
msgstr ""
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
-#, python-format
-msgid "environment variable; %s"
+#: sphinx/builders/html.py:136
+msgid "modules"
msgstr ""
-#: sphinx/roles.py:60
-#, python-format
-msgid "Python Enhancement Proposals!PEP %s"
+#: sphinx/builders/html.py:175
+msgid "next"
msgstr ""
-#: sphinx/textwriter.py:166
-#, python-format
-msgid "Platform: %s"
+#: sphinx/builders/html.py:182
+msgid "previous"
msgstr ""
-#: sphinx/textwriter.py:422
-msgid "[image]"
+#: sphinx/builders/latex.py:155
+msgid " (in "
msgstr ""
#: sphinx/directives/desc.py:25
@@ -215,11 +193,15 @@ msgstr ""
msgid "Return type"
msgstr ""
-#: sphinx/directives/desc.py:143
+#: sphinx/directives/desc.py:201
+msgid "Parameter"
+msgstr ""
+
+#: sphinx/directives/desc.py:205
msgid "Parameters"
msgstr ""
-#: sphinx/directives/desc.py:423
+#: sphinx/directives/desc.py:450
#, python-format
msgid "%scommand line option; %s"
msgstr ""
@@ -245,10 +227,15 @@ msgstr ""
msgid "Author: "
msgstr ""
-#: sphinx/directives/other.py:246
+#: sphinx/directives/other.py:249
msgid "See also"
msgstr ""
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr ""
@@ -345,6 +332,14 @@ msgstr ""
msgid "built-in function"
msgstr ""
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr ""
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr ""
+
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
msgstr ""
@@ -365,17 +360,17 @@ msgstr ""
msgid ", in "
msgstr ""
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
msgid "Search Results"
msgstr ""
-#: sphinx/static/searchtools.js:449
+#: sphinx/static/searchtools.js:455
msgid ""
"Your search did not match any documents. Please make sure that all words "
"are spelled correctly and that you've selected enough categories."
msgstr ""
-#: sphinx/static/searchtools.js:451
+#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr ""
@@ -451,83 +446,67 @@ msgstr ""
msgid "next chapter"
msgstr ""
-#: sphinx/templates/layout.html:55
+#: sphinx/templates/layout.html:56
msgid "This Page"
msgstr ""
-#: sphinx/templates/layout.html:59
-msgid "Suggest Change"
-msgstr ""
-
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:58
msgid "Show Source"
msgstr ""
-#: sphinx/templates/layout.html:71
+#: sphinx/templates/layout.html:67
msgid "Quick search"
msgstr ""
-#: sphinx/templates/layout.html:71
-msgid "Keyword search"
-msgstr ""
-
-#: sphinx/templates/layout.html:73
+#: sphinx/templates/layout.html:69
msgid "Go"
msgstr ""
-#: sphinx/templates/layout.html:78
-msgid "Enter a module, class or function name."
+#: sphinx/templates/layout.html:73
+msgid "Enter search terms or a module, class or function name."
msgstr ""
-#: sphinx/templates/layout.html:119
+#: sphinx/templates/layout.html:106
#, python-format
msgid "Search within %(docstitle)s"
msgstr ""
-#: sphinx/templates/layout.html:128
+#: sphinx/templates/layout.html:115
msgid "About these documents"
msgstr ""
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr ""
-#: sphinx/templates/layout.html:133
+#: sphinx/templates/layout.html:120
msgid "Copyright"
msgstr ""
-#: sphinx/templates/layout.html:178
+#: sphinx/templates/layout.html:165
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr ""
-#: sphinx/templates/layout.html:180
+#: sphinx/templates/layout.html:167
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr ""
-#: sphinx/templates/layout.html:183
+#: sphinx/templates/layout.html:170
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr ""
-#: sphinx/templates/layout.html:186
+#: sphinx/templates/layout.html:173
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s."
msgstr ""
-#: sphinx/templates/modindex.html:15
-msgid "Most popular modules:"
-msgstr ""
-
-#: sphinx/templates/modindex.html:24
-msgid "Show modules only available on these platforms"
-msgstr ""
-
-#: sphinx/templates/modindex.html:56
+#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr ""
@@ -536,13 +515,6 @@ msgstr ""
msgid "Search %(docstitle)s"
msgstr ""
-#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-
#: sphinx/templates/search.html:7
msgid ""
"From here you can search these documents. Enter your search\n"
@@ -587,3 +559,16 @@ msgstr ""
msgid "Other changes"
msgstr ""
+#: sphinx/writers/latex.py:173
+msgid "Release"
+msgstr ""
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr ""
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr ""
+
diff --git a/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po b/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po
index 2b824a35..0e27e947 100644
--- a/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po
@@ -8,93 +8,37 @@ msgstr ""
"Project-Id-Version: Sphinx 0.5\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2008-11-09 19:46+0100\n"
-"PO-Revision-Date: 2008-11-27 18:40+0100\n"
+"PO-Revision-Date: 2008-12-28 23:40+0100\n"
"Last-Translator: Fred Lin <gasolin@gmail.com>\n"
"Language-Team: tw <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.4\n"
+"Generated-By: Babel 0.9.3\n"
-#: sphinx/builder.py:408
-#, python-format
-msgid "%b %d, %Y"
-msgstr "%Y 年 %m 月 %d 日"
-
-#: sphinx/builder.py:427 sphinx/templates/defindex.html:21
-msgid "General Index"
-msgstr "總索引"
-
-#: sphinx/builder.py:427
-msgid "index"
-msgstr "索引"
-
-#: sphinx/builder.py:429 sphinx/htmlhelp.py:156
-#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
-#: sphinx/templates/modindex.html:13
-msgid "Global Module Index"
-msgstr ""
-
-#: sphinx/builder.py:429
-msgid "modules"
-msgstr "模組"
-
-#: sphinx/builder.py:466
-msgid "next"
-msgstr "下一頁"
-
-#: sphinx/builder.py:473
-msgid "previous"
-msgstr "上一頁"
-
-#: sphinx/builder.py:1054
-msgid " (in "
-msgstr ""
-
-#: sphinx/builder.py:1129
-msgid "Builtins"
-msgstr ""
-
-#: sphinx/builder.py:1131
-msgid "Module level"
-msgstr ""
-
-#: sphinx/environment.py:102 sphinx/latexwriter.py:169
+#: sphinx/environment.py:103 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%Y 年 %m 月 %d 日"
-#: sphinx/environment.py:291 sphinx/latexwriter.py:175
-#: sphinx/templates/genindex-single.html:2
+#: sphinx/environment.py:293 sphinx/templates/genindex-single.html:2
#: sphinx/templates/genindex-split.html:2
#: sphinx/templates/genindex-split.html:5 sphinx/templates/genindex.html:2
#: sphinx/templates/genindex.html:5 sphinx/templates/genindex.html:48
-#: sphinx/templates/layout.html:130
+#: sphinx/templates/layout.html:117 sphinx/writers/latex.py:176
msgid "Index"
msgstr "索引"
-#: sphinx/environment.py:292 sphinx/latexwriter.py:174
+#: sphinx/environment.py:294 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "模組索引"
-#: sphinx/environment.py:293 sphinx/templates/defindex.html:16
+#: sphinx/environment.py:295 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "搜尋頁面"
-#: sphinx/htmlwriter.py:79 sphinx/static/doctools.js:145
-msgid "Permalink to this definition"
-msgstr ""
-
-#: sphinx/htmlwriter.py:399 sphinx/static/doctools.js:139
-msgid "Permalink to this headline"
-msgstr ""
-
-#: sphinx/latexwriter.py:172
-msgid "Release"
-msgstr "釋出"
-
-#: sphinx/roles.py:53 sphinx/directives/desc.py:537
+#: sphinx/roles.py:53 sphinx/directives/desc.py:564
#, python-format
msgid "environment variable; %s"
msgstr "環境變數; %s"
@@ -104,14 +48,48 @@ msgstr "環境變數; %s"
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python 建議文件!PEP %s"
-#: sphinx/textwriter.py:166
+#: sphinx/builders/changes.py:64
+msgid "Builtins"
+msgstr ""
+
+#: sphinx/builders/changes.py:66
+msgid "Module level"
+msgstr ""
+
+#: sphinx/builders/html.py:115
#, python-format
-msgid "Platform: %s"
-msgstr "平台:%s"
+msgid "%b %d, %Y"
+msgstr "%Y 年 %m 月 %d 日"
-#: sphinx/textwriter.py:422
-msgid "[image]"
-msgstr "[圖片]"
+#: sphinx/builders/html.py:134 sphinx/templates/defindex.html:21
+msgid "General Index"
+msgstr "總索引"
+
+#: sphinx/builders/html.py:134
+msgid "index"
+msgstr "索引"
+
+#: sphinx/builders/html.py:136 sphinx/builders/htmlhelp.py:180
+#: sphinx/builders/qthelp.py:129 sphinx/templates/defindex.html:19
+#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
+msgid "Global Module Index"
+msgstr ""
+
+#: sphinx/builders/html.py:136
+msgid "modules"
+msgstr "模組"
+
+#: sphinx/builders/html.py:175
+msgid "next"
+msgstr "下一頁"
+
+#: sphinx/builders/html.py:182
+msgid "previous"
+msgstr "上一頁"
+
+#: sphinx/builders/latex.py:155
+msgid " (in "
+msgstr ""
#: sphinx/directives/desc.py:25
#, python-format
@@ -215,11 +193,16 @@ msgstr "返回"
msgid "Return type"
msgstr "返回類別"
-#: sphinx/directives/desc.py:143
+#: sphinx/directives/desc.py:201
+#, fuzzy
+msgid "Parameter"
+msgstr "參數"
+
+#: sphinx/directives/desc.py:205
msgid "Parameters"
msgstr "參數"
-#: sphinx/directives/desc.py:423
+#: sphinx/directives/desc.py:450
#, python-format
msgid "%scommand line option; %s"
msgstr "%s命令列選項; %s"
@@ -245,10 +228,15 @@ msgstr "模組作者:"
msgid "Author: "
msgstr "作者:"
-#: sphinx/directives/other.py:246
+#: sphinx/directives/other.py:249
msgid "See also"
msgstr ""
+#: sphinx/ext/autodoc.py:576 sphinx/ext/autodoc.py:590
+#, python-format
+msgid "alias of :class:`%s`"
+msgstr ""
+
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr "待辦"
@@ -345,6 +333,14 @@ msgstr ""
msgid "built-in function"
msgstr "內建函式"
+#: sphinx/static/doctools.js:139 sphinx/writers/html.py:415
+msgid "Permalink to this headline"
+msgstr ""
+
+#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
+msgid "Permalink to this definition"
+msgstr ""
+
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
msgstr ""
@@ -365,17 +361,17 @@ msgstr ""
msgid ", in "
msgstr ""
-#: sphinx/static/searchtools.js:447 sphinx/templates/search.html:18
+#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:18
msgid "Search Results"
msgstr "搜尋結果"
-#: sphinx/static/searchtools.js:449
+#: sphinx/static/searchtools.js:455
msgid ""
"Your search did not match any documents. Please make sure that all words "
"are spelled correctly and that you've selected enough categories."
msgstr ""
-#: sphinx/static/searchtools.js:451
+#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr ""
@@ -451,83 +447,68 @@ msgstr "下一個主題"
msgid "next chapter"
msgstr "下一章"
-#: sphinx/templates/layout.html:55
+#: sphinx/templates/layout.html:56
msgid "This Page"
msgstr "本頁"
-#: sphinx/templates/layout.html:59
-msgid "Suggest Change"
-msgstr ""
-
-#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
+#: sphinx/templates/layout.html:58
msgid "Show Source"
msgstr "顯示原始碼"
-#: sphinx/templates/layout.html:71
+#: sphinx/templates/layout.html:67
msgid "Quick search"
msgstr "快速搜尋"
-#: sphinx/templates/layout.html:71
-msgid "Keyword search"
-msgstr "關鍵字搜尋"
-
-#: sphinx/templates/layout.html:73
+#: sphinx/templates/layout.html:69
msgid "Go"
msgstr ""
-#: sphinx/templates/layout.html:78
-msgid "Enter a module, class or function name."
+#: sphinx/templates/layout.html:73
+#, fuzzy
+msgid "Enter search terms or a module, class or function name."
msgstr "輸入一個模組、類別、或是函式名稱."
-#: sphinx/templates/layout.html:119
+#: sphinx/templates/layout.html:106
#, python-format
msgid "Search within %(docstitle)s"
msgstr "在 %(docstitle)s 中搜尋"
-#: sphinx/templates/layout.html:128
+#: sphinx/templates/layout.html:115
msgid "About these documents"
msgstr ""
-#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
+#: sphinx/templates/layout.html:118 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "搜尋"
-#: sphinx/templates/layout.html:133
+#: sphinx/templates/layout.html:120
msgid "Copyright"
msgstr "版權所有"
-#: sphinx/templates/layout.html:178
+#: sphinx/templates/layout.html:165
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr ""
-#: sphinx/templates/layout.html:180
+#: sphinx/templates/layout.html:167
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr ""
-#: sphinx/templates/layout.html:183
+#: sphinx/templates/layout.html:170
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr "最後更新日期是 %(last_updated)s."
-#: sphinx/templates/layout.html:186
+#: sphinx/templates/layout.html:173
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s."
msgstr ""
-#: sphinx/templates/modindex.html:15
-msgid "Most popular modules:"
-msgstr ""
-
-#: sphinx/templates/modindex.html:24
-msgid "Show modules only available on these platforms"
-msgstr ""
-
-#: sphinx/templates/modindex.html:56
+#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "已移除"
@@ -536,13 +517,6 @@ msgstr "已移除"
msgid "Search %(docstitle)s"
msgstr "搜尋 %(docstitle)s"
-#: sphinx/templates/page.html:8
-msgid ""
-"<strong>Note:</strong> You requested an out-of-date URL from this server."
-" We've tried to redirect you to the new location of this page, but it may"
-" not be the right one."
-msgstr ""
-
#: sphinx/templates/search.html:7
msgid ""
"From here you can search these documents. Enter your search\n"
@@ -587,12 +561,36 @@ msgstr "C API 改變"
msgid "Other changes"
msgstr "其他改變:"
+#: sphinx/writers/latex.py:173
+msgid "Release"
+msgstr "釋出"
+
+#: sphinx/writers/text.py:166
+#, python-format
+msgid "Platform: %s"
+msgstr "平台:%s"
+
+#: sphinx/writers/text.py:427
+msgid "[image]"
+msgstr "[圖片]"
+
+#~ msgid "Suggest Change"
+#~ msgstr ""
+
+#~ msgid "Keyword search"
+#~ msgstr "關鍵字搜尋"
+
+#~ msgid "Most popular modules:"
+#~ msgstr ""
+
+#~ msgid "Show modules only available on these platforms"
+#~ msgstr ""
+
#~ msgid ""
-#~ "From here you can search these documents. Enter your search\n"
-#~ " words into the box below and"
-#~ " click \"search\". Note that the "
-#~ "search\n"
-#~ " function will automatically search for all of the words. Pages\n"
-#~ " containing less words won't appear in the result list."
+#~ "<strong>Note:</strong> You requested an "
+#~ "out-of-date URL from this server. "
+#~ "We've tried to redirect you to the"
+#~ " new location of this page, but "
+#~ "it may not be the right one."
#~ msgstr ""
diff --git a/sphinx/pycode/Grammar.txt b/sphinx/pycode/Grammar.txt
new file mode 100644
index 00000000..1f4a50ff
--- /dev/null
+++ b/sphinx/pycode/Grammar.txt
@@ -0,0 +1,155 @@
+# Grammar for Python
+
+# Note: Changing the grammar specified in this file will most likely
+# require corresponding changes in the parser module
+# (../Modules/parsermodule.c). If you can't make the changes to
+# that module yourself, please co-ordinate the required changes
+# with someone who can; ask around on python-dev for help. Fred
+# Drake <fdrake@acm.org> will probably be listening there.
+
+# NOTE WELL: You should also follow all the steps listed in PEP 306,
+# "How to Change Python's Grammar"
+
+# Commands for Kees Blom's railroad program
+#diagram:token NAME
+#diagram:token NUMBER
+#diagram:token STRING
+#diagram:token NEWLINE
+#diagram:token ENDMARKER
+#diagram:token INDENT
+#diagram:output\input python.bla
+#diagram:token DEDENT
+#diagram:output\textwidth 20.04cm\oddsidemargin 0.0cm\evensidemargin 0.0cm
+#diagram:rules
+
+# Start symbols for the grammar:
+# file_input is a module or sequence of commands read from an input file;
+# single_input is a single interactive statement;
+# eval_input is the input for the eval() and input() functions.
+# NB: compound_stmt in single_input is followed by extra NEWLINE!
+file_input: (NEWLINE | stmt)* ENDMARKER
+single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+eval_input: testlist NEWLINE* ENDMARKER
+
+decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+decorators: decorator+
+decorated: decorators (classdef | funcdef)
+funcdef: 'def' NAME parameters ['->' test] ':' suite
+parameters: '(' [typedargslist] ')'
+typedargslist: ((tfpdef ['=' test] ',')*
+ ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname)
+ | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
+tname: NAME [':' test]
+tfpdef: tname | '(' tfplist ')'
+tfplist: tfpdef (',' tfpdef)* [',']
+varargslist: ((vfpdef ['=' test] ',')*
+ ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname)
+ | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+vname: NAME
+vfpdef: vname | '(' vfplist ')'
+vfplist: vfpdef (',' vfpdef)* [',']
+
+stmt: simple_stmt | compound_stmt
+simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
+small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt |
+ import_stmt | global_stmt | exec_stmt | assert_stmt)
+expr_stmt: testlist (augassign (yield_expr|testlist) |
+ ('=' (yield_expr|testlist))*)
+augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
+ '<<=' | '>>=' | '**=' | '//=')
+# For normal assignments, additional restrictions enforced by the interpreter
+print_stmt: 'print' ( [ test (',' test)* [','] ] |
+ '>>' test [ (',' test)+ [','] ] )
+del_stmt: 'del' exprlist
+pass_stmt: 'pass'
+flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
+break_stmt: 'break'
+continue_stmt: 'continue'
+return_stmt: 'return' [testlist]
+yield_stmt: yield_expr
+raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]]
+import_stmt: import_name | import_from
+import_name: 'import' dotted_as_names
+import_from: ('from' ('.'* dotted_name | '.'+)
+ 'import' ('*' | '(' import_as_names ')' | import_as_names))
+import_as_name: NAME ['as' NAME]
+dotted_as_name: dotted_name ['as' NAME]
+import_as_names: import_as_name (',' import_as_name)* [',']
+dotted_as_names: dotted_as_name (',' dotted_as_name)*
+dotted_name: NAME ('.' NAME)*
+global_stmt: ('global' | 'nonlocal') NAME (',' NAME)*
+exec_stmt: 'exec' expr ['in' test [',' test]]
+assert_stmt: 'assert' test [',' test]
+
+compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
+if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+while_stmt: 'while' test ':' suite ['else' ':' suite]
+for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
+try_stmt: ('try' ':' suite
+ ((except_clause ':' suite)+
+ ['else' ':' suite]
+ ['finally' ':' suite] |
+ 'finally' ':' suite))
+with_stmt: 'with' test [ with_var ] ':' suite
+with_var: 'as' expr
+# NB compile.c makes sure that the default except clause is last
+except_clause: 'except' [test [(',' | 'as') test]]
+suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
+
+# Backward compatibility cruft to support:
+# [ x for x in lambda: True, lambda: False if x() ]
+# even while also allowing:
+# lambda x: 5 if x else 2
+# (But not a mix of the two)
+testlist_safe: old_test [(',' old_test)+ [',']]
+old_test: or_test | old_lambdef
+old_lambdef: 'lambda' [varargslist] ':' old_test
+
+test: or_test ['if' or_test 'else' test] | lambdef
+or_test: and_test ('or' and_test)*
+and_test: not_test ('and' not_test)*
+not_test: 'not' not_test | comparison
+comparison: expr (comp_op expr)*
+comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+expr: xor_expr ('|' xor_expr)*
+xor_expr: and_expr ('^' and_expr)*
+and_expr: shift_expr ('&' shift_expr)*
+shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+arith_expr: term (('+'|'-') term)*
+term: factor (('*'|'/'|'%'|'//') factor)*
+factor: ('+'|'-'|'~') factor | power
+power: atom trailer* ['**' factor]
+atom: ('(' [yield_expr|testlist_gexp] ')' |
+ '[' [listmaker] ']' |
+ '{' [dictsetmaker] '}' |
+ '`' testlist1 '`' |
+ NAME | NUMBER | STRING+ | '.' '.' '.')
+listmaker: test ( comp_for | (',' test)* [','] )
+testlist_gexp: test ( comp_for | (',' test)* [','] )
+lambdef: 'lambda' [varargslist] ':' test
+trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+subscriptlist: subscript (',' subscript)* [',']
+subscript: test | [test] ':' [test] [sliceop]
+sliceop: ':' [test]
+exprlist: expr (',' expr)* [',']
+testlist: test (',' test)* [',']
+dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
+ (test (comp_for | (',' test)* [','])) )
+
+classdef: 'class' NAME ['(' [arglist] ')'] ':' suite
+
+arglist: (argument ',')* (argument [',']
+ |'*' test (',' argument)* [',' '**' test]
+ |'**' test)
+argument: test [comp_for] | test '=' test # Really [keyword '='] test
+
+comp_iter: comp_for | comp_if
+comp_for: 'for' exprlist 'in' testlist_safe [comp_iter]
+comp_if: 'if' old_test [comp_iter]
+
+testlist1: test (',' test)*
+
+# not used in grammar, but may appear in "node" passed from Parser to Compiler
+encoding_decl: NAME
+
+yield_expr: 'yield' [testlist]
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py
new file mode 100644
index 00000000..c2086da5
--- /dev/null
+++ b/sphinx/pycode/__init__.py
@@ -0,0 +1,306 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.pycode
+ ~~~~~~~~~~~~~
+
+ Utilities parsing and analyzing Python code.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import re
+import sys
+from os import path
+from cStringIO import StringIO
+
+from sphinx.pycode import nodes
+from sphinx.pycode.pgen2 import driver, token, tokenize, parse, literals
+from sphinx.util.docstrings import prepare_docstring, prepare_commentdoc
+
+
+# load the Python grammar
+_grammarfile = path.join(path.dirname(__file__), 'Grammar.txt')
+pygrammar = driver.load_grammar(_grammarfile)
+pydriver = driver.Driver(pygrammar, convert=nodes.convert)
+
+# an object with attributes corresponding to token and symbol names
+class sym: pass
+for k, v in pygrammar.symbol2number.iteritems():
+ setattr(sym, k, v)
+for k, v in token.tok_name.iteritems():
+ setattr(sym, v, k)
+
+# a dict mapping terminal and nonterminal numbers to their names
+number2name = pygrammar.number2symbol.copy()
+number2name.update(token.tok_name)
+
+
+# a regex to recognize coding cookies
+_coding_re = re.compile(r'coding[:=]\s*([-\w.]+)')
+
+_eq = nodes.Leaf(token.EQUAL, '=')
+
+
+class AttrDocVisitor(nodes.NodeVisitor):
+ """
+ Visitor that collects docstrings for attribute assignments on toplevel and
+ in classes.
+
+ The docstrings can either be in special '#:' comments before the assignment
+ or in a docstring after it.
+ """
+ def init(self, scope, encoding):
+ self.scope = scope
+ self.encoding = encoding
+ self.namespace = []
+ self.collected = {}
+
+ def visit_classdef(self, node):
+ self.namespace.append(node[1].value)
+ self.generic_visit(node)
+ self.namespace.pop()
+
+ def visit_expr_stmt(self, node):
+ """Visit an assignment which may have a special comment before it."""
+ if _eq not in node.children:
+ # not an assignment (we don't care for augmented assignments)
+ return
+ pnode = node[0]
+ prefix = pnode.get_prefix()
+ # if the assignment is the first statement on a new indentation
+ # level, its preceding whitespace and comments are not assigned
+ # to that token, but the first INDENT or DEDENT token
+ while not prefix:
+ pnode = pnode.get_prev_leaf()
+ if not pnode or pnode.type not in (token.INDENT, token.DEDENT):
+ break
+ prefix = pnode.get_prefix()
+ prefix = prefix.decode(self.encoding)
+ docstring = prepare_commentdoc(prefix)
+ if docstring:
+ self.add_docstring(node, docstring)
+
+ def visit_simple_stmt(self, node):
+ """Visit a docstring statement which may have an assignment before."""
+ if node[0].type != token.STRING:
+ # not a docstring; but still need to visit children
+ return self.generic_visit(node)
+ prev = node.get_prev_sibling()
+ if not prev:
+ return
+ if prev.type == sym.simple_stmt and \
+ prev[0].type == sym.expr_stmt and _eq in prev[0].children:
+ # need to "eval" the string because it's returned in its original form
+ docstring = literals.evalString(node[0].value, self.encoding)
+ docstring = prepare_docstring(docstring)
+ self.add_docstring(prev[0], docstring)
+
+ def visit_funcdef(self, node):
+ # don't descend into functions -- nothing interesting there
+ return
+
+ def add_docstring(self, node, docstring):
+ # add an item for each assignment target
+ for i in range(0, len(node) - 1, 2):
+ target = node[i]
+ if target.type != token.NAME:
+ # don't care about complex targets
+ continue
+ namespace = '.'.join(self.namespace)
+ if namespace.startswith(self.scope):
+ self.collected[namespace, target.value] = docstring
+
+
+class PycodeError(Exception):
+ def __str__(self):
+ res = self.args[0]
+ if len(self.args) > 1:
+ res += ' (exception was: %r)' % self.args[1]
+ return res
+
+
+class ModuleAnalyzer(object):
+ # cache for analyzer objects -- caches both by module and file name
+ cache = {}
+
+ @classmethod
+ def for_string(cls, string, modname, srcname='<string>'):
+ return cls(StringIO(string), modname, srcname)
+
+ @classmethod
+ def for_file(cls, filename, modname):
+ if ('file', filename) in cls.cache:
+ return cls.cache['file', filename]
+ try:
+ fileobj = open(filename, 'r')
+ except Exception, err:
+ raise PycodeError('error opening %r' % filename, err)
+ obj = cls(fileobj, modname, filename)
+ cls.cache['file', filename] = obj
+ return obj
+
+ @classmethod
+ def for_module(cls, modname):
+ if ('module', modname) in cls.cache:
+ entry = cls.cache['module', modname]
+ if isinstance(entry, PycodeError):
+ raise entry
+ return entry
+
+ try:
+ if modname not in sys.modules:
+ try:
+ __import__(modname)
+ except ImportError, err:
+ raise PycodeError('error importing %r' % modname, err)
+ mod = sys.modules[modname]
+ if hasattr(mod, '__loader__'):
+ try:
+ source = mod.__loader__.get_source(modname)
+ except Exception, err:
+ raise PycodeError('error getting source for %r' % modname, err)
+ obj = cls.for_string(source, modname)
+ cls.cache['module', modname] = obj
+ return obj
+ filename = getattr(mod, '__file__', None)
+ if filename is None:
+ raise PycodeError('no source found for module %r' % modname)
+ filename = path.normpath(filename)
+ lfilename = filename.lower()
+ if lfilename.endswith('.pyo') or lfilename.endswith('.pyc'):
+ filename = filename[:-1]
+ elif not lfilename.endswith('.py'):
+ raise PycodeError('source is not a .py file: %r' % filename)
+ if not path.isfile(filename):
+ raise PycodeError('source file is not present: %r' % filename)
+ obj = cls.for_file(filename, modname)
+ except PycodeError, err:
+ cls.cache['module', modname] = err
+ raise
+ cls.cache['module', modname] = obj
+ return obj
+
+ def __init__(self, source, modname, srcname):
+ # name of the module
+ self.modname = modname
+ # name of the source file
+ self.srcname = srcname
+ # file-like object yielding source lines
+ self.source = source
+
+ # will be filled by tokenize()
+ self.tokens = None
+ # will be filled by parse()
+ self.parsetree = None
+ # will be filled by find_attr_docs()
+ self.attr_docs = None
+ # will be filled by find_tags()
+ self.tags = None
+
+ def tokenize(self):
+ """Generate tokens from the source."""
+ if self.tokens is not None:
+ return
+ self.tokens = list(tokenize.generate_tokens(self.source.readline))
+ self.source.close()
+
+ def parse(self):
+ """Parse the generated source tokens."""
+ if self.parsetree is not None:
+ return
+ self.tokenize()
+ try:
+ self.parsetree = pydriver.parse_tokens(self.tokens)
+ except parse.ParseError, err:
+ raise PycodeError('parsing failed', err)
+ # find the source code encoding
+ encoding = sys.getdefaultencoding()
+ comments = self.parsetree.get_prefix()
+ for line in comments.splitlines()[:2]:
+ match = _coding_re.search(line)
+ if match is not None:
+ encoding = match.group(1)
+ break
+ self.encoding = encoding
+
+ def find_attr_docs(self, scope=''):
+ """Find class and module-level attributes and their documentation."""
+ if self.attr_docs is not None:
+ return self.attr_docs
+ self.parse()
+ attr_visitor = AttrDocVisitor(number2name, scope, self.encoding)
+ attr_visitor.visit(self.parsetree)
+ self.attr_docs = attr_visitor.collected
+ return attr_visitor.collected
+
+ def find_tags(self):
+ """Find class, function and method definitions and their location."""
+ if self.tags is not None:
+ return self.tags
+ self.tokenize()
+ result = {}
+ namespace = []
+ stack = []
+ indent = 0
+ defline = False
+ expect_indent = False
+ def tokeniter(ignore = (token.COMMENT, token.NL)):
+ for tokentup in self.tokens:
+ if tokentup[0] not in ignore:
+ yield tokentup
+ tokeniter = tokeniter()
+ for type, tok, spos, epos, line in tokeniter:
+ if expect_indent:
+ if type != token.INDENT:
+ # no suite -- one-line definition
+ assert stack
+ dtype, fullname, startline, _ = stack.pop()
+ endline = epos[0]
+ namespace.pop()
+ result[fullname] = (dtype, startline, endline)
+ expect_indent = False
+ if tok in ('def', 'class'):
+ name = tokeniter.next()[1]
+ namespace.append(name)
+ fullname = '.'.join(namespace)
+ stack.append((tok, fullname, spos[0], indent))
+ defline = True
+ elif type == token.INDENT:
+ expect_indent = False
+ indent += 1
+ elif type == token.DEDENT:
+ indent -= 1
+ # if the stacklevel is the same as it was before the last
+ # def/class block, this dedent closes that block
+ if stack and indent == stack[-1][3]:
+ dtype, fullname, startline, _ = stack.pop()
+ endline = spos[0]
+ namespace.pop()
+ result[fullname] = (dtype, startline, endline)
+ elif type == token.NEWLINE:
+ # if this line contained a definition, expect an INDENT to start the
+ # suite; if there is no such INDENT it's a one-line definition
+ if defline:
+ defline = False
+ expect_indent = True
+ self.tags = result
+ return result
+
+
+if __name__ == '__main__':
+ import time, pprint
+ x0 = time.time()
+ #ma = ModuleAnalyzer.for_file(__file__.rstrip('c'), 'sphinx.builders.html')
+ ma = ModuleAnalyzer.for_file('sphinx/builders/html.py', 'sphinx.builders.html')
+ ma.tokenize()
+ x1 = time.time()
+ ma.parse()
+ x2 = time.time()
+ #for (ns, name), doc in ma.find_attr_docs().iteritems():
+ # print '>>', ns, name
+ # print '\n'.join(doc)
+ pprint.pprint(ma.find_tags())
+ x3 = time.time()
+ #print nodes.nice_repr(ma.parsetree, number2name)
+ print "tokenizing %.4f, parsing %.4f, finding %.4f" % (x1-x0, x2-x1, x3-x2)
diff --git a/sphinx/pycode/nodes.py b/sphinx/pycode/nodes.py
new file mode 100644
index 00000000..4d27fc66
--- /dev/null
+++ b/sphinx/pycode/nodes.py
@@ -0,0 +1,202 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.pycode.nodes
+ ~~~~~~~~~~~~~~~~~~~
+
+ Parse tree node implementations.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+
+class BaseNode(object):
+ """
+ Node superclass for both terminal and nonterminal nodes.
+ """
+
+ def _eq(self, other):
+ raise NotImplementedError
+
+ def __eq__(self, other):
+ if self.__class__ is not other.__class__:
+ return NotImplemented
+ return self._eq(other)
+
+ def __ne__(self, other):
+ if self.__class__ is not other.__class__:
+ return NotImplemented
+ return not self._eq(other)
+
+ def get_prev_sibling(self):
+ """Return previous child in parent's children, or None."""
+ if self.parent is None:
+ return None
+ for i, child in enumerate(self.parent.children):
+ if child is self:
+ if i == 0:
+ return None
+ return self.parent.children[i-1]
+
+ def get_next_sibling(self):
+ """Return next child in parent's children, or None."""
+ if self.parent is None:
+ return None
+ for i, child in enumerate(self.parent.children):
+ if child is self:
+ try:
+ return self.parent.children[i+1]
+ except IndexError:
+ return None
+
+ def get_prev_leaf(self):
+ """Return the leaf node that precedes this node in the parse tree."""
+ def last_child(node):
+ if isinstance(node, Leaf):
+ return node
+ elif not node.children:
+ return None
+ else:
+ return last_child(node.children[-1])
+ if self.parent is None:
+ return None
+ prev = self.get_prev_sibling()
+ if isinstance(prev, Leaf):
+ return prev
+ elif prev is not None:
+ return last_child(prev)
+ return self.parent.get_prev_leaf()
+
+ def get_next_leaf(self):
+ """Return self if leaf, otherwise the leaf node that succeeds this
+ node in the parse tree.
+ """
+ node = self
+ while not isinstance(node, Leaf):
+ assert node.children
+ node = node.children[0]
+ return node
+
+ def get_lineno(self):
+ """Return the line number which generated the invocant node."""
+ return self.get_next_leaf().lineno
+
+ def get_prefix(self):
+ """Return the prefix of the next leaf node."""
+ # only leaves carry a prefix
+ return self.get_next_leaf().prefix
+
+
+class Node(BaseNode):
+ """
+ Node implementation for nonterminals.
+ """
+
+ def __init__(self, type, children, context=None):
+ # type of nonterminals is >= 256
+ # assert type >= 256, type
+ self.type = type
+ self.children = list(children)
+ for ch in self.children:
+ # assert ch.parent is None, repr(ch)
+ ch.parent = self
+
+ def __repr__(self):
+ return '%s(%s, %r)' % (self.__class__.__name__, self.type, self.children)
+
+ def __str__(self):
+ """This reproduces the input source exactly."""
+ return ''.join(map(str, self.children))
+
+ def _eq(self, other):
+ return (self.type, self.children) == (other.type, other.children)
+
+ # support indexing the node directly instead of .children
+
+ def __getitem__(self, index):
+ return self.children[index]
+
+ def __iter__(self):
+ return iter(self.children)
+
+ def __len__(self):
+ return len(self.children)
+
+
+class Leaf(BaseNode):
+ """
+ Node implementation for leaf nodes (terminals).
+ """
+ prefix = '' # Whitespace and comments preceding this token in the input
+ lineno = 0 # Line where this token starts in the input
+ column = 0 # Column where this token tarts in the input
+
+ def __init__(self, type, value, context=None):
+ # type of terminals is below 256
+ # assert 0 <= type < 256, type
+ self.type = type
+ self.value = value
+ if context is not None:
+ self.prefix, (self.lineno, self.column) = context
+
+ def __repr__(self):
+ return '%s(%r, %r, %r)' % (self.__class__.__name__,
+ self.type, self.value, self.prefix)
+
+ def __str__(self):
+ """This reproduces the input source exactly."""
+ return self.prefix + str(self.value)
+
+ def _eq(self, other):
+ """Compares two nodes for equality."""
+ return (self.type, self.value) == (other.type, other.value)
+
+
+def convert(grammar, raw_node):
+ """Convert raw node to a Node or Leaf instance."""
+ type, value, context, children = raw_node
+ if children or type in grammar.number2symbol:
+ # If there's exactly one child, return that child instead of
+ # creating a new node.
+ if len(children) == 1:
+ return children[0]
+ return Node(type, children, context=context)
+ else:
+ return Leaf(type, value, context=context)
+
+
+def nice_repr(node, number2name, prefix=False):
+ def _repr(node):
+ if isinstance(node, Leaf):
+ return "%s(%r)" % (number2name[node.type], node.value)
+ else:
+ return "%s(%s)" % (number2name[node.type],
+ ', '.join(map(_repr, node.children)))
+ def _prepr(node):
+ if isinstance(node, Leaf):
+ return "%s(%r, %r)" % (number2name[node.type], node.prefix, node.value)
+ else:
+ return "%s(%s)" % (number2name[node.type],
+ ', '.join(map(_prepr, node.children)))
+ return (prefix and _prepr or _repr)(node)
+
+
+class NodeVisitor(object):
+ def __init__(self, number2name, *args):
+ self.number2name = number2name
+ self.init(*args)
+
+ def init(self, *args):
+ pass
+
+ def visit(self, node):
+ """Visit a node."""
+ method = 'visit_' + self.number2name[node.type]
+ visitor = getattr(self, method, self.generic_visit)
+ return visitor(node)
+
+ def generic_visit(self, node):
+ """Called if no explicit visitor function exists for a node."""
+ if isinstance(node, Node):
+ for child in node:
+ self.visit(child)
diff --git a/sphinx/pycode/pgen2/__init__.py b/sphinx/pycode/pgen2/__init__.py
new file mode 100644
index 00000000..af390484
--- /dev/null
+++ b/sphinx/pycode/pgen2/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""The pgen2 package."""
diff --git a/sphinx/pycode/pgen2/driver.py b/sphinx/pycode/pgen2/driver.py
new file mode 100644
index 00000000..edc882fa
--- /dev/null
+++ b/sphinx/pycode/pgen2/driver.py
@@ -0,0 +1,145 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+# Modifications:
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Parser driver.
+
+This provides a high-level interface to parse a file into a syntax tree.
+
+"""
+
+__author__ = "Guido van Rossum <guido@python.org>"
+
+__all__ = ["Driver", "load_grammar"]
+
+# Python imports
+import os
+import logging
+import sys
+
+# Pgen imports
+from sphinx.pycode.pgen2 import grammar, parse, token, tokenize, pgen
+
+
+class Driver(object):
+
+ def __init__(self, grammar, convert=None, logger=None):
+ self.grammar = grammar
+ if logger is None:
+ logger = logging.getLogger()
+ self.logger = logger
+ self.convert = convert
+
+ def parse_tokens(self, tokens, debug=False):
+ """Parse a series of tokens and return the syntax tree."""
+ # XXX Move the prefix computation into a wrapper around tokenize.
+ p = parse.Parser(self.grammar, self.convert)
+ p.setup()
+ lineno = 1
+ column = 0
+ type = value = start = end = line_text = None
+ prefix = ""
+ opmap = grammar.opmap
+ for type, value, start, end, line_text in tokens:
+ if start != (lineno, column):
+ assert (lineno, column) <= start, ((lineno, column), start)
+ s_lineno, s_column = start
+ if lineno < s_lineno:
+ prefix += "\n" * (s_lineno - lineno)
+ lineno = s_lineno
+ column = 0
+ if column < s_column:
+ prefix += line_text[column:s_column]
+ column = s_column
+ if type in (tokenize.COMMENT, tokenize.NL):
+ prefix += value
+ lineno, column = end
+ if value.endswith("\n"):
+ lineno += 1
+ column = 0
+ continue
+ if type == token.OP:
+ type = opmap[value]
+ # if debug:
+ # self.logger.debug("%s %r (prefix=%r)",
+ # token.tok_name[type], value, prefix)
+ if p.addtoken(type, value, (prefix, start)):
+ # if debug:
+ # self.logger.debug("Stop.")
+ break
+ prefix = ""
+ lineno, column = end
+ if value.endswith("\n"):
+ lineno += 1
+ column = 0
+ else:
+ # We never broke out -- EOF is too soon (how can this happen???)
+ raise parse.ParseError("incomplete input", type, value, line_text)
+ return p.rootnode
+
+ def parse_stream_raw(self, stream, debug=False):
+ """Parse a stream and return the syntax tree."""
+ tokens = tokenize.generate_tokens(stream.readline)
+ return self.parse_tokens(tokens, debug)
+
+ def parse_stream(self, stream, debug=False):
+ """Parse a stream and return the syntax tree."""
+ return self.parse_stream_raw(stream, debug)
+
+ def parse_file(self, filename, debug=False):
+ """Parse a file and return the syntax tree."""
+ stream = open(filename)
+ try:
+ return self.parse_stream(stream, debug)
+ finally:
+ stream.close()
+
+ def parse_string(self, text, debug=False):
+ """Parse a string and return the syntax tree."""
+ tokens = tokenize.generate_tokens(generate_lines(text).next)
+ return self.parse_tokens(tokens, debug)
+
+
+def generate_lines(text):
+ """Generator that behaves like readline without using StringIO."""
+ for line in text.splitlines(True):
+ yield line
+ while True:
+ yield ""
+
+
+def load_grammar(gt="Grammar.txt", gp=None,
+ save=True, force=False, logger=None):
+ """Load the grammar (maybe from a pickle)."""
+ if logger is None:
+ logger = logging.getLogger()
+ if gp is None:
+ head, tail = os.path.splitext(gt)
+ if tail == ".txt":
+ tail = ""
+ gp = head + tail + ".".join(map(str, sys.version_info)) + ".pickle"
+ if force or not _newer(gp, gt):
+ logger.info("Generating grammar tables from %s", gt)
+ g = pgen.generate_grammar(gt)
+ if save:
+ logger.info("Writing grammar tables to %s", gp)
+ try:
+ g.dump(gp)
+ except IOError, e:
+ logger.info("Writing failed:"+str(e))
+ else:
+ g = grammar.Grammar()
+ g.load(gp)
+ return g
+
+
+def _newer(a, b):
+ """Inquire whether file a was written since file b."""
+ if not os.path.exists(a):
+ return False
+ if not os.path.exists(b):
+ return True
+ return os.path.getmtime(a) >= os.path.getmtime(b)
diff --git a/sphinx/pycode/pgen2/grammar.py b/sphinx/pycode/pgen2/grammar.py
new file mode 100644
index 00000000..381d80e8
--- /dev/null
+++ b/sphinx/pycode/pgen2/grammar.py
@@ -0,0 +1,171 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""This module defines the data structures used to represent a grammar.
+
+These are a bit arcane because they are derived from the data
+structures used by Python's 'pgen' parser generator.
+
+There's also a table here mapping operators to their names in the
+token module; the Python tokenize module reports all operators as the
+fallback token code OP, but the parser needs the actual token code.
+
+"""
+
+# Python imports
+import pickle
+
+# Local imports
+from sphinx.pycode.pgen2 import token, tokenize
+
+
+class Grammar(object):
+ """Pgen parsing tables tables conversion class.
+
+ Once initialized, this class supplies the grammar tables for the
+ parsing engine implemented by parse.py. The parsing engine
+ accesses the instance variables directly. The class here does not
+ provide initialization of the tables; several subclasses exist to
+ do this (see the conv and pgen modules).
+
+ The load() method reads the tables from a pickle file, which is
+ much faster than the other ways offered by subclasses. The pickle
+ file is written by calling dump() (after loading the grammar
+ tables using a subclass). The report() method prints a readable
+ representation of the tables to stdout, for debugging.
+
+ The instance variables are as follows:
+
+ symbol2number -- a dict mapping symbol names to numbers. Symbol
+ numbers are always 256 or higher, to distinguish
+ them from token numbers, which are between 0 and
+ 255 (inclusive).
+
+ number2symbol -- a dict mapping numbers to symbol names;
+ these two are each other's inverse.
+
+ states -- a list of DFAs, where each DFA is a list of
+ states, each state is is a list of arcs, and each
+ arc is a (i, j) pair where i is a label and j is
+ a state number. The DFA number is the index into
+ this list. (This name is slightly confusing.)
+ Final states are represented by a special arc of
+ the form (0, j) where j is its own state number.
+
+ dfas -- a dict mapping symbol numbers to (DFA, first)
+ pairs, where DFA is an item from the states list
+ above, and first is a set of tokens that can
+ begin this grammar rule (represented by a dict
+ whose values are always 1).
+
+ labels -- a list of (x, y) pairs where x is either a token
+ number or a symbol number, and y is either None
+ or a string; the strings are keywords. The label
+ number is the index in this list; label numbers
+ are used to mark state transitions (arcs) in the
+ DFAs.
+
+ start -- the number of the grammar's start symbol.
+
+ keywords -- a dict mapping keyword strings to arc labels.
+
+ tokens -- a dict mapping token numbers to arc labels.
+
+ """
+
+ def __init__(self):
+ self.symbol2number = {}
+ self.number2symbol = {}
+ self.states = []
+ self.dfas = {}
+ self.labels = [(0, "EMPTY")]
+ self.keywords = {}
+ self.tokens = {}
+ self.symbol2label = {}
+ self.start = 256
+
+ def dump(self, filename):
+ """Dump the grammar tables to a pickle file."""
+ f = open(filename, "wb")
+ pickle.dump(self.__dict__, f, 2)
+ f.close()
+
+ def load(self, filename):
+ """Load the grammar tables from a pickle file."""
+ f = open(filename, "rb")
+ d = pickle.load(f)
+ f.close()
+ self.__dict__.update(d)
+
+ def report(self):
+ """Dump the grammar tables to standard output, for debugging."""
+ from pprint import pprint
+ print "s2n"
+ pprint(self.symbol2number)
+ print "n2s"
+ pprint(self.number2symbol)
+ print "states"
+ pprint(self.states)
+ print "dfas"
+ pprint(self.dfas)
+ print "labels"
+ pprint(self.labels)
+ print "start", self.start
+
+
+# Map from operator to number (since tokenize doesn't do this)
+
+opmap_raw = """
+( LPAR
+) RPAR
+[ LSQB
+] RSQB
+: COLON
+, COMMA
+; SEMI
++ PLUS
+- MINUS
+* STAR
+/ SLASH
+| VBAR
+& AMPER
+< LESS
+> GREATER
+= EQUAL
+. DOT
+% PERCENT
+` BACKQUOTE
+{ LBRACE
+} RBRACE
+@ AT
+== EQEQUAL
+!= NOTEQUAL
+<> NOTEQUAL
+<= LESSEQUAL
+>= GREATEREQUAL
+~ TILDE
+^ CIRCUMFLEX
+<< LEFTSHIFT
+>> RIGHTSHIFT
+** DOUBLESTAR
++= PLUSEQUAL
+-= MINEQUAL
+*= STAREQUAL
+/= SLASHEQUAL
+%= PERCENTEQUAL
+&= AMPEREQUAL
+|= VBAREQUAL
+^= CIRCUMFLEXEQUAL
+<<= LEFTSHIFTEQUAL
+>>= RIGHTSHIFTEQUAL
+**= DOUBLESTAREQUAL
+// DOUBLESLASH
+//= DOUBLESLASHEQUAL
+-> RARROW
+"""
+
+opmap = {}
+for line in opmap_raw.splitlines():
+ if line:
+ op, name = line.split()
+ opmap[op] = getattr(token, name)
diff --git a/sphinx/pycode/pgen2/literals.py b/sphinx/pycode/pgen2/literals.py
new file mode 100644
index 00000000..31900291
--- /dev/null
+++ b/sphinx/pycode/pgen2/literals.py
@@ -0,0 +1,96 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+# Extended to handle raw and unicode literals by Georg Brandl.
+
+"""Safely evaluate Python string literals without using eval()."""
+
+import re
+
+simple_escapes = {"a": "\a",
+ "b": "\b",
+ "f": "\f",
+ "n": "\n",
+ "r": "\r",
+ "t": "\t",
+ "v": "\v",
+ "'": "'",
+ '"': '"',
+ "\\": "\\"}
+
+def convert_hex(x, n):
+ if len(x) < n+1:
+ raise ValueError("invalid hex string escape ('\\%s')" % x)
+ try:
+ return int(x[1:], 16)
+ except ValueError:
+ raise ValueError("invalid hex string escape ('\\%s')" % x)
+
+def escape(m):
+ all, tail = m.group(0, 1)
+ assert all.startswith("\\")
+ esc = simple_escapes.get(tail)
+ if esc is not None:
+ return esc
+ elif tail.startswith("x"):
+ return chr(convert_hex(tail, 2))
+ elif tail.startswith('u'):
+ return unichr(convert_hex(tail, 4))
+ elif tail.startswith('U'):
+ return unichr(convert_hex(tail, 8))
+ elif tail.startswith('N'):
+ import unicodedata
+ try:
+ return unicodedata.lookup(tail[1:-1])
+ except KeyError:
+ raise ValueError("undefined character name %r" % tail[1:-1])
+ else:
+ try:
+ return chr(int(tail, 8))
+ except ValueError:
+ raise ValueError("invalid octal string escape ('\\%s')" % tail)
+
+def escaperaw(m):
+ all, tail = m.group(0, 1)
+ if tail.startswith('u'):
+ return unichr(convert_hex(tail, 4))
+ elif tail.startswith('U'):
+ return unichr(convert_hex(tail, 8))
+ else:
+ return all
+
+escape_re = re.compile(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})")
+uni_escape_re = re.compile(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3}|"
+ r"u[0-9a-fA-F]{0,4}|U[0-9a-fA-F]{0,8}|N\{.+?\})")
+
+def evalString(s, encoding=None):
+ regex = escape_re
+ repl = escape
+ if encoding:
+ s = s.decode(encoding)
+ if s.startswith('u') or s.startswith('U'):
+ regex = uni_escape_re
+ s = s[1:]
+ if s.startswith('r') or s.startswith('R'):
+ repl = escaperaw
+ s = s[1:]
+ assert s.startswith("'") or s.startswith('"'), repr(s[:1])
+ q = s[0]
+ if s[:3] == q*3:
+ q = q*3
+ assert s.endswith(q), repr(s[-len(q):])
+ assert len(s) >= 2*len(q)
+ s = s[len(q):-len(q)]
+ return regex.sub(repl, s)
+
+def test():
+ for i in range(256):
+ c = chr(i)
+ s = repr(c)
+ e = evalString(s)
+ if e != c:
+ print i, c, s, e
+
+
+if __name__ == "__main__":
+ test()
diff --git a/sphinx/pycode/pgen2/parse.c b/sphinx/pycode/pgen2/parse.c
new file mode 100644
index 00000000..fd0e9ff9
--- /dev/null
+++ b/sphinx/pycode/pgen2/parse.c
@@ -0,0 +1,3261 @@
+/* Generated by Cython 0.9.8.1 on Thu Jan 1 23:45:38 2009 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#if PY_VERSION_HEX < 0x02040000
+ #define METH_COEXIST 0
+#endif
+#if PY_VERSION_HEX < 0x02050000
+ typedef int Py_ssize_t;
+ #define PY_SSIZE_T_MAX INT_MAX
+ #define PY_SSIZE_T_MIN INT_MIN
+ #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+ #define PyInt_AsSsize_t(o) PyInt_AsLong(o)
+ #define PyNumber_Index(o) PyNumber_Int(o)
+ #define PyIndex_Check(o) PyNumber_Check(o)
+#endif
+#if PY_VERSION_HEX < 0x02060000
+ #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+ #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+ #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
+ #define PyVarObject_HEAD_INIT(type, size) \
+ PyObject_HEAD_INIT(type) size,
+ #define PyType_Modified(t)
+
+ typedef struct {
+ void *buf;
+ Py_ssize_t len;
+ int readonly;
+ const char *format;
+ int ndim;
+ Py_ssize_t *shape;
+ Py_ssize_t *strides;
+ Py_ssize_t *suboffsets;
+ Py_ssize_t itemsize;
+ void *internal;
+ } Py_buffer;
+
+ #define PyBUF_SIMPLE 0
+ #define PyBUF_WRITABLE 0x0001
+ #define PyBUF_LOCK 0x0002
+ #define PyBUF_FORMAT 0x0004
+ #define PyBUF_ND 0x0008
+ #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+ #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+ #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+ #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+ #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+
+#endif
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyString_Type PyBytes_Type
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define PyBytes_Type PyString_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+#else
+ #define _USE_MATH_DEFINES
+#endif
+#ifdef __cplusplus
+#define __PYX_EXTERN_C extern "C"
+#else
+#define __PYX_EXTERN_C extern
+#endif
+#include <math.h>
+#define __PYX_HAVE_API__sphinx__pycode__pgen2__parse
+
+
+#ifdef __GNUC__
+#define INLINE __inline__
+#elif _WIN32
+#define INLINE __inline
+#else
+#define INLINE
+#endif
+
+typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
+
+
+
+static int __pyx_skip_dispatch = 0;
+
+
+/* Type Conversion Predeclarations */
+
+#if PY_MAJOR_VERSION < 3
+#define __Pyx_PyBytes_FromString PyString_FromString
+#define __Pyx_PyBytes_AsString PyString_AsString
+#else
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_AsString PyBytes_AsString
+#endif
+
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static INLINE int __Pyx_PyObject_IsTrue(PyObject* x);
+static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x);
+static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x);
+static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b);
+
+#define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x))
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+
+static INLINE unsigned char __pyx_PyInt_unsigned_char(PyObject* x);
+static INLINE unsigned short __pyx_PyInt_unsigned_short(PyObject* x);
+static INLINE char __pyx_PyInt_char(PyObject* x);
+static INLINE short __pyx_PyInt_short(PyObject* x);
+static INLINE int __pyx_PyInt_int(PyObject* x);
+static INLINE long __pyx_PyInt_long(PyObject* x);
+static INLINE signed char __pyx_PyInt_signed_char(PyObject* x);
+static INLINE signed short __pyx_PyInt_signed_short(PyObject* x);
+static INLINE signed int __pyx_PyInt_signed_int(PyObject* x);
+static INLINE signed long __pyx_PyInt_signed_long(PyObject* x);
+static INLINE long double __pyx_PyInt_long_double(PyObject* x);
+#ifdef __GNUC__
+/* Test for GCC > 2.95 */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* __GNUC__ > 2 ... */
+#define likely(x) (x)
+#define unlikely(x) (x)
+#endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+#define likely(x) (x)
+#define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+static const char **__pyx_f;
+
+static INLINE void __Pyx_RaiseArgtupleTooLong(Py_ssize_t num_expected, Py_ssize_t num_found); /*proto*/
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
+
+static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) {
+ PyObject *r;
+ if (PyList_CheckExact(o) && 0 <= i && i < PyList_GET_SIZE(o)) {
+ r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ }
+ else if (PyTuple_CheckExact(o) && 0 <= i && i < PyTuple_GET_SIZE(o)) {
+ r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ }
+ else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0) || !is_unsigned))
+ r = PySequence_GetItem(o, i);
+ else {
+ PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i);
+ if (!j)
+ return 0;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ }
+ return r;
+}
+
+static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
+static int __Pyx_EndUnpack(PyObject *); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+
+static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
+ if (likely(PyList_CheckExact(L))) {
+ if (PyList_Append(L, x) < 0) return NULL;
+ Py_INCREF(Py_None);
+ return Py_None; // this is just to have an accurate signature
+ }
+ else {
+ return PyObject_CallMethod(L, "append", "(O)", x);
+ }
+}
+
+static INLINE int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v, int is_unsigned) {
+ int r;
+ if (PyList_CheckExact(o) && 0 <= i && i < PyList_GET_SIZE(o)) {
+ Py_DECREF(PyList_GET_ITEM(o, i));
+ Py_INCREF(v);
+ PyList_SET_ITEM(o, i, v);
+ return 1;
+ }
+ else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0) || !is_unsigned))
+ r = PySequence_SetItem(o, i, v);
+ else {
+ PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i);
+ if (!j)
+ return -1;
+ r = PyObject_SetItem(o, j, v);
+ Py_DECREF(j);
+ }
+ return r;
+}
+
+static void __Pyx_WriteUnraisable(const char *name); /*proto*/
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
+
+static void __Pyx_AddTraceback(const char *funcname); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+/* Type declarations */
+
+/* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":31
+ *
+ *
+ * cdef class Parser: # <<<<<<<<<<<<<<
+ * cdef public grammar, stack, rootnode, used_names
+ * cdef _grammar_dfas, _grammar_labels, _grammar_keywords, _grammar_tokens
+ */
+
+struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser *__pyx_vtab;
+ PyObject *grammar;
+ PyObject *stack;
+ PyObject *rootnode;
+ PyObject *used_names;
+ PyObject *_grammar_dfas;
+ PyObject *_grammar_labels;
+ PyObject *_grammar_keywords;
+ PyObject *_grammar_tokens;
+ PyObject *_grammar_number2symbol;
+};
+
+
+struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser {
+ int (*classify)(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *, PyObject *, PyObject *, PyObject *);
+ void (*shift)(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *, PyObject *, PyObject *, PyObject *, PyObject *);
+ void (*push)(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *, PyObject *, PyObject *, PyObject *, PyObject *);
+ void (*pop)(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *);
+ PyObject *(*convert)(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *, PyObject *);
+};
+static struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser *__pyx_vtabptr_6sphinx_6pycode_5pgen2_5parse_Parser;
+/* Module declarations from sphinx.pycode.pgen2.parse */
+
+static PyTypeObject *__pyx_ptype_6sphinx_6pycode_5pgen2_5parse_Parser = 0;
+
+
+/* Implementation of sphinx.pycode.pgen2.parse */
+static char __pyx_k_2[] = "Exception to signal the parser is stuck.";
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static char __pyx_k___init__[] = "__init__";
+static PyObject *__pyx_kp___init__;
+static char __pyx_k_setup[] = "setup";
+static PyObject *__pyx_kp_setup;
+static char __pyx_k_addtoken[] = "addtoken";
+static PyObject *__pyx_kp_addtoken;
+static char __pyx_k_1[] = "sphinx.pycode.nodes";
+static PyObject *__pyx_kp_1;
+static char __pyx_k_Node[] = "Node";
+static PyObject *__pyx_kp_Node;
+static char __pyx_k_Leaf[] = "Leaf";
+static PyObject *__pyx_kp_Leaf;
+static char __pyx_k_ParseError[] = "ParseError";
+static PyObject *__pyx_kp_ParseError;
+static char __pyx_k_Exception[] = "Exception";
+static PyObject *__pyx_kp_Exception;
+static char __pyx_k_msg[] = "msg";
+static PyObject *__pyx_kp_msg;
+static char __pyx_k_type[] = "type";
+static PyObject *__pyx_kp_type;
+static char __pyx_k_value[] = "value";
+static PyObject *__pyx_kp_value;
+static char __pyx_k_context[] = "context";
+static PyObject *__pyx_kp_context;
+static char __pyx_k_dfas[] = "dfas";
+static PyObject *__pyx_kp_dfas;
+static char __pyx_k_labels[] = "labels";
+static PyObject *__pyx_kp_labels;
+static char __pyx_k_keywords[] = "keywords";
+static PyObject *__pyx_kp_keywords;
+static char __pyx_k_tokens[] = "tokens";
+static PyObject *__pyx_kp_tokens;
+static char __pyx_k_4[] = "number2symbol";
+static PyObject *__pyx_kp_4;
+static char __pyx_k_start[] = "start";
+static PyObject *__pyx_kp_start;
+static char __pyx_k_add[] = "add";
+static PyObject *__pyx_kp_add;
+static char __pyx_k_get[] = "get";
+static PyObject *__pyx_kp_get;
+static char __pyx_k_append[] = "append";
+static PyObject *__pyx_kp_append;
+static char __pyx_k_pop[] = "pop";
+static PyObject *__pyx_kp_pop;
+static char __pyx_k_used_names[] = "used_names";
+static PyObject *__pyx_kp_used_names;
+static PyObject *__pyx_kp_2;
+static PyObject *__pyx_builtin_Exception;
+static PyObject *__pyx_kp_3;
+static char __pyx_k_3[] = "%s: type=%r, value=%r, context=%r";
+static PyObject *__pyx_kp_5;
+static PyObject *__pyx_kp_6;
+static char __pyx_k_5[] = "too much input";
+static char __pyx_k_6[] = "bad input";
+static PyObject *__pyx_kp_7;
+static char __pyx_k_7[] = "bad token";
+
+/* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":22
+ * """Exception to signal the parser is stuck."""
+ *
+ * def __init__(self, msg, type, value, context): # <<<<<<<<<<<<<<
+ * Exception.__init__(self, "%s: type=%r, value=%r, context=%r" %
+ * (msg, type, value, context))
+ */
+
+static PyObject *__pyx_pf_6sphinx_6pycode_5pgen2_5parse_10ParseError___init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_6sphinx_6pycode_5pgen2_5parse_10ParseError___init__ = {"__init__", (PyCFunction)__pyx_pf_6sphinx_6pycode_5pgen2_5parse_10ParseError___init__, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pf_6sphinx_6pycode_5pgen2_5parse_10ParseError___init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_msg = 0;
+ PyObject *__pyx_v_type = 0;
+ PyObject *__pyx_v_value = 0;
+ PyObject *__pyx_v_context = 0;
+ PyObject *__pyx_r;
+ PyObject *__pyx_1 = 0;
+ PyObject *__pyx_2 = 0;
+ PyObject *__pyx_3 = 0;
+ static char *__pyx_argnames[] = {"self","msg","type","value","context",0};
+ __pyx_self = __pyx_self;
+ if (likely(!__pyx_kwds) && likely(PyTuple_GET_SIZE(__pyx_args) == 5)) {
+ __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
+ __pyx_v_msg = PyTuple_GET_ITEM(__pyx_args, 1);
+ __pyx_v_type = PyTuple_GET_ITEM(__pyx_args, 2);
+ __pyx_v_value = PyTuple_GET_ITEM(__pyx_args, 3);
+ __pyx_v_context = PyTuple_GET_ITEM(__pyx_args, 4);
+ }
+ else {
+ if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OOOOO", __pyx_argnames, &__pyx_v_self, &__pyx_v_msg, &__pyx_v_type, &__pyx_v_value, &__pyx_v_context))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4;
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("sphinx.pycode.pgen2.parse.ParseError.__init__");
+ return NULL;
+ __pyx_L4:;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":23
+ *
+ * def __init__(self, msg, type, value, context):
+ * Exception.__init__(self, "%s: type=%r, value=%r, context=%r" % # <<<<<<<<<<<<<<
+ * (msg, type, value, context))
+ * self.msg = msg
+ */
+ __pyx_1 = PyObject_GetAttr(__pyx_builtin_Exception, __pyx_kp___init__); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":24
+ * def __init__(self, msg, type, value, context):
+ * Exception.__init__(self, "%s: type=%r, value=%r, context=%r" %
+ * (msg, type, value, context)) # <<<<<<<<<<<<<<
+ * self.msg = msg
+ * self.type = type
+ */
+ __pyx_2 = PyTuple_New(4); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_msg);
+ PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_msg);
+ Py_INCREF(__pyx_v_type);
+ PyTuple_SET_ITEM(__pyx_2, 1, __pyx_v_type);
+ Py_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_2, 2, __pyx_v_value);
+ Py_INCREF(__pyx_v_context);
+ PyTuple_SET_ITEM(__pyx_2, 3, __pyx_v_context);
+ __pyx_3 = PyNumber_Remainder(__pyx_kp_3, ((PyObject *)__pyx_2)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
+ __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_self);
+ PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_self);
+ PyTuple_SET_ITEM(__pyx_2, 1, __pyx_3);
+ __pyx_3 = 0;
+ __pyx_3 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
+ Py_DECREF(__pyx_3); __pyx_3 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":25
+ * Exception.__init__(self, "%s: type=%r, value=%r, context=%r" %
+ * (msg, type, value, context))
+ * self.msg = msg # <<<<<<<<<<<<<<
+ * self.type = type
+ * self.value = value
+ */
+ if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_msg, __pyx_v_msg) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":26
+ * (msg, type, value, context))
+ * self.msg = msg
+ * self.type = type # <<<<<<<<<<<<<<
+ * self.value = value
+ * self.context = context
+ */
+ if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_type, __pyx_v_type) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":27
+ * self.msg = msg
+ * self.type = type
+ * self.value = value # <<<<<<<<<<<<<<
+ * self.context = context
+ *
+ */
+ if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_value, __pyx_v_value) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":28
+ * self.type = type
+ * self.value = value
+ * self.context = context # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_context, __pyx_v_context) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ __pyx_r = Py_None; Py_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ Py_XDECREF(__pyx_1);
+ Py_XDECREF(__pyx_2);
+ Py_XDECREF(__pyx_3);
+ __Pyx_AddTraceback("sphinx.pycode.pgen2.parse.ParseError.__init__");
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":36
+ * cdef _grammar_number2symbol
+ *
+ * def __init__(self, grammar, convert=None): # <<<<<<<<<<<<<<
+ * self.grammar = grammar
+ * #self.convert = convert or noconvert
+ */
+
+static int __pyx_pf_6sphinx_6pycode_5pgen2_5parse_6Parser___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pf_6sphinx_6pycode_5pgen2_5parse_6Parser___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_grammar = 0;
+ PyObject *__pyx_v_convert = 0;
+ int __pyx_r;
+ PyObject *__pyx_1 = 0;
+ static char *__pyx_argnames[] = {"grammar","convert",0};
+ __pyx_v_convert = Py_None;
+ if (likely(!__pyx_kwds) && likely(1 <= PyTuple_GET_SIZE(__pyx_args)) && likely(PyTuple_GET_SIZE(__pyx_args) <= 2)) {
+ __pyx_v_grammar = PyTuple_GET_ITEM(__pyx_args, 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_convert = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ }
+ else {
+ if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O|O", __pyx_argnames, &__pyx_v_grammar, &__pyx_v_convert))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4;
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("sphinx.pycode.pgen2.parse.Parser.__init__");
+ return -1;
+ __pyx_L4:;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":37
+ *
+ * def __init__(self, grammar, convert=None):
+ * self.grammar = grammar # <<<<<<<<<<<<<<
+ * #self.convert = convert or noconvert
+ *
+ */
+ Py_INCREF(__pyx_v_grammar);
+ Py_DECREF(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->grammar);
+ ((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->grammar = __pyx_v_grammar;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":40
+ * #self.convert = convert or noconvert
+ *
+ * self._grammar_dfas = grammar.dfas # <<<<<<<<<<<<<<
+ * self._grammar_labels = grammar.labels
+ * self._grammar_keywords = grammar.keywords
+ */
+ __pyx_1 = PyObject_GetAttr(__pyx_v_grammar, __pyx_kp_dfas); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_dfas);
+ ((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_dfas = __pyx_1;
+ __pyx_1 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":41
+ *
+ * self._grammar_dfas = grammar.dfas
+ * self._grammar_labels = grammar.labels # <<<<<<<<<<<<<<
+ * self._grammar_keywords = grammar.keywords
+ * self._grammar_tokens = grammar.tokens
+ */
+ __pyx_1 = PyObject_GetAttr(__pyx_v_grammar, __pyx_kp_labels); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_labels);
+ ((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_labels = __pyx_1;
+ __pyx_1 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":42
+ * self._grammar_dfas = grammar.dfas
+ * self._grammar_labels = grammar.labels
+ * self._grammar_keywords = grammar.keywords # <<<<<<<<<<<<<<
+ * self._grammar_tokens = grammar.tokens
+ * self._grammar_number2symbol = grammar.number2symbol
+ */
+ __pyx_1 = PyObject_GetAttr(__pyx_v_grammar, __pyx_kp_keywords); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_keywords);
+ ((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_keywords = __pyx_1;
+ __pyx_1 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":43
+ * self._grammar_labels = grammar.labels
+ * self._grammar_keywords = grammar.keywords
+ * self._grammar_tokens = grammar.tokens # <<<<<<<<<<<<<<
+ * self._grammar_number2symbol = grammar.number2symbol
+ *
+ */
+ __pyx_1 = PyObject_GetAttr(__pyx_v_grammar, __pyx_kp_tokens); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_tokens);
+ ((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_tokens = __pyx_1;
+ __pyx_1 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":44
+ * self._grammar_keywords = grammar.keywords
+ * self._grammar_tokens = grammar.tokens
+ * self._grammar_number2symbol = grammar.number2symbol # <<<<<<<<<<<<<<
+ *
+ * def setup(self, start=None):
+ */
+ __pyx_1 = PyObject_GetAttr(__pyx_v_grammar, __pyx_kp_4); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_number2symbol);
+ ((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_number2symbol = __pyx_1;
+ __pyx_1 = 0;
+
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ Py_XDECREF(__pyx_1);
+ __Pyx_AddTraceback("sphinx.pycode.pgen2.parse.Parser.__init__");
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":46
+ * self._grammar_number2symbol = grammar.number2symbol
+ *
+ * def setup(self, start=None): # <<<<<<<<<<<<<<
+ * if start is None:
+ * start = self.grammar.start
+ */
+
+static PyObject *__pyx_pf_6sphinx_6pycode_5pgen2_5parse_6Parser_setup(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pf_6sphinx_6pycode_5pgen2_5parse_6Parser_setup(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_start = 0;
+ PyObject *__pyx_v_newnode;
+ PyObject *__pyx_v_stackentry;
+ PyObject *__pyx_r;
+ int __pyx_1;
+ PyObject *__pyx_2 = 0;
+ PyObject *__pyx_3 = 0;
+ static char *__pyx_argnames[] = {"start",0};
+ __pyx_v_start = Py_None;
+ if (likely(!__pyx_kwds) && likely(0 <= PyTuple_GET_SIZE(__pyx_args)) && likely(PyTuple_GET_SIZE(__pyx_args) <= 1)) {
+ if (PyTuple_GET_SIZE(__pyx_args) > 0) {
+ __pyx_v_start = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ }
+ else {
+ if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "|O", __pyx_argnames, &__pyx_v_start))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4;
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("sphinx.pycode.pgen2.parse.Parser.setup");
+ return NULL;
+ __pyx_L4:;
+ Py_INCREF(__pyx_v_start);
+ __pyx_v_newnode = Py_None; Py_INCREF(Py_None);
+ __pyx_v_stackentry = Py_None; Py_INCREF(Py_None);
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":47
+ *
+ * def setup(self, start=None):
+ * if start is None: # <<<<<<<<<<<<<<
+ * start = self.grammar.start
+ * # Each stack entry is a tuple: (dfa, state, node).
+ */
+ __pyx_1 = (__pyx_v_start == Py_None);
+ if (__pyx_1) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":48
+ * def setup(self, start=None):
+ * if start is None:
+ * start = self.grammar.start # <<<<<<<<<<<<<<
+ * # Each stack entry is a tuple: (dfa, state, node).
+ * # A node is a tuple: (type, value, context, children),
+ */
+ __pyx_2 = PyObject_GetAttr(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->grammar, __pyx_kp_start); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_start);
+ __pyx_v_start = __pyx_2;
+ __pyx_2 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":52
+ * # A node is a tuple: (type, value, context, children),
+ * # where children is a list of nodes or None, and context may be None.
+ * newnode = (start, None, None, []) # <<<<<<<<<<<<<<
+ * stackentry = (self._grammar_dfas[start], 0, newnode)
+ * self.stack = [stackentry]
+ */
+ __pyx_2 = PyList_New(0); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_3 = PyTuple_New(4); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_start);
+ PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_start);
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_3, 1, Py_None);
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_3, 2, Py_None);
+ PyTuple_SET_ITEM(__pyx_3, 3, ((PyObject *)__pyx_2));
+ __pyx_2 = 0;
+ Py_DECREF(__pyx_v_newnode);
+ __pyx_v_newnode = ((PyObject *)__pyx_3);
+ __pyx_3 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":53
+ * # where children is a list of nodes or None, and context may be None.
+ * newnode = (start, None, None, [])
+ * stackentry = (self._grammar_dfas[start], 0, newnode) # <<<<<<<<<<<<<<
+ * self.stack = [stackentry]
+ * self.rootnode = None
+ */
+ __pyx_2 = PyObject_GetItem(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_dfas, __pyx_v_start); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_3 = PyTuple_New(3); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2);
+ Py_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_3, 1, __pyx_int_0);
+ Py_INCREF(__pyx_v_newnode);
+ PyTuple_SET_ITEM(__pyx_3, 2, __pyx_v_newnode);
+ __pyx_2 = 0;
+ Py_DECREF(__pyx_v_stackentry);
+ __pyx_v_stackentry = ((PyObject *)__pyx_3);
+ __pyx_3 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":54
+ * newnode = (start, None, None, [])
+ * stackentry = (self._grammar_dfas[start], 0, newnode)
+ * self.stack = [stackentry] # <<<<<<<<<<<<<<
+ * self.rootnode = None
+ * self.used_names = set() # Aliased to self.rootnode.used_names in pop()
+ */
+ __pyx_2 = PyList_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_stackentry);
+ PyList_SET_ITEM(__pyx_2, 0, __pyx_v_stackentry);
+ Py_DECREF(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->stack);
+ ((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->stack = ((PyObject *)__pyx_2);
+ __pyx_2 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":55
+ * stackentry = (self._grammar_dfas[start], 0, newnode)
+ * self.stack = [stackentry]
+ * self.rootnode = None # <<<<<<<<<<<<<<
+ * self.used_names = set() # Aliased to self.rootnode.used_names in pop()
+ *
+ */
+ Py_INCREF(Py_None);
+ Py_DECREF(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->rootnode);
+ ((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->rootnode = Py_None;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":56
+ * self.stack = [stackentry]
+ * self.rootnode = None
+ * self.used_names = set() # Aliased to self.rootnode.used_names in pop() # <<<<<<<<<<<<<<
+ *
+ * def addtoken(self, type, value, context):
+ */
+ __pyx_3 = PyObject_Call(((PyObject*)&PySet_Type), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->used_names);
+ ((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->used_names = __pyx_3;
+ __pyx_3 = 0;
+
+ __pyx_r = Py_None; Py_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ Py_XDECREF(__pyx_2);
+ Py_XDECREF(__pyx_3);
+ __Pyx_AddTraceback("sphinx.pycode.pgen2.parse.Parser.setup");
+ __pyx_r = NULL;
+ __pyx_L0:;
+ Py_DECREF(__pyx_v_newnode);
+ Py_DECREF(__pyx_v_stackentry);
+ Py_DECREF(__pyx_v_start);
+ return __pyx_r;
+}
+
+/* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":58
+ * self.used_names = set() # Aliased to self.rootnode.used_names in pop()
+ *
+ * def addtoken(self, type, value, context): # <<<<<<<<<<<<<<
+ * """Add a token; return True iff this is the end of the program."""
+ * cdef int ilabel, i, t, state, newstate
+ */
+
+static PyObject *__pyx_pf_6sphinx_6pycode_5pgen2_5parse_6Parser_addtoken(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6sphinx_6pycode_5pgen2_5parse_6Parser_addtoken[] = "Add a token; return True iff this is the end of the program.";
+static PyObject *__pyx_pf_6sphinx_6pycode_5pgen2_5parse_6Parser_addtoken(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_type = 0;
+ PyObject *__pyx_v_value = 0;
+ PyObject *__pyx_v_context = 0;
+ int __pyx_v_ilabel;
+ int __pyx_v_i;
+ int __pyx_v_t;
+ int __pyx_v_state;
+ int __pyx_v_newstate;
+ PyObject *__pyx_v_dfa;
+ PyObject *__pyx_v_node;
+ PyObject *__pyx_v_states;
+ PyObject *__pyx_v_first;
+ PyObject *__pyx_v_arcs;
+ PyObject *__pyx_v_v;
+ PyObject *__pyx_v_itsdfa;
+ PyObject *__pyx_v_itsstates;
+ PyObject *__pyx_v_itsfirst;
+ PyObject *__pyx_r;
+ int __pyx_1;
+ PyObject *__pyx_2 = 0;
+ PyObject *__pyx_3 = 0;
+ PyObject *__pyx_4 = 0;
+ int __pyx_5;
+ Py_ssize_t __pyx_6 = 0;
+ PyObject *__pyx_7 = 0;
+ int __pyx_8;
+ static char *__pyx_argnames[] = {"type","value","context",0};
+ if (likely(!__pyx_kwds) && likely(PyTuple_GET_SIZE(__pyx_args) == 3)) {
+ __pyx_v_type = PyTuple_GET_ITEM(__pyx_args, 0);
+ __pyx_v_value = PyTuple_GET_ITEM(__pyx_args, 1);
+ __pyx_v_context = PyTuple_GET_ITEM(__pyx_args, 2);
+ }
+ else {
+ if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OOO", __pyx_argnames, &__pyx_v_type, &__pyx_v_value, &__pyx_v_context))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4;
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("sphinx.pycode.pgen2.parse.Parser.addtoken");
+ return NULL;
+ __pyx_L4:;
+ __pyx_v_dfa = Py_None; Py_INCREF(Py_None);
+ __pyx_v_node = Py_None; Py_INCREF(Py_None);
+ __pyx_v_states = Py_None; Py_INCREF(Py_None);
+ __pyx_v_first = Py_None; Py_INCREF(Py_None);
+ __pyx_v_arcs = Py_None; Py_INCREF(Py_None);
+ __pyx_v_v = Py_None; Py_INCREF(Py_None);
+ __pyx_v_itsdfa = Py_None; Py_INCREF(Py_None);
+ __pyx_v_itsstates = Py_None; Py_INCREF(Py_None);
+ __pyx_v_itsfirst = Py_None; Py_INCREF(Py_None);
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":62
+ * cdef int ilabel, i, t, state, newstate
+ * # Map from token to label
+ * ilabel = self.classify(type, value, context) # <<<<<<<<<<<<<<
+ * # Loop until the token is shifted; may raise exceptions
+ * while True:
+ */
+ __pyx_v_ilabel = ((struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser *)((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->__pyx_vtab)->classify(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self), __pyx_v_type, __pyx_v_value, __pyx_v_context);
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":64
+ * ilabel = self.classify(type, value, context)
+ * # Loop until the token is shifted; may raise exceptions
+ * while True: # <<<<<<<<<<<<<<
+ * dfa, state, node = self.stack[-1]
+ * states, first = dfa
+ */
+ while (1) {
+ __pyx_1 = 1;
+ if (!__pyx_1) break;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":65
+ * # Loop until the token is shifted; may raise exceptions
+ * while True:
+ * dfa, state, node = self.stack[-1] # <<<<<<<<<<<<<<
+ * states, first = dfa
+ * arcs = states[state]
+ */
+ __pyx_2 = __Pyx_GetItemInt(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->stack, -1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyTuple_CheckExact(__pyx_2) && PyTuple_GET_SIZE(__pyx_2) == 3) {
+ PyObject* tuple = __pyx_2;
+ __pyx_4 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_4);
+ Py_DECREF(__pyx_v_dfa);
+ __pyx_v_dfa = __pyx_4;
+ __pyx_4 = 0;
+ __pyx_4 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_4);
+ __pyx_5 = __pyx_PyInt_int(__pyx_4); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ __pyx_v_state = __pyx_5;
+ __pyx_4 = PyTuple_GET_ITEM(tuple, 2);
+ Py_INCREF(__pyx_4);
+ Py_DECREF(__pyx_v_node);
+ __pyx_v_node = __pyx_4;
+ __pyx_4 = 0;
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ }
+ else {
+ __pyx_3 = PyObject_GetIter(__pyx_2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ __pyx_4 = __Pyx_UnpackItem(__pyx_3, 0); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_dfa);
+ __pyx_v_dfa = __pyx_4;
+ __pyx_4 = 0;
+ __pyx_4 = __Pyx_UnpackItem(__pyx_3, 1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_5 = __pyx_PyInt_int(__pyx_4); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ __pyx_v_state = __pyx_5;
+ __pyx_4 = __Pyx_UnpackItem(__pyx_3, 2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_node);
+ __pyx_v_node = __pyx_4;
+ __pyx_4 = 0;
+ if (__Pyx_EndUnpack(__pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_3); __pyx_3 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":66
+ * while True:
+ * dfa, state, node = self.stack[-1]
+ * states, first = dfa # <<<<<<<<<<<<<<
+ * arcs = states[state]
+ * # Look for a state with this label
+ */
+ if (PyTuple_CheckExact(__pyx_v_dfa) && PyTuple_GET_SIZE(__pyx_v_dfa) == 2) {
+ PyObject* tuple = __pyx_v_dfa;
+ __pyx_2 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_2);
+ Py_DECREF(__pyx_v_states);
+ __pyx_v_states = __pyx_2;
+ __pyx_2 = 0;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_first);
+ __pyx_v_first = __pyx_3;
+ __pyx_3 = 0;
+ }
+ else {
+ __pyx_4 = PyObject_GetIter(__pyx_v_dfa); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_2 = __Pyx_UnpackItem(__pyx_4, 0); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_states);
+ __pyx_v_states = __pyx_2;
+ __pyx_2 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_4, 1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_first);
+ __pyx_v_first = __pyx_3;
+ __pyx_3 = 0;
+ if (__Pyx_EndUnpack(__pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":67
+ * dfa, state, node = self.stack[-1]
+ * states, first = dfa
+ * arcs = states[state] # <<<<<<<<<<<<<<
+ * # Look for a state with this label
+ * for i, newstate in arcs:
+ */
+ __pyx_2 = __Pyx_GetItemInt(__pyx_v_states, __pyx_v_state, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_arcs);
+ __pyx_v_arcs = __pyx_2;
+ __pyx_2 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":69
+ * arcs = states[state]
+ * # Look for a state with this label
+ * for i, newstate in arcs: # <<<<<<<<<<<<<<
+ * t, v = self._grammar_labels[i]
+ * if ilabel == i:
+ */
+ if (PyList_CheckExact(__pyx_v_arcs) || PyTuple_CheckExact(__pyx_v_arcs)) {
+ __pyx_6 = 0; __pyx_3 = __pyx_v_arcs; Py_INCREF(__pyx_3);
+ } else {
+ __pyx_6 = -1; __pyx_3 = PyObject_GetIter(__pyx_v_arcs); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(PyList_CheckExact(__pyx_3))) {
+ if (__pyx_6 >= PyList_GET_SIZE(__pyx_3)) break;
+ __pyx_4 = PyList_GET_ITEM(__pyx_3, __pyx_6); Py_INCREF(__pyx_4); __pyx_6++;
+ } else if (likely(PyTuple_CheckExact(__pyx_3))) {
+ if (__pyx_6 >= PyTuple_GET_SIZE(__pyx_3)) break;
+ __pyx_4 = PyTuple_GET_ITEM(__pyx_3, __pyx_6); Py_INCREF(__pyx_4); __pyx_6++;
+ } else {
+ __pyx_4 = PyIter_Next(__pyx_3);
+ if (!__pyx_4) {
+ if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ break;
+ }
+ }
+ if (PyTuple_CheckExact(__pyx_4) && PyTuple_GET_SIZE(__pyx_4) == 2) {
+ PyObject* tuple = __pyx_4;
+ __pyx_7 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_7);
+ __pyx_5 = __pyx_PyInt_int(__pyx_7); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ __pyx_v_i = __pyx_5;
+ __pyx_7 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_7);
+ __pyx_5 = __pyx_PyInt_int(__pyx_7); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ __pyx_v_newstate = __pyx_5;
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ }
+ else {
+ __pyx_2 = PyObject_GetIter(__pyx_4); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ __pyx_7 = __Pyx_UnpackItem(__pyx_2, 0); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_5 = __pyx_PyInt_int(__pyx_7); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ __pyx_v_i = __pyx_5;
+ __pyx_7 = __Pyx_UnpackItem(__pyx_2, 1); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_5 = __pyx_PyInt_int(__pyx_7); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ __pyx_v_newstate = __pyx_5;
+ if (__Pyx_EndUnpack(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":70
+ * # Look for a state with this label
+ * for i, newstate in arcs:
+ * t, v = self._grammar_labels[i] # <<<<<<<<<<<<<<
+ * if ilabel == i:
+ * # Look it up in the list of labels
+ */
+ __pyx_7 = __Pyx_GetItemInt(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_labels, __pyx_v_i, 0); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyTuple_CheckExact(__pyx_7) && PyTuple_GET_SIZE(__pyx_7) == 2) {
+ PyObject* tuple = __pyx_7;
+ __pyx_2 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_2);
+ __pyx_5 = __pyx_PyInt_int(__pyx_2); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ __pyx_v_t = __pyx_5;
+ __pyx_2 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_2);
+ Py_DECREF(__pyx_v_v);
+ __pyx_v_v = __pyx_2;
+ __pyx_2 = 0;
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ }
+ else {
+ __pyx_4 = PyObject_GetIter(__pyx_7); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ __pyx_2 = __Pyx_UnpackItem(__pyx_4, 0); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_5 = __pyx_PyInt_int(__pyx_2); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ __pyx_v_t = __pyx_5;
+ __pyx_2 = __Pyx_UnpackItem(__pyx_4, 1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_v);
+ __pyx_v_v = __pyx_2;
+ __pyx_2 = 0;
+ if (__Pyx_EndUnpack(__pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":71
+ * for i, newstate in arcs:
+ * t, v = self._grammar_labels[i]
+ * if ilabel == i: # <<<<<<<<<<<<<<
+ * # Look it up in the list of labels
+ * ## assert t < 256
+ */
+ __pyx_1 = (__pyx_v_ilabel == __pyx_v_i);
+ if (__pyx_1) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":75
+ * ## assert t < 256
+ * # Shift a token; we're done with it
+ * self.shift(type, value, newstate, context) # <<<<<<<<<<<<<<
+ * # Pop while we are in an accept-only state
+ * state = newstate
+ */
+ __pyx_2 = PyInt_FromLong(__pyx_v_newstate); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ ((struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser *)((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->__pyx_vtab)->shift(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self), __pyx_v_type, __pyx_v_value, __pyx_2, __pyx_v_context);
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":77
+ * self.shift(type, value, newstate, context)
+ * # Pop while we are in an accept-only state
+ * state = newstate # <<<<<<<<<<<<<<
+ * while states[state] == [(0, state)]:
+ * self.pop()
+ */
+ __pyx_v_state = __pyx_v_newstate;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":78
+ * # Pop while we are in an accept-only state
+ * state = newstate
+ * while states[state] == [(0, state)]: # <<<<<<<<<<<<<<
+ * self.pop()
+ * if not self.stack:
+ */
+ while (1) {
+ __pyx_7 = __Pyx_GetItemInt(__pyx_v_states, __pyx_v_state, 0); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_4 = PyInt_FromLong(__pyx_v_state); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_2, 0, __pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_2, 1, __pyx_4);
+ __pyx_4 = 0;
+ __pyx_4 = PyList_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ PyList_SET_ITEM(__pyx_4, 0, ((PyObject *)__pyx_2));
+ __pyx_2 = 0;
+ __pyx_2 = PyObject_RichCompare(__pyx_7, ((PyObject *)__pyx_4), Py_EQ); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
+ __pyx_1 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely(__pyx_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ if (!__pyx_1) break;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":79
+ * state = newstate
+ * while states[state] == [(0, state)]:
+ * self.pop() # <<<<<<<<<<<<<<
+ * if not self.stack:
+ * # Done parsing!
+ */
+ ((struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser *)((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->__pyx_vtab)->pop(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self));
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":80
+ * while states[state] == [(0, state)]:
+ * self.pop()
+ * if not self.stack: # <<<<<<<<<<<<<<
+ * # Done parsing!
+ * return True
+ */
+ __pyx_1 = __Pyx_PyObject_IsTrue(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->stack); if (unlikely(__pyx_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_8 = (!__pyx_1);
+ if (__pyx_8) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":82
+ * if not self.stack:
+ * # Done parsing!
+ * return True # <<<<<<<<<<<<<<
+ * dfa, state, node = self.stack[-1]
+ * states, first = dfa
+ */
+ __pyx_7 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = __pyx_7;
+ __pyx_7 = 0;
+ Py_DECREF(__pyx_3); __pyx_3 = 0;
+ goto __pyx_L0;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":83
+ * # Done parsing!
+ * return True
+ * dfa, state, node = self.stack[-1] # <<<<<<<<<<<<<<
+ * states, first = dfa
+ * # Done with this token
+ */
+ __pyx_4 = __Pyx_GetItemInt(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->stack, -1, 0); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyTuple_CheckExact(__pyx_4) && PyTuple_GET_SIZE(__pyx_4) == 3) {
+ PyObject* tuple = __pyx_4;
+ __pyx_7 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_7);
+ Py_DECREF(__pyx_v_dfa);
+ __pyx_v_dfa = __pyx_7;
+ __pyx_7 = 0;
+ __pyx_7 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_7);
+ __pyx_5 = __pyx_PyInt_int(__pyx_7); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ __pyx_v_state = __pyx_5;
+ __pyx_7 = PyTuple_GET_ITEM(tuple, 2);
+ Py_INCREF(__pyx_7);
+ Py_DECREF(__pyx_v_node);
+ __pyx_v_node = __pyx_7;
+ __pyx_7 = 0;
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ }
+ else {
+ __pyx_2 = PyObject_GetIter(__pyx_4); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ __pyx_7 = __Pyx_UnpackItem(__pyx_2, 0); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_dfa);
+ __pyx_v_dfa = __pyx_7;
+ __pyx_7 = 0;
+ __pyx_7 = __Pyx_UnpackItem(__pyx_2, 1); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_5 = __pyx_PyInt_int(__pyx_7); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ __pyx_v_state = __pyx_5;
+ __pyx_7 = __Pyx_UnpackItem(__pyx_2, 2); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_node);
+ __pyx_v_node = __pyx_7;
+ __pyx_7 = 0;
+ if (__Pyx_EndUnpack(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":84
+ * return True
+ * dfa, state, node = self.stack[-1]
+ * states, first = dfa # <<<<<<<<<<<<<<
+ * # Done with this token
+ * return False
+ */
+ if (PyTuple_CheckExact(__pyx_v_dfa) && PyTuple_GET_SIZE(__pyx_v_dfa) == 2) {
+ PyObject* tuple = __pyx_v_dfa;
+ __pyx_4 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_4);
+ Py_DECREF(__pyx_v_states);
+ __pyx_v_states = __pyx_4;
+ __pyx_4 = 0;
+ __pyx_2 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_2);
+ Py_DECREF(__pyx_v_first);
+ __pyx_v_first = __pyx_2;
+ __pyx_2 = 0;
+ }
+ else {
+ __pyx_7 = PyObject_GetIter(__pyx_v_dfa); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_4 = __Pyx_UnpackItem(__pyx_7, 0); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_states);
+ __pyx_v_states = __pyx_4;
+ __pyx_4 = 0;
+ __pyx_2 = __Pyx_UnpackItem(__pyx_7, 1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_first);
+ __pyx_v_first = __pyx_2;
+ __pyx_2 = 0;
+ if (__Pyx_EndUnpack(__pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ }
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":86
+ * states, first = dfa
+ * # Done with this token
+ * return False # <<<<<<<<<<<<<<
+ * elif t >= 256:
+ * # See if it's a symbol and if we're in its first set
+ */
+ __pyx_4 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = __pyx_4;
+ __pyx_4 = 0;
+ Py_DECREF(__pyx_3); __pyx_3 = 0;
+ goto __pyx_L0;
+ goto __pyx_L9;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":87
+ * # Done with this token
+ * return False
+ * elif t >= 256: # <<<<<<<<<<<<<<
+ * # See if it's a symbol and if we're in its first set
+ * itsdfa = self._grammar_dfas[t]
+ */
+ __pyx_1 = (__pyx_v_t >= 256);
+ if (__pyx_1) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":89
+ * elif t >= 256:
+ * # See if it's a symbol and if we're in its first set
+ * itsdfa = self._grammar_dfas[t] # <<<<<<<<<<<<<<
+ * itsstates, itsfirst = itsdfa
+ * if ilabel in itsfirst:
+ */
+ __pyx_2 = __Pyx_GetItemInt(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->_grammar_dfas, __pyx_v_t, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_itsdfa);
+ __pyx_v_itsdfa = __pyx_2;
+ __pyx_2 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":90
+ * # See if it's a symbol and if we're in its first set
+ * itsdfa = self._grammar_dfas[t]
+ * itsstates, itsfirst = itsdfa # <<<<<<<<<<<<<<
+ * if ilabel in itsfirst:
+ * # Push a symbol
+ */
+ if (PyTuple_CheckExact(__pyx_v_itsdfa) && PyTuple_GET_SIZE(__pyx_v_itsdfa) == 2) {
+ PyObject* tuple = __pyx_v_itsdfa;
+ __pyx_4 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_4);
+ Py_DECREF(__pyx_v_itsstates);
+ __pyx_v_itsstates = __pyx_4;
+ __pyx_4 = 0;
+ __pyx_2 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_2);
+ Py_DECREF(__pyx_v_itsfirst);
+ __pyx_v_itsfirst = __pyx_2;
+ __pyx_2 = 0;
+ }
+ else {
+ __pyx_7 = PyObject_GetIter(__pyx_v_itsdfa); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_4 = __Pyx_UnpackItem(__pyx_7, 0); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_itsstates);
+ __pyx_v_itsstates = __pyx_4;
+ __pyx_4 = 0;
+ __pyx_2 = __Pyx_UnpackItem(__pyx_7, 1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_itsfirst);
+ __pyx_v_itsfirst = __pyx_2;
+ __pyx_2 = 0;
+ if (__Pyx_EndUnpack(__pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":91
+ * itsdfa = self._grammar_dfas[t]
+ * itsstates, itsfirst = itsdfa
+ * if ilabel in itsfirst: # <<<<<<<<<<<<<<
+ * # Push a symbol
+ * self.push(t, itsdfa, newstate, context)
+ */
+ __pyx_4 = PyInt_FromLong(__pyx_v_ilabel); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_8 = (PySequence_Contains(__pyx_v_itsfirst, __pyx_4)); if (unlikely(__pyx_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ if (__pyx_8) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":93
+ * if ilabel in itsfirst:
+ * # Push a symbol
+ * self.push(t, itsdfa, newstate, context) # <<<<<<<<<<<<<<
+ * break # To continue the outer while loop
+ * else:
+ */
+ __pyx_2 = PyInt_FromLong(__pyx_v_t); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_7 = PyInt_FromLong(__pyx_v_newstate); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ ((struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser *)((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->__pyx_vtab)->push(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self), __pyx_2, __pyx_v_itsdfa, __pyx_7, __pyx_v_context);
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":94
+ * # Push a symbol
+ * self.push(t, itsdfa, newstate, context)
+ * break # To continue the outer while loop # <<<<<<<<<<<<<<
+ * else:
+ * if (0, state) in arcs:
+ */
+ goto __pyx_L8;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+ }
+ /*else*/ {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":96
+ * break # To continue the outer while loop
+ * else:
+ * if (0, state) in arcs: # <<<<<<<<<<<<<<
+ * # An accepting state, pop it and try something else
+ * self.pop()
+ */
+ __pyx_4 = PyInt_FromLong(__pyx_v_state); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_2, 0, __pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_2, 1, __pyx_4);
+ __pyx_4 = 0;
+ __pyx_1 = (PySequence_Contains(__pyx_v_arcs, ((PyObject *)__pyx_2))); if (unlikely(__pyx_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
+ if (__pyx_1) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":98
+ * if (0, state) in arcs:
+ * # An accepting state, pop it and try something else
+ * self.pop() # <<<<<<<<<<<<<<
+ * if not self.stack:
+ * # Done parsing, but another token is input
+ */
+ ((struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser *)((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->__pyx_vtab)->pop(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self));
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":99
+ * # An accepting state, pop it and try something else
+ * self.pop()
+ * if not self.stack: # <<<<<<<<<<<<<<
+ * # Done parsing, but another token is input
+ * raise ParseError("too much input",
+ */
+ __pyx_8 = __Pyx_PyObject_IsTrue(((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self)->stack); if (unlikely(__pyx_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_1 = (!__pyx_8);
+ if (__pyx_1) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":101
+ * if not self.stack:
+ * # Done parsing, but another token is input
+ * raise ParseError("too much input", # <<<<<<<<<<<<<<
+ * type, value, context)
+ * else:
+ */
+ __pyx_7 = __Pyx_GetName(__pyx_m, __pyx_kp_ParseError); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":102
+ * # Done parsing, but another token is input
+ * raise ParseError("too much input",
+ * type, value, context) # <<<<<<<<<<<<<<
+ * else:
+ * # No success finding a transition
+ */
+ __pyx_4 = PyTuple_New(4); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_kp_5);
+ PyTuple_SET_ITEM(__pyx_4, 0, __pyx_kp_5);
+ Py_INCREF(__pyx_v_type);
+ PyTuple_SET_ITEM(__pyx_4, 1, __pyx_v_type);
+ Py_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_4, 2, __pyx_v_value);
+ Py_INCREF(__pyx_v_context);
+ PyTuple_SET_ITEM(__pyx_4, 3, __pyx_v_context);
+ __pyx_2 = PyObject_Call(__pyx_7, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
+ __Pyx_Raise(__pyx_2, 0, 0);
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L15;
+ }
+ __pyx_L15:;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":105
+ * else:
+ * # No success finding a transition
+ * raise ParseError("bad input", type, value, context) # <<<<<<<<<<<<<<
+ *
+ * cdef int classify(self, type, value, context):
+ */
+ __pyx_7 = __Pyx_GetName(__pyx_m, __pyx_kp_ParseError); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_4 = PyTuple_New(4); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_kp_6);
+ PyTuple_SET_ITEM(__pyx_4, 0, __pyx_kp_6);
+ Py_INCREF(__pyx_v_type);
+ PyTuple_SET_ITEM(__pyx_4, 1, __pyx_v_type);
+ Py_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_4, 2, __pyx_v_value);
+ Py_INCREF(__pyx_v_context);
+ PyTuple_SET_ITEM(__pyx_4, 3, __pyx_v_context);
+ __pyx_2 = PyObject_Call(__pyx_7, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_7); __pyx_7 = 0;
+ Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
+ __Pyx_Raise(__pyx_2, 0, 0);
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L14:;
+ }
+ __pyx_L8:;
+ Py_DECREF(__pyx_3); __pyx_3 = 0;
+ }
+
+ __pyx_r = Py_None; Py_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ Py_XDECREF(__pyx_2);
+ Py_XDECREF(__pyx_3);
+ Py_XDECREF(__pyx_4);
+ Py_XDECREF(__pyx_7);
+ __Pyx_AddTraceback("sphinx.pycode.pgen2.parse.Parser.addtoken");
+ __pyx_r = NULL;
+ __pyx_L0:;
+ Py_DECREF(__pyx_v_dfa);
+ Py_DECREF(__pyx_v_node);
+ Py_DECREF(__pyx_v_states);
+ Py_DECREF(__pyx_v_first);
+ Py_DECREF(__pyx_v_arcs);
+ Py_DECREF(__pyx_v_v);
+ Py_DECREF(__pyx_v_itsdfa);
+ Py_DECREF(__pyx_v_itsstates);
+ Py_DECREF(__pyx_v_itsfirst);
+ return __pyx_r;
+}
+
+/* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":107
+ * raise ParseError("bad input", type, value, context)
+ *
+ * cdef int classify(self, type, value, context): # <<<<<<<<<<<<<<
+ * """Turn a token into a label. (Internal)"""
+ * if type == NAME:
+ */
+
+static int __pyx_f_6sphinx_6pycode_5pgen2_5parse_6Parser_classify(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *__pyx_v_self, PyObject *__pyx_v_type, PyObject *__pyx_v_value, PyObject *__pyx_v_context) {
+ PyObject *__pyx_v_ilabel;
+ int __pyx_r;
+ PyObject *__pyx_1 = 0;
+ int __pyx_2;
+ PyObject *__pyx_3 = 0;
+ PyObject *__pyx_4 = 0;
+ int __pyx_5;
+ __pyx_v_ilabel = Py_None; Py_INCREF(Py_None);
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":109
+ * cdef int classify(self, type, value, context):
+ * """Turn a token into a label. (Internal)"""
+ * if type == NAME: # <<<<<<<<<<<<<<
+ * # Keep a listing of all used names
+ * self.used_names.add(value)
+ */
+ __pyx_1 = PyObject_RichCompare(__pyx_v_type, __pyx_int_1, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_2 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ if (__pyx_2) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":111
+ * if type == NAME:
+ * # Keep a listing of all used names
+ * self.used_names.add(value) # <<<<<<<<<<<<<<
+ * # Check for reserved words
+ * ilabel = self._grammar_keywords.get(value)
+ */
+ __pyx_1 = PyObject_GetAttr(__pyx_v_self->used_names, __pyx_kp_add); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_value);
+ __pyx_4 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":113
+ * self.used_names.add(value)
+ * # Check for reserved words
+ * ilabel = self._grammar_keywords.get(value) # <<<<<<<<<<<<<<
+ * if ilabel is not None:
+ * return ilabel
+ */
+ __pyx_1 = PyObject_GetAttr(__pyx_v_self->_grammar_keywords, __pyx_kp_get); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_value);
+ __pyx_4 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
+ Py_DECREF(__pyx_v_ilabel);
+ __pyx_v_ilabel = __pyx_4;
+ __pyx_4 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":114
+ * # Check for reserved words
+ * ilabel = self._grammar_keywords.get(value)
+ * if ilabel is not None: # <<<<<<<<<<<<<<
+ * return ilabel
+ * ilabel = self._grammar_tokens.get(type)
+ */
+ __pyx_2 = (__pyx_v_ilabel != Py_None);
+ if (__pyx_2) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":115
+ * ilabel = self._grammar_keywords.get(value)
+ * if ilabel is not None:
+ * return ilabel # <<<<<<<<<<<<<<
+ * ilabel = self._grammar_tokens.get(type)
+ * if ilabel is None:
+ */
+ __pyx_5 = __pyx_PyInt_int(__pyx_v_ilabel); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = __pyx_5;
+ goto __pyx_L0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":116
+ * if ilabel is not None:
+ * return ilabel
+ * ilabel = self._grammar_tokens.get(type) # <<<<<<<<<<<<<<
+ * if ilabel is None:
+ * raise ParseError("bad token", type, value, context)
+ */
+ __pyx_1 = PyObject_GetAttr(__pyx_v_self->_grammar_tokens, __pyx_kp_get); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_type);
+ PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_type);
+ __pyx_4 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
+ Py_DECREF(__pyx_v_ilabel);
+ __pyx_v_ilabel = __pyx_4;
+ __pyx_4 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":117
+ * return ilabel
+ * ilabel = self._grammar_tokens.get(type)
+ * if ilabel is None: # <<<<<<<<<<<<<<
+ * raise ParseError("bad token", type, value, context)
+ * return ilabel
+ */
+ __pyx_2 = (__pyx_v_ilabel == Py_None);
+ if (__pyx_2) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":118
+ * ilabel = self._grammar_tokens.get(type)
+ * if ilabel is None:
+ * raise ParseError("bad token", type, value, context) # <<<<<<<<<<<<<<
+ * return ilabel
+ *
+ */
+ __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_ParseError); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_3 = PyTuple_New(4); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_kp_7);
+ PyTuple_SET_ITEM(__pyx_3, 0, __pyx_kp_7);
+ Py_INCREF(__pyx_v_type);
+ PyTuple_SET_ITEM(__pyx_3, 1, __pyx_v_type);
+ Py_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_3, 2, __pyx_v_value);
+ Py_INCREF(__pyx_v_context);
+ PyTuple_SET_ITEM(__pyx_3, 3, __pyx_v_context);
+ __pyx_4 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
+ __Pyx_Raise(__pyx_4, 0, 0);
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":119
+ * if ilabel is None:
+ * raise ParseError("bad token", type, value, context)
+ * return ilabel # <<<<<<<<<<<<<<
+ *
+ * cdef void shift(self, type, value, newstate, context):
+ */
+ __pyx_5 = __pyx_PyInt_int(__pyx_v_ilabel); if (unlikely((__pyx_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = __pyx_5;
+ goto __pyx_L0;
+
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ Py_XDECREF(__pyx_1);
+ Py_XDECREF(__pyx_3);
+ Py_XDECREF(__pyx_4);
+ __Pyx_WriteUnraisable("sphinx.pycode.pgen2.parse.Parser.classify");
+ __pyx_r = 0;
+ __pyx_L0:;
+ Py_DECREF(__pyx_v_ilabel);
+ return __pyx_r;
+}
+
+/* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":121
+ * return ilabel
+ *
+ * cdef void shift(self, type, value, newstate, context): # <<<<<<<<<<<<<<
+ * """Shift a token. (Internal)"""
+ * dfa, state, node = self.stack[-1]
+ */
+
+static void __pyx_f_6sphinx_6pycode_5pgen2_5parse_6Parser_shift(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *__pyx_v_self, PyObject *__pyx_v_type, PyObject *__pyx_v_value, PyObject *__pyx_v_newstate, PyObject *__pyx_v_context) {
+ PyObject *__pyx_v_dfa;
+ PyObject *__pyx_v_state;
+ PyObject *__pyx_v_node;
+ PyObject *__pyx_v_newnode;
+ PyObject *__pyx_1 = 0;
+ PyObject *__pyx_2 = 0;
+ PyObject *__pyx_3 = 0;
+ int __pyx_4;
+ __pyx_v_dfa = Py_None; Py_INCREF(Py_None);
+ __pyx_v_state = Py_None; Py_INCREF(Py_None);
+ __pyx_v_node = Py_None; Py_INCREF(Py_None);
+ __pyx_v_newnode = Py_None; Py_INCREF(Py_None);
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":123
+ * cdef void shift(self, type, value, newstate, context):
+ * """Shift a token. (Internal)"""
+ * dfa, state, node = self.stack[-1] # <<<<<<<<<<<<<<
+ * newnode = (type, value, context, None)
+ * newnode = self.convert(newnode)
+ */
+ __pyx_1 = __Pyx_GetItemInt(__pyx_v_self->stack, -1, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyTuple_CheckExact(__pyx_1) && PyTuple_GET_SIZE(__pyx_1) == 3) {
+ PyObject* tuple = __pyx_1;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_dfa);
+ __pyx_v_dfa = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_state);
+ __pyx_v_state = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 2);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_node);
+ __pyx_v_node = __pyx_3;
+ __pyx_3 = 0;
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ }
+ else {
+ __pyx_2 = PyObject_GetIter(__pyx_1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_2, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_dfa);
+ __pyx_v_dfa = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_2, 1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_state);
+ __pyx_v_state = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_2, 2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_node);
+ __pyx_v_node = __pyx_3;
+ __pyx_3 = 0;
+ if (__Pyx_EndUnpack(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":124
+ * """Shift a token. (Internal)"""
+ * dfa, state, node = self.stack[-1]
+ * newnode = (type, value, context, None) # <<<<<<<<<<<<<<
+ * newnode = self.convert(newnode)
+ * if newnode is not None:
+ */
+ __pyx_3 = PyTuple_New(4); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_type);
+ PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_type);
+ Py_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_3, 1, __pyx_v_value);
+ Py_INCREF(__pyx_v_context);
+ PyTuple_SET_ITEM(__pyx_3, 2, __pyx_v_context);
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_3, 3, Py_None);
+ Py_DECREF(__pyx_v_newnode);
+ __pyx_v_newnode = ((PyObject *)__pyx_3);
+ __pyx_3 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":125
+ * dfa, state, node = self.stack[-1]
+ * newnode = (type, value, context, None)
+ * newnode = self.convert(newnode) # <<<<<<<<<<<<<<
+ * if newnode is not None:
+ * node[-1].append(newnode)
+ */
+ __pyx_1 = ((struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self->__pyx_vtab)->convert(__pyx_v_self, __pyx_v_newnode); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_newnode);
+ __pyx_v_newnode = __pyx_1;
+ __pyx_1 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":126
+ * newnode = (type, value, context, None)
+ * newnode = self.convert(newnode)
+ * if newnode is not None: # <<<<<<<<<<<<<<
+ * node[-1].append(newnode)
+ * self.stack[-1] = (dfa, newstate, node)
+ */
+ __pyx_4 = (__pyx_v_newnode != Py_None);
+ if (__pyx_4) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":127
+ * newnode = self.convert(newnode)
+ * if newnode is not None:
+ * node[-1].append(newnode) # <<<<<<<<<<<<<<
+ * self.stack[-1] = (dfa, newstate, node)
+ *
+ */
+ __pyx_2 = __Pyx_GetItemInt(__pyx_v_node, -1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_3 = __Pyx_PyObject_Append(__pyx_2, __pyx_v_newnode); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ Py_DECREF(__pyx_3); __pyx_3 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":128
+ * if newnode is not None:
+ * node[-1].append(newnode)
+ * self.stack[-1] = (dfa, newstate, node) # <<<<<<<<<<<<<<
+ *
+ * cdef void push(self, type, newdfa, newstate, context):
+ */
+ __pyx_1 = PyTuple_New(3); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_dfa);
+ PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_dfa);
+ Py_INCREF(__pyx_v_newstate);
+ PyTuple_SET_ITEM(__pyx_1, 1, __pyx_v_newstate);
+ Py_INCREF(__pyx_v_node);
+ PyTuple_SET_ITEM(__pyx_1, 2, __pyx_v_node);
+ if (__Pyx_SetItemInt(__pyx_v_self->stack, -1, ((PyObject *)__pyx_1), 0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ Py_XDECREF(__pyx_1);
+ Py_XDECREF(__pyx_2);
+ Py_XDECREF(__pyx_3);
+ __Pyx_WriteUnraisable("sphinx.pycode.pgen2.parse.Parser.shift");
+ __pyx_L0:;
+ Py_DECREF(__pyx_v_dfa);
+ Py_DECREF(__pyx_v_state);
+ Py_DECREF(__pyx_v_node);
+ Py_DECREF(__pyx_v_newnode);
+}
+
+/* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":130
+ * self.stack[-1] = (dfa, newstate, node)
+ *
+ * cdef void push(self, type, newdfa, newstate, context): # <<<<<<<<<<<<<<
+ * """Push a nonterminal. (Internal)"""
+ * dfa, state, node = self.stack[-1]
+ */
+
+static void __pyx_f_6sphinx_6pycode_5pgen2_5parse_6Parser_push(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *__pyx_v_self, PyObject *__pyx_v_type, PyObject *__pyx_v_newdfa, PyObject *__pyx_v_newstate, PyObject *__pyx_v_context) {
+ PyObject *__pyx_v_dfa;
+ PyObject *__pyx_v_state;
+ PyObject *__pyx_v_node;
+ PyObject *__pyx_v_newnode;
+ PyObject *__pyx_1 = 0;
+ PyObject *__pyx_2 = 0;
+ PyObject *__pyx_3 = 0;
+ __pyx_v_dfa = Py_None; Py_INCREF(Py_None);
+ __pyx_v_state = Py_None; Py_INCREF(Py_None);
+ __pyx_v_node = Py_None; Py_INCREF(Py_None);
+ __pyx_v_newnode = Py_None; Py_INCREF(Py_None);
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":132
+ * cdef void push(self, type, newdfa, newstate, context):
+ * """Push a nonterminal. (Internal)"""
+ * dfa, state, node = self.stack[-1] # <<<<<<<<<<<<<<
+ * newnode = (type, None, context, [])
+ * self.stack[-1] = (dfa, newstate, node)
+ */
+ __pyx_1 = __Pyx_GetItemInt(__pyx_v_self->stack, -1, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyTuple_CheckExact(__pyx_1) && PyTuple_GET_SIZE(__pyx_1) == 3) {
+ PyObject* tuple = __pyx_1;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_dfa);
+ __pyx_v_dfa = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_state);
+ __pyx_v_state = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 2);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_node);
+ __pyx_v_node = __pyx_3;
+ __pyx_3 = 0;
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ }
+ else {
+ __pyx_2 = PyObject_GetIter(__pyx_1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_2, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_dfa);
+ __pyx_v_dfa = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_2, 1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_state);
+ __pyx_v_state = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_2, 2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_node);
+ __pyx_v_node = __pyx_3;
+ __pyx_3 = 0;
+ if (__Pyx_EndUnpack(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":133
+ * """Push a nonterminal. (Internal)"""
+ * dfa, state, node = self.stack[-1]
+ * newnode = (type, None, context, []) # <<<<<<<<<<<<<<
+ * self.stack[-1] = (dfa, newstate, node)
+ * self.stack.append((newdfa, 0, newnode))
+ */
+ __pyx_3 = PyList_New(0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_1 = PyTuple_New(4); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_type);
+ PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_type);
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_1, 1, Py_None);
+ Py_INCREF(__pyx_v_context);
+ PyTuple_SET_ITEM(__pyx_1, 2, __pyx_v_context);
+ PyTuple_SET_ITEM(__pyx_1, 3, ((PyObject *)__pyx_3));
+ __pyx_3 = 0;
+ Py_DECREF(__pyx_v_newnode);
+ __pyx_v_newnode = ((PyObject *)__pyx_1);
+ __pyx_1 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":134
+ * dfa, state, node = self.stack[-1]
+ * newnode = (type, None, context, [])
+ * self.stack[-1] = (dfa, newstate, node) # <<<<<<<<<<<<<<
+ * self.stack.append((newdfa, 0, newnode))
+ *
+ */
+ __pyx_2 = PyTuple_New(3); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_dfa);
+ PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_dfa);
+ Py_INCREF(__pyx_v_newstate);
+ PyTuple_SET_ITEM(__pyx_2, 1, __pyx_v_newstate);
+ Py_INCREF(__pyx_v_node);
+ PyTuple_SET_ITEM(__pyx_2, 2, __pyx_v_node);
+ if (__Pyx_SetItemInt(__pyx_v_self->stack, -1, ((PyObject *)__pyx_2), 0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":135
+ * newnode = (type, None, context, [])
+ * self.stack[-1] = (dfa, newstate, node)
+ * self.stack.append((newdfa, 0, newnode)) # <<<<<<<<<<<<<<
+ *
+ * cdef void pop(self):
+ */
+ __pyx_3 = PyTuple_New(3); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_newdfa);
+ PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_newdfa);
+ Py_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_3, 1, __pyx_int_0);
+ Py_INCREF(__pyx_v_newnode);
+ PyTuple_SET_ITEM(__pyx_3, 2, __pyx_v_newnode);
+ __pyx_1 = __Pyx_PyObject_Append(__pyx_v_self->stack, ((PyObject *)__pyx_3)); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ Py_XDECREF(__pyx_1);
+ Py_XDECREF(__pyx_2);
+ Py_XDECREF(__pyx_3);
+ __Pyx_WriteUnraisable("sphinx.pycode.pgen2.parse.Parser.push");
+ __pyx_L0:;
+ Py_DECREF(__pyx_v_dfa);
+ Py_DECREF(__pyx_v_state);
+ Py_DECREF(__pyx_v_node);
+ Py_DECREF(__pyx_v_newnode);
+}
+
+/* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":137
+ * self.stack.append((newdfa, 0, newnode))
+ *
+ * cdef void pop(self): # <<<<<<<<<<<<<<
+ * """Pop a nonterminal. (Internal)"""
+ * popdfa, popstate, popnode = self.stack.pop()
+ */
+
+static void __pyx_f_6sphinx_6pycode_5pgen2_5parse_6Parser_pop(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *__pyx_v_self) {
+ PyObject *__pyx_v_popdfa;
+ PyObject *__pyx_v_popstate;
+ PyObject *__pyx_v_popnode;
+ PyObject *__pyx_v_newnode;
+ PyObject *__pyx_v_dfa;
+ PyObject *__pyx_v_state;
+ PyObject *__pyx_v_node;
+ PyObject *__pyx_1 = 0;
+ PyObject *__pyx_2 = 0;
+ PyObject *__pyx_3 = 0;
+ int __pyx_4;
+ __pyx_v_popdfa = Py_None; Py_INCREF(Py_None);
+ __pyx_v_popstate = Py_None; Py_INCREF(Py_None);
+ __pyx_v_popnode = Py_None; Py_INCREF(Py_None);
+ __pyx_v_newnode = Py_None; Py_INCREF(Py_None);
+ __pyx_v_dfa = Py_None; Py_INCREF(Py_None);
+ __pyx_v_state = Py_None; Py_INCREF(Py_None);
+ __pyx_v_node = Py_None; Py_INCREF(Py_None);
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":139
+ * cdef void pop(self):
+ * """Pop a nonterminal. (Internal)"""
+ * popdfa, popstate, popnode = self.stack.pop() # <<<<<<<<<<<<<<
+ * newnode = self.convert(popnode)
+ * if newnode is not None:
+ */
+ __pyx_1 = PyObject_GetAttr(__pyx_v_self->stack, __pyx_kp_pop); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_2 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ if (PyTuple_CheckExact(__pyx_2) && PyTuple_GET_SIZE(__pyx_2) == 3) {
+ PyObject* tuple = __pyx_2;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_popdfa);
+ __pyx_v_popdfa = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_popstate);
+ __pyx_v_popstate = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 2);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_popnode);
+ __pyx_v_popnode = __pyx_3;
+ __pyx_3 = 0;
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ }
+ else {
+ __pyx_1 = PyObject_GetIter(__pyx_2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_1, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_popdfa);
+ __pyx_v_popdfa = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_1, 1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_popstate);
+ __pyx_v_popstate = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_1, 2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_popnode);
+ __pyx_v_popnode = __pyx_3;
+ __pyx_3 = 0;
+ if (__Pyx_EndUnpack(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":140
+ * """Pop a nonterminal. (Internal)"""
+ * popdfa, popstate, popnode = self.stack.pop()
+ * newnode = self.convert(popnode) # <<<<<<<<<<<<<<
+ * if newnode is not None:
+ * if self.stack:
+ */
+ __pyx_3 = ((struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser *)__pyx_v_self->__pyx_vtab)->convert(__pyx_v_self, __pyx_v_popnode); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_newnode);
+ __pyx_v_newnode = __pyx_3;
+ __pyx_3 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":141
+ * popdfa, popstate, popnode = self.stack.pop()
+ * newnode = self.convert(popnode)
+ * if newnode is not None: # <<<<<<<<<<<<<<
+ * if self.stack:
+ * dfa, state, node = self.stack[-1]
+ */
+ __pyx_4 = (__pyx_v_newnode != Py_None);
+ if (__pyx_4) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":142
+ * newnode = self.convert(popnode)
+ * if newnode is not None:
+ * if self.stack: # <<<<<<<<<<<<<<
+ * dfa, state, node = self.stack[-1]
+ * node[-1].append(newnode)
+ */
+ __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_v_self->stack); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_4) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":143
+ * if newnode is not None:
+ * if self.stack:
+ * dfa, state, node = self.stack[-1] # <<<<<<<<<<<<<<
+ * node[-1].append(newnode)
+ * else:
+ */
+ __pyx_2 = __Pyx_GetItemInt(__pyx_v_self->stack, -1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyTuple_CheckExact(__pyx_2) && PyTuple_GET_SIZE(__pyx_2) == 3) {
+ PyObject* tuple = __pyx_2;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_dfa);
+ __pyx_v_dfa = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_state);
+ __pyx_v_state = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = PyTuple_GET_ITEM(tuple, 2);
+ Py_INCREF(__pyx_3);
+ Py_DECREF(__pyx_v_node);
+ __pyx_v_node = __pyx_3;
+ __pyx_3 = 0;
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ }
+ else {
+ __pyx_1 = PyObject_GetIter(__pyx_2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_1, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_dfa);
+ __pyx_v_dfa = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_1, 1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_state);
+ __pyx_v_state = __pyx_3;
+ __pyx_3 = 0;
+ __pyx_3 = __Pyx_UnpackItem(__pyx_1, 2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_node);
+ __pyx_v_node = __pyx_3;
+ __pyx_3 = 0;
+ if (__Pyx_EndUnpack(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":144
+ * if self.stack:
+ * dfa, state, node = self.stack[-1]
+ * node[-1].append(newnode) # <<<<<<<<<<<<<<
+ * else:
+ * self.rootnode = newnode
+ */
+ __pyx_3 = __Pyx_GetItemInt(__pyx_v_node, -1, 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_2 = __Pyx_PyObject_Append(__pyx_3, __pyx_v_newnode); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_3); __pyx_3 = 0;
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":146
+ * node[-1].append(newnode)
+ * else:
+ * self.rootnode = newnode # <<<<<<<<<<<<<<
+ * self.rootnode.used_names = self.used_names
+ *
+ */
+ Py_INCREF(__pyx_v_newnode);
+ Py_DECREF(__pyx_v_self->rootnode);
+ __pyx_v_self->rootnode = __pyx_v_newnode;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":147
+ * else:
+ * self.rootnode = newnode
+ * self.rootnode.used_names = self.used_names # <<<<<<<<<<<<<<
+ *
+ * cdef convert(self, raw_node):
+ */
+ if (PyObject_SetAttr(__pyx_v_self->rootnode, __pyx_kp_used_names, __pyx_v_self->used_names) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ Py_XDECREF(__pyx_1);
+ Py_XDECREF(__pyx_2);
+ Py_XDECREF(__pyx_3);
+ __Pyx_WriteUnraisable("sphinx.pycode.pgen2.parse.Parser.pop");
+ __pyx_L0:;
+ Py_DECREF(__pyx_v_popdfa);
+ Py_DECREF(__pyx_v_popstate);
+ Py_DECREF(__pyx_v_popnode);
+ Py_DECREF(__pyx_v_newnode);
+ Py_DECREF(__pyx_v_dfa);
+ Py_DECREF(__pyx_v_state);
+ Py_DECREF(__pyx_v_node);
+}
+
+/* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":149
+ * self.rootnode.used_names = self.used_names
+ *
+ * cdef convert(self, raw_node): # <<<<<<<<<<<<<<
+ * type, value, context, children = raw_node
+ * if children or type in self._grammar_number2symbol:
+ */
+
+static PyObject *__pyx_f_6sphinx_6pycode_5pgen2_5parse_6Parser_convert(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *__pyx_v_self, PyObject *__pyx_v_raw_node) {
+ PyObject *__pyx_v_type;
+ PyObject *__pyx_v_value;
+ PyObject *__pyx_v_context;
+ PyObject *__pyx_v_children;
+ PyObject *__pyx_r;
+ PyObject *__pyx_1 = 0;
+ PyObject *__pyx_2 = 0;
+ int __pyx_3;
+ Py_ssize_t __pyx_4 = 0;
+ PyObject *__pyx_5 = 0;
+ PyObject *__pyx_6 = 0;
+ __pyx_v_type = Py_None; Py_INCREF(Py_None);
+ __pyx_v_value = Py_None; Py_INCREF(Py_None);
+ __pyx_v_context = Py_None; Py_INCREF(Py_None);
+ __pyx_v_children = Py_None; Py_INCREF(Py_None);
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":150
+ *
+ * cdef convert(self, raw_node):
+ * type, value, context, children = raw_node # <<<<<<<<<<<<<<
+ * if children or type in self._grammar_number2symbol:
+ * # If there's exactly one child, return that child instead of
+ */
+ if (PyTuple_CheckExact(__pyx_v_raw_node) && PyTuple_GET_SIZE(__pyx_v_raw_node) == 4) {
+ PyObject* tuple = __pyx_v_raw_node;
+ __pyx_2 = PyTuple_GET_ITEM(tuple, 0);
+ Py_INCREF(__pyx_2);
+ Py_DECREF(__pyx_v_type);
+ __pyx_v_type = __pyx_2;
+ __pyx_2 = 0;
+ __pyx_2 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(__pyx_2);
+ Py_DECREF(__pyx_v_value);
+ __pyx_v_value = __pyx_2;
+ __pyx_2 = 0;
+ __pyx_2 = PyTuple_GET_ITEM(tuple, 2);
+ Py_INCREF(__pyx_2);
+ Py_DECREF(__pyx_v_context);
+ __pyx_v_context = __pyx_2;
+ __pyx_2 = 0;
+ __pyx_2 = PyTuple_GET_ITEM(tuple, 3);
+ Py_INCREF(__pyx_2);
+ Py_DECREF(__pyx_v_children);
+ __pyx_v_children = __pyx_2;
+ __pyx_2 = 0;
+ }
+ else {
+ __pyx_1 = PyObject_GetIter(__pyx_v_raw_node); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_2 = __Pyx_UnpackItem(__pyx_1, 0); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_type);
+ __pyx_v_type = __pyx_2;
+ __pyx_2 = 0;
+ __pyx_2 = __Pyx_UnpackItem(__pyx_1, 1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_value);
+ __pyx_v_value = __pyx_2;
+ __pyx_2 = 0;
+ __pyx_2 = __Pyx_UnpackItem(__pyx_1, 2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_context);
+ __pyx_v_context = __pyx_2;
+ __pyx_2 = 0;
+ __pyx_2 = __Pyx_UnpackItem(__pyx_1, 3); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_v_children);
+ __pyx_v_children = __pyx_2;
+ __pyx_2 = 0;
+ if (__Pyx_EndUnpack(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ }
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":151
+ * cdef convert(self, raw_node):
+ * type, value, context, children = raw_node
+ * if children or type in self._grammar_number2symbol: # <<<<<<<<<<<<<<
+ * # If there's exactly one child, return that child instead of
+ * # creating a new node.
+ */
+ __pyx_2 = __pyx_v_children;
+ Py_INCREF(__pyx_2);
+ __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_3) {
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ __pyx_3 = (PySequence_Contains(__pyx_v_self->_grammar_number2symbol, __pyx_v_type)); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_2 = __Pyx_PyBool_FromLong(__pyx_3); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ if (__pyx_3) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":154
+ * # If there's exactly one child, return that child instead of
+ * # creating a new node.
+ * if len(children) == 1: # <<<<<<<<<<<<<<
+ * return children[0]
+ * return Node(type, children, context=context)
+ */
+ __pyx_4 = PyObject_Length(__pyx_v_children); if (unlikely(__pyx_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_3 = (__pyx_4 == 1);
+ if (__pyx_3) {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":155
+ * # creating a new node.
+ * if len(children) == 1:
+ * return children[0] # <<<<<<<<<<<<<<
+ * return Node(type, children, context=context)
+ * else:
+ */
+ __pyx_1 = __Pyx_GetItemInt(__pyx_v_children, 0, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = __pyx_1;
+ __pyx_1 = 0;
+ goto __pyx_L0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":156
+ * if len(children) == 1:
+ * return children[0]
+ * return Node(type, children, context=context) # <<<<<<<<<<<<<<
+ * else:
+ * return Leaf(type, value, context=context)
+ */
+ __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_kp_Node); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_type);
+ PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_type);
+ Py_INCREF(__pyx_v_children);
+ PyTuple_SET_ITEM(__pyx_1, 1, __pyx_v_children);
+ __pyx_5 = PyDict_New(); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyDict_SetItem(__pyx_5, __pyx_kp_context, __pyx_v_context) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_6 = PyEval_CallObjectWithKeywords(__pyx_2, ((PyObject *)__pyx_1), ((PyObject *)__pyx_5)); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
+ Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
+ __pyx_r = __pyx_6;
+ __pyx_6 = 0;
+ goto __pyx_L0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":158
+ * return Node(type, children, context=context)
+ * else:
+ * return Leaf(type, value, context=context) # <<<<<<<<<<<<<<
+ */
+ __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_kp_Leaf); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_v_type);
+ PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_type);
+ Py_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_1, 1, __pyx_v_value);
+ __pyx_5 = PyDict_New(); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyDict_SetItem(__pyx_5, __pyx_kp_context, __pyx_v_context) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_6 = PyEval_CallObjectWithKeywords(__pyx_2, ((PyObject *)__pyx_1), ((PyObject *)__pyx_5)); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+ Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
+ Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
+ __pyx_r = __pyx_6;
+ __pyx_6 = 0;
+ goto __pyx_L0;
+ }
+ __pyx_L3:;
+
+ __pyx_r = Py_None; Py_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ Py_XDECREF(__pyx_1);
+ Py_XDECREF(__pyx_2);
+ Py_XDECREF(__pyx_5);
+ Py_XDECREF(__pyx_6);
+ __Pyx_AddTraceback("sphinx.pycode.pgen2.parse.Parser.convert");
+ __pyx_r = 0;
+ __pyx_L0:;
+ Py_DECREF(__pyx_v_type);
+ Py_DECREF(__pyx_v_value);
+ Py_DECREF(__pyx_v_context);
+ Py_DECREF(__pyx_v_children);
+ return __pyx_r;
+}
+static struct __pyx_vtabstruct_6sphinx_6pycode_5pgen2_5parse_Parser __pyx_vtable_6sphinx_6pycode_5pgen2_5parse_Parser;
+
+static PyObject *__pyx_tp_new_6sphinx_6pycode_5pgen2_5parse_Parser(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *p;
+ PyObject *o = (*t->tp_alloc)(t, 0);
+ if (!o) return 0;
+ p = ((struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)o);
+ p->__pyx_vtab = __pyx_vtabptr_6sphinx_6pycode_5pgen2_5parse_Parser;
+ p->grammar = Py_None; Py_INCREF(Py_None);
+ p->stack = Py_None; Py_INCREF(Py_None);
+ p->rootnode = Py_None; Py_INCREF(Py_None);
+ p->used_names = Py_None; Py_INCREF(Py_None);
+ p->_grammar_dfas = Py_None; Py_INCREF(Py_None);
+ p->_grammar_labels = Py_None; Py_INCREF(Py_None);
+ p->_grammar_keywords = Py_None; Py_INCREF(Py_None);
+ p->_grammar_tokens = Py_None; Py_INCREF(Py_None);
+ p->_grammar_number2symbol = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_6sphinx_6pycode_5pgen2_5parse_Parser(PyObject *o) {
+ struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *p = (struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)o;
+ Py_XDECREF(p->grammar);
+ Py_XDECREF(p->stack);
+ Py_XDECREF(p->rootnode);
+ Py_XDECREF(p->used_names);
+ Py_XDECREF(p->_grammar_dfas);
+ Py_XDECREF(p->_grammar_labels);
+ Py_XDECREF(p->_grammar_keywords);
+ Py_XDECREF(p->_grammar_tokens);
+ Py_XDECREF(p->_grammar_number2symbol);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6sphinx_6pycode_5pgen2_5parse_Parser(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *p = (struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)o;
+ if (p->grammar) {
+ e = (*v)(p->grammar, a); if (e) return e;
+ }
+ if (p->stack) {
+ e = (*v)(p->stack, a); if (e) return e;
+ }
+ if (p->rootnode) {
+ e = (*v)(p->rootnode, a); if (e) return e;
+ }
+ if (p->used_names) {
+ e = (*v)(p->used_names, a); if (e) return e;
+ }
+ if (p->_grammar_dfas) {
+ e = (*v)(p->_grammar_dfas, a); if (e) return e;
+ }
+ if (p->_grammar_labels) {
+ e = (*v)(p->_grammar_labels, a); if (e) return e;
+ }
+ if (p->_grammar_keywords) {
+ e = (*v)(p->_grammar_keywords, a); if (e) return e;
+ }
+ if (p->_grammar_tokens) {
+ e = (*v)(p->_grammar_tokens, a); if (e) return e;
+ }
+ if (p->_grammar_number2symbol) {
+ e = (*v)(p->_grammar_number2symbol, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_6sphinx_6pycode_5pgen2_5parse_Parser(PyObject *o) {
+ struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *p = (struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser *)o;
+ PyObject* tmp;
+ tmp = ((PyObject*)p->grammar);
+ p->grammar = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->stack);
+ p->stack = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->rootnode);
+ p->rootnode = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->used_names);
+ p->used_names = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_grammar_dfas);
+ p->_grammar_dfas = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_grammar_labels);
+ p->_grammar_labels = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_grammar_keywords);
+ p->_grammar_keywords = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_grammar_tokens);
+ p->_grammar_tokens = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_grammar_number2symbol);
+ p->_grammar_number2symbol = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static struct PyMethodDef __pyx_methods_6sphinx_6pycode_5pgen2_5parse_Parser[] = {
+ {"setup", (PyCFunction)__pyx_pf_6sphinx_6pycode_5pgen2_5parse_6Parser_setup, METH_VARARGS|METH_KEYWORDS, 0},
+ {"addtoken", (PyCFunction)__pyx_pf_6sphinx_6pycode_5pgen2_5parse_6Parser_addtoken, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6sphinx_6pycode_5pgen2_5parse_6Parser_addtoken},
+ {0, 0, 0, 0}
+};
+
+static struct PyMemberDef __pyx_members_6sphinx_6pycode_5pgen2_5parse_Parser[] = {
+ {"grammar", T_OBJECT, offsetof(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser, grammar), 0, 0},
+ {"stack", T_OBJECT, offsetof(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser, stack), 0, 0},
+ {"rootnode", T_OBJECT, offsetof(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser, rootnode), 0, 0},
+ {"used_names", T_OBJECT, offsetof(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser, used_names), 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_Parser = {
+ 0, /*nb_add*/
+ 0, /*nb_subtract*/
+ 0, /*nb_multiply*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*nb_divide*/
+ #endif
+ 0, /*nb_remainder*/
+ 0, /*nb_divmod*/
+ 0, /*nb_power*/
+ 0, /*nb_negative*/
+ 0, /*nb_positive*/
+ 0, /*nb_absolute*/
+ 0, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ 0, /*nb_and*/
+ 0, /*nb_xor*/
+ 0, /*nb_or*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*nb_coerce*/
+ #endif
+ 0, /*nb_int*/
+ 0, /*nb_long*/
+ 0, /*nb_float*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*nb_oct*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*nb_hex*/
+ #endif
+ 0, /*nb_inplace_add*/
+ 0, /*nb_inplace_subtract*/
+ 0, /*nb_inplace_multiply*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*nb_inplace_divide*/
+ #endif
+ 0, /*nb_inplace_remainder*/
+ 0, /*nb_inplace_power*/
+ 0, /*nb_inplace_lshift*/
+ 0, /*nb_inplace_rshift*/
+ 0, /*nb_inplace_and*/
+ 0, /*nb_inplace_xor*/
+ 0, /*nb_inplace_or*/
+ 0, /*nb_floor_divide*/
+ 0, /*nb_true_divide*/
+ 0, /*nb_inplace_floor_divide*/
+ 0, /*nb_inplace_true_divide*/
+ #if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & Py_TPFLAGS_HAVE_INDEX)
+ 0, /*nb_index*/
+ #endif
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_Parser = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ 0, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_Parser = {
+ 0, /*mp_length*/
+ 0, /*mp_subscript*/
+ 0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_Parser = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ #if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & Py_TPFLAGS_HAVE_NEWBUFFER)
+ 0, /*bf_getbuffer*/
+ #endif
+ #if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & Py_TPFLAGS_HAVE_NEWBUFFER)
+ 0, /*bf_releasebuffer*/
+ #endif
+};
+
+PyTypeObject __pyx_type_6sphinx_6pycode_5pgen2_5parse_Parser = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "sphinx.pycode.pgen2.parse.Parser", /*tp_name*/
+ sizeof(struct __pyx_obj_6sphinx_6pycode_5pgen2_5parse_Parser), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_6sphinx_6pycode_5pgen2_5parse_Parser, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ &__pyx_tp_as_number_Parser, /*tp_as_number*/
+ &__pyx_tp_as_sequence_Parser, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_Parser, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_Parser, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_6sphinx_6pycode_5pgen2_5parse_Parser, /*tp_traverse*/
+ __pyx_tp_clear_6sphinx_6pycode_5pgen2_5parse_Parser, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_6sphinx_6pycode_5pgen2_5parse_Parser, /*tp_methods*/
+ __pyx_members_6sphinx_6pycode_5pgen2_5parse_Parser, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_pf_6sphinx_6pycode_5pgen2_5parse_6Parser___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_6sphinx_6pycode_5pgen2_5parse_Parser, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+};
+
+static struct PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+static void __pyx_init_filenames(void); /*proto*/
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "parse",
+ 0, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp___init__, __pyx_k___init__, sizeof(__pyx_k___init__), 0, 1, 1},
+ {&__pyx_kp_setup, __pyx_k_setup, sizeof(__pyx_k_setup), 0, 1, 1},
+ {&__pyx_kp_addtoken, __pyx_k_addtoken, sizeof(__pyx_k_addtoken), 0, 1, 1},
+ {&__pyx_kp_1, __pyx_k_1, sizeof(__pyx_k_1), 1, 1, 1},
+ {&__pyx_kp_Node, __pyx_k_Node, sizeof(__pyx_k_Node), 1, 1, 1},
+ {&__pyx_kp_Leaf, __pyx_k_Leaf, sizeof(__pyx_k_Leaf), 1, 1, 1},
+ {&__pyx_kp_ParseError, __pyx_k_ParseError, sizeof(__pyx_k_ParseError), 0, 1, 1},
+ {&__pyx_kp_Exception, __pyx_k_Exception, sizeof(__pyx_k_Exception), 1, 1, 1},
+ {&__pyx_kp_msg, __pyx_k_msg, sizeof(__pyx_k_msg), 1, 1, 1},
+ {&__pyx_kp_type, __pyx_k_type, sizeof(__pyx_k_type), 1, 1, 1},
+ {&__pyx_kp_value, __pyx_k_value, sizeof(__pyx_k_value), 1, 1, 1},
+ {&__pyx_kp_context, __pyx_k_context, sizeof(__pyx_k_context), 1, 1, 1},
+ {&__pyx_kp_dfas, __pyx_k_dfas, sizeof(__pyx_k_dfas), 1, 1, 1},
+ {&__pyx_kp_labels, __pyx_k_labels, sizeof(__pyx_k_labels), 1, 1, 1},
+ {&__pyx_kp_keywords, __pyx_k_keywords, sizeof(__pyx_k_keywords), 1, 1, 1},
+ {&__pyx_kp_tokens, __pyx_k_tokens, sizeof(__pyx_k_tokens), 1, 1, 1},
+ {&__pyx_kp_4, __pyx_k_4, sizeof(__pyx_k_4), 1, 1, 1},
+ {&__pyx_kp_start, __pyx_k_start, sizeof(__pyx_k_start), 1, 1, 1},
+ {&__pyx_kp_add, __pyx_k_add, sizeof(__pyx_k_add), 1, 1, 1},
+ {&__pyx_kp_get, __pyx_k_get, sizeof(__pyx_k_get), 1, 1, 1},
+ {&__pyx_kp_append, __pyx_k_append, sizeof(__pyx_k_append), 1, 1, 1},
+ {&__pyx_kp_pop, __pyx_k_pop, sizeof(__pyx_k_pop), 1, 1, 1},
+ {&__pyx_kp_used_names, __pyx_k_used_names, sizeof(__pyx_k_used_names), 1, 1, 1},
+ {&__pyx_kp_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 0},
+ {&__pyx_kp_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 0},
+ {&__pyx_kp_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 0},
+ {&__pyx_kp_6, __pyx_k_6, sizeof(__pyx_k_6), 0, 0, 0},
+ {&__pyx_kp_7, __pyx_k_7, sizeof(__pyx_k_7), 0, 0, 0},
+ {0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_Exception = __Pyx_GetName(__pyx_b, __pyx_kp_Exception); if (!__pyx_builtin_Exception) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initparse(void); /*proto*/
+PyMODINIT_FUNC initparse(void)
+#else
+PyMODINIT_FUNC PyInit_parse(void); /*proto*/
+PyMODINIT_FUNC PyInit_parse(void)
+#endif
+{
+ PyObject *__pyx_1 = 0;
+ PyObject *__pyx_2 = 0;
+ PyObject *__pyx_3 = 0;
+ PyObject *__pyx_4 = 0;
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Libary function declarations ---*/
+ __pyx_init_filenames();
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("parse", __pyx_methods, 0, 0, PYTHON_API_VERSION);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ #if PY_MAJOR_VERSION < 3
+ Py_INCREF(__pyx_m);
+ #endif
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME);
+ if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_skip_dispatch = 0;
+ /*--- Global init code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ __pyx_vtabptr_6sphinx_6pycode_5pgen2_5parse_Parser = &__pyx_vtable_6sphinx_6pycode_5pgen2_5parse_Parser;
+ *(void(**)(void))&__pyx_vtable_6sphinx_6pycode_5pgen2_5parse_Parser.classify = (void(*)(void))__pyx_f_6sphinx_6pycode_5pgen2_5parse_6Parser_classify;
+ *(void(**)(void))&__pyx_vtable_6sphinx_6pycode_5pgen2_5parse_Parser.shift = (void(*)(void))__pyx_f_6sphinx_6pycode_5pgen2_5parse_6Parser_shift;
+ *(void(**)(void))&__pyx_vtable_6sphinx_6pycode_5pgen2_5parse_Parser.push = (void(*)(void))__pyx_f_6sphinx_6pycode_5pgen2_5parse_6Parser_push;
+ *(void(**)(void))&__pyx_vtable_6sphinx_6pycode_5pgen2_5parse_Parser.pop = (void(*)(void))__pyx_f_6sphinx_6pycode_5pgen2_5parse_6Parser_pop;
+ *(void(**)(void))&__pyx_vtable_6sphinx_6pycode_5pgen2_5parse_Parser.convert = (void(*)(void))__pyx_f_6sphinx_6pycode_5pgen2_5parse_6Parser_convert;
+ if (PyType_Ready(&__pyx_type_6sphinx_6pycode_5pgen2_5parse_Parser) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__Pyx_SetVtable(__pyx_type_6sphinx_6pycode_5pgen2_5parse_Parser.tp_dict, __pyx_vtabptr_6sphinx_6pycode_5pgen2_5parse_Parser) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyObject_SetAttrString(__pyx_m, "Parser", (PyObject *)&__pyx_type_6sphinx_6pycode_5pgen2_5parse_Parser) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_6sphinx_6pycode_5pgen2_5parse_Parser = &__pyx_type_6sphinx_6pycode_5pgen2_5parse_Parser;
+ /*--- Type import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":15
+ * """
+ *
+ * from sphinx.pycode.nodes import Node, Leaf # <<<<<<<<<<<<<<
+ *
+ * DEF NAME = 1
+ */
+ __pyx_1 = PyList_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_kp_Node);
+ PyList_SET_ITEM(__pyx_1, 0, __pyx_kp_Node);
+ Py_INCREF(__pyx_kp_Leaf);
+ PyList_SET_ITEM(__pyx_1, 1, __pyx_kp_Leaf);
+ __pyx_2 = __Pyx_Import(__pyx_kp_1, ((PyObject *)__pyx_1)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
+ __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_Node); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyObject_SetAttr(__pyx_m, __pyx_kp_Node, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_Leaf); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyObject_SetAttr(__pyx_m, __pyx_kp_Leaf, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ Py_DECREF(__pyx_2); __pyx_2 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":19
+ * DEF NAME = 1
+ *
+ * class ParseError(Exception): # <<<<<<<<<<<<<<
+ * """Exception to signal the parser is stuck."""
+ *
+ */
+ __pyx_2 = PyDict_New(); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_builtin_Exception);
+ PyTuple_SET_ITEM(__pyx_1, 0, __pyx_builtin_Exception);
+ if (PyDict_SetItemString(((PyObject *)__pyx_2), "__doc__", __pyx_kp_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_3 = __Pyx_CreateClass(((PyObject *)__pyx_1), ((PyObject *)__pyx_2), __pyx_kp_ParseError, "sphinx.pycode.pgen2.parse"); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":22
+ * """Exception to signal the parser is stuck."""
+ *
+ * def __init__(self, msg, type, value, context): # <<<<<<<<<<<<<<
+ * Exception.__init__(self, "%s: type=%r, value=%r, context=%r" %
+ * (msg, type, value, context))
+ */
+ __pyx_1 = PyCFunction_New(&__pyx_mdef_6sphinx_6pycode_5pgen2_5parse_10ParseError___init__, 0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_4 = PyMethod_New(__pyx_1, 0, __pyx_3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_1); __pyx_1 = 0;
+ if (PyObject_SetAttr(__pyx_3, __pyx_kp___init__, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_4); __pyx_4 = 0;
+ if (PyObject_SetAttr(__pyx_m, __pyx_kp_ParseError, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_DECREF(__pyx_3); __pyx_3 = 0;
+ Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
+
+ /* "/home/gbr/devel/sphinx/sphinx/pycode/pgen2/parse.pyx":149
+ * self.rootnode.used_names = self.used_names
+ *
+ * cdef convert(self, raw_node): # <<<<<<<<<<<<<<
+ * type, value, context, children = raw_node
+ * if children or type in self._grammar_number2symbol:
+ */
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+ __pyx_L1_error:;
+ Py_XDECREF(__pyx_1);
+ Py_XDECREF(__pyx_2);
+ Py_XDECREF(__pyx_3);
+ Py_XDECREF(__pyx_4);
+ __Pyx_AddTraceback("sphinx.pycode.pgen2.parse");
+ #if PY_MAJOR_VERSION >= 3
+ return NULL;
+ #endif
+}
+
+static const char *__pyx_filenames[] = {
+ "parse.pyx",
+};
+
+/* Runtime support code */
+
+static void __pyx_init_filenames(void) {
+ __pyx_f = __pyx_filenames;
+}
+
+static INLINE void __Pyx_RaiseArgtupleTooLong(
+ Py_ssize_t num_expected,
+ Py_ssize_t num_found)
+{
+ const char* error_message =
+ #if PY_VERSION_HEX < 0x02050000
+ "function takes at most %d positional arguments (%d given)";
+ #else
+ "function takes at most %zd positional arguments (%zd given)";
+ #endif
+ PyErr_Format(PyExc_TypeError, error_message, num_expected, num_found);
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
+ PyObject *__import__ = 0;
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ __import__ = PyObject_GetAttrString(__pyx_b, "__import__");
+ if (!__import__)
+ goto bad;
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ module = PyObject_CallFunction(__import__, "OOOO",
+ name, global_dict, empty_dict, list);
+bad:
+ Py_XDECREF(empty_list);
+ Py_XDECREF(__import__);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+ PyObject *result;
+ result = PyObject_GetAttr(dict, name);
+ if (!result)
+ PyErr_SetObject(PyExc_NameError, name);
+ return result;
+}
+
+static PyObject *__Pyx_CreateClass(
+ PyObject *bases, PyObject *dict, PyObject *name, char *modname)
+{
+ PyObject *py_modname;
+ PyObject *result = 0;
+
+ #if PY_MAJOR_VERSION < 3
+ py_modname = PyString_FromString(modname);
+ #else
+ py_modname = PyUnicode_FromString(modname);
+ #endif
+ if (!py_modname)
+ goto bad;
+ if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
+ goto bad;
+ #if PY_MAJOR_VERSION < 3
+ result = PyClass_New(bases, dict, name);
+ #else
+ result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
+ #endif
+bad:
+ Py_XDECREF(py_modname);
+ return result;
+}
+
+
+static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
+ PyObject *item;
+ if (!(item = PyIter_Next(iter))) {
+ if (!PyErr_Occurred()) {
+ PyErr_Format(PyExc_ValueError,
+ #if PY_VERSION_HEX < 0x02050000
+ "need more than %d values to unpack", (int)index);
+ #else
+ "need more than %zd values to unpack", index);
+ #endif
+ }
+ }
+ return item;
+}
+
+static int __Pyx_EndUnpack(PyObject *iter) {
+ PyObject *item;
+ if ((item = PyIter_Next(iter))) {
+ Py_DECREF(item);
+ PyErr_SetString(PyExc_ValueError, "too many values to unpack");
+ return -1;
+ }
+ else if (!PyErr_Occurred())
+ return 0;
+ else
+ return -1;
+}
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
+ Py_XINCREF(type);
+ Py_XINCREF(value);
+ Py_XINCREF(tb);
+ /* First, check the traceback argument, replacing None with NULL. */
+ if (tb == Py_None) {
+ Py_DECREF(tb);
+ tb = 0;
+ }
+ else if (tb != NULL && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ /* Next, replace a missing value with None */
+ if (value == NULL) {
+ value = Py_None;
+ Py_INCREF(value);
+ }
+ #if PY_VERSION_HEX < 0x02050000
+ if (!PyClass_Check(type))
+ #else
+ if (!PyType_Check(type))
+ #endif
+ {
+ /* Raising an instance. The value should be a dummy. */
+ if (value != Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ /* Normalize to raise <class>, <instance> */
+ Py_DECREF(value);
+ value = type;
+ #if PY_VERSION_HEX < 0x02050000
+ if (PyInstance_Check(type)) {
+ type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+ Py_INCREF(type);
+ }
+ else {
+ type = 0;
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception must be an old-style class or instance");
+ goto raise_error;
+ }
+ #else
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ #endif
+ }
+ PyErr_Restore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+
+
+static void __Pyx_WriteUnraisable(const char *name) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ PyErr_Fetch(&old_exc, &old_val, &old_tb);
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ PyErr_Restore(old_exc, old_val, old_tb);
+ if (!ctx)
+ ctx = Py_None;
+ PyErr_WriteUnraisable(ctx);
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+ PyObject *pycobj = 0;
+ int result;
+
+ pycobj = PyCObject_FromVoidPtr(vtable, 0);
+ if (!pycobj)
+ goto bad;
+ if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
+ goto bad;
+ result = 0;
+ goto done;
+
+bad:
+ result = -1;
+done:
+ Py_XDECREF(pycobj);
+ return result;
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+
+static void __Pyx_AddTraceback(const char *funcname) {
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ PyObject *py_globals = 0;
+ PyObject *empty_string = 0;
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(__pyx_filename);
+ #else
+ py_srcfile = PyUnicode_FromString(__pyx_filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (__pyx_clineno) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_globals = PyModule_GetDict(__pyx_m);
+ if (!py_globals) goto bad;
+ #if PY_MAJOR_VERSION < 3
+ empty_string = PyString_FromStringAndSize("", 0);
+ #else
+ empty_string = PyBytes_FromStringAndSize("", 0);
+ #endif
+ if (!empty_string) goto bad;
+ py_code = PyCode_New(
+ 0, /*int argcount,*/
+ #if PY_MAJOR_VERSION >= 3
+ 0, /*int kwonlyargcount,*/
+ #endif
+ 0, /*int nlocals,*/
+ 0, /*int stacksize,*/
+ 0, /*int flags,*/
+ empty_string, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ __pyx_lineno, /*int firstlineno,*/
+ empty_string /*PyObject *lnotab*/
+ );
+ if (!py_code) goto bad;
+ py_frame = PyFrame_New(
+ PyThreadState_Get(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ py_globals, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = __pyx_lineno;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ Py_XDECREF(empty_string);
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode && (!t->is_identifier)) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else /* Python 3+ has unicode identifiers */
+ if (t->is_identifier || (t->is_unicode && t->intern)) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->is_unicode) {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+/* Type Conversion Functions */
+
+static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject* x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+
+static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ if (x == Py_True) return 1;
+ else if (x == Py_False) return 0;
+ else return PyObject_IsTrue(x);
+}
+
+static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) {
+ if (PyInt_CheckExact(x)) {
+ return PyInt_AS_LONG(x);
+ }
+ else if (PyLong_CheckExact(x)) {
+ return PyLong_AsLongLong(x);
+ }
+ else {
+ PY_LONG_LONG val;
+ PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
+ val = __pyx_PyInt_AsLongLong(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+}
+
+static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+ if (PyInt_CheckExact(x)) {
+ long val = PyInt_AS_LONG(x);
+ if (unlikely(val < 0)) {
+ PyErr_SetString(PyExc_TypeError, "Negative assignment to unsigned type.");
+ return (unsigned PY_LONG_LONG)-1;
+ }
+ return val;
+ }
+ else if (PyLong_CheckExact(x)) {
+ return PyLong_AsUnsignedLongLong(x);
+ }
+ else {
+ PY_LONG_LONG val;
+ PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
+ val = __pyx_PyInt_AsUnsignedLongLong(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+}
+
+
+static INLINE unsigned char __pyx_PyInt_unsigned_char(PyObject* x) {
+ if (sizeof(unsigned char) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ unsigned char val = (unsigned char)long_val;
+ if (unlikely((val != long_val) || (long_val < 0))) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to unsigned char");
+ return (unsigned char)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
+static INLINE unsigned short __pyx_PyInt_unsigned_short(PyObject* x) {
+ if (sizeof(unsigned short) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ unsigned short val = (unsigned short)long_val;
+ if (unlikely((val != long_val) || (long_val < 0))) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to unsigned short");
+ return (unsigned short)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
+static INLINE char __pyx_PyInt_char(PyObject* x) {
+ if (sizeof(char) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ char val = (char)long_val;
+ if (unlikely((val != long_val) )) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to char");
+ return (char)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
+static INLINE short __pyx_PyInt_short(PyObject* x) {
+ if (sizeof(short) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ short val = (short)long_val;
+ if (unlikely((val != long_val) )) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to short");
+ return (short)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
+static INLINE int __pyx_PyInt_int(PyObject* x) {
+ if (sizeof(int) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ int val = (int)long_val;
+ if (unlikely((val != long_val) )) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to int");
+ return (int)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
+static INLINE long __pyx_PyInt_long(PyObject* x) {
+ if (sizeof(long) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ long val = (long)long_val;
+ if (unlikely((val != long_val) )) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to long");
+ return (long)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
+static INLINE signed char __pyx_PyInt_signed_char(PyObject* x) {
+ if (sizeof(signed char) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ signed char val = (signed char)long_val;
+ if (unlikely((val != long_val) )) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed char");
+ return (signed char)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
+static INLINE signed short __pyx_PyInt_signed_short(PyObject* x) {
+ if (sizeof(signed short) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ signed short val = (signed short)long_val;
+ if (unlikely((val != long_val) )) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed short");
+ return (signed short)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
+static INLINE signed int __pyx_PyInt_signed_int(PyObject* x) {
+ if (sizeof(signed int) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ signed int val = (signed int)long_val;
+ if (unlikely((val != long_val) )) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed int");
+ return (signed int)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
+static INLINE signed long __pyx_PyInt_signed_long(PyObject* x) {
+ if (sizeof(signed long) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ signed long val = (signed long)long_val;
+ if (unlikely((val != long_val) )) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed long");
+ return (signed long)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
+static INLINE long double __pyx_PyInt_long_double(PyObject* x) {
+ if (sizeof(long double) < sizeof(long)) {
+ long long_val = __pyx_PyInt_AsLong(x);
+ long double val = (long double)long_val;
+ if (unlikely((val != long_val) )) {
+ PyErr_SetString(PyExc_OverflowError, "value too large to convert to long double");
+ return (long double)-1;
+ }
+ return val;
+ }
+ else {
+ return __pyx_PyInt_AsLong(x);
+ }
+}
+
diff --git a/sphinx/pycode/pgen2/parse.py b/sphinx/pycode/pgen2/parse.py
new file mode 100644
index 00000000..60eec05e
--- /dev/null
+++ b/sphinx/pycode/pgen2/parse.py
@@ -0,0 +1,201 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Parser engine for the grammar tables generated by pgen.
+
+The grammar table must be loaded first.
+
+See Parser/parser.c in the Python distribution for additional info on
+how this parsing engine works.
+
+"""
+
+# Local imports
+from sphinx.pycode.pgen2 import token
+
+class ParseError(Exception):
+ """Exception to signal the parser is stuck."""
+
+ def __init__(self, msg, type, value, context):
+ Exception.__init__(self, "%s: type=%r, value=%r, context=%r" %
+ (msg, type, value, context))
+ self.msg = msg
+ self.type = type
+ self.value = value
+ self.context = context
+
+class Parser(object):
+ """Parser engine.
+
+ The proper usage sequence is:
+
+ p = Parser(grammar, [converter]) # create instance
+ p.setup([start]) # prepare for parsing
+ <for each input token>:
+ if p.addtoken(...): # parse a token; may raise ParseError
+ break
+ root = p.rootnode # root of abstract syntax tree
+
+ A Parser instance may be reused by calling setup() repeatedly.
+
+ A Parser instance contains state pertaining to the current token
+ sequence, and should not be used concurrently by different threads
+ to parse separate token sequences.
+
+ See driver.py for how to get input tokens by tokenizing a file or
+ string.
+
+ Parsing is complete when addtoken() returns True; the root of the
+ abstract syntax tree can then be retrieved from the rootnode
+ instance variable. When a syntax error occurs, addtoken() raises
+ the ParseError exception. There is no error recovery; the parser
+ cannot be used after a syntax error was reported (but it can be
+ reinitialized by calling setup()).
+
+ """
+
+ def __init__(self, grammar, convert=None):
+ """Constructor.
+
+ The grammar argument is a grammar.Grammar instance; see the
+ grammar module for more information.
+
+ The parser is not ready yet for parsing; you must call the
+ setup() method to get it started.
+
+ The optional convert argument is a function mapping concrete
+ syntax tree nodes to abstract syntax tree nodes. If not
+ given, no conversion is done and the syntax tree produced is
+ the concrete syntax tree. If given, it must be a function of
+ two arguments, the first being the grammar (a grammar.Grammar
+ instance), and the second being the concrete syntax tree node
+ to be converted. The syntax tree is converted from the bottom
+ up.
+
+ A concrete syntax tree node is a (type, value, context, nodes)
+ tuple, where type is the node type (a token or symbol number),
+ value is None for symbols and a string for tokens, context is
+ None or an opaque value used for error reporting (typically a
+ (lineno, offset) pair), and nodes is a list of children for
+ symbols, and None for tokens.
+
+ An abstract syntax tree node may be anything; this is entirely
+ up to the converter function.
+
+ """
+ self.grammar = grammar
+ self.convert = convert or (lambda grammar, node: node)
+
+ def setup(self, start=None):
+ """Prepare for parsing.
+
+ This *must* be called before starting to parse.
+
+ The optional argument is an alternative start symbol; it
+ defaults to the grammar's start symbol.
+
+ You can use a Parser instance to parse any number of programs;
+ each time you call setup() the parser is reset to an initial
+ state determined by the (implicit or explicit) start symbol.
+
+ """
+ if start is None:
+ start = self.grammar.start
+ # Each stack entry is a tuple: (dfa, state, node).
+ # A node is a tuple: (type, value, context, children),
+ # where children is a list of nodes or None, and context may be None.
+ newnode = (start, None, None, [])
+ stackentry = (self.grammar.dfas[start], 0, newnode)
+ self.stack = [stackentry]
+ self.rootnode = None
+ self.used_names = set() # Aliased to self.rootnode.used_names in pop()
+
+ def addtoken(self, type, value, context):
+ """Add a token; return True iff this is the end of the program."""
+ # Map from token to label
+ ilabel = self.classify(type, value, context)
+ # Loop until the token is shifted; may raise exceptions
+ while True:
+ dfa, state, node = self.stack[-1]
+ states, first = dfa
+ arcs = states[state]
+ # Look for a state with this label
+ for i, newstate in arcs:
+ t, v = self.grammar.labels[i]
+ if ilabel == i:
+ # Look it up in the list of labels
+ assert t < 256
+ # Shift a token; we're done with it
+ self.shift(type, value, newstate, context)
+ # Pop while we are in an accept-only state
+ state = newstate
+ while states[state] == [(0, state)]:
+ self.pop()
+ if not self.stack:
+ # Done parsing!
+ return True
+ dfa, state, node = self.stack[-1]
+ states, first = dfa
+ # Done with this token
+ return False
+ elif t >= 256:
+ # See if it's a symbol and if we're in its first set
+ itsdfa = self.grammar.dfas[t]
+ itsstates, itsfirst = itsdfa
+ if ilabel in itsfirst:
+ # Push a symbol
+ self.push(t, self.grammar.dfas[t], newstate, context)
+ break # To continue the outer while loop
+ else:
+ if (0, state) in arcs:
+ # An accepting state, pop it and try something else
+ self.pop()
+ if not self.stack:
+ # Done parsing, but another token is input
+ raise ParseError("too much input",
+ type, value, context)
+ else:
+ # No success finding a transition
+ raise ParseError("bad input", type, value, context)
+
+ def classify(self, type, value, context):
+ """Turn a token into a label. (Internal)"""
+ if type == token.NAME:
+ # Keep a listing of all used names
+ self.used_names.add(value)
+ # Check for reserved words
+ ilabel = self.grammar.keywords.get(value)
+ if ilabel is not None:
+ return ilabel
+ ilabel = self.grammar.tokens.get(type)
+ if ilabel is None:
+ raise ParseError("bad token", type, value, context)
+ return ilabel
+
+ def shift(self, type, value, newstate, context):
+ """Shift a token. (Internal)"""
+ dfa, state, node = self.stack[-1]
+ newnode = (type, value, context, None)
+ newnode = self.convert(self.grammar, newnode)
+ if newnode is not None:
+ node[-1].append(newnode)
+ self.stack[-1] = (dfa, newstate, node)
+
+ def push(self, type, newdfa, newstate, context):
+ """Push a nonterminal. (Internal)"""
+ dfa, state, node = self.stack[-1]
+ newnode = (type, None, context, [])
+ self.stack[-1] = (dfa, newstate, node)
+ self.stack.append((newdfa, 0, newnode))
+
+ def pop(self):
+ """Pop a nonterminal. (Internal)"""
+ popdfa, popstate, popnode = self.stack.pop()
+ newnode = self.convert(self.grammar, popnode)
+ if newnode is not None:
+ if self.stack:
+ dfa, state, node = self.stack[-1]
+ node[-1].append(newnode)
+ else:
+ self.rootnode = newnode
+ self.rootnode.used_names = self.used_names
diff --git a/sphinx/pycode/pgen2/parse.pyx b/sphinx/pycode/pgen2/parse.pyx
new file mode 100644
index 00000000..537d7393
--- /dev/null
+++ b/sphinx/pycode/pgen2/parse.pyx
@@ -0,0 +1,158 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+# Adapted from parse.py to be compiled with Cython by Georg Brandl.
+
+"""Parser engine for the grammar tables generated by pgen.
+
+The grammar table must be loaded first.
+
+See Parser/parser.c in the Python distribution for additional info on
+how this parsing engine works.
+
+"""
+
+from sphinx.pycode.nodes import Node, Leaf
+
+DEF NAME = 1
+
+class ParseError(Exception):
+ """Exception to signal the parser is stuck."""
+
+ def __init__(self, msg, type, value, context):
+ Exception.__init__(self, "%s: type=%r, value=%r, context=%r" %
+ (msg, type, value, context))
+ self.msg = msg
+ self.type = type
+ self.value = value
+ self.context = context
+
+
+cdef class Parser:
+ cdef public grammar, stack, rootnode, used_names
+ cdef _grammar_dfas, _grammar_labels, _grammar_keywords, _grammar_tokens
+ cdef _grammar_number2symbol
+
+ def __init__(self, grammar, convert=None):
+ self.grammar = grammar
+ #self.convert = convert or noconvert
+
+ self._grammar_dfas = grammar.dfas
+ self._grammar_labels = grammar.labels
+ self._grammar_keywords = grammar.keywords
+ self._grammar_tokens = grammar.tokens
+ self._grammar_number2symbol = grammar.number2symbol
+
+ def setup(self, start=None):
+ if start is None:
+ start = self.grammar.start
+ # Each stack entry is a tuple: (dfa, state, node).
+ # A node is a tuple: (type, value, context, children),
+ # where children is a list of nodes or None, and context may be None.
+ newnode = (start, None, None, [])
+ stackentry = (self._grammar_dfas[start], 0, newnode)
+ self.stack = [stackentry]
+ self.rootnode = None
+ self.used_names = set() # Aliased to self.rootnode.used_names in pop()
+
+ def addtoken(self, type, value, context):
+ """Add a token; return True iff this is the end of the program."""
+ cdef int ilabel, i, t, state, newstate
+ # Map from token to label
+ ilabel = self.classify(type, value, context)
+ # Loop until the token is shifted; may raise exceptions
+ while True:
+ dfa, state, node = self.stack[-1]
+ states, first = dfa
+ arcs = states[state]
+ # Look for a state with this label
+ for i, newstate in arcs:
+ t, v = self._grammar_labels[i]
+ if ilabel == i:
+ # Look it up in the list of labels
+ ## assert t < 256
+ # Shift a token; we're done with it
+ self.shift(type, value, newstate, context)
+ # Pop while we are in an accept-only state
+ state = newstate
+ while states[state] == [(0, state)]:
+ self.pop()
+ if not self.stack:
+ # Done parsing!
+ return True
+ dfa, state, node = self.stack[-1]
+ states, first = dfa
+ # Done with this token
+ return False
+ elif t >= 256:
+ # See if it's a symbol and if we're in its first set
+ itsdfa = self._grammar_dfas[t]
+ itsstates, itsfirst = itsdfa
+ if ilabel in itsfirst:
+ # Push a symbol
+ self.push(t, itsdfa, newstate, context)
+ break # To continue the outer while loop
+ else:
+ if (0, state) in arcs:
+ # An accepting state, pop it and try something else
+ self.pop()
+ if not self.stack:
+ # Done parsing, but another token is input
+ raise ParseError("too much input",
+ type, value, context)
+ else:
+ # No success finding a transition
+ raise ParseError("bad input", type, value, context)
+
+ cdef int classify(self, type, value, context):
+ """Turn a token into a label. (Internal)"""
+ if type == NAME:
+ # Keep a listing of all used names
+ self.used_names.add(value)
+ # Check for reserved words
+ ilabel = self._grammar_keywords.get(value)
+ if ilabel is not None:
+ return ilabel
+ ilabel = self._grammar_tokens.get(type)
+ if ilabel is None:
+ raise ParseError("bad token", type, value, context)
+ return ilabel
+
+ cdef void shift(self, type, value, newstate, context):
+ """Shift a token. (Internal)"""
+ dfa, state, node = self.stack[-1]
+ newnode = (type, value, context, None)
+ newnode = self.convert(newnode)
+ if newnode is not None:
+ node[-1].append(newnode)
+ self.stack[-1] = (dfa, newstate, node)
+
+ cdef void push(self, type, newdfa, newstate, context):
+ """Push a nonterminal. (Internal)"""
+ dfa, state, node = self.stack[-1]
+ newnode = (type, None, context, [])
+ self.stack[-1] = (dfa, newstate, node)
+ self.stack.append((newdfa, 0, newnode))
+
+ cdef void pop(self):
+ """Pop a nonterminal. (Internal)"""
+ popdfa, popstate, popnode = self.stack.pop()
+ newnode = self.convert(popnode)
+ if newnode is not None:
+ if self.stack:
+ dfa, state, node = self.stack[-1]
+ node[-1].append(newnode)
+ else:
+ self.rootnode = newnode
+ self.rootnode.used_names = self.used_names
+
+ cdef convert(self, raw_node):
+ type, value, context, children = raw_node
+ if children or type in self._grammar_number2symbol:
+ # If there's exactly one child, return that child instead of
+ # creating a new node.
+ if len(children) == 1:
+ return children[0]
+ return Node(type, children, context=context)
+ else:
+ return Leaf(type, value, context=context)
diff --git a/sphinx/pycode/pgen2/pgen.py b/sphinx/pycode/pgen2/pgen.py
new file mode 100644
index 00000000..d6895eae
--- /dev/null
+++ b/sphinx/pycode/pgen2/pgen.py
@@ -0,0 +1,384 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+# Pgen imports
+from sphinx.pycode.pgen2 import grammar, token, tokenize
+
+class PgenGrammar(grammar.Grammar):
+ pass
+
+class ParserGenerator(object):
+
+ def __init__(self, filename, stream=None):
+ close_stream = None
+ if stream is None:
+ stream = open(filename)
+ close_stream = stream.close
+ self.filename = filename
+ self.stream = stream
+ self.generator = tokenize.generate_tokens(stream.readline)
+ self.gettoken() # Initialize lookahead
+ self.dfas, self.startsymbol = self.parse()
+ if close_stream is not None:
+ close_stream()
+ self.first = {} # map from symbol name to set of tokens
+ self.addfirstsets()
+
+ def make_grammar(self):
+ c = PgenGrammar()
+ names = self.dfas.keys()
+ names.sort()
+ names.remove(self.startsymbol)
+ names.insert(0, self.startsymbol)
+ for name in names:
+ i = 256 + len(c.symbol2number)
+ c.symbol2number[name] = i
+ c.number2symbol[i] = name
+ for name in names:
+ dfa = self.dfas[name]
+ states = []
+ for state in dfa:
+ arcs = []
+ for label, next in state.arcs.iteritems():
+ arcs.append((self.make_label(c, label), dfa.index(next)))
+ if state.isfinal:
+ arcs.append((0, dfa.index(state)))
+ states.append(arcs)
+ c.states.append(states)
+ c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name))
+ c.start = c.symbol2number[self.startsymbol]
+ return c
+
+ def make_first(self, c, name):
+ rawfirst = self.first[name]
+ first = {}
+ for label in rawfirst:
+ ilabel = self.make_label(c, label)
+ ##assert ilabel not in first # XXX failed on <> ... !=
+ first[ilabel] = 1
+ return first
+
+ def make_label(self, c, label):
+ # XXX Maybe this should be a method on a subclass of converter?
+ ilabel = len(c.labels)
+ if label[0].isalpha():
+ # Either a symbol name or a named token
+ if label in c.symbol2number:
+ # A symbol name (a non-terminal)
+ if label in c.symbol2label:
+ return c.symbol2label[label]
+ else:
+ c.labels.append((c.symbol2number[label], None))
+ c.symbol2label[label] = ilabel
+ return ilabel
+ else:
+ # A named token (NAME, NUMBER, STRING)
+ itoken = getattr(token, label, None)
+ assert isinstance(itoken, int), label
+ assert itoken in token.tok_name, label
+ if itoken in c.tokens:
+ return c.tokens[itoken]
+ else:
+ c.labels.append((itoken, None))
+ c.tokens[itoken] = ilabel
+ return ilabel
+ else:
+ # Either a keyword or an operator
+ assert label[0] in ('"', "'"), label
+ value = eval(label)
+ if value[0].isalpha():
+ # A keyword
+ if value in c.keywords:
+ return c.keywords[value]
+ else:
+ c.labels.append((token.NAME, value))
+ c.keywords[value] = ilabel
+ return ilabel
+ else:
+ # An operator (any non-numeric token)
+ itoken = grammar.opmap[value] # Fails if unknown token
+ if itoken in c.tokens:
+ return c.tokens[itoken]
+ else:
+ c.labels.append((itoken, None))
+ c.tokens[itoken] = ilabel
+ return ilabel
+
+ def addfirstsets(self):
+ names = self.dfas.keys()
+ names.sort()
+ for name in names:
+ if name not in self.first:
+ self.calcfirst(name)
+ #print name, self.first[name].keys()
+
+ def calcfirst(self, name):
+ dfa = self.dfas[name]
+ self.first[name] = None # dummy to detect left recursion
+ state = dfa[0]
+ totalset = {}
+ overlapcheck = {}
+ for label, next in state.arcs.iteritems():
+ if label in self.dfas:
+ if label in self.first:
+ fset = self.first[label]
+ if fset is None:
+ raise ValueError("recursion for rule %r" % name)
+ else:
+ self.calcfirst(label)
+ fset = self.first[label]
+ totalset.update(fset)
+ overlapcheck[label] = fset
+ else:
+ totalset[label] = 1
+ overlapcheck[label] = {label: 1}
+ inverse = {}
+ for label, itsfirst in overlapcheck.iteritems():
+ for symbol in itsfirst:
+ if symbol in inverse:
+ raise ValueError("rule %s is ambiguous; %s is in the"
+ " first sets of %s as well as %s" %
+ (name, symbol, label, inverse[symbol]))
+ inverse[symbol] = label
+ self.first[name] = totalset
+
+ def parse(self):
+ dfas = {}
+ startsymbol = None
+ # MSTART: (NEWLINE | RULE)* ENDMARKER
+ while self.type != token.ENDMARKER:
+ while self.type == token.NEWLINE:
+ self.gettoken()
+ # RULE: NAME ':' RHS NEWLINE
+ name = self.expect(token.NAME)
+ self.expect(token.OP, ":")
+ a, z = self.parse_rhs()
+ self.expect(token.NEWLINE)
+ #self.dump_nfa(name, a, z)
+ dfa = self.make_dfa(a, z)
+ #self.dump_dfa(name, dfa)
+ oldlen = len(dfa)
+ self.simplify_dfa(dfa)
+ newlen = len(dfa)
+ dfas[name] = dfa
+ #print name, oldlen, newlen
+ if startsymbol is None:
+ startsymbol = name
+ return dfas, startsymbol
+
+ def make_dfa(self, start, finish):
+ # To turn an NFA into a DFA, we define the states of the DFA
+ # to correspond to *sets* of states of the NFA. Then do some
+ # state reduction. Let's represent sets as dicts with 1 for
+ # values.
+ assert isinstance(start, NFAState)
+ assert isinstance(finish, NFAState)
+ def closure(state):
+ base = {}
+ addclosure(state, base)
+ return base
+ def addclosure(state, base):
+ assert isinstance(state, NFAState)
+ if state in base:
+ return
+ base[state] = 1
+ for label, next in state.arcs:
+ if label is None:
+ addclosure(next, base)
+ states = [DFAState(closure(start), finish)]
+ for state in states: # NB states grows while we're iterating
+ arcs = {}
+ for nfastate in state.nfaset:
+ for label, next in nfastate.arcs:
+ if label is not None:
+ addclosure(next, arcs.setdefault(label, {}))
+ for label, nfaset in arcs.iteritems():
+ for st in states:
+ if st.nfaset == nfaset:
+ break
+ else:
+ st = DFAState(nfaset, finish)
+ states.append(st)
+ state.addarc(st, label)
+ return states # List of DFAState instances; first one is start
+
+ def dump_nfa(self, name, start, finish):
+ print "Dump of NFA for", name
+ todo = [start]
+ for i, state in enumerate(todo):
+ print " State", i, state is finish and "(final)" or ""
+ for label, next in state.arcs:
+ if next in todo:
+ j = todo.index(next)
+ else:
+ j = len(todo)
+ todo.append(next)
+ if label is None:
+ print " -> %d" % j
+ else:
+ print " %s -> %d" % (label, j)
+
+ def dump_dfa(self, name, dfa):
+ print "Dump of DFA for", name
+ for i, state in enumerate(dfa):
+ print " State", i, state.isfinal and "(final)" or ""
+ for label, next in state.arcs.iteritems():
+ print " %s -> %d" % (label, dfa.index(next))
+
+ def simplify_dfa(self, dfa):
+ # This is not theoretically optimal, but works well enough.
+ # Algorithm: repeatedly look for two states that have the same
+ # set of arcs (same labels pointing to the same nodes) and
+ # unify them, until things stop changing.
+
+ # dfa is a list of DFAState instances
+ changes = True
+ while changes:
+ changes = False
+ for i, state_i in enumerate(dfa):
+ for j in range(i+1, len(dfa)):
+ state_j = dfa[j]
+ if state_i == state_j:
+ #print " unify", i, j
+ del dfa[j]
+ for state in dfa:
+ state.unifystate(state_j, state_i)
+ changes = True
+ break
+
+ def parse_rhs(self):
+ # RHS: ALT ('|' ALT)*
+ a, z = self.parse_alt()
+ if self.value != "|":
+ return a, z
+ else:
+ aa = NFAState()
+ zz = NFAState()
+ aa.addarc(a)
+ z.addarc(zz)
+ while self.value == "|":
+ self.gettoken()
+ a, z = self.parse_alt()
+ aa.addarc(a)
+ z.addarc(zz)
+ return aa, zz
+
+ def parse_alt(self):
+ # ALT: ITEM+
+ a, b = self.parse_item()
+ while (self.value in ("(", "[") or
+ self.type in (token.NAME, token.STRING)):
+ c, d = self.parse_item()
+ b.addarc(c)
+ b = d
+ return a, b
+
+ def parse_item(self):
+ # ITEM: '[' RHS ']' | ATOM ['+' | '*']
+ if self.value == "[":
+ self.gettoken()
+ a, z = self.parse_rhs()
+ self.expect(token.OP, "]")
+ a.addarc(z)
+ return a, z
+ else:
+ a, z = self.parse_atom()
+ value = self.value
+ if value not in ("+", "*"):
+ return a, z
+ self.gettoken()
+ z.addarc(a)
+ if value == "+":
+ return a, z
+ else:
+ return a, a
+
+ def parse_atom(self):
+ # ATOM: '(' RHS ')' | NAME | STRING
+ if self.value == "(":
+ self.gettoken()
+ a, z = self.parse_rhs()
+ self.expect(token.OP, ")")
+ return a, z
+ elif self.type in (token.NAME, token.STRING):
+ a = NFAState()
+ z = NFAState()
+ a.addarc(z, self.value)
+ self.gettoken()
+ return a, z
+ else:
+ self.raise_error("expected (...) or NAME or STRING, got %s/%s",
+ self.type, self.value)
+
+ def expect(self, type, value=None):
+ if self.type != type or (value is not None and self.value != value):
+ self.raise_error("expected %s/%s, got %s/%s",
+ type, value, self.type, self.value)
+ value = self.value
+ self.gettoken()
+ return value
+
+ def gettoken(self):
+ tup = self.generator.next()
+ while tup[0] in (tokenize.COMMENT, tokenize.NL):
+ tup = self.generator.next()
+ self.type, self.value, self.begin, self.end, self.line = tup
+ #print token.tok_name[self.type], repr(self.value)
+
+ def raise_error(self, msg, *args):
+ if args:
+ try:
+ msg = msg % args
+ except:
+ msg = " ".join([msg] + map(str, args))
+ raise SyntaxError(msg, (self.filename, self.end[0],
+ self.end[1], self.line))
+
+class NFAState(object):
+
+ def __init__(self):
+ self.arcs = [] # list of (label, NFAState) pairs
+
+ def addarc(self, next, label=None):
+ assert label is None or isinstance(label, str)
+ assert isinstance(next, NFAState)
+ self.arcs.append((label, next))
+
+class DFAState(object):
+
+ def __init__(self, nfaset, final):
+ assert isinstance(nfaset, dict)
+ assert isinstance(iter(nfaset).next(), NFAState)
+ assert isinstance(final, NFAState)
+ self.nfaset = nfaset
+ self.isfinal = final in nfaset
+ self.arcs = {} # map from label to DFAState
+
+ def addarc(self, next, label):
+ assert isinstance(label, str)
+ assert label not in self.arcs
+ assert isinstance(next, DFAState)
+ self.arcs[label] = next
+
+ def unifystate(self, old, new):
+ for label, next in self.arcs.iteritems():
+ if next is old:
+ self.arcs[label] = new
+
+ def __eq__(self, other):
+ # Equality test -- ignore the nfaset instance variable
+ assert isinstance(other, DFAState)
+ if self.isfinal != other.isfinal:
+ return False
+ # Can't just return self.arcs == other.arcs, because that
+ # would invoke this method recursively, with cycles...
+ if len(self.arcs) != len(other.arcs):
+ return False
+ for label, next in self.arcs.iteritems():
+ if next is not other.arcs.get(label):
+ return False
+ return True
+
+def generate_grammar(filename="Grammar.txt"):
+ p = ParserGenerator(filename)
+ return p.make_grammar()
diff --git a/sphinx/pycode/pgen2/token.py b/sphinx/pycode/pgen2/token.py
new file mode 100755
index 00000000..61468b31
--- /dev/null
+++ b/sphinx/pycode/pgen2/token.py
@@ -0,0 +1,82 @@
+#! /usr/bin/env python
+
+"""Token constants (from "token.h")."""
+
+# Taken from Python (r53757) and modified to include some tokens
+# originally monkeypatched in by pgen2.tokenize
+
+#--start constants--
+ENDMARKER = 0
+NAME = 1
+NUMBER = 2
+STRING = 3
+NEWLINE = 4
+INDENT = 5
+DEDENT = 6
+LPAR = 7
+RPAR = 8
+LSQB = 9
+RSQB = 10
+COLON = 11
+COMMA = 12
+SEMI = 13
+PLUS = 14
+MINUS = 15
+STAR = 16
+SLASH = 17
+VBAR = 18
+AMPER = 19
+LESS = 20
+GREATER = 21
+EQUAL = 22
+DOT = 23
+PERCENT = 24
+BACKQUOTE = 25
+LBRACE = 26
+RBRACE = 27
+EQEQUAL = 28
+NOTEQUAL = 29
+LESSEQUAL = 30
+GREATEREQUAL = 31
+TILDE = 32
+CIRCUMFLEX = 33
+LEFTSHIFT = 34
+RIGHTSHIFT = 35
+DOUBLESTAR = 36
+PLUSEQUAL = 37
+MINEQUAL = 38
+STAREQUAL = 39
+SLASHEQUAL = 40
+PERCENTEQUAL = 41
+AMPEREQUAL = 42
+VBAREQUAL = 43
+CIRCUMFLEXEQUAL = 44
+LEFTSHIFTEQUAL = 45
+RIGHTSHIFTEQUAL = 46
+DOUBLESTAREQUAL = 47
+DOUBLESLASH = 48
+DOUBLESLASHEQUAL = 49
+AT = 50
+OP = 51
+COMMENT = 52
+NL = 53
+RARROW = 54
+ERRORTOKEN = 55
+N_TOKENS = 56
+NT_OFFSET = 256
+#--end constants--
+
+tok_name = {}
+for _name, _value in globals().items():
+ if type(_value) is type(0):
+ tok_name[_value] = _name
+
+
+def ISTERMINAL(x):
+ return x < NT_OFFSET
+
+def ISNONTERMINAL(x):
+ return x >= NT_OFFSET
+
+def ISEOF(x):
+ return x == ENDMARKER
diff --git a/sphinx/pycode/pgen2/tokenize.py b/sphinx/pycode/pgen2/tokenize.py
new file mode 100644
index 00000000..4489db89
--- /dev/null
+++ b/sphinx/pycode/pgen2/tokenize.py
@@ -0,0 +1,410 @@
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation.
+# All rights reserved.
+
+"""Tokenization help for Python programs.
+
+generate_tokens(readline) is a generator that breaks a stream of
+text into Python tokens. It accepts a readline-like method which is called
+repeatedly to get the next line of input (or "" for EOF). It generates
+5-tuples with these members:
+
+ the token type (see token.py)
+ the token (a string)
+ the starting (row, column) indices of the token (a 2-tuple of ints)
+ the ending (row, column) indices of the token (a 2-tuple of ints)
+ the original line (string)
+
+It is designed to match the working of the Python tokenizer exactly, except
+that it produces COMMENT tokens for comments and gives type OP for all
+operators
+
+Older entry points
+ tokenize_loop(readline, tokeneater)
+ tokenize(readline, tokeneater=printtoken)
+are the same, except instead of generating tokens, tokeneater is a callback
+function to which the 5 fields described above are passed as 5 arguments,
+each time a new token is found."""
+
+__author__ = 'Ka-Ping Yee <ping@lfw.org>'
+__credits__ = \
+ 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro'
+
+import string, re
+from sphinx.pycode.pgen2.token import *
+from sphinx.pycode.pgen2 import token
+
+__all__ = [x for x in dir(token) if x[0] != '_'] + ["tokenize",
+ "generate_tokens", "untokenize"]
+del token
+
+def group(*choices): return '(' + '|'.join(choices) + ')'
+def any(*choices): return group(*choices) + '*'
+def maybe(*choices): return group(*choices) + '?'
+
+Whitespace = r'[ \f\t]*'
+Comment = r'#[^\r\n]*'
+Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment)
+Name = r'[a-zA-Z_]\w*'
+
+Binnumber = r'0[bB][01]*'
+Hexnumber = r'0[xX][\da-fA-F]*[lL]?'
+Octnumber = r'0[oO]?[0-7]*[lL]?'
+Decnumber = r'[1-9]\d*[lL]?'
+Intnumber = group(Binnumber, Hexnumber, Octnumber, Decnumber)
+Exponent = r'[eE][-+]?\d+'
+Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent)
+Expfloat = r'\d+' + Exponent
+Floatnumber = group(Pointfloat, Expfloat)
+Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]')
+Number = group(Imagnumber, Floatnumber, Intnumber)
+
+# Tail end of ' string.
+Single = r"[^'\\]*(?:\\.[^'\\]*)*'"
+# Tail end of " string.
+Double = r'[^"\\]*(?:\\.[^"\\]*)*"'
+# Tail end of ''' string.
+Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''"
+# Tail end of """ string.
+Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""'
+Triple = group("[ubUB]?[rR]?'''", '[ubUB]?[rR]?"""')
+# Single-line ' or " string.
+String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'",
+ r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"')
+
+# Because of leftmost-then-longest match semantics, be sure to put the
+# longest operators first (e.g., if = came before ==, == would get
+# recognized as two instances of =).
+Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=",
+ r"//=?", r"->",
+ r"[+\-*/%&|^=<>]=?",
+ r"~")
+
+Bracket = '[][(){}]'
+Special = group(r'\r?\n', r'[:;.,`@]')
+Funny = group(Operator, Bracket, Special)
+
+PlainToken = group(Number, Funny, String, Name)
+Token = Ignore + PlainToken
+
+# First (or only) line of ' or " string.
+ContStr = group(r"[uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" +
+ group("'", r'\\\r?\n'),
+ r'[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' +
+ group('"', r'\\\r?\n'))
+PseudoExtras = group(r'\\\r?\n', Comment, Triple)
+PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name)
+
+tokenprog, pseudoprog, single3prog, double3prog = map(
+ re.compile, (Token, PseudoToken, Single3, Double3))
+endprogs = {"'": re.compile(Single), '"': re.compile(Double),
+ "'''": single3prog, '"""': double3prog,
+ "r'''": single3prog, 'r"""': double3prog,
+ "u'''": single3prog, 'u"""': double3prog,
+ "b'''": single3prog, 'b"""': double3prog,
+ "ur'''": single3prog, 'ur"""': double3prog,
+ "br'''": single3prog, 'br"""': double3prog,
+ "R'''": single3prog, 'R"""': double3prog,
+ "U'''": single3prog, 'U"""': double3prog,
+ "B'''": single3prog, 'B"""': double3prog,
+ "uR'''": single3prog, 'uR"""': double3prog,
+ "Ur'''": single3prog, 'Ur"""': double3prog,
+ "UR'''": single3prog, 'UR"""': double3prog,
+ "bR'''": single3prog, 'bR"""': double3prog,
+ "Br'''": single3prog, 'Br"""': double3prog,
+ "BR'''": single3prog, 'BR"""': double3prog,
+ 'r': None, 'R': None,
+ 'u': None, 'U': None,
+ 'b': None, 'B': None}
+
+triple_quoted = {}
+for t in ("'''", '"""',
+ "r'''", 'r"""', "R'''", 'R"""',
+ "u'''", 'u"""', "U'''", 'U"""',
+ "b'''", 'b"""', "B'''", 'B"""',
+ "ur'''", 'ur"""', "Ur'''", 'Ur"""',
+ "uR'''", 'uR"""', "UR'''", 'UR"""',
+ "br'''", 'br"""', "Br'''", 'Br"""',
+ "bR'''", 'bR"""', "BR'''", 'BR"""',):
+ triple_quoted[t] = t
+single_quoted = {}
+for t in ("'", '"',
+ "r'", 'r"', "R'", 'R"',
+ "u'", 'u"', "U'", 'U"',
+ "b'", 'b"', "B'", 'B"',
+ "ur'", 'ur"', "Ur'", 'Ur"',
+ "uR'", 'uR"', "UR'", 'UR"',
+ "br'", 'br"', "Br'", 'Br"',
+ "bR'", 'bR"', "BR'", 'BR"', ):
+ single_quoted[t] = t
+
+tabsize = 8
+
+class TokenError(Exception): pass
+
+class StopTokenizing(Exception): pass
+
+def printtoken(type, token, (srow, scol), (erow, ecol), line): # for testing
+ print "%d,%d-%d,%d:\t%s\t%s" % \
+ (srow, scol, erow, ecol, tok_name[type], repr(token))
+
+def tokenize(readline, tokeneater=printtoken):
+ """
+ The tokenize() function accepts two parameters: one representing the
+ input stream, and one providing an output mechanism for tokenize().
+
+ The first parameter, readline, must be a callable object which provides
+ the same interface as the readline() method of built-in file objects.
+ Each call to the function should return one line of input as a string.
+
+ The second parameter, tokeneater, must also be a callable object. It is
+ called once for each token, with five arguments, corresponding to the
+ tuples generated by generate_tokens().
+ """
+ try:
+ tokenize_loop(readline, tokeneater)
+ except StopTokenizing:
+ pass
+
+# backwards compatible interface
+def tokenize_loop(readline, tokeneater):
+ for token_info in generate_tokens(readline):
+ tokeneater(*token_info)
+
+class Untokenizer:
+
+ def __init__(self):
+ self.tokens = []
+ self.prev_row = 1
+ self.prev_col = 0
+
+ def add_whitespace(self, start):
+ row, col = start
+ assert row <= self.prev_row
+ col_offset = col - self.prev_col
+ if col_offset:
+ self.tokens.append(" " * col_offset)
+
+ def untokenize(self, iterable):
+ for t in iterable:
+ if len(t) == 2:
+ self.compat(t, iterable)
+ break
+ tok_type, token, start, end, line = t
+ self.add_whitespace(start)
+ self.tokens.append(token)
+ self.prev_row, self.prev_col = end
+ if tok_type in (NEWLINE, NL):
+ self.prev_row += 1
+ self.prev_col = 0
+ return "".join(self.tokens)
+
+ def compat(self, token, iterable):
+ startline = False
+ indents = []
+ toks_append = self.tokens.append
+ toknum, tokval = token
+ if toknum in (NAME, NUMBER):
+ tokval += ' '
+ if toknum in (NEWLINE, NL):
+ startline = True
+ for tok in iterable:
+ toknum, tokval = tok[:2]
+
+ if toknum in (NAME, NUMBER):
+ tokval += ' '
+
+ if toknum == INDENT:
+ indents.append(tokval)
+ continue
+ elif toknum == DEDENT:
+ indents.pop()
+ continue
+ elif toknum in (NEWLINE, NL):
+ startline = True
+ elif startline and indents:
+ toks_append(indents[-1])
+ startline = False
+ toks_append(tokval)
+
+def untokenize(iterable):
+ """Transform tokens back into Python source code.
+
+ Each element returned by the iterable must be a token sequence
+ with at least two elements, a token number and token value. If
+ only two tokens are passed, the resulting output is poor.
+
+ Round-trip invariant for full input:
+ Untokenized source will match input source exactly
+
+ Round-trip invariant for limited intput:
+ # Output text will tokenize the back to the input
+ t1 = [tok[:2] for tok in generate_tokens(f.readline)]
+ newcode = untokenize(t1)
+ readline = iter(newcode.splitlines(1)).next
+ t2 = [tok[:2] for tokin generate_tokens(readline)]
+ assert t1 == t2
+ """
+ ut = Untokenizer()
+ return ut.untokenize(iterable)
+
+def generate_tokens(readline):
+ """
+ The generate_tokens() generator requires one argment, readline, which
+ must be a callable object which provides the same interface as the
+ readline() method of built-in file objects. Each call to the function
+ should return one line of input as a string. Alternately, readline
+ can be a callable function terminating with StopIteration:
+ readline = open(myfile).next # Example of alternate readline
+
+ The generator produces 5-tuples with these members: the token type; the
+ token string; a 2-tuple (srow, scol) of ints specifying the row and
+ column where the token begins in the source; a 2-tuple (erow, ecol) of
+ ints specifying the row and column where the token ends in the source;
+ and the line on which the token was found. The line passed is the
+ logical line; continuation lines are included.
+ """
+ lnum = parenlev = continued = 0
+ namechars, numchars = string.ascii_letters + '_', '0123456789'
+ contstr, needcont = '', 0
+ contline = None
+ indents = [0]
+
+ while 1: # loop over lines in stream
+ try:
+ line = readline()
+ except StopIteration:
+ line = ''
+ # if we are not at the end of the file make sure the
+ # line ends with a newline because the parser depends
+ # on that.
+ if line:
+ line = line.rstrip() + '\n'
+ lnum = lnum + 1
+ pos, max = 0, len(line)
+
+ if contstr: # continued string
+ if not line:
+ raise TokenError("EOF in multi-line string", strstart)
+ endmatch = endprog.match(line)
+ if endmatch:
+ pos = end = endmatch.end(0)
+ yield (STRING, contstr + line[:end],
+ strstart, (lnum, end), contline + line)
+ contstr, needcont = '', 0
+ contline = None
+ elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n':
+ yield (ERRORTOKEN, contstr + line,
+ strstart, (lnum, len(line)), contline)
+ contstr = ''
+ contline = None
+ continue
+ else:
+ contstr = contstr + line
+ contline = contline + line
+ continue
+
+ elif parenlev == 0 and not continued: # new statement
+ if not line: break
+ column = 0
+ while pos < max: # measure leading whitespace
+ if line[pos] == ' ': column = column + 1
+ elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize
+ elif line[pos] == '\f': column = 0
+ else: break
+ pos = pos + 1
+ if pos == max: break
+
+ if line[pos] in '#\r\n': # skip comments or blank lines
+ if line[pos] == '#':
+ comment_token = line[pos:].rstrip('\r\n')
+ nl_pos = pos + len(comment_token)
+ yield (COMMENT, comment_token,
+ (lnum, pos), (lnum, pos + len(comment_token)), line)
+ yield (NL, line[nl_pos:],
+ (lnum, nl_pos), (lnum, len(line)), line)
+ else:
+ yield ((NL, COMMENT)[line[pos] == '#'], line[pos:],
+ (lnum, pos), (lnum, len(line)), line)
+ continue
+
+ if column > indents[-1]: # count indents or dedents
+ indents.append(column)
+ yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line)
+ while column < indents[-1]:
+ if column not in indents:
+ raise IndentationError(
+ "unindent does not match any outer indentation level",
+ ("<tokenize>", lnum, pos, line))
+ indents = indents[:-1]
+ yield (DEDENT, '', (lnum, pos), (lnum, pos), line)
+
+ else: # continued statement
+ if not line:
+ raise TokenError("EOF in multi-line statement", (lnum, 0))
+ continued = 0
+
+ while pos < max:
+ pseudomatch = pseudoprog.match(line, pos)
+ if pseudomatch: # scan for tokens
+ start, end = pseudomatch.span(1)
+ spos, epos, pos = (lnum, start), (lnum, end), end
+ token, initial = line[start:end], line[start]
+
+ if initial in numchars or \
+ (initial == '.' and token != '.'): # ordinary number
+ yield (NUMBER, token, spos, epos, line)
+ elif initial in '\r\n':
+ newline = NEWLINE
+ if parenlev > 0:
+ newline = NL
+ yield (newline, token, spos, epos, line)
+ elif initial == '#':
+ assert not token.endswith("\n")
+ yield (COMMENT, token, spos, epos, line)
+ elif token in triple_quoted:
+ endprog = endprogs[token]
+ endmatch = endprog.match(line, pos)
+ if endmatch: # all on one line
+ pos = endmatch.end(0)
+ token = line[start:pos]
+ yield (STRING, token, spos, (lnum, pos), line)
+ else:
+ strstart = (lnum, start) # multiple lines
+ contstr = line[start:]
+ contline = line
+ break
+ elif initial in single_quoted or \
+ token[:2] in single_quoted or \
+ token[:3] in single_quoted:
+ if token[-1] == '\n': # continued string
+ strstart = (lnum, start)
+ endprog = (endprogs[initial] or endprogs[token[1]] or
+ endprogs[token[2]])
+ contstr, needcont = line[start:], 1
+ contline = line
+ break
+ else: # ordinary string
+ yield (STRING, token, spos, epos, line)
+ elif initial in namechars: # ordinary name
+ yield (NAME, token, spos, epos, line)
+ elif initial == '\\': # continued stmt
+ # This yield is new; needed for better idempotency:
+ yield (NL, token, spos, (lnum, pos), line)
+ continued = 1
+ else:
+ if initial in '([{': parenlev = parenlev + 1
+ elif initial in ')]}': parenlev = parenlev - 1
+ yield (OP, token, spos, epos, line)
+ else:
+ yield (ERRORTOKEN, line[pos],
+ (lnum, pos), (lnum, pos+1), line)
+ pos = pos + 1
+
+ for indent in indents[1:]: # pop remaining indent levels
+ yield (DEDENT, '', (lnum, 0), (lnum, 0), '')
+ yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '')
+
+if __name__ == '__main__': # testing
+ import sys
+ if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline)
+ else: tokenize(sys.stdin.readline)
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index 4ab26b86..67ab6273 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -16,7 +16,7 @@ TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
from sphinx.util import make_filename
from sphinx.util.console import purple, bold, red, turquoise, nocolor, color_terminal
-from sphinx.util.texescape import tex_escape_map
+from sphinx.util import texescape
PROMPT_PREFIX = '> '
@@ -165,8 +165,8 @@ html_static_path = ['%(dot)sstatic']
# If true, the index is split into individual pages for each letter.
#html_split_index = False
-# If true, the reST sources are included in the HTML build as _sources/<name>.
-#html_copy_source = True
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = 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
@@ -257,7 +257,7 @@ PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d %(rbuilddir)s/doctrees $(PAPEROPT_$(PAPER)) \
$(SPHINXOPTS) %(rsrcdir)s
-.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
+.PHONY: help clean html pickle json htmlhelp qthelp latex changes linkcheck
help:
\t@echo "Please use \\`make <target>' where <target> is one of"
@@ -265,6 +265,7 @@ help:
\t@echo " pickle to make pickle files"
\t@echo " json to make JSON files"
\t@echo " htmlhelp to make HTML files and a HTML help project"
+\t@echo " qthelp to make HTML files and a qthelp project"
\t@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
\t@echo " changes to make an overview over all changed/added/deprecated items"
\t@echo " linkcheck to check all external links for integrity"
@@ -273,34 +274,36 @@ clean:
\t-rm -rf %(rbuilddir)s/*
html:
-\tmkdir -p %(rbuilddir)s/html %(rbuilddir)s/doctrees
\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) %(rbuilddir)s/html
\t@echo
\t@echo "Build finished. The HTML pages are in %(rbuilddir)s/html."
pickle:
-\tmkdir -p %(rbuilddir)s/pickle %(rbuilddir)s/doctrees
\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) %(rbuilddir)s/pickle
\t@echo
\t@echo "Build finished; now you can process the pickle files."
-web: pickle
-
json:
-\tmkdir -p %(rbuilddir)s/json %(rbuilddir)s/doctrees
\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) %(rbuilddir)s/json
\t@echo
\t@echo "Build finished; now you can process the JSON files."
htmlhelp:
-\tmkdir -p %(rbuilddir)s/htmlhelp %(rbuilddir)s/doctrees
\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) %(rbuilddir)s/htmlhelp
\t@echo
\t@echo "Build finished; now you can run HTML Help Workshop with the" \\
\t ".hhp project file in %(rbuilddir)s/htmlhelp."
+qthelp:
+\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) %(rbuilddir)s/qthelp
+\t@echo
+\t@echo "Build finished; now you can run "qcollectiongenerator" with the" \\
+\t ".qhcp project file in %(rbuilddir)s/qthelp, like this:"
+\t@echo "# qcollectiongenerator %(rbuilddir)s/qthelp/%(project)s.qhcp"
+\t@echo "To view the help file:"
+\t@echo "# assistant -collectionFile %(rbuilddir)s/qthelp/%(project)s.qhc"
+
latex:
-\tmkdir -p %(rbuilddir)s/latex %(rbuilddir)s/doctrees
\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) %(rbuilddir)s/latex
\t@echo
\t@echo "Build finished; the LaTeX files are in %(rbuilddir)s/latex."
@@ -308,19 +311,115 @@ latex:
\t "run these through (pdf)latex."
changes:
-\tmkdir -p %(rbuilddir)s/changes %(rbuilddir)s/doctrees
\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) %(rbuilddir)s/changes
\t@echo
\t@echo "The overview file is in %(rbuilddir)s/changes."
linkcheck:
-\tmkdir -p %(rbuilddir)s/linkcheck %(rbuilddir)s/doctrees
\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) %(rbuilddir)s/linkcheck
\t@echo
\t@echo "Link check complete; look for any errors in the above output " \\
\t "or in %(rbuilddir)s/linkcheck/output.txt."
'''
+BATCHFILE = '''\
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+set SPHINXBUILD=sphinx-build
+set ALLSPHINXOPTS=-d %(rbuilddir)s/doctrees %%SPHINXOPTS%% %(rsrcdir)s
+if NOT "%%PAPER%%" == "" (
+\tset ALLSPHINXOPTS=-D latex_paper_size=%%PAPER%% %%ALLSPHINXOPTS%%
+)
+
+if "%%1" == "" goto help
+
+if "%%1" == "help" (
+\t:help
+\techo.Please use `make ^<target^>` where ^<target^> is one of
+\techo. html to make standalone HTML files
+\techo. pickle to make pickle files
+\techo. json to make JSON files
+\techo. htmlhelp to make HTML files and a HTML help project
+\techo. qthelp to make HTML files and a qthelp project
+\techo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+\techo. changes to make an overview over all changed/added/deprecated items
+\techo. linkcheck to check all external links for integrity
+\tgoto end
+)
+
+if "%%1" == "clean" (
+\tfor /d %%%%i in (%(rbuilddir)s\*) do rmdir /q /s %%%%i
+\tdel /q /s %(rbuilddir)s\*
+\tgoto end
+)
+
+if "%%1" == "html" (
+\t%%SPHINXBUILD%% -b html %%ALLSPHINXOPTS%% %(rbuilddir)s/html
+\techo.
+\techo.Build finished. The HTML pages are in %(rbuilddir)s/html.
+\tgoto end
+)
+
+if "%%1" == "pickle" (
+\t%%SPHINXBUILD%% -b pickle %%ALLSPHINXOPTS%% %(rbuilddir)s/pickle
+\techo.
+\techo.Build finished; now you can process the pickle files.
+\tgoto end
+)
+
+if "%%1" == "json" (
+\t%%SPHINXBUILD%% -b json %%ALLSPHINXOPTS%% %(rbuilddir)s/json
+\techo.
+\techo.Build finished; now you can process the JSON files.
+\tgoto end
+)
+
+if "%%1" == "htmlhelp" (
+\t%%SPHINXBUILD%% -b htmlhelp %%ALLSPHINXOPTS%% %(rbuilddir)s/htmlhelp
+\techo.
+\techo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %(rbuilddir)s/htmlhelp.
+\tgoto end
+)
+
+if "%%1" == "qthelp" (
+\t%%SPHINXBUILD%% -b qthelp %%ALLSPHINXOPTS%% %(rbuilddir)s/qthelp
+\techo.
+\techo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %(rbuilddir)s/qthelp, like this:
+\techo.^> qcollectiongenerator %(rbuilddir)s\\qthelp\\%(project)s.qhcp
+\techo.To view the help file:
+\techo.^> assistant -collectionFile %(rbuilddir)s\\qthelp\\%(project)s.ghc
+\tgoto end
+)
+
+if "%%1" == "latex" (
+\t%%SPHINXBUILD%% -b latex %%ALLSPHINXOPTS%% %(rbuilddir)s/latex
+\techo.
+\techo.Build finished; the LaTeX files are in %(rbuilddir)s/latex.
+\tgoto end
+)
+
+if "%%1" == "changes" (
+\t%%SPHINXBUILD%% -b changes %%ALLSPHINXOPTS%% %(rbuilddir)s/changes
+\techo.
+\techo.The overview file is in %(rbuilddir)s/changes.
+\tgoto end
+)
+
+if "%%1" == "linkcheck" (
+\t%%SPHINXBUILD%% -b linkcheck %%ALLSPHINXOPTS%% %(rbuilddir)s/linkcheck
+\techo.
+\techo.Link check complete; look for any errors in the above output ^
+or in %(rbuilddir)s/linkcheck/output.txt.
+\tgoto end
+)
+
+:end
+'''
+
def mkdir_p(dir):
if path.isdir(dir):
@@ -382,6 +481,7 @@ def do_prompt(d, key, text, default=None, validator=nonempty):
def inner_main(args):
d = {}
+ texescape.init()
if not sys.stdout.isatty() or not color_terminal():
nocolor()
@@ -409,16 +509,16 @@ Enter the root path for documentation.'''
print '''
You have two options for placing the build directory for Sphinx output.
-Either, you use a directory ".build" within the root path, or you separate
+Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.'''
do_prompt(d, 'sep', 'Separate source and build directories (y/N)', 'n',
boolean)
+
print '''
-Inside the root directory, two more directories will be created; ".templates"
-for custom HTML templates and ".static" for custom stylesheets and other
-static files. Since the leading dot may be inconvenient for Windows users,
-you can enter another prefix (such as "_") to replace the dot.'''
- do_prompt(d, 'dot', 'Name prefix for templates and static dir', '.', ok)
+Inside the root directory, two more directories will be created; "_templates"
+for custom HTML templates and "_static" for custom stylesheets and other
+static files. You can enter another prefix (such as ".") to replace the underscore.'''
+ do_prompt(d, 'dot', 'Name prefix for templates and static dir', '_', ok)
print '''
The project name will occur in several places in the built documentation.'''
@@ -452,11 +552,11 @@ Please indicate if you want to use one of the following Sphinx extensions:'''
do_prompt(d, 'ext_intersphinx', 'intersphinx: link between Sphinx documentation '
'of different projects (y/N)', 'n', boolean)
print '''
-If you are under Unix, a Makefile can be generated for you so that you
+A Makefile and a Windows command file can be generated for you so that you
only have to run e.g. `make html' instead of invoking sphinx-build
directly.'''
- do_prompt(d, 'makefile', 'Create Makefile? (Y/n)',
- os.name == 'posix' and 'y' or 'n', boolean)
+ do_prompt(d, 'makefile', 'Create Makefile? (Y/n)', 'y', boolean)
+ do_prompt(d, 'batchfile', 'Create Windows command file? (Y/n)', 'y', boolean)
d['project_fn'] = make_filename(d['project'])
d['now'] = time.asctime()
@@ -465,10 +565,10 @@ directly.'''
repr('sphinx.ext.' + name) for name in ('autodoc', 'doctest', 'intersphinx')
if d['ext_' + name].upper() in ('Y', 'YES'))
d['copyright'] = time.strftime('%Y') + ', ' + d['author']
- d['author_texescaped'] = unicode(d['author']).translate(tex_escape_map)
+ d['author_texescaped'] = unicode(d['author']).translate(texescape.tex_escape_map)
d['project_doc'] = d['project'] + ' Documentation'
d['project_doc_texescaped'] = \
- unicode(d['project'] + ' Documentation').translate(tex_escape_map)
+ unicode(d['project'] + ' Documentation').translate(texescape.tex_escape_map)
if not path.isdir(d['path']):
mkdir_p(d['path'])
@@ -508,11 +608,19 @@ directly.'''
f.write((MAKEFILE % d).encode('utf-8'))
f.close()
+ create_batch = d['batchfile'].upper() in ('Y', 'YES')
+ if create_batch:
+ d['rsrcdir'] = separate and 'source' or '.'
+ d['rbuilddir'] = separate and 'build' or d['dot'] + 'build'
+ f = open(path.join(d['path'], 'make.bat'), 'w')
+ f.write((BATCHFILE % d).encode('utf-8'))
+ f.close()
+
print
print bold('Finished: An initial directory structure has been created.')
print '''
You should now populate your master file %s and create other documentation
-source files. ''' % masterfile + (create_makefile and '''\
+source files. ''' % masterfile + ((create_makefile or create_batch) and '''\
Use the Makefile to build the docs, like so:
make builder
''' or '''\
diff --git a/sphinx/roles.py b/sphinx/roles.py
index 0b66c8e8..d2e9558e 100644
--- a/sphinx/roles.py
+++ b/sphinx/roles.py
@@ -24,7 +24,7 @@ generic_docroles = {
'guilabel' : nodes.strong,
'kbd' : nodes.literal,
'mailheader' : addnodes.literal_emphasis,
- 'makevar' : nodes.Text,
+ 'makevar' : nodes.strong,
'manpage' : addnodes.literal_emphasis,
'mimetype' : addnodes.literal_emphasis,
'newsgroup' : addnodes.literal_emphasis,
@@ -96,6 +96,7 @@ innernodetypes = {
'term': nodes.emphasis,
'token': nodes.strong,
'envvar': nodes.strong,
+ 'download': nodes.strong,
'option': addnodes.literal_emphasis,
}
@@ -122,8 +123,10 @@ def xfileref_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
return [innernodetypes.get(typ, nodes.literal)(
rawtext, text, classes=['xref'])], []
# we want a cross-reference, create the reference node
- pnode = addnodes.pending_xref(rawtext, reftype=typ, refcaption=False,
- modname=env.currmodule, classname=env.currclass)
+ nodeclass = (typ == 'download') and addnodes.download_reference or \
+ addnodes.pending_xref
+ pnode = nodeclass(rawtext, reftype=typ, refcaption=False,
+ modname=env.currmodule, classname=env.currclass)
# we may need the line number for warnings
pnode.line = lineno
# the link title may differ from the target, but by default they are the same
@@ -235,6 +238,8 @@ specific_docroles = {
'token': xfileref_role,
'term': xfileref_role,
'option': xfileref_role,
+ 'doc': xfileref_role,
+ 'download': xfileref_role,
'menuselection': menusel_role,
'file': emph_literal_role,
diff --git a/sphinx/templates/changes/versionchanges.html b/sphinx/templates/changes/versionchanges.html
index 14d5efd3..09651bf1 100644
--- a/sphinx/templates/changes/versionchanges.html
+++ b/sphinx/templates/changes/versionchanges.html
@@ -1,4 +1,4 @@
-{% macro entries changes %}
+{% macro entries(changes) %}
<ul>{% for entry, docname, lineno in changes %}
<li><a href="rst/{{ docname }}.html#L{{ lineno-10 }}" target="src">{{ entry }}</a></li>
{% endfor %}</ul>
diff --git a/sphinx/templates/layout.html b/sphinx/templates/layout.html
index d9c9045d..fb0df9e0 100644
--- a/sphinx/templates/layout.html
+++ b/sphinx/templates/layout.html
@@ -4,7 +4,7 @@
{%- endblock %}
{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
-{%- macro relbar %}
+{%- macro relbar() %}
<div class="related">
<h3>{{ _('Navigation') }}</h3>
<ul>
@@ -24,8 +24,8 @@
</ul>
</div>
{%- endmacro %}
-{%- macro sidebar %}
- {%- if builder != 'htmlhelp' %}
+{%- macro sidebar() %}
+ {%- if not embedded %}
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
{%- block sidebarlogo %}
@@ -44,65 +44,60 @@
{%- block sidebarrel %}
{%- if prev %}
<h4>{{ _('Previous topic') }}</h4>
- <p class="topless"><a href="{{ prev.link|e }}" title="{{ _('previous chapter') }}">{{ prev.title }}</a></p>
+ <p class="topless"><a href="{{ prev.link|e }}"
+ title="{{ _('previous chapter') }}">{{ prev.title }}</a></p>
{%- endif %}
{%- if next %}
<h4>{{ _('Next topic') }}</h4>
- <p class="topless"><a href="{{ next.link|e }}" title="{{ _('next chapter') }}">{{ next.title }}</a></p>
+ <p class="topless"><a href="{{ next.link|e }}"
+ title="{{ _('next chapter') }}">{{ next.title }}</a></p>
{%- endif %}
{%- endblock %}
- {%- if sourcename %}
+ {%- block sidebarsourcelink %}
+ {%- if show_source and has_source and sourcename %}
<h3>{{ _('This Page') }}</h3>
<ul class="this-page-menu">
- {%- if builder == 'web' %}
- <li><a href="#comments">Comments ({{ comments|length }} so far)</a></li>
- <li><a href="{{ pathto('@edit/' + sourcename)|e }}">{{ _('Suggest Change') }}</a></li>
- <li><a href="{{ pathto('@source/' + sourcename)|e }}">{{ _('Show Source') }}</a></li>
- {%- elif builder == 'html' %}
- <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}">{{ _('Show Source') }}</a></li>
- {%- endif %}
+ <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
+ rel="nofollow">{{ _('Show Source') }}</a></li>
</ul>
{%- endif %}
+ {%- endblock %}
{%- if customsidebar %}
- {{ rendertemplate(customsidebar) }}
+ {% include customsidebar %}
{%- endif %}
{%- block sidebarsearch %}
- {%- if pagename != "search" %}
- <h3>{% if builder == 'web' %}{{ _('Keyword search')}}{% else %}{{ _('Quick search') }}{% endif %}</h3>
- <form class="search" action="{{ pathto('search') }}" method="get">
- <input type="text" name="q" size="18" /> <input type="submit" value="{{ _('Go') }}" />
- <input type="hidden" name="check_keywords" value="yes" />
- <input type="hidden" name="area" value="default" />
- </form>
- {%- if builder == 'web' %}
- <p style="font-size: 90%">{{ _('Enter a module, class or function name.') }}</p>
- {%- endif %}
+ {%- if pagename != "search" %}
+ <div id="searchbox" style="display: none">
+ <h3>{{ _('Quick search') }}</h3>
+ <form class="search" action="{{ pathto('search') }}" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="{{ _('Go') }}" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p style="font-size: 90%">{{ _('Enter search terms or a module, class or function name.') }}</p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
{%- endif %}
{%- endblock %}
</div>
</div>
{%- endif %}
-{%- endmacro -%}
+{%- endmacro %}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
{{ metatags }}
- {%- if builder != 'htmlhelp' %}
- {%- set titlesuffix = " &mdash; " + docstitle|e %}
+ {%- if not embedded %}
+ {%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
+ {%- else %}
+ {%- set titlesuffix = "" %}
{%- endif %}
<title>{{ title|striptags }}{{ titlesuffix }}</title>
- {%- if builder == 'web' %}
- <link rel="stylesheet" href="{{ pathto('index') }}?do=stylesheet{%
- if in_admin_panel %}&admin=yes{% endif %}" type="text/css" />
- {%- for link, type, title in page_links %}
- <link rel="alternate" type="{{ type|e(true) }}" title="{{ title|e(true) }}" href="{{ link|e(true) }}" />
- {%- endfor %}
- {%- else %}
<link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
- {%- endif %}
- {%- if builder != 'htmlhelp' %}
+ {%- if not embedded %}
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '{{ pathto("", 1) }}',
@@ -155,13 +150,13 @@
{%- block document %}
<div class="document">
<div class="documentwrapper">
- {%- if builder != 'htmlhelp' %}
+ {%- if not embedded %}
<div class="bodywrapper">
{%- endif %}
<div class="body">
{% block body %} {% endblock %}
</div>
- {%- if builder != 'htmlhelp' %}
+ {%- if not embedded %}
</div>
{%- endif %}
</div>
diff --git a/sphinx/templates/modindex.html b/sphinx/templates/modindex.html
index d6b505da..6e33e55c 100644
--- a/sphinx/templates/modindex.html
+++ b/sphinx/templates/modindex.html
@@ -2,7 +2,7 @@
{% set title = _('Global Module Index') %}
{% block extrahead %}
{{ super() }}
-{% if builder != 'htmlhelp' and collapse_modindex %}
+{% if not embedded and collapse_modindex %}
<script type="text/javascript">
DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX = true;
</script>
@@ -11,26 +11,6 @@
{% block body %}
<h1 id="global-module-index">{{ _('Global Module Index') }}</h1>
-{% if builder == 'web' and freqentries %}
- <p>{{ _('Most popular modules:') }}</p>
- <div class="modulecloud">
- {%- for module in freqentries %}
- <a href="../q/{{ module.name|e }}/" style="font-size: {{ module.size }}%">{{ module.name|e }}</a>
- {%- endfor %}
- </div>
-{% endif %}
-{% if builder == 'web' %}
- <form class="pfform" action="" method="get">
- {{ _('Show modules only available on these platforms') }}:<br>
- {% for pl in platforms -%}
- <input type="checkbox" name="pf" value="{{ pl }}" id="pl-{{ pl }}"
- {%- if pl in showpf %} checked="checked"{% endif %}>
- <label for="pl-{{ pl }}">{{ pl }}</label>
- {% endfor %}
- <input type="hidden" name="newpf" value="true">
- <input type="submit" value="Apply">
- </form>
-{% endif %}
{%- for letter in letters %}
<a href="#cap-{{ letter }}"><strong>{{ letter }}</strong></a> {% if not loop.last %}| {% endif %}
@@ -52,7 +32,7 @@
{% if fname %}<a href="{{ fname }}">{% endif -%}
<tt class="xref">{{ modname|e }}</tt>
{%- if fname %}</a>{% endif %}
- {%- if pform[0] %} <em>({{ pform|join(', ') }})</em>{% endif -%}
+ {%- if pform and pform[0] %} <em>({{ pform|join(', ') }})</em>{% endif -%}
</td><td>{% if dep %}<strong>{{ _('Deprecated')}}:</strong>{% endif %}
<em>{{ synops|e }}</em></td></tr>
{%- endif -%}
diff --git a/sphinx/templates/page.html b/sphinx/templates/page.html
index 4de23b13..17a93016 100644
--- a/sphinx/templates/page.html
+++ b/sphinx/templates/page.html
@@ -1,12 +1,4 @@
{% extends "layout.html" %}
-{% set page_links = [
- (pathto('@rss/' + sourcename), 'application/rss+xml', 'Page Comments'),
-] %}
{% block body %}
- {% if oldurl %}
- <div class="docwarning">
- {% trans %}<strong>Note:</strong> You requested an out-of-date URL from this server. We've tried to redirect you to the new location of this page, but it may not be the right one.{% endtrans %}
- </div>
- {% endif %}
{{ body }}
{% endblock %}
diff --git a/sphinx/templates/search.html b/sphinx/templates/search.html
index 545a459b..224d87b8 100644
--- a/sphinx/templates/search.html
+++ b/sphinx/templates/search.html
@@ -3,6 +3,13 @@
{% set script_files = script_files + ['_static/searchtools.js'] %}
{% block body %}
<h1 id="search-documentation">{{ _('Search') }}</h1>
+ <div id="fallback" class="admonition warning">
+ <script type="text/javascript">$('#fallback').hide();</script>
+ <p>
+ {% trans %}Please activate JavaScript to enable the search
+ functionality.{% endtrans %}
+ </p>
+ </div>
<p>
{% trans %}From here you can search these documents. Enter your search
words into the box below and click "search". Note that the search
diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty
index e5ed4d79..bb247664 100644
--- a/sphinx/texinputs/sphinx.sty
+++ b/sphinx/texinputs/sphinx.sty
@@ -451,6 +451,35 @@
\fi
}{\end{fulllineitems}}
+% class method ----------------------------------------------------------
+% \begin{classmethoddesc}[classname]{methodname}{args}
+\newcommand{\classmethodline}[3][\@undefined]{
+ \classmethodlineni{#2}{#3}
+ \ifx\@undefined#1\relax
+ \index{#2@{\py@idxcode{#2()}} (\py@thisclass\ class method)}
+ \else
+ \index{#2@{\py@idxcode{#2()}} (#1 class method)}
+ \fi
+}
+\newenvironment{classmethoddesc}[3][\@undefined]{
+ \begin{fulllineitems}
+ \ifx\@undefined#1\relax
+ \classmethodline{#2}{#3}
+ \else
+ \def\py@thisclass{#1}
+ \classmethodline{#2}{#3}
+ \fi
+}{\end{fulllineitems}}
+
+% similar to {classmethoddesc}, but doesn't add to the index
+% (never actually uses the optional argument)
+\newcommand{\classmethodlineni}[3][\py@classbadkey]{%
+ \py@sigline{class \bfcode{#2}}{#3}}
+\newenvironment{classmethoddescni}[3][\py@classbadkey]{
+ \begin{fulllineitems}
+ \classmethodlineni{#2}{#3}
+}{\end{fulllineitems}}
+
% object data attribute --------------------------------------------------
% \begin{memberdesc}[classname]{membername}
\newcommand{\memberline}[2][\py@classbadkey]{%
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 3e315e61..08e619ee 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -15,6 +15,7 @@ import sys
import time
import fnmatch
import tempfile
+import posixpath
import traceback
from os import path
@@ -48,6 +49,11 @@ def relative_uri(base, to):
return ('..' + SEP) * (len(b2)-1) + SEP.join(t2)
+def docname_join(basedocname, docname):
+ return posixpath.normpath(
+ posixpath.join('/' + basedocname, '..', docname))[1:]
+
+
def ensuredir(path):
"""Ensure that a path exists."""
try:
@@ -284,10 +290,82 @@ def ustrftime(format, *args):
return time.strftime(unicode(format).encode('utf-8'), *args).decode('utf-8')
+class FilenameUniqDict(dict):
+ """
+ A dictionary that automatically generates unique names for its keys,
+ interpreted as filenames, and keeps track of a set of docnames they
+ appear in. Used for images and downloadable files in the environment.
+ """
+ def __init__(self):
+ self._existing = set()
+
+ def add_file(self, docname, newfile):
+ if newfile in self:
+ self[newfile][0].add(docname)
+ return
+ uniquename = path.basename(newfile)
+ base, ext = path.splitext(uniquename)
+ i = 0
+ while uniquename in self._existing:
+ i += 1
+ uniquename = '%s%s%s' % (base, i, ext)
+ self[newfile] = (set([docname]), uniquename)
+ self._existing.add(uniquename)
+ return uniquename
+
+ def purge_doc(self, docname):
+ for filename, (docs, _) in self.items():
+ docs.discard(docname)
+ if not docs:
+ del self[filename]
+
+ def __getstate__(self):
+ return self._existing
+
+ def __setstate__(self, state):
+ self._existing = state
+
+
+def parselinenos(spec, total):
+ """
+ Parse a line number spec (such as "1,2,4-6") and return a list of
+ wanted line numbers.
+ """
+ items = list()
+ parts = spec.split(',')
+ for part in parts:
+ try:
+ begend = part.strip().split('-')
+ if len(begend) > 2:
+ raise ValueError
+ if len(begend) == 1:
+ items.append(int(begend[0])-1)
+ else:
+ start = (begend[0] == '') and 0 or int(begend[0])-1
+ end = (begend[1] == '') and total or int(begend[1])
+ items.extend(xrange(start, end))
+ except Exception, err:
+ raise ValueError('invalid line number spec: %r' % spec)
+ return items
+
+
+def force_decode(string, encoding):
+ if isinstance(string, str):
+ if encoding:
+ string = string.decode(encoding)
+ else:
+ try:
+ # try decoding with utf-8, should only work for real UTF-8
+ string = string.decode('utf-8')
+ except UnicodeError:
+ # last resort -- can't fail
+ string = string.decode('latin1')
+ return string
+
+
def movefile(source, dest):
# move a file, removing the destination if it exists
if os.path.exists(dest):
- try:
os.unlink(dest)
except OSError:
pass
diff --git a/sphinx/util/compat.py b/sphinx/util/compat.py
index 4d5e1996..56ac9e80 100644
--- a/sphinx/util/compat.py
+++ b/sphinx/util/compat.py
@@ -27,7 +27,7 @@ def make_admonition(node_class, name, arguments, options, content, lineno,
textnodes, messages = state.inline_text(title_text, lineno)
admonition_node += nodes.title(title_text, '', *textnodes)
admonition_node += messages
- if options.has_key('class'):
+ if 'class' in options:
classes = options['class']
else:
classes = ['admonition-' + nodes.make_id(title_text)]
diff --git a/sphinx/util/docstrings.py b/sphinx/util/docstrings.py
new file mode 100644
index 00000000..1b0a599a
--- /dev/null
+++ b/sphinx/util/docstrings.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.util.docstrings
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ Utilities for docstring processing.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import sys
+
+
+def prepare_docstring(s):
+ """
+ Convert a docstring into lines of parseable reST. Return it as a list of
+ lines usable for inserting into a docutils ViewList (used as argument
+ of nested_parse().) An empty line is added to act as a separator between
+ this docstring and following content.
+ """
+ lines = s.expandtabs().splitlines()
+ # Find minimum indentation of any non-blank lines after first line.
+ margin = sys.maxint
+ for line in lines[1:]:
+ content = len(line.lstrip())
+ if content:
+ indent = len(line) - content
+ margin = min(margin, indent)
+ # Remove indentation.
+ if lines:
+ lines[0] = lines[0].lstrip()
+ if margin < sys.maxint:
+ for i in range(1, len(lines)): lines[i] = lines[i][margin:]
+ # Remove any leading blank lines.
+ while lines and not lines[0]:
+ lines.pop(0)
+ # make sure there is an empty line at the end
+ if lines and lines[-1]:
+ lines.append('')
+ return lines
+
+
+def prepare_commentdoc(s):
+ """
+ Extract documentation comment lines (starting with #:) and return them as a
+ list of lines. Returns an empty list if there is no documentation.
+ """
+ result = []
+ lines = [line.strip() for line in s.expandtabs().splitlines()]
+ for line in lines:
+ if line.startswith('#: '):
+ result.append(line[3:])
+ if result and result[-1]:
+ result.append('')
+ return result
diff --git a/sphinx/util/jsdump.py b/sphinx/util/jsdump.py
index 2eb4619e..8c760b68 100644
--- a/sphinx/util/jsdump.py
+++ b/sphinx/util/jsdump.py
@@ -6,7 +6,7 @@
This module implements a simple JavaScript serializer.
Uses the basestring encode function from simplejson by Bob Ippolito.
- :copyright: Copyright 2008 by the Sphinx team, see AUTHORS.
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
diff --git a/sphinx/writers/__init__.py b/sphinx/writers/__init__.py
new file mode 100644
index 00000000..7bb8cad9
--- /dev/null
+++ b/sphinx/writers/__init__.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.writers
+ ~~~~~~~~~~~~~~
+
+ Custom docutils writers.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
diff --git a/sphinx/htmlwriter.py b/sphinx/writers/html.py
index f983aa76..8c1a87ba 100644
--- a/sphinx/htmlwriter.py
+++ b/sphinx/writers/html.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
- sphinx.htmlwriter
- ~~~~~~~~~~~~~~~~~
+ sphinx.writers.html
+ ~~~~~~~~~~~~~~~~~~~
docutils writers handling Sphinx' custom nodes.
@@ -58,6 +58,7 @@ class HTMLTranslator(BaseTranslator):
self.highlightlang = builder.config.highlight_language
self.highlightlinenothreshold = sys.maxint
self.protect_literal_text = 0
+ self.add_permalinks = builder.config.html_add_permalinks
def visit_desc(self, node):
self.body.append(self.starttag(node, 'dl', CLASS=node['desctype']))
@@ -73,7 +74,7 @@ class HTMLTranslator(BaseTranslator):
if node.parent['desctype'] in ('class', 'exception'):
self.body.append('%s ' % node.parent['desctype'])
def depart_desc_signature(self, node):
- if node['ids'] and self.builder.add_definition_links:
+ if node['ids'] and self.add_permalinks and self.builder.add_permalinks:
self.body.append(u'<a class="headerlink" href="#%s" ' % node['ids'][0] +
u'title="%s">\u00B6</a>' %
_('Permalink to this definition'))
@@ -89,6 +90,11 @@ class HTMLTranslator(BaseTranslator):
def depart_desc_type(self, node):
pass
+ def visit_desc_returns(self, node):
+ self.body.append(' &rarr; ')
+ def depart_desc_returns(self, node):
+ pass
+
def visit_desc_name(self, node):
self.body.append(self.starttag(node, 'tt', '', CLASS='descname'))
def depart_desc_name(self, node):
@@ -253,6 +259,16 @@ class HTMLTranslator(BaseTranslator):
def depart_highlightlang(self, node):
pass
+ def visit_download_reference(self, node):
+ if node.hasattr('filename'):
+ self.body.append('<a href="%s">' % posixpath.join(
+ self.builder.dlpath, node['filename']))
+ self.context.append('</a>')
+ else:
+ self.context.append('')
+ def depart_download_reference(self, node):
+ self.body.append(self.context.pop())
+
# overwritten
def visit_image(self, node):
olduri = node['uri']
@@ -305,6 +321,16 @@ class HTMLTranslator(BaseTranslator):
def depart_module(self, node):
pass
+ def visit_hlist(self, node):
+ self.body.append('<table class="hlist"><tr>')
+ def depart_hlist(self, node):
+ self.body.append('</tr></table>\n')
+
+ def visit_hlistcol(self, node):
+ self.body.append('<td>')
+ def depart_hlistcol(self, node):
+ self.body.append('</td>')
+
def bulk_text_processor(self, text):
return text
@@ -388,7 +414,7 @@ class HTMLTranslator(BaseTranslator):
def depart_title(self, node):
close_tag = self.context[-1]
- if self.builder.add_header_links and \
+ if self.add_permalinks and self.builder.add_permalinks and \
(close_tag.startswith('</h') or
close_tag.startswith('</a></h')) and \
node.parent.hasattr('ids') and node.parent['ids']:
diff --git a/sphinx/latexwriter.py b/sphinx/writers/latex.py
index bfc9165a..885cac44 100644
--- a/sphinx/latexwriter.py
+++ b/sphinx/writers/latex.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
- sphinx.latexwriter
- ~~~~~~~~~~~~~~~~~~
+ sphinx.writers.latex
+ ~~~~~~~~~~~~~~~~~~~~
Custom docutils writer for LaTeX.
@@ -91,7 +91,7 @@ class LaTeXWriter(writers.Writer):
class ExtBabel(Babel):
def get_shorthandoff(self):
shortlang = self.language.split('_')[0]
- if shortlang in ('de', 'sl', 'pt', 'es', 'nl', 'pl'):
+ if shortlang in ('de', 'sl', 'pt', 'es', 'nl', 'pl', 'it'):
return '\\shorthandoff{"}'
return ''
@@ -112,7 +112,8 @@ class Table(object):
class Desc(object):
def __init__(self, node):
self.env = LaTeXTranslator.desc_map.get(node['desctype'], 'describe')
- self.type = self.cls = self.name = self.params = self.annotation = ''
+ self.type = self.cls = self.name = self.params = \
+ self.annotation = self.returns = ''
self.count = 0
@@ -222,6 +223,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.this_is_the_title = 1
self.literal_whitespace = 0
self.no_contractions = 0
+ self.compact_list = 0
def astext(self):
return (HEADER % self.elements + self.highlighter.get_stylesheet() +
@@ -237,6 +239,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
# ... and all others are the appendices
self.body.append('\n\\appendix\n')
self.first_document = -1
+ if 'docname' in node:
+ self.body.append('\\hypertarget{--doc-%s}{}' % node['docname'])
# "- 1" because the level is increased before the title is visited
self.sectionlevel = self.top_sectionlevel - 1
def depart_document(self, node):
@@ -259,6 +263,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.body.append('\n\\resetcurrentobjects\n')
# and also, new footnotes
self.footnotestack.append(self.collect_footnotes(node))
+ # also add a document target
+ self.body.append('\\hypertarget{--doc-%s}{}' % node['docname'])
def collect_footnotes(self, node):
fnotes = {}
@@ -394,6 +400,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
'function' : 'funcdesc',
'class': 'classdesc',
'method': 'methoddesc',
+ 'classmethod': 'classmethoddesc',
'staticmethod': 'staticmethoddesc',
'exception': 'excdesc',
'data': 'datadesc',
@@ -436,7 +443,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
t2 = "{%s}{%s}" % (d.name, d.params)
elif d.env in ('datadesc', 'excdesc', 'csimplemacrodesc'):
t2 = "{%s}" % (d.name)
- elif d.env in ('methoddesc', 'staticmethoddesc'):
+ elif d.env in ('methoddesc', 'classmethoddesc', 'staticmethoddesc'):
if d.cls:
t2 = "[%s]{%s}{%s}" % (d.cls, d.name, d.params)
else:
@@ -477,6 +484,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.descstack[-1].type = self.encode(node.astext().strip())
raise nodes.SkipNode
+ def visit_desc_returns(self, node):
+ d = self.descstack[-1]
+ if d.env == 'describe':
+ d.name += ' $\\rightarrow$ ' + self.encode(node.astext())
+ else:
+ self.descstack[-1].returns = self.encode(node.astext().strip())
+ raise nodes.SkipNode
+
def visit_desc_name(self, node):
d = self.descstack[-1]
if d.env == 'describe':
@@ -638,9 +653,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
raise nodes.SkipNode
def visit_bullet_list(self, node):
- self.body.append('\\begin{itemize}\n' )
+ if not self.compact_list:
+ self.body.append('\\begin{itemize}\n' )
def depart_bullet_list(self, node):
- self.body.append('\\end{itemize}\n' )
+ if not self.compact_list:
+ self.body.append('\\end{itemize}\n' )
def visit_enumerated_list(self, node):
self.body.append('\\begin{enumerate}\n' )
@@ -709,6 +726,21 @@ class LaTeXTranslator(nodes.NodeVisitor):
def depart_centered(self, node):
self.body.append('\n\\end{centering}')
+ def visit_hlist(self, node):
+ # for now, we don't support a more compact list format
+ # don't add individual itemize environments, but one for all columns
+ self.compact_list += 1
+ self.body.append('\\begin{itemize}\\setlength{\\itemsep}{0pt}'
+ '\\setlength{\\parskip}{0pt}\n')
+ def depart_hlist(self, node):
+ self.compact_list -= 1
+ self.body.append('\\end{itemize}\n')
+
+ def visit_hlistcol(self, node):
+ pass
+ def depart_hlistcol(self, node):
+ pass
+
def visit_module(self, node):
modname = node['modname']
self.body.append('\n\\declaremodule[%s]{}{%s}' % (modname.replace('_', ''),
@@ -923,6 +955,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
elif uri.startswith('#'):
self.body.append('\\hyperlink{%s}{' % uri[1:])
self.context.append('}')
+ elif uri.startswith('%'):
+ hashindex = uri.find('#')
+ targetname = (hashindex == -1) and '--doc-' + uri[1:] or uri[hashindex+1:]
+ self.body.append('\\hyperlink{%s}{' % targetname)
+ self.context.append('}')
elif uri.startswith('@token'):
if self.in_production_list:
self.body.append('\\token{')
@@ -935,6 +972,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
def depart_reference(self, node):
self.body.append(self.context.pop())
+ def visit_download_reference(self, node):
+ pass
+ def depart_download_reference(self, node):
+ pass
+
def visit_pending_xref(self, node):
pass
def depart_pending_xref(self, node):
diff --git a/sphinx/textwriter.py b/sphinx/writers/text.py
index 383af782..4718d41d 100644
--- a/sphinx/textwriter.py
+++ b/sphinx/writers/text.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
- sphinx.textwriter
- ~~~~~~~~~~~~~~~~~
+ sphinx.writers.text
+ ~~~~~~~~~~~~~~~~~~~
Custom docutils writer for plain text.
@@ -195,6 +195,11 @@ class TextTranslator(nodes.NodeVisitor):
def depart_desc_type(self, node):
pass
+ def visit_desc_returns(self, node):
+ self.add_text(' -> ')
+ def depart_desc_returns(self, node):
+ pass
+
def visit_desc_parameterlist(self, node):
self.add_text('(')
self.first_param = 1
@@ -511,6 +516,16 @@ class TextTranslator(nodes.NodeVisitor):
def depart_centered(self, node):
pass
+ def visit_hlist(self, node):
+ pass
+ def depart_hlist(self, node):
+ pass
+
+ def visit_hlistcol(self, node):
+ pass
+ def depart_hlistcol(self, node):
+ pass
+
def visit_admonition(self, node):
self.new_state(0)
def depart_admonition(self, node):
@@ -609,6 +624,11 @@ class TextTranslator(nodes.NodeVisitor):
def depart_reference(self, node):
pass
+ def visit_download_reference(self, node):
+ pass
+ def depart_download_reference(self, node):
+ pass
+
def visit_emphasis(self, node):
self.add_text('*')
def depart_emphasis(self, node):
diff --git a/tests/root/includes.txt b/tests/root/includes.txt
index ad507fc6..44e33af0 100644
--- a/tests/root/includes.txt
+++ b/tests/root/includes.txt
@@ -14,3 +14,33 @@ Test file and literal inclusion
:encoding: latin-1
.. include:: wrongenc.inc
:encoding: latin-1
+
+Literalinclude options
+======================
+
+.. highlight:: text
+
+.. cssclass:: inc-pyobj1
+.. literalinclude:: literal.inc
+ :pyobject: Foo
+
+.. cssclass:: inc-pyobj2
+.. literalinclude:: literal.inc
+ :pyobject: Bar.baz
+
+.. cssclass:: inc-lines
+.. literalinclude:: literal.inc
+ :lines: 6-7,9
+
+.. cssclass:: inc-startend
+.. literalinclude:: literal.inc
+ :start-after: coding: utf-8
+ :end-before: class Foo
+
+
+Testing downloadable files
+==========================
+
+Download :download:`img.png` here.
+Download :download:`this <subdir/img.png>` there.
+Don't download :download:`this <nonexisting.png>`.
diff --git a/tests/root/literal.inc b/tests/root/literal.inc
index a4ce93d2..d5b9890c 100644
--- a/tests/root/literal.inc
+++ b/tests/root/literal.inc
@@ -2,3 +2,12 @@
# -*- coding: utf-8 -*-
foo = u"Including Unicode characters: üöä"
+
+class Foo:
+ pass
+
+class Bar:
+ def baz():
+ pass
+
+def bar(): pass
diff --git a/tests/root/markup.txt b/tests/root/markup.txt
index 454762e3..777fbd2f 100644
--- a/tests/root/markup.txt
+++ b/tests/root/markup.txt
@@ -104,6 +104,16 @@ Reference lookup: [Ref1]_ (defined in another file).
`Google <http://www.google.com>`_
For everything.
+.. hlist::
+ :columns: 4
+
+ * This
+ * is
+ * a horizontal
+ * list
+ * with several
+ * items
+
.. rubric:: Side note
This is a side note.
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py
index 752c0725..67220180 100644
--- a/tests/test_autodoc.py
+++ b/tests/test_autodoc.py
@@ -24,6 +24,7 @@ def setup_module():
app.builder.env.app = app
app.connect('autodoc-process-docstring', process_docstring)
app.connect('autodoc-process-signature', process_signature)
+ app.connect('autodoc-skip-member', skip_member)
options = Struct(
inherited_members = False,
@@ -71,44 +72,51 @@ def process_signature(app, what, name, obj, options, args, retann):
return '42', None
+def skip_member(app, what, name, obj, skip, options):
+ if name.startswith('_'):
+ return True
+ if name == 'skipmeth':
+ return True
+
+
def test_resolve_name():
# for modules
assert gen.resolve_name('module', 'test_autodoc') == \
- ('test_autodoc', 'test_autodoc', [], None, None)
+ ('test_autodoc', [], None, None)
assert gen.resolve_name('module', 'test.test_autodoc') == \
- ('test.test_autodoc', 'test.test_autodoc', [], None, None)
+ ('test.test_autodoc', [], None, None)
assert gen.resolve_name('module', 'test(arg)') == \
- ('test', 'test', [], None, None)
+ ('test', [], None, None)
assert 'ignoring signature arguments' in gen.warnings[0]
del gen.warnings[:]
# for functions/classes
assert gen.resolve_name('function', 'util.raises') == \
- ('util.raises', 'util', ['raises'], None, None)
+ ('util', ['raises'], None, None)
assert gen.resolve_name('function', 'util.raises(exc) -> None') == \
- ('util.raises', 'util', ['raises'], 'exc', ' -> None')
+ ('util', ['raises'], 'exc', 'None')
gen.env.autodoc_current_module = 'util'
assert gen.resolve_name('function', 'raises') == \
- ('raises', 'util', ['raises'], None, None)
+ ('util', ['raises'], None, None)
gen.env.autodoc_current_module = None
gen.env.currmodule = 'util'
assert gen.resolve_name('function', 'raises') == \
- ('raises', 'util', ['raises'], None, None)
+ ('util', ['raises'], None, None)
assert gen.resolve_name('class', 'TestApp') == \
- ('TestApp', 'util', ['TestApp'], None, None)
+ ('util', ['TestApp'], None, None)
# for members
gen.env.currmodule = 'foo'
assert gen.resolve_name('method', 'util.TestApp.cleanup') == \
- ('util.TestApp.cleanup', 'util', ['TestApp', 'cleanup'], None, None)
+ ('util', ['TestApp', 'cleanup'], None, None)
gen.env.currmodule = 'util'
gen.env.currclass = 'Foo'
gen.env.autodoc_current_class = 'TestApp'
assert gen.resolve_name('method', 'cleanup') == \
- ('cleanup', 'util', ['TestApp', 'cleanup'], None, None)
+ ('util', ['TestApp', 'cleanup'], None, None)
assert gen.resolve_name('method', 'TestApp.cleanup') == \
- ('TestApp.cleanup', 'util', ['TestApp', 'cleanup'], None, None)
+ ('util', ['TestApp', 'cleanup'], None, None)
# and clean up
gen.env.currmodule = None
@@ -126,7 +134,7 @@ def test_format_signature():
assert gen.format_signature('function', 'f', f, None, None) == '(a, b, c=1, **d)'
assert gen.format_signature('function', 'f', f, 'a, b, c, d', None) == \
'(a, b, c, d)'
- assert gen.format_signature('function', 'f', f, None, ' -> None') == \
+ assert gen.format_signature('function', 'f', f, None, 'None') == \
'(a, b, c=1, **d) -> None'
# test for classes
@@ -144,7 +152,7 @@ def test_format_signature():
pass
for C in (F, G):
assert gen.format_signature('class', 'C', C, None, None) == '(a, b=None)'
- assert gen.format_signature('class', 'C', D, 'a, b', ' -> X') == '(a, b) -> X'
+ assert gen.format_signature('class', 'C', D, 'a, b', 'X') == '(a, b) -> X'
# test for methods
class H:
@@ -165,13 +173,14 @@ def test_format_signature():
def test_get_doc():
def getdocl(*args):
- # strip the empty line at the end
- return list(gen.get_doc(*args))[:-1]
+ ds = gen.get_doc(*args)
+ # for testing purposes, concat them and strip the empty line at the end
+ return sum(ds, [])[:-1]
# objects without docstring
def f():
pass
- assert getdocl('function', 'f', f) == []
+ assert getdocl('function', f) == []
# standard function, diverse docstring styles...
def f():
@@ -181,7 +190,7 @@ def test_get_doc():
Docstring
"""
for func in (f, g):
- assert getdocl('function', 'f', func) == ['Docstring']
+ assert getdocl('function', func) == ['Docstring']
# first line vs. other lines indentation
def f():
@@ -190,17 +199,17 @@ def test_get_doc():
Other
lines
"""
- assert getdocl('function', 'f', f) == ['First line', '', 'Other', ' lines']
+ assert getdocl('function', f) == ['First line', '', 'Other', ' lines']
# charset guessing (this module is encoded in utf-8)
def f():
"""Döcstring"""
- assert getdocl('function', 'f', f) == [u'Döcstring']
+ assert getdocl('function', f) == [u'Döcstring']
# already-unicode docstrings must be taken literally
def f():
u"""Döcstring"""
- assert getdocl('function', 'f', f) == [u'Döcstring']
+ assert getdocl('function', f) == [u'Döcstring']
# class docstring: depends on config value which one is taken
class C:
@@ -208,11 +217,11 @@ def test_get_doc():
def __init__(self):
"""Init docstring"""
gen.env.config.autoclass_content = 'class'
- assert getdocl('class', 'C', C) == ['Class docstring']
+ assert getdocl('class', C) == ['Class docstring']
gen.env.config.autoclass_content = 'init'
- assert getdocl('class', 'C', C) == ['Init docstring']
+ assert getdocl('class', C) == ['Init docstring']
gen.env.config.autoclass_content = 'both'
- assert getdocl('class', 'C', C) == ['Class docstring', '', 'Init docstring']
+ assert getdocl('class', C) == ['Class docstring', '', 'Init docstring']
class D:
"""Class docstring"""
@@ -224,18 +233,21 @@ def test_get_doc():
"""
# Indentation is normalized for 'both'
- assert getdocl('class', 'D', D) == ['Class docstring', '', 'Init docstring',
- '', 'Other', ' lines']
+ assert getdocl('class', D) == ['Class docstring', '', 'Init docstring',
+ '', 'Other', ' lines']
+
+
+def test_docstring_processing():
+ def process(what, name, obj):
+ return list(gen.process_doc(gen.get_doc(what, obj), what, name, obj))
class E:
def __init__(self):
"""Init docstring"""
# docstring processing by event handler
- assert getdocl('class', 'bar', E) == ['Init docstring', '', '42']
-
+ assert process('class', 'bar', E) == ['Init docstring', '', '42', '']
-def test_docstring_processing_functions():
lid = app.connect('autodoc-process-docstring', cut_lines(1, 1, ['function']))
def f():
"""
@@ -243,7 +255,7 @@ def test_docstring_processing_functions():
second line
third line
"""
- assert list(gen.get_doc('function', 'f', f)) == ['second line', '']
+ assert process('function', 'f', f) == ['second line', '']
app.disconnect(lid)
lid = app.connect('autodoc-process-docstring', between('---', ['function']))
@@ -255,7 +267,7 @@ def test_docstring_processing_functions():
---
third line
"""
- assert list(gen.get_doc('function', 'f', f)) == ['second line', '']
+ assert process('function', 'f', f) == ['second line', '']
app.disconnect(lid)
@@ -281,7 +293,7 @@ def test_generate():
def assert_result_contains(item, *args):
gen.generate(*args)
- print '\n'.join(gen.result)
+ #print '\n'.join(gen.result)
assert len(gen.warnings) == 0, gen.warnings
assert item in gen.result
del gen.result[:]
@@ -313,17 +325,20 @@ def test_generate():
assert_works('exception', 'test_autodoc.CustomEx', [], None)
# test diverse inclusion settings for members
- should = [('class', 'Class')]
+ should = [('class', 'test_autodoc.Class')]
assert_processes(should, 'class', 'Class', [], None)
- should.extend([('method', 'Class.meth')])
+ should.extend([('method', 'test_autodoc.Class.meth')])
assert_processes(should, 'class', 'Class', ['meth'], None)
- should.extend([('attribute', 'Class.prop')])
+ should.extend([('attribute', 'test_autodoc.Class.prop'),
+ ('attribute', 'test_autodoc.Class.attr'),
+ ('attribute', 'test_autodoc.Class.docattr'),
+ ('attribute', 'test_autodoc.Class.udocattr')])
assert_processes(should, 'class', 'Class', ['__all__'], None)
options.undoc_members = True
- should.append(('method', 'Class.undocmeth'))
+ should.append(('method', 'test_autodoc.Class.undocmeth'))
assert_processes(should, 'class', 'Class', ['__all__'], None)
options.inherited_members = True
- should.append(('method', 'Class.inheritedmeth'))
+ should.append(('method', 'test_autodoc.Class.inheritedmeth'))
assert_processes(should, 'class', 'Class', ['__all__'], None)
# test module flags
@@ -355,6 +370,17 @@ def test_generate():
assert_result_contains('.. class:: CustomDict', 'class', 'CustomDict',
['__all__'], None)
+ # test inner class handling
+ assert_processes([('class', 'test_autodoc.Outer'),
+ ('class', 'test_autodoc.Outer.Inner'),
+ ('method', 'test_autodoc.Outer.Inner.meth')],
+ 'class', 'Outer', ['__all__'], None)
+
+ # test generation for C modules (which have no source file)
+ gen.env.currmodule = 'time'
+ assert_processes([('function', 'time.asctime')], 'function', 'asctime', [], None)
+ assert_processes([('function', 'time.asctime')], 'function', 'asctime', [], None)
+
# --- generate fodder ------------
@@ -380,10 +406,26 @@ class Class(Base):
def undocmeth(self):
pass
+ def skipmeth(self):
+ """Method that should be skipped."""
+ pass
+
+ # should not be documented
+ skipattr = 'foo'
+
+ #: should be documented -- süß
+ attr = 'bar'
+
@property
def prop(self):
"""Property."""
+ docattr = 'baz'
+ """should likewise be documented -- süß"""
+
+ udocattr = 'quux'
+ u"""should be documented as well - süß"""
+
class CustomDict(dict):
"""Docstring."""
@@ -392,3 +434,16 @@ def function(foo, *args, **kwds):
Return spam.
"""
pass
+
+
+class Outer(object):
+ """Foo"""
+
+ class Inner(object):
+ """Foo"""
+
+ def meth(self):
+ """Foo"""
+
+ # should be documented as an alias
+ factory = dict
diff --git a/tests/test_build.py b/tests/test_build.py
index aed56a8c..9999abd0 100644
--- a/tests/test_build.py
+++ b/tests/test_build.py
@@ -10,6 +10,7 @@
"""
import os
+import re
import sys
import difflib
import htmlentitydefs
@@ -19,8 +20,9 @@ from subprocess import Popen, PIPE
from util import *
from etree13 import ElementTree as ET
-from sphinx.builder import StandaloneHTMLBuilder, LaTeXBuilder
-from sphinx.latexwriter import LaTeXTranslator
+from sphinx.builders.html import StandaloneHTMLBuilder
+from sphinx.builders.latex import LaTeXBuilder
+from sphinx.writers.latex import LaTeXTranslator
html_warnfile = StringIO()
@@ -31,6 +33,7 @@ WARNING: %(root)s/images.txt:9: Image file not readable: foo.png
WARNING: %(root)s/images.txt:23: Nonlocal image URI found: http://www.python.org/logo.png
WARNING: %(root)s/includes.txt:: (WARNING/2) Encoding 'utf-8' used for reading included \
file u'wrongenc.inc' seems to be wrong, try giving an :encoding: option
+WARNING: %(root)s/includes.txt:56: Download file not readable: nonexisting.png
"""
HTML_WARNINGS = ENV_WARNINGS + """\
@@ -57,11 +60,21 @@ HTML_XPATH = {
'includes.html': {
".//pre/span[@class='s']": u'üöä',
".//pre": u'Max Strauß',
+ ".//a[@href='_downloads/img.png']": '',
+ ".//a[@href='_downloads/img1.png']": '',
+ ".//div[@class='inc-pyobj1 highlight-text']/div/pre":
+ r'^class Foo:\n pass\n\s*$',
+ ".//div[@class='inc-pyobj2 highlight-text']/div/pre":
+ r'^ def baz\(\):\n pass\n\s*$',
+ ".//div[@class='inc-lines highlight-text']/div/pre":
+ r'^class Foo:\n pass\nclass Bar:\n$',
+ ".//div[@class='inc-startend highlight-text']/div/pre":
+ ur'^foo = u"Including Unicode characters: üöä"\n$',
},
'autodoc.html': {
".//dt[@id='test_autodoc.Class']": '',
- ".//dt[@id='test_autodoc.function']/em": '**kwds',
- ".//dd": 'Return spam.',
+ ".//dt[@id='test_autodoc.function']/em": r'\*\*kwds',
+ ".//dd": r'Return spam\.',
},
'markup.html': {
".//meta[@name='author'][@content='Me']": '',
@@ -77,7 +90,7 @@ HTML_XPATH = {
},
'contents.html': {
".//meta[@name='hc'][@content='hcval']": '',
- ".//td[@class='label']": '[Ref1]',
+ ".//td[@class='label']": r'\[Ref1\]',
".//li[@class='toctree-l1']/a": 'Testing various markup',
".//li[@class='toctree-l2']/a": 'Admonitions',
".//title": 'Sphinx <Tests>',
@@ -113,18 +126,23 @@ def test_html(app):
parser = NslessParser()
parser.entity.update(htmlentitydefs.entitydefs)
etree = ET.parse(os.path.join(app.outdir, fname), parser)
- for path, text in paths.iteritems():
+ for path, check in paths.iteritems():
nodes = list(etree.findall(path))
assert nodes != []
- if not text:
+ if hasattr(check, '__call__'):
+ check(nodes)
+ elif not check:
# only check for node presence
continue
- for node in nodes:
- if node.text and text in node.text:
- break
else:
- assert False, ('%r not found in any node matching '
- 'path %s in %s' % (text, path, fname))
+ rex = re.compile(check)
+ for node in nodes:
+ if node.text and rex.search(node.text):
+ break
+ else:
+ assert False, ('%r not found in any node matching '
+ 'path %s in %s: %r' % (check, path, fname,
+ [node.text for node in nodes]))
@with_app(buildername='latex', warning=latex_warnfile)
diff --git a/tests/test_config.py b/tests/test_config.py
index bc5ab8a0..6343a364 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -15,7 +15,8 @@ from util import *
from sphinx.application import ExtensionError
-@with_app(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True'})
+@with_app(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True',
+ 'latex_elements.docclass': 'scrartcl'})
def test_core_config(app):
cfg = app.config
@@ -26,6 +27,7 @@ def test_core_config(app):
# overrides
assert cfg.master_doc == 'master'
+ assert cfg.latex_elements['docclass'] == 'scrartcl'
# simple default values
assert 'exclude_dirs' not in cfg.__dict__
diff --git a/tests/test_env.py b/tests/test_env.py
index 390c6999..685311e6 100644
--- a/tests/test_env.py
+++ b/tests/test_env.py
@@ -12,7 +12,8 @@
from util import *
from sphinx.environment import BuildEnvironment
-from sphinx.builder import StandaloneHTMLBuilder, LaTeXBuilder
+from sphinx.builders.html import StandaloneHTMLBuilder
+from sphinx.builders.latex import LaTeXBuilder
app = env = None
warnings = []
@@ -76,11 +77,13 @@ def test_second_update():
(root / 'new.txt').write_text('New file\n========\n')
it = env.update(app.config, app.srcdir, app.doctreedir, app)
msg = it.next()
- assert '1 added, 1 changed, 1 removed' in msg
+ assert '1 added, 2 changed, 1 removed' in msg
docnames = set()
for docname in it:
docnames.add(docname)
- assert docnames == set(['contents', 'new'])
+ # "includes" is in there because it contains a reference to a nonexisting
+ # downloadable file, which is given another chance to exist
+ assert docnames == set(['contents', 'new', 'includes'])
assert 'images' not in env.all_docs
assert 'images' not in env.found_docs
diff --git a/tests/test_highlighting.py b/tests/test_highlighting.py
new file mode 100644
index 00000000..198f7a0a
--- /dev/null
+++ b/tests/test_highlighting.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+"""
+ test_highlighting
+ ~~~~~~~~~~~~~~~~~
+
+ Test the Pygments highlighting bridge.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+from util import *
+
+from pygments.lexer import RegexLexer
+from pygments.token import Text, Name
+from pygments.formatters.html import HtmlFormatter
+
+from sphinx.highlighting import PygmentsBridge
+
+
+class MyLexer(RegexLexer):
+ name = 'testlexer'
+
+ tokens = {
+ 'root': [
+ ('a', Name),
+ ('b', Text),
+ ],
+ }
+
+class ComplainOnUnhighlighted(PygmentsBridge):
+
+ def unhighlighted(self, source):
+ raise AssertionError("should highlight %r" % source)
+
+class MyFormatter(HtmlFormatter):
+ def format(self, tokensource, outfile):
+ outfile.write('test')
+
+
+@with_app()
+def test_add_lexer(app):
+ app.add_lexer('test', MyLexer())
+
+ bridge = PygmentsBridge('html')
+ ret = bridge.highlight_block('ab', 'test')
+ assert '<span class="n">a</span>b' in ret
+
+def test_detect_interactive():
+ bridge = ComplainOnUnhighlighted('html')
+ blocks = [
+ """
+ >>> testing()
+ True
+ """,
+ ]
+ for block in blocks:
+ ret = bridge.highlight_block(block.lstrip(), 'python')
+ assert ret.startswith("<div class=\"highlight\">")
+
+def test_set_formatter():
+ PygmentsBridge.html_formatter = MyFormatter
+ try:
+ bridge = PygmentsBridge('html')
+ ret = bridge.highlight_block('foo', 'python')
+ assert ret == 'test'
+ finally:
+ PygmentsBridge.html_formatter = HtmlFormatter
diff --git a/tests/test_markup.py b/tests/test_markup.py
index 5fd70f05..99c85911 100644
--- a/tests/test_markup.py
+++ b/tests/test_markup.py
@@ -17,11 +17,13 @@ from docutils import frontend, utils, nodes
from docutils.parsers import rst
from sphinx import addnodes
-from sphinx.htmlwriter import HTMLWriter, SmartyPantsHTMLTranslator
-from sphinx.latexwriter import LaTeXWriter, LaTeXTranslator
+from sphinx.util import texescape
+from sphinx.writers.html import HTMLWriter, SmartyPantsHTMLTranslator
+from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
def setup_module():
global app, settings, parser
+ texescape.init() # otherwise done by the latex builder
app = TestApp(cleanenv=True)
optparser = frontend.OptionParser(components=(rst.Parser, HTMLWriter, LaTeXWriter))
settings = optparser.get_default_values()
diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py
index 4c2d0f3e..976e2bee 100644
--- a/tests/test_quickstart.py
+++ b/tests/test_quickstart.py
@@ -70,6 +70,7 @@ def test_do_prompt():
assert d['k5'] == 'no'
raises(AssertionError, qs.do_prompt, d, 'k6', 'Q6', validator=qs.boolean)
+
@with_tempdir
def test_quickstart_defaults(tempdir):
answers = {
@@ -86,29 +87,31 @@ def test_quickstart_defaults(tempdir):
ns = {}
execfile(conffile, ns)
assert ns['extensions'] == []
- assert ns['templates_path'] == ['.templates']
+ assert ns['templates_path'] == ['_templates']
assert ns['source_suffix'] == '.rst'
assert ns['master_doc'] == 'index'
assert ns['project'] == 'Sphinx Test'
assert ns['copyright'] == '%s, Georg Brandl' % time.strftime('%Y')
assert ns['version'] == '0.1'
assert ns['release'] == '0.1'
- assert ns['html_static_path'] == ['.static']
+ assert ns['html_static_path'] == ['_static']
assert ns['latex_documents'] == [
('index', 'SphinxTest.tex', 'Sphinx Test Documentation',
'Georg Brandl', 'manual')]
- assert (tempdir / '.static').isdir()
- assert (tempdir / '.templates').isdir()
+ assert (tempdir / '_static').isdir()
+ assert (tempdir / '_templates').isdir()
assert (tempdir / 'index.rst').isfile()
assert (tempdir / 'Makefile').isfile()
+ assert (tempdir / 'make.bat').isfile()
+
@with_tempdir
def test_quickstart_all_answers(tempdir):
answers = {
'Root path': tempdir,
'Separate source and build': 'y',
- 'Name prefix for templates': '_',
+ 'Name prefix for templates': '.',
'Project name': 'STASI\xe2\x84\xa2',
'Author name': 'Wolfgang Sch\xc3\xa4uble & G. Beckstein',
'Project version': '2.0',
@@ -119,6 +122,7 @@ def test_quickstart_all_answers(tempdir):
'doctest': 'yes',
'intersphinx': 'no',
'Create Makefile': 'no',
+ 'Create Windows command file': 'no',
}
qs.raw_input = mock_raw_input(answers, needanswer=True)
qs.TERM_ENCODING = 'utf-8'
@@ -129,7 +133,7 @@ def test_quickstart_all_answers(tempdir):
ns = {}
execfile(conffile, ns)
assert ns['extensions'] == ['sphinx.ext.autodoc', 'sphinx.ext.doctest']
- assert ns['templates_path'] == ['_templates']
+ assert ns['templates_path'] == ['.templates']
assert ns['source_suffix'] == '.txt'
assert ns['master_doc'] == 'contents'
assert ns['project'] == u'STASI™'
@@ -137,12 +141,12 @@ def test_quickstart_all_answers(tempdir):
time.strftime('%Y')
assert ns['version'] == '2.0'
assert ns['release'] == '2.0.1'
- assert ns['html_static_path'] == ['_static']
+ assert ns['html_static_path'] == ['.static']
assert ns['latex_documents'] == [
('contents', 'STASI.tex', u'STASI™ Documentation',
ur'Wolfgang Schäuble \& G. Beckstein', 'manual')]
assert (tempdir / 'build').isdir()
- assert (tempdir / 'source' / '_static').isdir()
- assert (tempdir / 'source' / '_templates').isdir()
+ assert (tempdir / 'source' / '.static').isdir()
+ assert (tempdir / 'source' / '.templates').isdir()
assert (tempdir / 'source' / 'contents.txt').isfile()
diff --git a/tests/util.py b/tests/util.py
index 2cd2c031..03363af9 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -19,7 +19,7 @@ except ImportError:
# functools is new in 2.4
wraps = lambda f: (lambda w: w)
-from sphinx import application, builder
+from sphinx import application
from path import path