merge with autosummary branch

This commit is contained in:
Georg Brandl 2009-03-14 21:14:48 +01:00
commit 2c1d0a62fb
231 changed files with 24728 additions and 7181 deletions

View File

@ -1,6 +1,10 @@
.*\.pyc
.*\.egg
.*\.so
build/
dist/
tests/.coverage
sphinx/pycode/Grammar.*pickle
Sphinx.egg-info/
doc/_build/
TAGS

33
AUTHORS
View File

@ -1,8 +1,31 @@
The doctools are written and maintained by Georg Brandl <georg@python.org>.
Substantial parts of the templates and the web application were written by
Armin Ronacher <armin.ronacher@active-4.com>.
Sphinx is written and maintained by Georg Brandl <georg@python.org>.
Other contributors are noted in the :copyright: fields within the docstrings
of the respective files.
Substantial parts of the templates were written by Armin Ronacher
<armin.ronacher@active-4.com>.
Other contributors, listed alphabetically, are:
* Daniel Bültmann -- todo extension
* Michael Droettboom -- inheritance_diagram extension
* Charles Duffy -- original graphviz extension
* Josip Dzolonga -- coverage builder
* Horst Gutmann -- internationalization support
* Martin Hans -- autodoc improvements
* Dave Kuhlman -- original LaTeX writer
* Thomas Lamb -- linkcheck builder
* Will Maier -- directory HTML builder
* Benjamin Peterson -- unittests
* Stefan Seefeld -- toctree improvements
* Antonio Valentino -- qthelp builder
* Pauli Virtanen -- autodoc improvements
* Sebastian Wiesner -- image handling, distutils support
Many thanks for all contributions!
There are also a few modules or functions incorporated from other
authors and projects:
* sphinx.util.jsdump uses the basestring encoding from simplejson,
written by Bob Ippolito, released under the MIT license
* sphinx.util.stemmer was written by Vivake Gupta, placed in the
Public Domain

330
CHANGES
View File

@ -1,9 +1,292 @@
Release 0.5 (in development)
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 "document" div tag has been moved out of the ``layout.html``
template's "document" block, because the closing tag was already
outside. If you overwrite this block, you need to remove your
"document" div tag as well.
- 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
* Theming support, see the new section in the documentation.
* 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.
- Added an ``only`` directive that can selectively include text
based on enabled "tags". Tags can be given on the command
line. Also, the current builder output format (e.g. "html" or
"latex") is always a defined tag.
- #10: Added HTML section numbers, enabled by giving a
``:numbered:`` flag to the ``toctree`` directive.
- #114: Added an ``abbr`` role to markup abbreviations and
acronyms.
- 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.
- Paths to images, literal include files and download files
can now be absolute (like ``/images/foo.png``). They are
treated as relative to the top source directory.
- #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``.
- Scaled images now get a link to the unscaled version.
- SVG images are now supported in HTML (via ``<object>`` and
``<embed>`` tags).
- Added a ``toctree`` callable to the templates, and the ability
to include external links in toctrees. The 'collapse' keyword
argument indicates whether or not to only display subitems of
the current page. (Defaults to True.)
* Configuration:
- The new config value ``rst_epilog`` can contain reST that is
appended to each source file that is read. This is the right
place for global substitutions.
- 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.
- The new ``modindex_common_prefix`` config value can be used to
ignore certain package names for module index sorting.
- The new ``trim_footnote_reference_space`` config value mirrors
the docutils config value of the same name and removes the
space before a footnote reference that is necessary for reST
to recognize the reference.
- The new ``latex_additional_files`` config value can be used to
copy files (that Sphinx doesn't copy automatically, e.g. if they
are referenced in custom LaTeX added in ``latex_elements``) to
the build directory.
* Builders:
- The HTML builder now stores a small file named ``.buildinfo`` in
its output directory. It stores a hash of config values that
can be used to determine if a full rebuild needs to be done (e.g.
after changing ``html_theme``).
- New builder for Qt help collections, by Antonio Valentino.
- The new ``DirectoryHTMLBuilder`` (short name ``dirhtml``) creates
a separate directory for every page, and places the page there
in a file called ``index.html``. Therefore, page URLs and links
don't need to contain ``.html``.
- The new ``html_link_suffix`` config value can be used to select
the suffix of generated links between HTML files.
- #96: The LaTeX builder now supports figures wrapped by text, when
using the ``figwidth`` option and right/left alignment.
* New translations:
- Italian by Sandro Dentella.
- Ukrainian by Petro Sasnyk.
- Finnish by Jukka Inkeri.
* Extensions and API:
- New ``graphviz`` extension to embed graphviz graphs.
- New ``inheritance_diagram`` extension to embed... inheritance
diagrams!
- Autodoc now has a reusable Python API, which can be used to
create custom types of objects to auto-document (e.g. Zope
interfaces). See also ``Sphinx.add_autodocumenter()``.
- Autodoc now handles documented attributes.
- Autodoc now handles inner classes and their methods.
- Autodoc can document classes as functions now if explicitly
marked with `autofunction`.
- Autodoc can now order members either alphabetically (like
previously) or by member type; configurable either with the
config value ``autodoc_member_order`` or a ``member-order``
option per directive.
- The function ``Sphinx.add_directive()`` now also supports
docutils 0.5-style directive classes. If they inherit from
``sphinx.util.compat.Directive``, they also work with
docutils 0.4.
- There is now a ``Sphinx.add_lexer()`` method to be able to use
custom Pygments lexers easily.
- There is now ``Sphinx.add_generic_role()`` to mirror the
docutils' own function.
* 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.
- #62: There is now a ``-w`` option for sphinx-build that writes
warnings to a file, in addition to stderr.
- There is now a ``-W`` option for sphinx-build that turns warnings
into errors.
Release 0.5.2 (in development)
==============================
* Properly escape ``|`` in LaTeX output.
* #71: If a decoding error occurs in source files, print a
warning and replace the characters by "?".
* Fix a problem in the HTML search if the index takes too long
to load.
* Don't output system messages while resolving, because they
would stay in the doctrees even if keep_warnings is false.
* #82: Determine the correct path for dependencies noted by
docutils. This fixes behavior where a source with dependent
files was always reported as changed.
* Recognize toctree directives that are not on section toplevel,
but within block items, such as tables.
* Use a new RFC base URL, since rfc.org seems down.
* Fix a crash in the todolist directive when no todo items are
defined.
* Don't call LaTeX or dvipng over and over again if it was not
found once, and use text-only latex as a substitute in that case.
* Fix problems with footnotes in the LaTeX output.
* Prevent double hyphens becoming en-dashes in literal code in
the LaTeX output.
* Open literalinclude files in universal newline mode to allow
arbitrary newline conventions.
* Actually make the ``-Q`` option work.
* #86: Fix explicit document titles in toctrees.
* #81: Write environment and search index in a manner that is safe
from exceptions that occur during dumping.
* #80: Fix UnicodeErrors when a locale is set with setlocale().
Release 0.5.1 (Dec 15, 2008)
============================
* #67: Output warnings about failed doctests in the doctest extension
even when running in quiet mode.
* #72: In pngmath, make it possible to give a full path to LaTeX and
dvipng on Windows. For that to work, the ``pngmath_latex`` and
``pngmath_dvipng`` options are no longer split into command and
additional arguments; use ``pngmath_latex_args`` and
``pngmath_dvipng_args`` to give additional arguments.
* Don't crash on failing doctests with non-ASCII characters.
* Don't crash on writing status messages and warnings containing
unencodable characters.
* Warn if a doctest extension block doesn't contain any code.
* Fix the handling of ``:param:`` and ``:type:`` doc fields when
they contain markup (especially cross-referencing roles).
* #65: Fix storage of depth information for PNGs generated by the
pngmath extension.
* Fix autodoc crash when automethod is used outside a class context.
* #68: Fix LaTeX writer output for images with specified height.
* #60: Fix wrong generated image path when including images in sources
in subdirectories.
* Fix the JavaScript search when html_copy_source is off.
* Fix an indentation problem in autodoc when documenting classes
with the option ``autoclass_content = "both"`` set.
* Don't crash on empty index entries, only emit a warning.
* Fix a typo in the search JavaScript code, leading to unusable
search function in some setups.
Release 0.5 (Nov 23, 2008) -- Birthday release!
===============================================
New features added
------------------
* Markup features:
- Citations are now global: all citation defined in any file can be
@ -31,6 +314,9 @@ New features added
- The ``seealso`` directive can now also be given arguments, as a short
form.
- You can now document several programs and their options with the
new ``program`` directive.
* HTML output and templates:
- Incompatible change: The "root" relation link (top left in the
@ -42,6 +328,12 @@ New features added
- The JavaScript search now searches for objects before searching in
the full text.
- TOC tree entries now have CSS classes that make it possible to
style them depending on their depth.
- Highlighted code blocks now have CSS classes that make it possible
to style them depending on their language.
- HTML ``<meta>`` tags via the docutils ``meta`` directive are now
supported.
@ -76,6 +368,10 @@ New features added
* Michał Kandulski -- Polish
* Yasushi Masuda -- Japanese
* Guillem Borrell -- Spanish
* Luc Saffre and Peter Bertels -- Dutch
* Fred Lin -- Traditional Chinese
* Roger Demetrescu -- Brazilian Portuguese
* Rok Garbas -- Slovenian
- The new config value ``highlight_language`` set a global default for
highlighting. When ``'python3'`` is selected, console output blocks
@ -100,6 +396,10 @@ New features added
creates links to Sphinx documentation of Python objects in other
projects.
- The new extension ``sphinx.ext.todo`` allows the insertion of
"To do" directives whose visibility in the output can be toggled.
It also adds a directive to compile a list of all todo items.
- sphinx.ext.autodoc has a new event ``autodoc-process-signature``
that allows tuning function signature introspection.
@ -121,7 +421,7 @@ New features added
default HTML template.
- Added new events: ``source-read``, ``env-updated``,
``missing-reference``, ``build-finished``.
``env-purge-doc``, ``missing-reference``, ``build-finished``.
* Other changes:
@ -130,6 +430,9 @@ New features added
- Added a command-line switch ``-A``: it can be used to supply
additional values into the HTML templates.
- Added a command-line switch ``-C``: if it is given, no configuration
file ``conf.py`` is required.
- Added a distutils command `build_sphinx`: When Sphinx is installed,
you can call ``python setup.py build_sphinx`` for projects that have
Sphinx documentation, which will build the docs and place them in
@ -141,16 +444,33 @@ New features added
Bugs fixed
----------
* Support option lists in the text writer. Make sure that dashes
* #51: Escape configuration values placed in HTML templates.
* #44: Fix small problems in HTML help index generation.
* Fix LaTeX output for line blocks in tables.
* #38: Fix "illegal unit" error when using pixel image widths/heights.
* Support table captions in LaTeX output.
* #39: Work around a bug in Jinja that caused "<generator ...>" to be
emitted in HTML output.
* Fix a problem with module links not being generated in LaTeX output.
* Fix the handling of images in different directories.
* #29: Support option lists in the text writer. Make sure that dashes
introducing long option names are not contracted to en-dashes.
* Support the "scale" option for images in HTML output.
* Properly escape quotes in HTML help attribute values.
* #25: Properly escape quotes in HTML help attribute values.
* Fix LaTeX build for some description environments with ``:noindex:``.
* Don't crash on weird casing of role names (like ``:Class:``).
* #24: Don't crash on uncommon casing of role names (like ``:Class:``).
* Only output ANSI colors on color terminals.

View File

@ -1,37 +1,71 @@
Projects using Sphinx
=====================
This is an (incomplete) list of projects that use Sphinx or are
experimenting with using it for their documentation. If you like
to be included, please mail to `the Google group
This is an (incomplete) alphabetic list of projects that use Sphinx or are
experimenting with using it for their documentation. If you like to be
included, please mail to `the Google group
<http://groups.google.com/group/sphinx-dev>`_.
* Sphinx: http://sphinx.pocoo.org/
* Python: http://docs.python.org/dev/
* NumPy: http://mentat.za.net/numpy/refguide/
* Matplotlib: http://matplotlib.sourceforge.net/
* Pylons: http://docs.pylonshq.com/
* Django: http://docs.djangoproject.com/
* Grok: http://grok.zope.org/doc/current/
* TurboGears: http://turbogears.org/2.0/docs/
* Jinja: http://jinja.pocoo.org/2/documentation/
* Cython: http://docs.cython.org/
* F2py: http://www.f2py.org/html/
* zc.async: http://packages.python.org/zc.async/1.5.0/
* Mayavi: http://code.enthought.com/projects/mayavi/docs/development/html/mayavi
* Chaco: http://code.enthought.com/projects/chaco/docs/html/
* Paver: http://www.blueskyonmars.com/projects/paver/
* Satchmo: http://www.satchmoproject.com/docs/svn/
* PyEphem: http://rhodesmill.org/pyephem/
* Paste: http://pythonpaste.org/script/
* Director: http://packages.python.org/director/
* APSW: http://apsw.googlecode.com/svn/publish/index.html
* boostmpi: http://documen.tician.de/boostmpi/
* Calibre: http://calibre.kovidgoyal.net/user_manual/
* PyUblas: http://tiker.net/doc/pyublas/
* Py on Windows: http://timgolden.me.uk/python-on-windows/
* mpmath: http://mpmath.googlecode.com/svn/trunk/doc/build/index.html
* Zope 3: e.g. http://docs.carduner.net/z3c-tutorial/
* Glashammer: http://glashammer.org/
* SymPy: http://docs.sympy.org/
* Chaco: http://code.enthought.com/projects/chaco/docs/html/
* CodePy: http://documen.tician.de/codepy/
* Cython: http://docs.cython.org/
* C\\C++ Python language binding project: http://language-binding.net/index.html
* Director: http://packages.python.org/director/
* Django: http://docs.djangoproject.com/
* F2py: http://www.f2py.org/html/
* GeoDjango: http://geodjango.org/docs/
* Glashammer: http://glashammer.org/
* Grok: http://grok.zope.org/doc/current/
* Hedge: http://documen.tician.de/hedge/
* 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
* MeshPy: http://documen.tician.de/meshpy/
* Mixin.com: http://dev.mixin.com/
* mpmath: http://mpmath.googlecode.com/svn/trunk/doc/build/index.html
* MyHDL: http://www.myhdl.org/doc/0.6/
* NetworkX: http://networkx.lanl.gov/
* NumPy: http://docs.scipy.org/doc/numpy/reference/
* ObjectListView: http://objectlistview.sourceforge.net/python
* OpenLayers: http://docs.openlayers.org/
* openWNS: http://docs.openwns.org/
* Paste: http://pythonpaste.org/script/
* Paver: http://www.blueskyonmars.com/projects/paver/
* Py on Windows: http://timgolden.me.uk/python-on-windows/
* PyCuda: http://documen.tician.de/pycuda/
* PyEphem: http://rhodesmill.org/pyephem/
* Pyevolve: http://pyevolve.sourceforge.net/
* PyLit: http://pylit.berlios.de/
* Pylo: http://documen.tician.de/pylo/
* Pylons: http://docs.pylonshq.com/
* PyMOTW: http://www.doughellmann.com/PyMOTW/
* PyPubSub: http://pubsub.sourceforge.net/
* pyrticle: http://documen.tician.de/pyrticle/
* Pysparse: http://pysparse.sourceforge.net/
* Python: http://docs.python.org/
* python-apt: http://people.debian.org/~jak/python-apt-doc/
* PyUblas: http://documen.tician.de/pyublas/
* Quex: http://quex.sourceforge.net/
* Reteisi: http://docs.argolinux.org/reteisi/
* Roundup: http://www.roundup-tracker.org/
* Satchmo: http://www.satchmoproject.com/docs/svn/
* Scapy: http://www.secdev.org/projects/scapy/doc/
* Self: http://selflanguage.org/
* SimPy: http://simpy.sourceforge.net/
* Sphinx: http://sphinx.pocoo.org/
* Sprox: http://sprox.org/
* SQLAlchemy: http://www.sqlalchemy.org/docs/
* Sqlkit: http://sqlkit.argolinux.org/
* SymPy: http://docs.sympy.org/
* tinyTiM: http://tinytim.sourceforge.net/docs/2.0/
* TurboGears: http://turbogears.org/2.0/docs/
* VOR: http://www.vor-cycling.be/
* WFront: http://discorporate.us/projects/WFront/
* WTForms: http://wtforms.simplecodes.com/docs/
* Zope 3: e.g. http://docs.carduner.net/z3c-tutorial/
* zc.async: http://packages.python.org/zc.async/1.5.0/

249
LICENSE
View File

@ -1,30 +1,219 @@
Copyright (c) 2007-2008 by the respective authors (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:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* The names of the contributors may not be used to endorse or
promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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:
----------------------------------------------------------------------
SmartyPants_ license::
Copyright (c) 2003 John Gruber
(http://daringfireball.net/)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name "SmartyPants" nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
This software is provided by the copyright holders and
contributors "as is" and any express or implied warranties,
including, but not limited to, the implied warranties of
merchantability and fitness for a particular purpose are
disclaimed. In no event shall the copyright owner or contributors
be liable for any direct, indirect, incidental, special,
exemplary, or consequential damages (including, but not limited
to, procurement of substitute goods or services; loss of use,
data, or profits; or business interruption) however caused and on
any theory of liability, whether in contract, strict liability, or
tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of
such damage.
smartypants.py license::
smartypants.py is a derivative work of SmartyPants.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
This software is provided by the copyright holders and
contributors "as is" and any express or implied warranties,
including, but not limited to, the implied warranties of
merchantability and fitness for a particular purpose are
disclaimed. In no event shall the copyright owner or contributors
be liable for any direct, indirect, incidental, special,
exemplary, or consequential damages (including, but not limited
to, procurement of substitute goods or services; loss of use,
data, or profits; or business interruption) however caused and on
any theory of liability, whether in contract, strict liability, or
tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of
such damage.
----------------------------------------------------------------------
The ElementTree package, included in this distribution in
test/etree13, is available under the following license:
----------------------------------------------------------------------
The ElementTree toolkit is
Copyright (c) 1999-2007 by Fredrik Lundh
By obtaining, using, and/or copying this software and/or its
associated documentation, you agree that you have read, understood,
and will comply with the following terms and conditions:
Permission to use, copy, modify, and distribute this software and its
associated documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies, and that both that copyright notice and this permission notice
appear in supporting documentation, and that the name of Secret Labs
AB or the author not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- ABILITY
AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
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.
----------------------------------------------------------------------

View File

@ -12,11 +12,11 @@ include sphinx-build.py
include sphinx-quickstart.py
recursive-include sphinx/texinputs *
recursive-include sphinx/templates *.html *.xml
recursive-include sphinx/static *
recursive-include sphinx/themes *
recursive-include sphinx/locale *
recursive-include tests *
recursive-include utils *
include sphinx/pycode/Grammar.txt
recursive-include doc *
prune doc/_build

View File

@ -7,7 +7,9 @@ export PYTHONPATH = $(shell echo "$$PYTHONPATH"):./sphinx
all: clean-pyc check test
check:
@$(PYTHON) utils/check_sources.py -i sphinx/style/jquery.js sphinx
@$(PYTHON) utils/check_sources.py -i sphinx/style/jquery.js \
-i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py \
-i doc/_build -i ez_setup.py -i tests/path.py .
clean: clean-pyc clean-patchfiles
@ -28,3 +30,6 @@ reindent:
test:
@cd tests; $(PYTHON) run.py -d -m '^[tT]est' $(TEST)
covertest:
@cd tests; $(PYTHON) run.py -d -m '^[tT]est' --with-coverage --cover-package=sphinx $(TEST)

8
README
View File

@ -1,3 +1,5 @@
.. -*- restructuredtext -*-
=================
README for Sphinx
=================
@ -17,9 +19,9 @@ Reading the docs
After installing::
cd doc
mkdir -p _build/html
sphinx-build . _build/html
browser _build/index.html
Then, direct your browser to ``_build/html/index.html``.
Or read them online at <http://sphinx.pocoo.org/>.
@ -27,4 +29,4 @@ Or read them online at <http://sphinx.pocoo.org/>.
Contributing
============
Send wishes, comments, patches, etc. to georg@python.org.
Send wishes, comments, patches, etc. to sphinx-dev@googlegroups.com.

View File

@ -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]

View File

@ -11,12 +11,13 @@ 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 dirhtml 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 " dirhtml to make HTML files called index.html in directories"
@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 +32,21 @@ html:
@echo
@echo "Build finished. The HTML pages are in _build/html."
dirhtml:
mkdir -p _build/dirhtml _build/doctrees
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml
@echo
@echo "Build finished. The HTML pages are in _build/dirhtml."
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 +55,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

View File

@ -3,17 +3,22 @@
{% block body %}
<h1>Welcome</h1>
<div class="quotebar">
<p>What users say:</p>
<p>&ldquo;Cheers for a great tool that actually makes programmers <b>want</b>
to write documentation!&rdquo;</p>
</div>
<p>
Sphinx is a tool that makes it easy to create intelligent and beautiful
documentation for Python projects, written by Georg Brandl and licensed
under the BSD license.</p>
documentation, written by Georg Brandl and licensed under the BSD license.</p>
<p>It was originally created to translate <a href="http://docs.python.org/dev/">the
new Python documentation</a>, but has now been cleaned up in the hope that
it will be useful to many other projects. (Of course, this site is also
created from reStructuredText sources using Sphinx!)
new Python documentation</a>, and it has excellent support for the documentation
of Python projects, but other documents can be written with it too. Of course,
this site is also created from reStructuredText sources using Sphinx!
</p>
<p>
Although it is still under constant development, the following features are
It is still under constant development, and the following features are
already present, work fine and can be seen &#8220;in action&#8221; in the
Python docs:
</p>
@ -76,5 +81,5 @@
</p>
<p>The code can be found in a Mercurial repository, at
<tt>http://bitbucket.org/birkenfeld/sphinx/</tt>.</p>
{% endblock %}

View File

@ -10,7 +10,7 @@
<p>Current version: <b>{{ version }}</b></p>
<p>Get Sphinx from the <a href="http://pypi.python.org/pypi/Sphinx">Python Package
Index</a>, or install it with:</p>
<pre>easy_install Sphinx</pre>
<pre>easy_install -U Sphinx</pre>
{% endif %}
<h3>Questions? Suggestions?</h3>
@ -23,4 +23,4 @@ Index</a>, or install it with:</p>
</form>
<p>or come to the <tt>#python-docs</tt> channel on FreeNode.</p>
<p>You can also open an issue at the
<a href="http://code.google.com/p/sphinx/issues/list">tracker</a>.</p>
<a href="http://www.bitbucket.org/birkenfeld/sphinx/issues/">tracker</a>.</p>

View File

@ -1,17 +1,12 @@
{% extends "!layout.html" %}
{% block rootrellink %}
<li><a href="{{ pathto('index') }}">Sphinx home </a> |&nbsp;</li>
<li><a href="{{ pathto('contents') }}">Documentation </a> &raquo;</li>
<li><a href="{{ pathto('index') }}">Sphinx home</a>&nbsp;|&nbsp;</li>
<li><a href="{{ pathto('contents') }}">Documentation</a>&raquo;</li>
{% endblock %}
{% block relbar1 %}
{% block header %}
<div style="background-color: white; text-align: left; padding: 10px 10px 15px 15px">
<img src="{{ pathto("_static/sphinx.png", 1) }}" alt="Sphinx logo" />
</div>
{{ super() }}
{% endblock %}
{# put the sidebar before the body #}
{% block sidebar1 %}{{ sidebar() }}{% endblock %}
{% block sidebar2 %}{% endblock %}

View File

@ -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
@ -22,13 +23,106 @@ The builder's "name" must be given to the **-b** command-line option of
Its name is ``html``.
.. class:: DirectoryHTMLBuilder
This is a subclass of the standard HTML builder. Its output is a directory
with HTML files, where each file is called ``index.html`` and placed in a
subdirectory named like its page name. For example, the document
``markup/rest.rst`` will not result in an output file ``markup/rest.html``,
but ``markup/rest/index.html``. When generating links between pages, the
``index.html`` is omitted, so that the URL would look like ``markup/rest/``.
Its name is ``dirhtml``.
.. versionadded:: 0.6
.. class:: HTMLHelpBuilder
This builder produces the same output as the standalone HTML builder, but
also generates HTML Help support files that allow the Microsoft HTML Help
Workshop to compile them into a CHM file.
Its name is ``htmlhelp``.
Its name is ``htmlhelp``.
.. module:: sphinx.builders.latex
.. class:: LaTeXBuilder
This builder produces a bunch of LaTeX files in the output directory. You
have to specify which documents are to be included in which LaTeX files via
the :confval:`latex_documents` configuration value. There are a few
configuration values that customize the output of this builder, see the
chapter :ref:`latex-options` for details.
.. note::
The produced LaTeX file uses several LaTeX packages that may not be
present in a "minimal" TeX distribution installation. For TeXLive,
the following packages need to be installed:
* latex-recommended
* latex-extra
* fonts-recommended
Its name is ``latex``.
.. module:: sphinx.builders.text
.. class:: TextBuilder
This builder produces a text file for each reST file -- this is almost the
same as the reST source, but with much of the markup stripped for better
readability.
Its name is ``text``.
.. versionadded:: 0.4
.. currentmodule:: sphinx.builders.html
.. class:: SerializingHTMLBuilder
This builder uses a module that implements the Python serialization API
(`pickle`, `simplejson`, `phpserialize`, and others) to dump the generated
HTML documentation. The pickle builder is a subclass of it.
A concreate subclass of this builder serializing to the `PHP serialization`_
format could look like this::
import phpserialize
class PHPSerializedBuilder(SerializingHTMLBuilder):
name = 'phpserialized'
implementation = phpserialize
out_suffix = '.file.phpdump'
globalcontext_filename = 'globalcontext.phpdump'
searchindex_filename = 'searchindex.phpdump'
.. _PHP serialization: http://pypi.python.org/pypi/phpserialize
.. attribute:: implementation
A module that implements `dump()`, `load()`, `dumps()` and `loads()`
functions that conform to the functions with the same names from the
pickle module. Known modules implementing this interface are
`simplejson` (or `json` in Python 2.6), `phpserialize`, `plistlib`,
and others.
.. attribute:: out_suffix
The suffix for all regular files.
.. attribute:: globalcontext_filename
The filename for the file that contains the "global context". This
is a dict with some general configuration values such as the name
of the project.
.. attribute:: searchindex_filename
The filename for the search index Sphinx generates.
See :ref:`serialization-details` for details about the output format.
.. versionadded:: 0.5
.. class:: PickleHTMLBuilder
@ -58,73 +152,7 @@ The builder's "name" must be given to the **-b** command-line option of
.. versionadded:: 0.5
.. class:: LaTeXBuilder
This builder produces a bunch of LaTeX files in the output directory. You
have to specify which documents are to be included in which LaTeX files via
the :confval:`latex_documents` configuration value. There are a few
configuration values that customize the output of this builder, see the
chapter :ref:`latex-options` for details.
Its name is ``latex``.
.. class:: TextBuilder
This builder produces a text file for each reST file -- this is almost the
same as the reST source, but with much of the markup stripped for better
readability.
Its name is ``text``.
.. versionadded:: 0.4
.. class:: SerializingHTMLBuilder
This builder uses a module that implements the Python serialization API
(`pickle`, `simplejson`, `phpserialize`, and others) to dump the generated
HTML documentation. The pickle builder is a subclass of it.
A concreate subclass of this builder serializing to the `PHP serialization`_
format could look like this::
import phpserialize
class PHPSerializedBuilder(SerializingHTMLBuilder):
name = 'phpserialized'
implementation = phpserialize
out_suffix = '.file.phpdump'
globalcontext_filename = 'globalcontext.phpdump'
searchindex_filename = 'searchindex.phpdump'
.. _PHP serialization: http://pypi.python.org/pypi/phpserialize
.. attribute:: implementation
A module that implements `dump()`, `load()`, `dumps()` and `loads()`
functions that conform to the functions with the same names from the
pickle module. Known modules implementing this interface are
`simplejson` (or `json` in Python 2.6), `phpserialize`, `plistlib`,
and others.
.. attribute:: out_suffix
The suffix for all regular files.
.. attribute:: globalcontext_filename
The filename for the file that contains the "global context". This
is a dict with some general configuration values such as the name
of the project.
.. attribute:: searchindex_filename
The filename for the search index Sphinx generates.
See :ref:`serialization-details` for details about the output format.
.. versionadded:: 0.5
.. module:: sphinx.builders.changes
.. class:: ChangesBuilder
This builder produces an HTML overview of all :dir:`versionadded`,
@ -134,6 +162,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

View File

@ -16,6 +16,9 @@ directory`, the extension is stripped, and path separators are converted to
slashes. All values, parameters and suchlike referring to "documents" expect
such a document name.
Examples for document names are ``index``, ``library/zipfile``, or
``reference/datamodel/types``. Note that there is no leading slash.
The TOC tree
------------
@ -55,22 +58,37 @@ tables of contents. The ``toctree`` directive is the central element.
``strings`` and so forth, and it knows that they are children of the shown
document, the library index. From this information it generates "next
chapter", "previous chapter" and "parent chapter" links.
Document titles in the :dir:`toctree` will be automatically read from the
title of the referenced document. If that isn't what you want, you can give
the specify an explicit title and target using a similar syntax to reST
title of the referenced document. If that isn't what you want, you can
specify an explicit title and target using a similar syntax to reST
hyperlinks (and Sphinx's :ref:`cross-referencing syntax <xref-syntax>`). This
looks like::
.. toctree::
intro
All about strings <strings>
datatypes
The second line above will link to the ``strings`` document, but will use the
title "All about strings" instead of the title of the ``strings`` document.
You can also add external links, by giving an HTTP URL instead of a document
name.
If you want to have section numbers even in HTML output, give the toctree a
``numbered`` flag option. For example::
.. toctree::
:numbered:
foo
bar
Numbering then starts at the heading of ``foo``. Sub-toctrees are
automatically numbered (don't give the ``numbered`` flag to those).
You can use "globbing" in toctree directives, by giving the ``glob`` flag
option. All entries are then matched against the list of available
documents, and matches are inserted into the list alphabetically. Example::
@ -85,7 +103,24 @@ 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.) [#]_
The special entry name ``self`` stands for the document containing the
toctree directive. This is useful if you want to generate a "sitemap" from
the toctree.
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, or in the HTML
sidebar.
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
finds a file that is not included, because that means that this file will not
@ -100,6 +135,10 @@ tables of contents. The ``toctree`` directive is the central element.
.. versionchanged:: 0.3
Added "globbing" option.
.. versionchanged:: 0.6
Added "numbered" and "hidden" options as well as external links and
support for "self" references.
Special names
-------------

View File

@ -1,27 +1,12 @@
# -*- coding: utf-8 -*-
#
# Sphinx documentation build configuration file, created by
# sphinx-quickstart.py on Sat Mar 8 21:47:50 2008.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# The contents of this file are pickled, so don't put values in the namespace
# that aren't pickleable (module imports are okay, they're removed automatically).
#
# All configuration values have a default value; values that are commented out
# serve to show the default value.
# Sphinx documentation build configuration file
import sys, os, re
# If your extensions are in another directory, add it here.
#sys.path.append(os.path.dirname(__file__))
# General configuration
# ---------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest']
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@ -34,46 +19,22 @@ 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.
#
# The short X.Y version.
import sphinx
version = sphinx.__released__
# The full version, including alpha/beta/rc tags.
release = version
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# Show author directives in the output.
show_authors = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'friendly'
# The HTML template theme.
html_theme = 'sphinxdoc'
# Options for HTML output
# -----------------------
# The style sheet to use for HTML and HTML Help pages. A file of that name
# must exist either in Sphinx' static/ path, or in one of the custom paths
# given in html_static_path.
html_style = 'sphinxdoc.css'
# A list of ignored prefixes names for module index sorting.
modindex_common_prefix = ['sphinx.']
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
@ -84,10 +45,6 @@ html_static_path = ['_static']
# using the given strftime format.
html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Content template for the index page.
html_index = 'index.html'
@ -98,44 +55,30 @@ html_sidebars = {'index': 'indexsidebar.html'}
# templates.
html_additional_pages = {'index': 'index.html'}
# If true, the reST sources are included in the HTML build as _sources/<name>.
#html_copy_source = True
# Generate an OpenSearch description with that URL as the base.
html_use_opensearch = 'http://sphinx.pocoo.org'
# Output file base name for HTML help builder.
htmlhelp_basename = 'Sphinxdoc'
# Options for LaTeX output
# ------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation',
'Georg Brandl', 'manual', 1)]
# Add our logo to the LaTeX file.
latex_logo = '_static/sphinx.png'
#latex_use_parts = True
# Additional stuff for the LaTeX preamble.
latex_elements = {
'fontpkg': '\\usepackage{palatino}'
}
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# Put TODOs into the output.
todo_include_todos = True
# Extension interface
# -------------------
# -- Extension interface -------------------------------------------------------
from sphinx import addnodes
@ -182,7 +125,9 @@ def parse_event(env, sig, signode):
def setup(app):
from sphinx.ext.autodoc import cut_lines
app.connect('autodoc-process-docstring', cut_lines(4, what=['module']))
app.add_description_unit('directive', 'dir', 'pair: %s; directive', parse_directive)
app.add_description_unit('directive', 'dir', 'pair: %s; directive',
parse_directive)
app.add_description_unit('role', 'role', 'pair: %s; role', parse_role)
app.add_description_unit('confval', 'confval', 'pair: %s; configuration value')
app.add_description_unit('confval', 'confval',
'pair: %s; configuration value')
app.add_description_unit('event', 'event', 'pair: %s; event', parse_event)

View File

@ -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.
@ -38,6 +38,11 @@ Important points to note:
delete them from the namespace with ``del`` if appropriate. Modules are
removed automatically, so you don't need to ``del`` your imports after use.
* There is a special object named ``tags`` available in the config file.
It can be used to query and change the tags (see :ref:`tags`). Use
``tags.has('tag')`` to query, ``tags.add('tag')`` and ``tags.remove('tag')``
to change.
General configuration
---------------------
@ -45,7 +50,7 @@ General configuration
.. confval:: extensions
A list of strings that are module names of Sphinx extensions. These can be
extensions coming with Sphinx (named ``sphinx.addons.*``) or custom ones.
extensions coming with Sphinx (named ``sphinx.ext.*``) or custom ones.
Note that you can extend :data:`sys.path` within the conf file if your
extensions live in another directory -- but make sure you use absolute paths.
@ -76,7 +81,7 @@ General configuration
.. versionadded:: 0.5
Previously, Sphinx accepted only UTF-8 encoded sources.
.. confval:: master_doc
The document name of the "master" document, that is, the document that
@ -131,18 +136,35 @@ General configuration
.. confval:: templates_path
A list of paths that contain extra templates (or templates that overwrite
builtin templates). Relative paths are taken as relative to the
configuration directory.
builtin/theme-specific templates). Relative paths are taken as relative to
the configuration directory.
.. confval:: template_bridge
A string with the fully-qualified name of a callable (or simply a class) that
returns an instance of :class:`~sphinx.application.TemplateBridge`. This
instance is then used to render HTML documents, and possibly the output of
other builders (currently the changes builder).
other builders (currently the changes builder). (Note that the template
bridge must be made theme-aware if HTML themes are to be used.)
.. confval:: rst_epilog
.. index:: pair: global; substitutions
A string of reStructuredText that will be included at the end of every source
file that is read. This is the right place to add substitutions that should
be available in every file. An example::
rst_epilog = """
.. |psf| replace:: Python Software Foundation
"""
.. versionadded:: 0.6
.. confval:: default_role
.. index:: default; role
The name of a reST role (builtin or Sphinx extension) to use as the default
role, that is, for text marked up ```like this```. This can be set to
``'obj'`` to make ```filter``` a cross-reference to the function "filter".
@ -164,9 +186,19 @@ General configuration
.. versionadded:: 0.5
.. confval:: modindex_common_prefix
A list of prefixes that are ignored for sorting the module index (e.g.,
if this is set to ``['foo.']``, then ``foo.bar`` is shown under ``B``, not
``F``). This can be handy if you document a project that consists of a single
package. Works only for the HTML builder currently. Default is ``[]``.
.. versionadded:: 0.6
Project information
-------------------
.. confval:: project
The documented project's name.
@ -203,8 +235,16 @@ Project information
* ``cs`` -- Czech
* ``de`` -- German
* ``en`` -- English
* ``es`` -- Spanish
* ``fi`` -- Finnish
* ``fr`` -- French
* ``it`` -- Italian
* ``nl`` -- Dutch
* ``pl`` -- Polish
* ``pt_BR`` -- Brazilian Portuguese
* ``sl`` -- Slovenian
* ``uk_UA`` -- Ukrainian
* ``zh_TW`` -- Traditional Chinese
.. confval:: today
today_fmt
@ -227,7 +267,7 @@ Project information
:ref:`code-examples` for more details.
.. versionadded:: 0.5
.. confval:: pygments_style
The style name to use for Pygments highlighting of source code. Default is
@ -255,6 +295,13 @@ Project information
A boolean that decides whether :dir:`moduleauthor` and :dir:`sectionauthor`
directives produce any output in the built files.
.. confval:: trim_footnote_reference_space
Trim spaces before footnote references that are necessary for the reST parser
to recognize the footnote, but do not look too nice in the output.
.. versionadded:: 0.6
.. _html-options:
@ -264,6 +311,37 @@ Options for HTML output
These options influence HTML as well as HTML Help output, and other builders
that use Sphinx' HTMLWriter class.
.. confval:: html_theme
The "theme" that the HTML output should use. See the :doc:`section about
theming <theming>`. The default is ``'default'``.
.. versionadded:: 0.6
.. confval:: html_theme_options
A dictionary of options that influence the look and feel of the selected
theme. These are theme-specific. For the options understood by the builtin
themes, see :ref:`this section <builtin-themes>`.
.. versionadded:: 0.6
.. confval:: html_theme_path
A list of paths that contain custom themes, either as subdirectories or as
zip files. Relative paths are taken as relative to the configuration
directory.
.. versionadded:: 0.6
.. confval:: html_style
The style sheet to use for HTML pages. A file of that name must exist either
in Sphinx' :file:`static/` path, or in one of the custom paths given in
:confval:`html_static_path`. Default is the stylesheet given by the selected
theme. If you only want to add or override a few things compared to the
theme's stylesheet, use CSS ``@import`` to import the theme's stylesheet.
.. confval:: html_title
The "title" for HTML documentation generated with Sphinx' own templates.
@ -280,12 +358,6 @@ that use Sphinx' HTMLWriter class.
.. versionadded:: 0.4
.. confval:: html_style
The style sheet to use for HTML pages. A file of that name must exist either
in Sphinx' :file:`static/` path, or in one of the custom paths given in
:confval:`html_static_path`. Default is ``'default.css'``.
.. confval:: html_logo
If given, this must be the name of an image file that is the logo of the
@ -309,8 +381,8 @@ that use Sphinx' HTMLWriter class.
A list of paths that contain custom static files (such as style sheets or
script files). Relative paths are taken as relative to the configuration
directory. They are copied to the output directory after the builtin static
files, so a file named :file:`default.css` will overwrite the builtin
directory. They are copied to the output directory after the theme's static
files, so a file named :file:`default.css` will overwrite the theme's
:file:`default.css`.
.. versionchanged:: 0.4
@ -327,6 +399,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
@ -388,6 +469,19 @@ that use Sphinx' HTMLWriter class.
If true, the reST sources are included in the HTML build as
:file:`_sources/{name}`. The default is ``True``.
.. warning::
If this config value is set to ``False``, the JavaScript search function
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
@ -404,10 +498,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).
@ -491,7 +593,7 @@ These options influence LaTeX output.
avoid interpretation as escape sequences.
* Keys that you may want to override include:
``'papersize'``
Paper size option of the document class (``'a4paper'`` or
``'letterpaper'``), default ``'letterpaper'``.
@ -515,9 +617,9 @@ These options influence LaTeX output.
Additional preamble content, default empty.
``'footer'```
Additional footer content (before the indices), default empty.
* Keys that don't need be overridden unless in special cases are:
``'inputenc'``
"inputenc" package inclusion, default
``'\\usepackage[utf8]{inputenc}'``.
@ -534,9 +636,9 @@ These options influence LaTeX output.
"printindex" call, the last thing in the file, default
``'\\printindex'``. Override if you want to generate the index
differently or append some content after the index.
* Keys that are set by other options and therefore should not be overridden are:
``'docclass'``
``'classoptions'``
``'title'``
@ -549,7 +651,20 @@ These options influence LaTeX output.
``'makemodindex'``
``'shorthandoff'``
``'printmodindex'``
.. confval:: latex_additional_files
A list of file names, relative to the configuration directory, to copy to the
build directory when building LaTeX output. This is useful to copy files
that Sphinx doesn't copy automatically, e.g. if they are referenced in custom
LaTeX added in ``latex_elements``. Image files that are referenced in source
files (e.g. via ``.. image::``) are copied automatically.
You have to make sure yourself that the filenames don't collide with those of
any automatically copied files.
.. versionadded:: 0.6
.. confval:: latex_preamble
Additional LaTeX markup for the preamble.

View File

@ -12,9 +12,11 @@ Sphinx documentation contents
markup/index
builders
config
theming
templating
extensions
faq
glossary
changes
examples

View File

@ -13,22 +13,31 @@ 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)
.. method:: Sphinx.add_config_value(name, default, rebuild)
Register a configuration value. This is necessary for Sphinx to recognize
new values and set default values accordingly. The *name* should be prefixed
with the extension name, to avoid clashes. The *default* value can be any
Python object. The boolean value *rebuild_env* must be ``True`` if a change
in the setting only takes effect when a document is parsed -- this means that
the whole environment must be rebuilt.
Python object. The string value *rebuild* must be one of those values:
* ``'env'`` if a change in the setting only takes effect when a document is
parsed -- this means that the whole environment must be rebuilt.
* ``'html'`` if a change in the setting needs a full rebuild of HTML
documents.
* ``''`` if a change in the setting will not need any special rebuild.
.. versionchanged:: 0.4
If the *default* value is a callable, it will be called with the config
object as its argument in order to get the default value. This can be
used to implement config values whose default depends on other values.
.. versionchanged:: 0.6
Changed *rebuild* from a simple boolean (equivalent to ``''`` or
``'env'``) to a string. However, booleans are still accepted and
converted internally.
.. method:: Sphinx.add_event(name)
Register an event called *name*.
@ -45,12 +54,12 @@ the following public API:
:exc:`docutils.nodes.SkipNode`. Example::
class math(docutils.nodes.Element)
def visit_math_html(self, node):
self.body.append(self.starttag(node, 'math'))
def depart_math_html(self, node):
self.body.append('</math>')
app.add_node(math, html=(visit_math_html, depart_math_html))
Obviously, translators for which you don't specify visitor methods will choke
@ -59,16 +68,42 @@ the following public API:
.. versionchanged:: 0.5
Added the support for keyword arguments giving visit functions.
.. method:: Sphinx.add_directive(name, cls, content, arguments, **options)
.. method:: Sphinx.add_directive(name, func, content, arguments, **options)
Sphinx.add_directive(name, directiveclass)
Register a Docutils directive. *name* must be the prospective directive
name, *func* the directive function for details about the signature and
return value. *content*, *arguments* and *options* are set as attributes on
the function and determine whether the directive has content, arguments and
options, respectively. For their exact meaning, please consult the Docutils
documentation.
name. There are two possible ways to write a directive:
.. XXX once we target docutils 0.5, update this
* In the docutils 0.4 style, *func* is the directive function. *content*,
*arguments* and *options* are set as attributes on the function and
determine whether the directive has content, arguments and options,
respectively.
* In the docutils 0.5 style, *directiveclass* is the directive class. It
must already have attributes named *has_content*, *required_arguments*,
*optional_arguments*, *final_argument_whitespace* and *option_spec* that
correspond to the options for the function way. See `the Docutils docs
<http://docutils.sourceforge.net/docs/howto/rst-directives.html>`_ for
details.
The directive class normally must inherit from the class
``docutils.parsers.rst.Directive``. When writing a directive for usage in
a Sphinx extension, you inherit from ``sphinx.util.compat.Directive``
instead which does the right thing even on docutils 0.4 (which doesn't
support directive classes otherwise).
For example, the (already existing) :dir:`literalinclude` directive would be
added like this::
from docutils.parsers.rst import directives
add_directive('literalinclude', literalinclude_directive,
content = 0, arguments = (1, 0, 0),
linenos = directives.flag,
language = direcitves.unchanged,
encoding = directives.encoding)
.. versionchanged:: 0.6
Docutils 0.5-style directive classes are now supported.
.. method:: Sphinx.add_role(name, role)
@ -76,6 +111,13 @@ the following public API:
source, *role* the role function (see the `Docutils documentation
<http://docutils.sourceforge.net/docs/howto/rst-roles.html>`_ on details).
.. method:: Sphinx.add_generic_role(name, nodeclass)
Register a Docutils role that does nothing but wrap its contents in the
node given by *nodeclass*.
.. versionadded:: 0.6
.. method:: Sphinx.add_description_unit(directivename, rolename, indextemplate='', parse_node=None, ref_nodeclass=None)
This method is a very convenient way to add a new type of information that
@ -157,7 +199,32 @@ 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.add_autodocumenter(cls)
Add *cls* as a new documenter class for the :mod:`sphinx.ext.autodoc`
extension. It must be a subclass of :class:`sphinx.ext.autodoc.Documenter`.
This allows to auto-document new types of objects. See the source of the
autodoc module for examples on how to subclass :class:`Documenter`.
.. versionadded:: 0.6
.. method:: Sphinx.add_autodoc_attrgetter(type, getter)
Add *getter*, which must be a function with an interface compatible to the
:func:`getattr` builtin, as the autodoc attribute getter for objects that are
instances of *type*. All cases where autodoc needs to get an attribute of a
type are then handled by this function instead of :func:`getattr`.
.. versionadded:: 0.6
.. method:: Sphinx.connect(event, callback)
Register *callback* to be called when *event* is emitted. For details on
@ -208,14 +275,31 @@ registered event handlers.
Emitted when the builder object has been created. It is available as
``app.builder``.
.. event:: env-purge-doc (app, env, docname)
Emitted when all traces of a source file should be cleaned from the
environment, that is, if the source file is removed or before it is freshly
read. This is for extensions that keep their own caches in attributes of the
environment.
For example, there is a cache of all modules on the environment. When a
source file has been changed, the cache's entries for the file are cleared,
since the module declarations could have been removed from the file.
.. versionadded:: 0.5
.. event:: source-read (app, docname, source)
Emitted when a source file has been read. The *source* argument is a list
whose single element is the contents of the source file. You can process the
contents and replace this item to implement source-level transformations.
For example, if you want to use ``$`` signs to delimit inline math, like in
LaTeX, you can use a regular expression to replace ``$...$`` by
``:math:`...```.
.. versionadded:: 0.5
.. event:: doctree-read (app, doctree)
Emitted when a doctree has been parsed and read by the environment, and is
@ -237,11 +321,15 @@ registered event handlers.
future reference and should be a child of the returned reference node.
.. versionadded:: 0.5
.. event:: doctree-resolved (app, doctree, docname)
Emitted when a doctree has been "resolved" by the environment, that is, all
references have been resolved and TOCs have been inserted.
references have been resolved and TOCs have been inserted. The *doctree* can
be modified in place.
Here is the place to replace custom nodes that don't have visitor methods in
the writers, so that they don't cause errors when the writers encounter them.
.. event:: env-updated (app, env)
@ -249,7 +337,7 @@ registered event handlers.
completed, that is, the environment and all doctrees are now up-to-date.
.. versionadded:: 0.5
.. event:: page-context (app, pagename, templatename, context, doctree)
Emitted when the HTML builder has created a context dictionary to render a
@ -280,7 +368,7 @@ registered event handlers.
cleanup actions depending on the exception status.
.. versionadded:: 0.5
.. _template-bridge:

View File

@ -12,6 +12,13 @@
This extension can import the modules you are documenting, and pull in
documentation from docstrings in a semi-automatic way.
.. note::
For Sphinx (actually, the Python interpreter that executes Sphinx) to find
your module, it must be importable. That means that the module or the
package must be in one of the directories on :data:`sys.path` -- adapt your
:data:`sys.path` in the configuration file accordingly.
For this to work, the docstrings must of course be written in correct
reStructuredText. You can then use all of the usual Sphinx markup in the
docstrings, and it will end up correctly in the documentation. Together with
@ -61,7 +68,7 @@ directive.
Boil the noodle *time* minutes.
**Options and advanced usage**
* If you want to automatically document members, there's a ``members``
option::
@ -108,9 +115,11 @@ directive.
.. versionadded:: 0.4
* The :dir:`autoclass` and :dir:`autoexception` directives also support a
flag option called ``show-inheritance``. When given, a list of base
classes will be inserted just below the class signature.
* The :dir:`automodule`, :dir:`autoclass` and :dir:`autoexception` directives
also support a flag option called ``show-inheritance``. When given, a list
of base classes will be inserted just below the class signature (when used
with :dir:`automodule`, this will be inserted for every class that is
documented in the module).
.. versionadded:: 0.4
@ -126,6 +135,12 @@ directive.
.. versionadded:: 0.5
* :dir:`automodule` and :dir:`autoclass` also has an ``member-order`` option
that can be used to override the global value of
:confval:`autodoc_member_order` for one directive.
.. versionadded:: 0.6
.. note::
In an :dir:`automodule` directive with the ``members`` option set, only
@ -135,12 +150,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
@ -155,19 +188,6 @@ directive.
There are also new config values that you can set:
.. confval:: automodule_skip_lines
This value (whose default is ``0``) can be used to skip an amount of lines in
every module docstring that is processed by an :dir:`automodule` directive.
This is provided because some projects like to put headings in the module
docstring, which would then interfere with your sectioning, or automatic
fields with version control tags, that you don't want to put in the generated
documentation.
.. deprecated:: 0.4
Use the more versatile docstring processing provided by
:event:`autodoc-process-docstring`.
.. confval:: autoclass_content
This value selects what content will be inserted into the main body of an
@ -185,6 +205,14 @@ There are also new config values that you can set:
.. versionadded:: 0.3
.. confval:: autodoc_member_order
This value selects if automatically documented members are sorted
alphabetical (value ``'alphabetical'``) or by member type (value
``'groupwise'``). The default is alphabetical.
.. versionadded:: 0.6
Docstring preprocessing
-----------------------

View File

@ -3,9 +3,9 @@
Writing new builders
====================
XXX to be expanded.
.. todo:: Expand this.
.. currentmodule:: sphinx.builder
.. currentmodule:: sphinx.builders
.. class:: Builder
@ -20,7 +20,7 @@ XXX to be expanded.
.. 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,4 @@ XXX to be expanded.
.. automethod:: prepare_writing
.. automethod:: write_doc
.. automethod:: finish

View File

@ -12,7 +12,7 @@ This extension features one additional builder, the :class:`CoverageBuilder`.
To use this builder, activate the coverage extension in your configuration
file and give ``-b coverage`` on the command line.
XXX to be expanded.
.. todo:: Write this section.
Several new configuration values can be used to specify what the builder
should check:

View File

@ -131,7 +131,7 @@ completely equivalent. ::
Test-Output example:
.. testcode::
.. testcode::
parrot.voom(3000)
@ -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
@ -179,7 +187,7 @@ There are also these config values for customizing the doctest extension:
>>> print 1
1
Some more documentation text.
Some more documentation text.
This feature makes it easy for you to test doctests in docstrings included
with the :mod:`~sphinx.ext.autodoc` extension without marking them up with a

77
doc/ext/graphviz.rst Normal file
View File

@ -0,0 +1,77 @@
.. highlight:: rest
:mod:`sphinx.ext.graphviz` -- Add Graphviz graphs
=================================================
.. module:: sphinx.ext.graphviz
:synopsis: Support for Graphviz graphs.
.. versionadded:: 0.6
This extension allows you to embed `Graphviz <http://graphviz.org/>`_ graphs in
your documents.
It adds these directives:
.. directive:: graphviz
Directive to embed graphviz code. The input code for ``dot`` is given as the
content. For example::
.. graphviz::
digraph foo {
"bar" -> "baz";
}
In HTML output, the code will be rendered to a PNG image. In LaTeX output,
the code will be rendered to an embeddable PDF file.
.. directive:: graph
Directive for embedding a single undirected graph. The name is given as a
directive argument, the contents of the graph are the directive content.
This is a convenience directive to generate ``graph <name> { <content> }``.
For example::
.. graph:: foo
"bar" -- "baz";
.. directive:: digraph
Directive for embedding a single directed graph. The name is given as a
directive argument, the contents of the graph are the directive content.
This is a convenience directive to generate ``digraph <name> { <content> }``.
For example::
.. digraph:: foo
"bar" -> "baz" -> "quux";
There are also these new config values:
.. confval:: graphviz_dot
The command name with which to invoke ``dot``. The default is ``'dot'``; you
may need to set this to a full path if ``dot`` is not in the executable
search path.
Since this setting is not portable from system to system, it is normally not
useful to set it in ``conf.py``; rather, giving it on the
:program:`sphinx-build` command line via the :option:`-D` option should be
preferable, like this::
sphinx-build -b html -D graphviz_dot=C:\graphviz\bin\dot.exe . _build/html
.. confval:: graphviz_dot_args
Additional command-line arguments to give to dot, as a list. The default is
an empty list. This is the right place to set global graph, node or edge
attributes via dot's ``-G``, ``-N`` and ``-E`` options.

46
doc/ext/inheritance.rst Normal file
View File

@ -0,0 +1,46 @@
.. highlight:: rest
:mod:`sphinx.ext.inheritance_diagram` -- Include inheritance diagrams
=====================================================================
.. module:: sphinx.ext.inheritance_diagram
:synopsis: Support for displaying inheritance diagrams via graphviz.
.. versionadded:: 0.6
This extension allows you to include inheritance diagrams, rendered via the
:mod:`Graphviz extension <sphinx.ext.graphviz>`.
It adds this directive:
.. directive:: inheritance-diagram
This directive has one or more arguments, each giving a module or class
name. Class names can be unqualified; in that case they are taken to exist
in the currently described module (see :dir:`module`).
For each given class, and each class in each given module, the base classes
are determined. Then, from all classes and their base classes, a graph is
generated which is then rendered via the graphviz extension to a directed
graph.
This directive supports an option called ``parts`` that, if given, must be an
integer, advising the directive to remove that many parts of module names
from the displayed names. (For example, if all your class names start with
``lib.``, you can give ``:parts: 1`` to remove that prefix from the displayed
node names.)
New config values are:
.. confval:: inheritance_graph_attrs
A dictionary of graphviz graph attributes for inheritance diagrams.
.. confval:: inheritance_node_attrs
A dictionary of graphviz node attributes for inheritance diagrams.
.. confval:: inheritance_edge_attrs
A dictionary of graphviz edge attributes for inheritance diagrams.

View File

@ -49,7 +49,7 @@ linking:
This will download the corresponding :file:`objects.inv` file from the
Internet and generate links to the pages under the given URI. The downloaded
inventory is cached in the Sphinx environment, so it must be redownloaded
whenever you do a full rebuild.
whenever you do a full rebuild.
A second example, showing the meaning of a non-``None`` value::

View File

@ -12,8 +12,14 @@ Since mathematical notation isn't natively supported by HTML in any way, Sphinx
supports math in documentation with two extensions.
The basic math support that is common to both extensions is contained in
:mod:`sphinx.ext.mathbase`. Other math support extensions should, if possible,
reuse that support too.
:mod:`sphinx.ext.mathbase`. Other math support extensions should,
if possible, reuse that support too.
.. note::
:mod:`sphinx.ext.mathbase` is not meant to be added to the
:confval:`extensions` config value, instead, use either
:mod:`sphinx.ext.pngmath` or :mod:`sphinx.ext.jsmath` as described below.
The input language for mathematics is LaTeX markup. This is the de-facto
standard for plain-text math notation and has the added advantage that no
@ -85,7 +91,7 @@ further translation is necessary when building LaTeX output.
Euler's identity, equation :eq:`euler`, was elected one of the most
beautiful mathematical formulas.
:mod:`sphinx.ext.pngmath` -- Render math as PNG images
------------------------------------------------------
@ -102,11 +108,8 @@ There are various config values you can set to influence how the images are buil
.. confval:: pngmath_latex
The command name with which to invoke LaTeX. The default is ``'latex'``; you
may need to set this to a full path if ``latex`` not in the executable search
path.
This string is split into words with :func:`shlex.split`, so that you can
include arguments as well if needed.
may need to set this to a full path if ``latex`` is not in the executable
search path.
Since this setting is not portable from system to system, it is normally not
useful to set it in ``conf.py``; rather, giving it on the
@ -115,12 +118,23 @@ There are various config values you can set to influence how the images are buil
sphinx-build -b html -D pngmath_latex=C:\tex\latex.exe . _build/html
.. versionchanged:: 0.5.1
This value should only contain the path to the latex executable, not
further arguments; use :confval:`pngmath_latex_args` for that purpose.
.. confval:: pngmath_dvipng
The command name with which to invoke ``dvipng``. The default is
``'dvipng'``; you may need to set this to a full path if ``dvipng`` is not in
the executable search path.
.. confval:: pngmath_latex_args
Additional arguments to give to latex, as a list. The default is an empty
list.
.. versionadded:: 0.5.1
.. confval:: pngmath_latex_preamble
Additional LaTeX code to put into the preamble of the short LaTeX files that
@ -129,11 +143,21 @@ There are various config values you can set to influence how the images are buil
.. confval:: pngmath_dvipng_args
Additional arguments to give to dvipng, as a list. This is empty by default.
Arguments you might want to add here are e.g. ``['-bg', 'Transparent']``,
Additional arguments to give to dvipng, as a list. The default value is
``['-gamma 1.5', '-D 110']`` which makes the image a bit darker and larger
then it is by default.
An arguments you might want to add here is e.g. ``'-bg Transparent'``,
which produces PNGs with a transparent background. This is not enabled by
default because some Internet Explorer versions don't like transparent PNGs.
.. note::
When you "add" an argument, you need to reproduce the default arguments if
you want to keep them; that is, like this::
pngmath_dvipng_args = ['-gamma 1.5', '-D 110', '-bg Transparent']
.. confval:: pngmath_use_preview
``dvipng`` has the ability to determine the "depth" of the rendered text: for

View File

@ -4,4 +4,4 @@
.. module:: sphinx.ext.refcounting
:synopsis: Keep track of reference counting behavior.
XXX to be written.
.. todo:: Write this section.

30
doc/ext/todo.rst Normal file
View File

@ -0,0 +1,30 @@
:mod:`sphinx.ext.todo` -- Support for todo items
================================================
.. module:: sphinx.ext.todo
:synopsis: Allow inserting todo items into documents.
.. moduleauthor:: Daniel Bültmann
.. versionadded:: 0.5
There are two additional directives when using this extension:
.. directive:: todo
Use this directive like, for example, :dir:`note`.
It will only show up in the output if :confval:`todo_include_todos` is true.
.. directive:: todolist
This directive is replaced by a list of all todo directives in the whole
documentation, if :confval:`todo_include_todos` is true.
There is also an additional config value:
.. confval:: todo_include_todos
If this is ``True``, :dir:`todo` and :dir:`todolist` produce output, else
they produce nothing. The default is ``False``.

343
doc/ext/tutorial.rst Normal file
View File

@ -0,0 +1,343 @@
.. _exttut:
Tutorial: Writing a simple extension
====================================
This section is intended as a walkthrough for the creation of custom extensions.
It covers the basics of writing and activating an extensions, as well as
commonly used features of extensions.
As an example, we will cover a "todo" extension that adds capabilities to
include todo entries in the documentation, and collecting these in a central
place. (A similar "todo" extension is distributed with Sphinx.)
Build Phases
------------
One thing that is vital in order to understand extension mechanisms is the way
in which a Sphinx project is built: this works in several phases.
**Phase 0: Initialization**
In this phase, almost nothing interesting for us happens. The source
directory is searched for source files, and extensions are initialized.
Should a stored build environment exist, it is loaded, otherwise a new one is
created.
**Phase 1: Reading**
In Phase 1, all source files (and on subsequent builds, those that are new or
changed) are read and parsed. This is the phase where directives and roles
are encountered by the docutils, and the corresponding functions are called.
The output of this phase is a *doctree* for each source files, that is a tree
of docutils nodes. For document elements that aren't fully known until all
existing files are read, temporary nodes are created.
During reading, the build environment is updated with all meta- and cross
reference data of the read documents, such as labels, the names of headings,
described Python objects and index entries. This will later be used to
replace the temporary nodes.
The parsed doctrees are stored on the disk, because it is not possible to
hold all of them in memory.
**Phase 2: Consistency checks**
Some checking is done to ensure no surprises in the built documents.
**Phase 3: Resolving**
Now that the metadata and cross-reference data of all existing documents is
known, all temporary nodes are replaced by nodes that can be converted into
output. For example, links are created for object references that exist, and
simple literal nodes are created for those that don't.
**Phase 4: Writing**
This phase converts the resolved doctrees to the desired output format, such
as HTML or LaTeX. This happens via a so-called docutils writer that visits
the individual nodes of each doctree and produces some output in the process.
.. note::
Some builders deviate from this general build plan, for example, the builder
that checks external links does not need anything more than the parsed
doctrees and therefore does not have phases 2--4.
Extension Design
----------------
We want the extension to add the following to Sphinx:
* A "todo" directive, containing some content that is marked with "TODO", and
only shown in the output if a new config value is set. (Todo entries should
not be in the output by default.)
* A "todolist" directive that creates a list of all todo entries throughout the
documentation.
For that, we will need to add the following elements to Sphinx:
* New directives, called ``todo`` and ``todolist``.
* New document tree nodes to represent these directives, conventionally also
called ``todo`` and ``todolist``. We wouldn't need new nodes if the new
directives only produced some content representable by existing nodes.
* A new config value ``todo_include_todos`` (config value names should start
with the extension name, in order to stay unique) that controls whether todo
entries make it into the output.
* New event handlers: one for the :event:`doctree-resolved` event, to replace
the todo and todolist nodes, and one for :event:`env-purge-doc` (the reason
for that will be covered later).
The Setup Function
------------------
.. currentmodule:: sphinx.application
The new elements are added in the extension's setup function. Let us create a
new Python module called :file:`todo.py` and add the setup function::
def setup(app):
app.add_config_value('todo_include_todos', False, False)
app.add_node(todolist)
app.add_node(todo,
html=(visit_todo_node, depart_todo_node),
latex=(visit_todo_node, depart_todo_node),
text=(visit_todo_node, depart_todo_node))
app.add_directive('todo', TodoDirective)
app.add_directive('todolist', TodolistDirective)
app.connect('doctree-resolved', process_todo_nodes)
app.connect('env-purge-doc', purge_todos)
The calls in this function refer to classes and functions not yet written. What
the individual calls do is the following:
* :meth:`~Sphinx.add_config_value` lets Sphinx know that it should recognize the
new *config value* ``todo_include_todos``, whose default value should be
``False`` (this also tells Sphinx that it is a boolean value).
If the third argument was ``True``, all documents would be re-read if the
config value changed its value. This is needed for config values that
influence reading (build phase 1).
* :meth:`~Sphinx.add_node` adds a new *node class* to the build system. It also
can specify visitor functions for each supported output format. These visitor
functions are needed when the new nodes stay until phase 4 -- since the
``todolist`` node is always replaced in phase 3, it doesn't need any.
We need to create the two node classes ``todo`` and ``todolist`` later.
* :meth:`~Sphinx.add_directive` adds a new *directive*, given by name and class.
The handler functions are created later.
* Finally, :meth:`~Sphinx.connect` adds an *event handler* to the event whose
name is given by the first argument. The event handler function is called
with several arguments which are documented with the event.
The Node Classes
----------------
Let's start with the node classes::
from docutils import nodes
class todo(nodes.Admonition, nodes.Element):
pass
class todolist(nodes.General, nodes.Element):
pass
def visit_todo_node(self, node):
self.visit_admonition(node)
def depart_todo_node(self, node):
self.depart_admonition(node)
Node classes usually don't have to do anything except inherit from the standard
docutils classes defined in :mod:`docutils.nodes`. ``todo`` inherits from
``Admonition`` because it should be handled like a note or warning, ``todolist``
is just a "general" node.
The Directive Classes
---------------------
A directive class is a class deriving usually from
``docutils.parsers.rst.Directive``. Since the class-based directive interface
doesn't exist yet in Docutils 0.4, Sphinx has another base class called
``sphinx.util.compat.Directive`` that you can derive your directive from, and it
will work with both Docutils 0.4 and 0.5 upwards. The directive interface is
covered in detail in the docutils documentation; the important thing is that the
class has a method ``run`` that returns a list of nodes.
The ``todolist`` directive is quite simple::
from sphinx.util.compat import Directive
class TodolistDirective(Directive):
def run(self):
return [todolist('')]
An instance of our ``todolist`` node class is created and returned. The
todolist directive has neither content nor arguments that need to be handled.
The ``todo`` directive function looks like this::
from sphinx.util.compat import make_admonition
class TodoDirective(Directive):
# this enables content in the directive
has_content = True
def run(self):
env = self.state.document.settings.env
targetid = "todo-%s" % env.index_num
env.index_num += 1
targetnode = nodes.target('', '', ids=[targetid])
ad = make_admonition(todo, self.name, [_('Todo')], self.options,
self.content, self.lineno, self.content_offset,
self.block_text, self.state, self.state_machine)
if not hasattr(env, 'todo_all_todos'):
env.todo_all_todos = []
env.todo_all_todos.append({
'docname': env.docname,
'lineno': self.lineno,
'todo': ad[0].deepcopy(),
'target': targetnode,
})
return [targetnode] + ad
Several important things are covered here. First, as you can see, you can refer
to the build environment instance using ``self.state.document.settings.env``.
Then, to act as a link target (from the todolist), the todo directive needs to
return a target node in addition to the todo node. The target ID (in HTML, this
will be the anchor name) is generated by using ``env.index_num`` which is
persistent between directive calls and therefore leads to unique target names.
The target node is instantiated without any text (the first two arguments).
An admonition is created using a standard docutils function (wrapped in Sphinx
for docutils cross-version compatibility). The first argument gives the node
class, in our case ``todo``. The third argument gives the admonition title (use
``arguments`` here to let the user specify the title). A list of nodes is
returned from ``make_admonition``.
Then, the todo node is added to the environment. This is needed to be able to
create a list of all todo entries throughout the documentation, in the place
where the author puts a ``todolist`` directive. For this case, the environment
attribute ``todo_all_todos`` is used (again, the name should be unique, so it is
prefixed by the extension name). It does not exist when a new environment is
created, so the directive must check and create it if necessary. Various
information about the todo entry's location are stored along with a copy of the
node.
In the last line, the nodes that should be put into the doctree are returned:
the target node and the admonition node.
The node structure that the directive returns looks like this::
+--------------------+
| target node |
+--------------------+
+--------------------+
| todo node |
+--------------------+
\__+--------------------+
| admonition title |
+--------------------+
| paragraph |
+--------------------+
| ... |
+--------------------+
The Event Handlers
------------------
Finally, let's look at the event handlers. First, the one for the
:event:`env-purge-doc` event::
def purge_todos(app, env, docname):
if not hasattr(env, 'todo_all_todos'):
return
env.todo_all_todos = [todo for todo in env.todo_all_todos
if todo['docname'] != docname]
Since we store information from source files in the environment, which is
persistent, it may become out of date when the source file changes. Therefore,
before each source file is read, the environment's records of it are cleared,
and the :event:`env-purge-doc` event gives extensions a chance to do the same.
Here we clear out all todos whose docname matches the given one from the
``todo_all_todos`` list. If there are todos left in the document, they will be
added again during parsing.
The other handler belongs to the :event:`doctree-resolved` event. This event is
emitted at the end of phase 3 and allows custom resolving to be done::
def process_todo_nodes(app, doctree, fromdocname):
if not app.config.todo_include_todos:
for node in doctree.traverse(todo):
node.parent.remove(node)
# Replace all todolist nodes with a list of the collected todos.
# Augment each todo with a backlink to the original location.
env = app.builder.env
for node in doctree.traverse(todolist):
if not app.config.todo_include_todos:
node.replace_self([])
continue
content = []
for todo_info in env.todo_all_todos:
para = nodes.paragraph()
filename = env.doc2path(todo_info['docname'], base=None)
description = (
_('(The original entry is located in %s, line %d and can be found ') %
(filename, todo_info['lineno']))
para += nodes.Text(description, description)
# Create a reference
newnode = nodes.reference('', '')
innernode = nodes.emphasis(_('here'), _('here'))
newnode['refdocname'] = todo_info['docname']
newnode['refuri'] = app.builder.get_relative_uri(
fromdocname, todo_info['docname'])
newnode['refuri'] += '#' + todo_info['target']['refid']
newnode.append(innernode)
para += newnode
para += nodes.Text('.)', '.)')
# Insert into the todolist
content.append(todo_info['todo'])
content.append(para)
node.replace_self(content)
It is a bit more involved. If our new "todo_include_todos" config value is
false, all todo and todolist nodes are removed from the documents.
If not, todo nodes just stay where and how they are. Todolist nodes are
replaced by a list of todo entries, complete with backlinks to the location
where they come from. The list items are composed of the nodes from the todo
entry and docutils nodes created on the fly: a paragraph for each entry,
containing text that gives the location, and a link (reference node containing
an italic node) with the backreference. The reference URI is built by
``app.builder.get_relative_uri`` which creates a suitable URI depending on the
used builder, and appending the todo node's (the target's) ID as the anchor
name.

View File

@ -9,17 +9,25 @@ Sphinx Extensions
Since many projects will need special features in their documentation, Sphinx is
designed to be extensible on several levels.
First, you can add new :term:`builder`\s to support new output formats or
actions on the parsed documents. Then, it is possible to register custom
reStructuredText roles and directives, extending the markup. And finally, there
are so-called "hook points" at strategic places throughout the build process,
where an extension can register a hook and run specialized code.
This is what you can do in an extension: First, you can add new
:term:`builder`\s to support new output formats or actions on the parsed
documents. Then, it is possible to register custom reStructuredText roles and
directives, extending the markup. And finally, there are so-called "hook
points" at strategic places throughout the build process, where an extension can
register a hook and run specialized code.
The configuration file itself can be an extension, see the :confval:`extensions`
configuration value docs.
An extension is simply a Python module. When an extension is loaded, Sphinx
imports this module and executes its ``setup()`` function, which in turn
notifies Sphinx of everything the extension offers -- see the extension tutorial
for examples.
The configuration file itself can be treated as an extension if it contains a
``setup()`` function. All other extensions to load must be listed in the
:confval:`extensions` configuration value.
.. toctree::
ext/tutorial
ext/appapi
ext/builderapi
@ -36,6 +44,41 @@ These extensions are built in and can be activated by respective entries in the
ext/doctest
ext/intersphinx
ext/math
ext/graphviz
ext/inheritance
ext/refcounting
ext/ifconfig
ext/coverage
ext/todo
Third-party extensions
----------------------
There are several extensions that are not (yet) maintained in the Sphinx
distribution. The `Wiki at BitBucket`_ maintains a list of those.
If you write an extension that you think others will find useful, please write
to the project mailing list (sphinx-dev@googlegroups.com) and we'll find the
proper way of including or hosting it for the public.
.. _Wiki at BitBucket: http://www.bitbucket.org/birkenfeld/sphinx/wiki/Home
Where to put your own extensions?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Extensions local to a project should be put within the project's directory
structure. Set Python's module search path, ``sys.path``, accordingly so that
Sphinx can find them.
E.g., if your extension ``foo.py`` lies in the ``exts`` subdirectory of the
project root, put into :file:`conf.py`::
import sys, os
sys.path.append(os.path.abspath('exts'))
extensions = ['foo']
You can also install extensions anywhere else on ``sys.path``, e.g. in the
``site-packages`` directory.

30
doc/faq.rst Normal file
View File

@ -0,0 +1,30 @@
.. _faq:
Sphinx FAQ
==========
This is a list of Frequently Asked Questions about Sphinx. Feel free to
suggest new entries!
How do I...
-----------
... get section numbers?
They are automatic in LaTeX output; for HTML, give a ``:numbered:`` option to
the :dir:`toctree` directive where you want to start numbering.
... customize the look of the built HTML files?
Use themes, see :doc:`theming`.
... add global substitutions or includes?
Add them in the :confval:`rst_epilog` config value.
... write my own extension?
See the :ref:`extension tutorial <exttut>`.
... use Sphinx with Epydoc?
There's a third-party extension providing an `api role`_ which refers to
Epydoc's API docs for a given identifier.
.. _api role: http://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py

View File

@ -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

View File

@ -89,6 +89,12 @@ The :program:`sphinx-build` script has several more options:
cross-references), but rebuild it completely. The default is to only read
and parse source files that are new or have changed since the last run.
**-t** *tag*
Define the tag *tag*. This is relevant for :dir:`only` directives that only
include their content if this tag is set.
.. versionadded:: 0.6
**-d** *path*
Since Sphinx has to read and parse all source files before it can write an
output file, the parsed source files are cached as "doctree pickles".
@ -105,9 +111,18 @@ The :program:`sphinx-build` script has several more options:
.. versionadded:: 0.3
**-C**
Don't look for a configuration file; only take options via the ``-D`` option.
.. 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.
@ -124,6 +139,13 @@ The :program:`sphinx-build` script has several more options:
Do not output anything on standard output, also suppress warnings. Only
errors are written to standard error.
**-w** *file*
Write warnings (and errors) to the given file, in addition to standard error.
**-W**
Turn warnings into errors. This means that the build stops at the first
warning and ``sphinx-build`` exits with exit status 1.
**-P**
(Useful for debugging only.) Run the Python debugger, :mod:`pdb`, if an
unhandled exception occurs while building.

View File

@ -30,7 +30,10 @@ installed) and handled in a smart way:
config value.
* Within Python highlighting mode, interactive sessions are recognized
automatically and highlighted appropriately.
automatically and highlighted appropriately. Normal Python code is only
highlighted if it is parseable (so you can use Python as the default, but
interspersed snippets of shell commands or other code blocks will not be
highlighted as Python).
* The highlighting language can be changed using the ``highlight`` directive,
used as follows::
@ -96,12 +99,14 @@ Includes
.. literalinclude:: example.py
The file name is relative to the current file's path.
The file name is usually relative to the current file's path. However, if it
is absolute (starting with ``/``), it is relative to the top source
directory.
The directive also supports the ``linenos`` flag option to switch on line
numbers, and a ``language`` option to select a language different from the
current file's standard language. Example with options::
.. literalinclude:: example.rb
:language: ruby
:linenos:
@ -113,8 +118,36 @@ 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,
as well as support for absolute filenames.
.. rubric:: Footnotes

View File

@ -17,7 +17,7 @@ typical module section might start like this::
.. moduleauthor:: John Idle <john@python.invalid>
The directives you can use for module are:
The directives you can use for module declarations are:
.. directive:: .. module:: name
@ -67,8 +67,8 @@ The directives you can use for module are:
.. _desc-units:
Description units
-----------------
Object description units
------------------------
There are a number of directives used to describe specific features provided by
modules. Each directive requires one or more signatures to provide basic
@ -204,39 +204,12 @@ The directives are:
Like :dir:`method`, but indicates that the method is a static method.
.. versionadded:: 0.4
.. directive:: .. cmdoption:: name args, name args, ...
Describes a command line option or switch. Option argument names should be
enclosed in angle brackets. Example::
.. directive:: .. classmethod:: name(signature)
.. cmdoption:: -m <module>, --module <module>
Like :dir:`method`, but indicates that the method is a class method.
Run a module as a script.
The directive will create a cross-reference target named after the *first*
option, referencable by :role:`option` (in the example case, you'd use
something like ``:option:`-m```).
.. directive:: .. envvar:: name
Describes an environment variable that the documented code uses or defines.
There is also a generic version of these directives:
.. directive:: .. describe:: text
This directive produces the same formatting as the specific ones explained
above but does not create index entries or cross-referencing targets. It is
used, for example, to describe the directives in this document. Example::
.. describe:: opcode
Describes a Python bytecode instruction.
Extensions may add more directives like that, using the
:func:`~sphinx.application.Sphinx.add_description_unit` method.
.. versionadded:: 0.6
.. _signatures:
@ -287,7 +260,7 @@ explained by an example::
.. function:: format_exception(etype, value, tb[, limit=None])
Format the exception with a traceback.
:param etype: exception type
:param value: exception value
:param tb: traceback object
@ -308,3 +281,77 @@ This will render like this:
:param limit: maximum number of stack frames to show
:type limit: integer or None
:rtype: list of strings
Command-line program markup
~~~~~~~~~~~~~~~~~~~~~~~~~~~
There is a set of directives allowing documenting command-line programs:
.. directive:: .. cmdoption:: name args, name args, ...
Describes a command line option or switch. Option argument names should be
enclosed in angle brackets. Example::
.. cmdoption:: -m <module>, --module <module>
Run a module as a script.
The directive will create a cross-reference target named after the *first*
option, referencable by :role:`option` (in the example case, you'd use
something like ``:option:`-m```).
.. directive:: .. envvar:: name
Describes an environment variable that the documented code or program uses or
defines.
.. directive:: .. program:: name
Like :dir:`currentmodule`, this directive produces no output. Instead, it
serves to notify Sphinx that all following :dir:`cmdoption` directives
document options for the program called *name*.
If you use :dir:`program`, you have to qualify the references in your
:role:`option` roles by the program name, so if you have the following
situation ::
.. program:: rm
.. cmdoption:: -r
Work recursively.
.. program:: svn
.. cmdoption:: -r revision
Specify the revision to work upon.
then ``:option:`rm -r``` would refer to the first option, while
``:option:`svn -r``` would refer to the second one.
The program name may contain spaces (in case you want to document subcommands
like ``svn add`` and ``svn commit`` separately).
.. versionadded:: 0.5
Custom description units
~~~~~~~~~~~~~~~~~~~~~~~~
There is also a generic version of these directives:
.. directive:: .. describe:: text
This directive produces the same formatting as the specific ones explained
above but does not create index entries or cross-referencing targets. It is
used, for example, to describe the directives in this document. Example::
.. describe:: opcode
Describes a Python bytecode instruction.
Extensions may add more directives like that, using the
:func:`~sphinx.application.Sphinx.add_description_unit` method.

View File

@ -12,7 +12,8 @@ For all other roles, you have to write ``:rolename:`content```.
.. note::
The default role (```content```) has no special meaning by default. You are
free to use it for anything you like.
free to use it for anything you like; use the :confval:`default_role` config
value to set it to a known role.
.. _xref-syntax:
@ -223,7 +224,53 @@ 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 usually relative to the directory the current source
file is contained in, but if it absolute (starting with ``/``), it is taken
as relative to the top source directory.
The ``example.py`` file will be copied to the output directory, and a
suitable link generated to it.
Other semantic markup
---------------------
@ -231,6 +278,16 @@ Other semantic markup
The following roles don't do anything special except formatting the text
in a different style:
.. role:: abbr
An abbreviation. If the role content contains a parenthesized explanation,
it will be treated specially: it will be shown in a tool-tip in HTML, and
output only once in LaTeX.
Example: ``:abbr:`LIFO (last-in, first-out)```.
.. versionadded:: 0.6
.. role:: command
The name of an OS-level command, such as ``rm``.
@ -329,7 +386,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:
@ -350,6 +407,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
@ -372,6 +430,6 @@ They are set in the build configuration file.
.. describe:: |today|
Replaced by either today's date, or the date set in the build configuration
file. Normally has the format ``April 14, 2007``. Set by
:confval:`today_fmt` and :confval:`today`.
Replaced by either today's date (the date on which the document is read), or
the date set in the build configuration file. Normally has the format
``April 14, 2007``. Set by :confval:`today_fmt` and :confval:`today`.

View File

@ -3,6 +3,8 @@
Miscellaneous markup
====================
.. _metadata:
File-wide metadata
------------------
@ -46,6 +48,28 @@ Meta-information markup
output.
.. _tags:
Including content based on tags
-------------------------------
.. directive:: .. only:: <expression>
Include the content of the directive only if the *expression* is true. The
expression should consist of tags, like this::
.. only:: html and draft
Undefined tags are false, defined tags (via the ``-t`` command-line option or
within :file:`conf.py`) are true. Boolean expressions, also using
parentheses (like ``html and (latex or draft)`` are supported.
The format of the current builder (``html``, ``latex`` or ``text``) is always
set as a tag.
.. versionadded:: 0.6
Tables
------

View File

@ -1,4 +1,4 @@
.. highlight:: rest
x.. highlight:: rest
Paragraph-level markup
----------------------
@ -85,9 +85,9 @@ units as well as normal text:
This directive creates a paragraph heading that is not used to create a
table of contents node.
.. note::
If the *title* of the rubric is "Footnotes", this rubric is ignored by
the LaTeX writer, since it is assumed to only contain footnote
definitions and therefore would create an empty heading.
@ -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
------------------------
@ -218,7 +239,7 @@ the definition of the symbol. There is this directive:
Note that no further reST parsing is done in the production, so that you
don't have to escape ``*`` or ``|`` characters.
.. XXX describe optional first parameter
.. XXX describe optional first parameter
The following is an example taken from the Python Reference Manual::

View File

@ -212,10 +212,19 @@ reST supports an image directive, used like so::
.. image:: gnu.png
(options)
When used within Sphinx, the file name given (here ``gnu.png``) must be relative
to the source file, and Sphinx will automatically copy image files over to a
subdirectory of the output directory on building (e.g. the ``_static`` directory
for HTML output.)
When used within Sphinx, the file name given (here ``gnu.png``) must either be
relative to the source file, or absolute which means that they are relative to
the top source directory. For example, the file ``sketch/spam.rst`` could refer
to the image ``images/spam.png`` as ``../images/spam.png`` or
``/images/spam.png``.
Sphinx will automatically copy image files over to a subdirectory of the output
directory on building (e.g. the ``_static`` directory for HTML output.)
Interpretation of image size options (``width`` and ``height``) is as follows:
if the size has no unit or the unit is pixels, the given size will only be
respected for output channels that support pixels (i.e. not in LaTeX output).
Other units (like ``pt`` for points) will be used for HTML and LaTeX output.
Sphinx extends the standard docutils behavior by allowing an asterisk for the
extension::
@ -231,6 +240,9 @@ the former, while the HTML builder would prefer the latter.
.. versionchanged:: 0.4
Added the support for file names ending in an asterisk.
.. versionchanged:: 0.6
Image paths can now be absolute.
Footnotes
---------
@ -277,7 +289,7 @@ markup blocks, like this::
See the `reST reference for substitutions
<http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#substitution-definitions>`_
for details.
If you want to use some substitutions for all documents, put them into a
separate file and include it into all documents you want to use them in, using
the :dir:`include` directive. Be sure to give the include file a file name
@ -291,7 +303,17 @@ Comments
--------
Every explicit markup block which isn't a valid markup construct (like the
footnotes above) is regarded as a comment.
footnotes above) is regarded as a comment. For example::
.. This is a comment.
You can indent text after a comment start to form multiline comments::
..
This whole indented block
is a comment.
Still in the comment.
Source encoding
@ -312,4 +334,7 @@ There are some problems one commonly runs into while authoring reST documents:
separated from the surrounding text by non-word characters, you have to use
a backslash-escaped space to get around that.
* **No nested inline markup:** Something like ``*see :func:`foo`*`` is not
possible.
.. XXX more?

102
doc/sphinx-build.1 Normal file
View File

@ -0,0 +1,102 @@
.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-w\fR <file>
Write warnings and errors into the given file, in addition to stderr.
.TP
\fB-W\fR
Turn warnings into 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.

17
doc/sphinx-quickstart.1 Normal file
View File

@ -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.

View File

@ -1,3 +1,5 @@
.. highlight:: html+jinja
.. _templating:
Templating
@ -19,10 +21,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.
@ -37,27 +39,26 @@ template, customizing it while also keeping the changes at a minimum.
To customize the output of your documentation you can override all the templates
(both the layout templates and the child templates) by adding files with the
same name as the original filename into the template directory of the folder the
Sphinx quickstart generated for you.
same name as the original filename into the template directory of the structure
the Sphinx quickstart generated for you.
Sphinx will look for templates in the folders of :confval:`templates_path`
first, and if it can't find the template it's looking for there, it falls back
to the builtin templates that come with Sphinx.
to the selected theme's templates.
A template contains **variables**, which are replaced with values when the
template is evaluated, **tags**, which control the logic of the template and
**blocks** which are used for template inheritance.
Sphinx provides base templates with a couple of blocks it will fill with data.
The default templates are located in the :file:`templates` folder of the Sphinx
installation directory. Templates with the same name in the
:confval:`templates_path` override templates located in the builtin folder.
Sphinx' *basic* theme provides base templates with a couple of blocks it will
fill with data. These are located in the :file:`themes/basic` subdirectory of
the Sphinx installation directory, and used by all builtin Sphinx themes.
Templates with the same name in the :confval:`templates_path` override templates
supplied by the selected theme.
For example, to add a new link to the template area containing related links all
you have to do is to add a new template called ``layout.html`` with the
following contents:
.. sourcecode:: html+jinja
following contents::
{% extends "!layout.html" %}
{% block rootrellink %}
@ -65,16 +66,24 @@ following contents:
{{ super() }}
{% endblock %}
By prefixing the name of the extended template with an exclamation mark, Sphinx
will load the builtin layout template. If you override a block, you should call
``{{ super() }}`` somewhere to render the block's content in the extended
template -- unless you don't want that content to show up.
By prefixing the name of the overridden template with an exclamation mark,
Sphinx will load the layout template from the underlying HTML theme.
**Important**: If you override a block, call ``{{ super() }}`` somewhere to
render the block's content in the extended template -- unless you don't want
that content to show up.
Working the the builtin templates
---------------------------------
The builtin **basic** theme supplies the templates that all builtin Sphinx
themes are based on. It has the following elements you can override or use:
Blocks
~~~~~~
The following blocks exist in the ``layout`` template:
The following blocks exist in the ``layout.html`` template:
`doctype`
The doctype of the output format. By default this is XHTML 1.0 Transitional
@ -92,11 +101,11 @@ The following blocks exist in the ``layout`` template:
add references to JavaScript or extra CSS files.
`relbar1` / `relbar2`
This block contains the list of related links (the parent documents on the
left, and the links to index, modules etc. on the right). `relbar1` appears
before the document, `relbar2` after the document. By default, both blocks
are filled; to show the relbar only before the document, you would override
`relbar2` like this::
This block contains the *relation bar*, the list of related links (the
parent documents on the left, and the links to index, modules etc. on the
right). `relbar1` appears before the document, `relbar2` after the
document. By default, both blocks are filled; to show the relbar only
before the document, you would override `relbar2` like this::
{% block relbar2 %}{% endblock %}
@ -109,7 +118,8 @@ The following blocks exist in the ``layout`` template:
the :data:`reldelim1`.
`document`
The contents of the document itself.
The contents of the document itself. It contains the block "body" where the
individual content is put by subtemplates like ``page.html``.
`sidebar1` / `sidebar2`
A possible location for a sidebar. `sidebar1` appears before the document
@ -135,6 +145,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.
@ -162,13 +176,17 @@ using the ``{% set %}`` tag:
defaults to ``' |'``. Each item except of the last one in the related bar
ends with the value of this variable.
Overriding works like this:
.. sourcecode:: html+jinja
Overriding works like this::
{% extends "!layout.html" %}
{% set reldelim1 = ' &gt;' %}
.. data:: script_files
Add additional script files here, like this::
{% set script_files = script_files + [pathto("_static/myscript.js", 1)] %}
Helper Functions
~~~~~~~~~~~~~~~~
@ -196,7 +214,7 @@ them to generate links or output multiply used elements.
.. function:: relbar()
Return the rendered relbar.
Return the rendered relation bar.
Global Variables
@ -206,32 +224,145 @@ These global variables are available in every template and are safe to use.
There are more, but most of them are an implementation detail and might change
in the future.
.. data:: builder
The name of the builder (e.g. ``html`` or ``htmlhelp``).
.. data:: copyright
The value of :confval:`copyright`.
.. data:: docstitle
The title of the documentation (the value of :confval:`html_title`).
.. data:: embedded
True if the built HTML is meant to be embedded in some viewing application
that handles navigation, not the web browser, such as for HTML help or Qt
help formats. In this case, the sidebar is not included.
.. data:: favicon
The path to the HTML favicon in the static path, or ``''``.
.. data:: file_suffix
The value of the builder's :attr:`out_suffix` attribute, i.e. the file name
extension that the output files will get. For a standard HTML builder, this
is usually ``.html``.
.. data:: has_source
True if the reST document sources are copied (if :confval:`html_copy_source`
is true).
.. data:: last_updated
The build date.
.. data:: logo
The path to the HTML logo image in the static path, or ``''``.
.. data:: master_doc
The value of :confval:`master_doc`, for usage with :func:`pathto`.
.. data:: next
The next document for the navigation. This variable is either false or has
two attributes `link` and `title`. The title contains HTML markup. For
example, to generate a link to the next page, you can use this snippet::
{% if next %}
<a href="{{ next.link|e }}">{{ next.title }}</a>
{% endif %}
.. data:: pagename
The "page name" of the current file, i.e. either the document name if the
file is generated from a reST source, or the equivalent hierarchical name
relative to the output directory (``[directory/]filename_without_extension``).
.. data:: parents
A list of parent documents for navigation, structured like the :data:`next`
item.
.. data:: prev
Like :data:`next`, but for the previous page.
.. data:: project
The value of :confval:`project`.
.. data:: release
The value of :confval:`release`.
.. data:: rellinks
A list of links to put at the left side of the relbar, next to "next" and
"prev". This usually contains links to the index and the modindex. If you
add something yourself, it must be a tuple ``(pagename, link title,
accesskey, link text)``.
.. data:: shorttitle
The value of :confval:`html_short_title`.
.. data:: show_source
True if :confval:`html_show_sourcelink` is true.
.. data:: sphinx_version
The version of Sphinx used to build.
.. data:: style
The name of the main stylesheet, as given by the theme or
:confval:`html_style`.
.. data:: title
The title of the current document, as used in the ``<title>`` tag.
.. data:: use_opensearch
The value of :confval:`html_use_opensearch`.
.. data:: version
The value of :confval:`version`.
In addition to these values, there are also all **theme options** available
(prefixed by ``theme_``), as well as the values given by the user in
:confval:`html_context`.
In documents that are created from source files (as opposed to
automatically-generated files like the module index, or documents that already
are in HTML form), these variables are also available:
.. data:: meta
Document metadata, see :ref:`metadata`.
.. data:: sourcename
The name of the copied source file for the current document. This is only
nonempty if the :confval:`html_copy_source` value is true.
.. data:: builder
.. data:: toc
The name of the builder (for builtin builders, ``html``, ``htmlhelp``, or
``web``).
The local table of contents for the current page, rendered as HTML bullet
lists.
.. data:: next
.. data:: toctree
The next document for the navigation. This variable is either false or has
two attributes `link` and `title`. The title contains HTML markup. For
example, to generate a link to the next page, you can use this snippet:
.. sourcecode:: html+jinja
{% if next %}
<a href="{{ next.link|e }}">{{ next.title }}</a>
{% endif %}
.. data:: prev
Like :data:`next`, but for the previous page.
A callable yielding the global TOC tree containing the current page, rendered
as HTML bullet lists. If the optional keyword argument ``collapse`` is true,
all TOC entries that are not ancestors of the current page are collapsed.

187
doc/theming.rst Normal file
View File

@ -0,0 +1,187 @@
.. highlightlang:: python
HTML theming support
====================
.. versionadded:: 0.6
Sphinx supports changing the appearance of its HTML output via *themes*. A
theme is a collection of HTML templates, stylesheet(s) and other static files.
Additionally, it has a configuration file which specifies from which theme to
inherit, which highlighting style to use, and what options exist for customizing
the theme's look and feel.
Themes are meant to be project-unaware, so they can be used for different
projects without change.
Using a theme
-------------
Using an existing theme is easy. If the theme is builtin to Sphinx, you only
need to set the :confval:`html_theme` config value. With the
:confval:`html_theme_options` config value you can set theme-specific options
that change the look and feel. For example, you could have the following in
your :file:`conf.py`::
html_theme = "default"
html_theme_options = {
"rightsidebar": "true",
"relbarbgcolor: "black"
}
That would give you the default theme, but with a sidebar on the right side and
a black background for the relation bar (the bar with the navigation links at
the page's top and bottom).
If the theme does not come with Sphinx, it can be in two forms: either a
directory (containing :file:`theme.conf` and other needed files), or a zip file
with the same contents. Either of them must be put where Sphinx can find it;
for this there is the config value :confval:`html_theme_path`. It gives a list
of directories, relative to the directory containing :file:`conf.py`, that can
contain theme directories or zip files. For example, if you have a theme in the
file :file:`blue.zip`, you can put it right in the directory containing
:file:`conf.py` and use this configuration::
html_theme = "blue"
html_theme_path = ["."]
.. _builtin-themes:
Builtin themes
--------------
Sphinx comes with a selection of themes to choose from:
* **basic** -- This is a basically unstyled layout used as the base for the
*default* and *sphinxdoc* themes, and usable as the base for custom themes as
well. The HTML contains all important elements like sidebar and relation bar.
There is one option (which is inherited by *default* and *sphinxdoc*):
- **nosidebar** (true or false): Don't include the sidebar. Defaults to
false.
* **default** -- This is the default theme. It can be customized via these
options:
- **rightsidebar** (true or false): Put the sidebar on the right side.
Defaults to false.
- **stickysidebar** (true or false): Make the sidebar "fixed" so that it
doesn't scroll out of view for long body content. This may not work well
with all browsers. Defaults to false.
There are also various color and font options that can change the color scheme
without having to write a custom stylesheet:
- **footerbgcolor** (CSS color): Background color for the footer line.
- **footertextcolor** (CSS color): Text color for the footer line.
- **sidebarbgcolor** (CSS color): Background color for the sidebar.
- **sidebartextcolor** (CSS color): Text color for the sidebar.
- **sidebarlinkcolor** (CSS color): Link color for the sidebar.
- **relbarbgcolor** (CSS color): Background color for the relation bar.
- **relbartextcolor** (CSS color): Text color for the relation bar.
- **relbarlinkcolor** (CSS color): Link color for the relation bar.
- **bgcolor** (CSS color): Body background color.
- **textcolor** (CSS color): Body text color.
- **linkcolor** (CSS color): Body link color.
- **headbgcolor** (CSS color): Background color for headings.
- **headtextcolor** (CSS color): Text color for headings.
- **headlinkcolor** (CSS color): Link color for headings.
- **codebgcolor** (CSS color): Background color for code blocks.
- **codetextcolor** (CSS color): Default text color for code blocks, if not
set differently by the highlighting style.
- **bodyfont** (CSS font-family): Font for normal text.
- **headfont** (CSS font-family): Font for headings.
* **sphinxdoc** -- The theme used for this documentation. It features a sidebar
on the right side. There are currently no options beyond *nosidebar*.
* **traditional** -- A theme resembling the old Python documentation. There are
currently no options beyond *nosidebar*.
Creating themes
---------------
As said, themes are either a directory or a zipfile (whose name is the theme
name), containing the following:
* A :file:`theme.conf` file, see below.
* HTML templates, if needed.
* A ``static/`` directory containing any static files that will be copied to the
output statid directory on build. These can be images, styles, script files.
The :file:`theme.conf` file is in INI format [1]_ (readable by the standard
Python :mod:`ConfigParser` module) and has the following structure:
.. sourcecode:: ini
[theme]
inherit = base theme
stylesheet = main CSS name
pygments_style = stylename
[options]
variable = default value
* The **inherit** setting gives the name of a "base theme", or ``none``. The
base theme will be used to locate missing templates (most themes will not have
to supply most templates if they use ``basic`` as the base theme), its options
will be inherited, and all of its static files will be used as well.
* The **stylesheet** setting gives the name of a CSS file which will be
referenced in the HTML header. If you need more than one CSS file, either
include one from the other via CSS' ``@import``, or use a custom HTML template
that adds ``<link rel="stylesheet">`` tags as necessary. Setting the
:confval:`html_style` config value will override this setting.
* The **pygments_style** setting gives the name of a Pygments style to use for
highlighting. This can be overridden by the user in the
:confval:`pygments_style` config value.
* The **options** section contains pairs of variable names and default values.
These options can be overridden by the user in :confval:`html_theme_options`
and are accessible from all templates as ``theme_<name>``.
Templating
~~~~~~~~~~
The :doc:`guide to templating <templating>` is helpful if you want to write your
own templates. What is important to keep in mind is the order in which Sphinx
searches for templates:
* First, in the user's ``templates_path`` directories.
* Then, in the selected theme.
* Then, in its base theme, its base's base theme, etc.
When extending a template in the base theme with the same name, use the theme
name as an explicit directory: ``{% extends "basic/layout.html" %}``. From a
user ``templates_path`` template, you can still use the "exclamation mark"
syntax as described in the templating document.
Static templates
~~~~~~~~~~~~~~~~
Since theme options are meant for the user to configure a theme more easily,
without having to write a custom stylesheet, it is necessary to be able to
template static files as well as HTML files. Therefore, Sphinx supports
so-called "static templates", like this:
If the name of a file in the ``static/`` directory of a theme (or in the user's
static path, for that matter) ends with ``_t``, it will be processed by the
template engine. The ``_t`` will be left from the final file name. For
example, the *default* theme has a file ``static/default.css_t`` which uses
templating to put the color options into the stylesheet. When a documentation
is built with the default theme, the output directory will contain a
``_static/default.css`` file where all template tags have been processed.
.. [1] It is not an executable Python file, as opposed to :file:`conf.py`,
because that would pose an unnecessary security risk if themes are
shared.

View File

@ -14,7 +14,7 @@ the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools.
"""
import sys
DEFAULT_VERSION = "0.6c8"
DEFAULT_VERSION = "0.6c9"
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
md5_data = {
@ -48,13 +48,18 @@ md5_data = {
'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
}
import sys, os
try: from hashlib import md5
except ImportError: from md5 import md5
def _validate_md5(egg_name, data):
if egg_name in md5_data:
from md5 import md5
digest = md5(data).hexdigest()
if digest != md5_data[egg_name]:
print >>sys.stderr, (
@ -64,7 +69,6 @@ def _validate_md5(egg_name, data):
sys.exit(2)
return data
def use_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
download_delay=15
@ -233,7 +237,6 @@ def update_md5(filenames):
"""Update our built-in md5 registry"""
import re
from md5 import md5
for name in filenames:
base = os.path.basename(name)
@ -270,3 +273,4 @@ if __name__=='__main__':

View File

@ -24,7 +24,7 @@ parsing and translating suite, the Docutils.
Although it is still under constant development, the following features
are already present, work fine and can be seen "in action" in the Python docs:
* Output formats: HTML (including Windows HTML Help) and LaTeX,
* Output formats: HTML (including Windows HTML Help), plain text and LaTeX,
for printable PDF versions
* Extensive cross-references: semantic markup and automatic links
for functions, classes, glossary terms and similar pieces of information
@ -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.1', 'docutils>=0.4']
if sys.version_info < (2, 4):
print 'ERROR: Sphinx requires at least Python 2.4 to run.'
@ -98,7 +98,8 @@ else:
else:
for locale in os.listdir(self.directory):
po_file = os.path.join(self.directory, locale,
'LC_MESSAGES', self.domain + '.po')
'LC_MESSAGES',
self.domain + '.po')
if os.path.exists(po_file):
po_files.append((locale, po_file))
js_files.append(os.path.join(self.directory, locale,

View File

@ -4,8 +4,8 @@
Sphinx - Python documentation toolchain
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: 2007-2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import sys

View File

@ -4,8 +4,8 @@
Sphinx - Python documentation toolchain
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import sys

View File

@ -5,199 +5,52 @@
The Sphinx documentation toolchain.
:copyright: 2007-2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import sys
import getopt
import traceback
from os import path
from cStringIO import StringIO
from sphinx.util import format_exception_cut_frames, save_traceback
from sphinx.util.console import darkred, nocolor, color_terminal
__revision__ = '$Revision$'
__version__ = '0.5'
__released__ = '0.5 (hg)'
__version__ = '0.6'
__released__ = '0.6 (hg)'
def usage(argv, msg=None):
if msg:
print >>sys.stderr, msg
print >>sys.stderr
print >>sys.stderr, """\
Sphinx v%s
Usage: %s [options] sourcedir outdir [filenames...]
Options: -b <builder> -- builder to use; default is html
-a -- write all files; default is to only write new and changed files
-E -- don't use a saved environment, always read all files
-d <path> -- path for the cached environment and doctree files
(default: outdir/.doctrees)
-c <path> -- path where configuration file (conf.py) is located
(default: same as sourcedir)
-D <setting=value> -- override a setting in configuration
-A <name=value> -- pass a value into the templates, for HTML builder
-N -- do not do colored output
-q -- no output on stdout, just warnings on stderr
-Q -- no output at all, not even warnings
-P -- run Pdb on exception
-g <path> -- create autogenerated files
Modi:
* without -a and without filenames, write new and changed files.
* with -a, write all files.
* with filenames, write these.""" % (__version__, argv[0])
package_dir = path.abspath(path.dirname(__file__))
def main(argv=sys.argv):
# delay-import these to be able to get sphinx.__version__ from setup.py
# even without docutils installed
from sphinx.application import Sphinx, SphinxError
from docutils.utils import SystemMessage
if not sys.stdout.isatty() or not color_terminal():
# Windows' poor cmd box doesn't understand ANSI sequences
nocolor()
if sys.version_info[:3] < (2, 4, 0):
print >>sys.stderr, \
'Error: Sphinx requires at least Python 2.4 to run.'
return 1
try:
opts, args = getopt.getopt(argv[1:], 'ab:d:c:D:A:g:NEqP')
srcdir = confdir = path.abspath(args[0])
if not path.isdir(srcdir):
print >>sys.stderr, 'Error: Cannot find source directory.'
return 1
if not path.isfile(path.join(srcdir, 'conf.py')) and \
'-c' not in (opt[0] for opt in opts):
print >>sys.stderr, 'Error: Source directory doesn\'t contain conf.py file.'
return 1
outdir = path.abspath(args[1])
if not path.isdir(outdir):
print >>sys.stderr, 'Making output directory...'
os.makedirs(outdir)
except (IndexError, getopt.error):
usage(argv)
return 1
filenames = args[2:]
err = 0
for filename in filenames:
if not path.isfile(filename):
print >>sys.stderr, 'Cannot find file %r.' % filename
err = 1
if err:
return 1
buildername = all_files = None
freshenv = use_pdb = False
status = sys.stdout
warning = sys.stderr
confoverrides = {}
htmlcontext = {}
doctreedir = path.join(outdir, '.doctrees')
for opt, val in opts:
if opt == '-g':
source_filenames =[srcdir+'/'+f for f in os.listdir(srcdir) if f.endswith('.rst')]
if val is None:
print >>sys.stderr, \
'Error: you must provide a destination directory for autodoc generation.'
return 1
p = path.abspath(val)
from sphinx.ext.autosummary.generate import generate_autosummary_docs
generate_autosummary_docs(source_filenames, p)
elif opt == '-b':
buildername = val
elif opt == '-a':
if filenames:
usage(argv, 'Cannot combine -a option and filenames.')
return 1
all_files = True
elif opt == '-d':
doctreedir = path.abspath(val)
elif opt == '-c':
confdir = path.abspath(val)
if not path.isfile(path.join(confdir, 'conf.py')):
print >>sys.stderr, \
'Error: Configuration directory doesn\'t contain conf.py file.'
return 1
elif opt == '-D':
try:
key, val = val.split('=')
except ValueError:
print >>sys.stderr, \
'Error: -D option argument must be in the form name=value.'
return 1
try:
val = int(val)
except ValueError:
pass
confoverrides[key] = val
elif opt == '-A':
try:
key, val = val.split('=')
except ValueError:
print >>sys.stderr, \
'Error: -A option argument must be in the form name=value.'
return 1
try:
val = int(val)
except ValueError:
pass
htmlcontext[key] = val
elif opt == '-N':
nocolor()
elif opt == '-E':
freshenv = True
elif opt == '-q':
status = StringIO()
elif opt == '-Q':
status = StringIO()
warning = StringIO()
elif opt == '-P':
use_pdb = True
confoverrides['html_context'] = htmlcontext
try:
app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername,
confoverrides, status, warning, freshenv)
app.build(all_files, filenames)
except KeyboardInterrupt:
if use_pdb:
import pdb
print >>sys.stderr, darkred('Interrupted while building, starting debugger:')
traceback.print_exc()
pdb.post_mortem(sys.exc_info()[2])
return 1
except Exception, err:
if use_pdb:
import pdb
print >>sys.stderr, darkred('Exception occurred while building, '
'starting debugger:')
traceback.print_exc()
pdb.post_mortem(sys.exc_info()[2])
else:
if isinstance(err, SystemMessage):
print >>sys.stderr, darkred('reST markup error:')
print >>sys.stderr, err.args[0].encode('ascii', 'backslashreplace')
elif isinstance(err, SphinxError):
print >>sys.stderr, darkred('%s:' % err.category)
print >>sys.stderr, err
from sphinx import cmdline
except ImportError, err:
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:
print >>sys.stderr, darkred('Exception occurred:')
print >>sys.stderr, format_exception_cut_frames().rstrip()
tbpath = save_traceback()
print >>sys.stderr, darkred('The full traceback has been saved '
'in %s, if you want to report the '
'issue to the author.' % tbpath)
print >>sys.stderr, ('Please also report this if it was a user '
'error, so that a better error message '
'can be provided next time.')
print >>sys.stderr, ('Send reports to sphinx-dev@googlegroups.com. '
'Thanks!')
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)
if __name__ == '__main__':

View File

@ -1,113 +0,0 @@
# -*- coding: utf-8 -*-
"""
sphinx._jinja
~~~~~~~~~~~~~
Jinja glue.
:copyright: 2007-2008 by Georg Brandl, Horst Gutmann.
:license: BSD.
"""
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)

View File

@ -5,8 +5,8 @@
Additional docutils nodes.
:copyright: 2007-2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from docutils import nodes
@ -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,15 +68,25 @@ 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
# like emphasis, but doesn't apply further text processors, e.g. smartypants
class literal_emphasis(nodes.emphasis): pass
# for abbreviations (with explanations)
class abbreviation(nodes.Inline, nodes.TextElement): pass
# glossary
class glossary(nodes.Element): pass
@ -85,13 +99,18 @@ class start_of_file(nodes.Element): pass
# tabular column specification, used for the LaTeX writer
class tabular_col_spec(nodes.Element): pass
# only (in/exclusion based on tags)
class only(nodes.Element): pass
# meta directive -- same as docutils' standard meta node, but pickleable
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())
abbreviation glossary acks module start_of_file tabular_col_spec
meta""".split())

View File

@ -7,13 +7,14 @@
Gracefully adapted from the TextPress system by Armin.
:copyright: 2008 by Georg Brandl, Armin Ronacher.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import sys
import types
import posixpath
from cStringIO import StringIO
from docutils import nodes
from docutils.parsers.rst import directives, roles
@ -21,43 +22,22 @@ 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.directives import desc_directive, target_directive, additional_xref_types
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError
from sphinx.builders import BUILTIN_BUILDERS
from sphinx.directives import GenericDesc, Target, additional_xref_types
from sphinx.environment import SphinxStandaloneReader
from sphinx.util.tags import Tags
from sphinx.util.compat import Directive, directive_dwim
from sphinx.util.console import bold
class SphinxError(Exception):
"""
Base class for Sphinx errors that are shown to the user in a nicer
way than normal exceptions.
"""
category = 'Sphinx error'
class ExtensionError(SphinxError):
"""Raised if something's wrong with the configuration."""
category = 'Extension error'
def __init__(self, message, orig_exc=None):
super(ExtensionError, self).__init__(message)
self.orig_exc = orig_exc
def __repr__(self):
if self.orig_exc:
return '%s(%r, %r)' % (self.__class__.__name__,
self.message, self.orig_exc)
return '%s(%r)' % (self.__class__.__name__, self.message)
def __str__(self):
parent_str = super(ExtensionError, self).__str__()
if self.orig_exc:
return '%s (exception: %s)' % (parent_str, self.orig_exc)
return parent_str
# Directive is either new-style or old-style
clstypes = (type, types.ClassType)
# List of all known core events. Maps name to arguments description.
events = {
'builder-inited': '',
'env-purge-doc': 'env, docname',
'source-read': 'docname, source text',
'doctree-read': 'the doctree before being pickled',
'missing-reference': 'env, node, contnode',
@ -69,13 +49,16 @@ events = {
CONFIG_FILENAME = 'conf.py'
class Sphinx(object):
def __init__(self, srcdir, confdir, outdir, doctreedir, buildername,
confoverrides, status, warning=sys.stderr, freshenv=False):
confoverrides, status, warning=sys.stderr, freshenv=False,
warningiserror=False, tags=None):
self.next_listener_id = 0
self._extensions = {}
self._listeners = {}
self.builderclasses = builtin_builders.copy()
self.builderclasses = BUILTIN_BUILDERS.copy()
self.builder = None
self.srcdir = srcdir
@ -83,14 +66,28 @@ class Sphinx(object):
self.outdir = outdir
self.doctreedir = doctreedir
self._status = status
self._warning = warning
if status is None:
self._status = StringIO()
self.quiet = True
else:
self._status = status
self.quiet = False
if warning is None:
self._warning = StringIO()
else:
self._warning = warning
self._warncount = 0
self.warningiserror = warningiserror
self._events = events.copy()
# status code for command-line application
self.statuscode = 0
# read config
self.config = Config(confdir, CONFIG_FILENAME, confoverrides)
self.tags = Tags(tags)
self.config = Config(confdir, CONFIG_FILENAME, confoverrides, self.tags)
# load all extension modules
for extension in self.config.extensions:
@ -108,10 +105,18 @@ class Sphinx(object):
if buildername not in self.builderclasses:
raise SphinxError('Builder name %s not registered' % buildername)
self.info(bold('Sphinx v%s, building %s' % (sphinx.__version__, buildername)))
self.info(bold('Sphinx v%s, building %s' % (sphinx.__released__,
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.builder.tags = self.tags
self.builder.tags.add(self.builder.format)
self.emit('builder-inited')
def build(self, all_files, filenames):
@ -127,28 +132,44 @@ class Sphinx(object):
raise
else:
self.emit('build-finished', None)
self.builder.cleanup()
def warn(self, message):
def warn(self, message, location=None, prefix='WARNING: '):
warntext = location and '%s: %s%s\n' % (location, prefix, message) or \
'%s%s\n' % (prefix, message)
if self.warningiserror:
raise SphinxWarning(warntext)
self._warncount += 1
self._warning.write('WARNING: %s\n' % message)
try:
self._warning.write(warntext)
except UnicodeEncodeError:
encoding = getattr(self._warning, 'encoding', 'ascii')
self._warning.write(warntext.encode(encoding, 'replace'))
def info(self, message='', nonl=False):
if nonl:
try:
self._status.write(message)
else:
self._status.write(message + '\n')
except UnicodeEncodeError:
encoding = getattr(self._status, 'encoding', 'ascii')
self._status.write(message.encode(encoding, 'replace'))
if not nonl:
self._status.write('\n')
self._status.flush()
# general extensibility interface
def setup_extension(self, extension):
"""Import and setup a Sphinx extension module."""
"""Import and setup a Sphinx extension module. No-op if called twice."""
if extension in self._extensions:
return
try:
mod = __import__(extension, None, None, ['setup'])
except ImportError, err:
raise ExtensionError('Could not import extension %s' % extension, err)
raise ExtensionError('Could not import extension %s' % extension,
err)
if hasattr(mod, 'setup'):
mod.setup(self)
self._extensions[extension] = mod
def import_object(self, objname, source=None):
"""Import an object from a 'module.name' string."""
@ -156,15 +177,18 @@ class Sphinx(object):
module, name = objname.rsplit('.', 1)
except ValueError, err:
raise ExtensionError('Invalid full object name %s' % objname +
(source and ' (needed for %s)' % source or ''), err)
(source and ' (needed for %s)' % source or ''),
err)
try:
return getattr(__import__(module, None, None, [name]), name)
except ImportError, err:
raise ExtensionError('Could not import %s' % module +
(source and ' (needed for %s)' % source or ''), err)
(source and ' (needed for %s)' % source or ''),
err)
except AttributeError, err:
raise ExtensionError('Could not find %s' % objname +
(source and ' (needed for %s)' % source or ''), err)
(source and ' (needed for %s)' % source or ''),
err)
# event interface
@ -204,16 +228,24 @@ class Sphinx(object):
def add_builder(self, builder):
if not hasattr(builder, 'name'):
raise ExtensionError('Builder class %s has no "name" attribute' % builder)
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):
def add_config_value(self, name, default, rebuild):
if name in self.config.values:
raise ExtensionError('Config value %r already present' % name)
self.config.values[name] = (default, rebuild_env)
if rebuild in (False, True):
rebuild = rebuild and 'env' or ''
self.config.values[name] = (default, rebuild)
def add_event(self, name):
if name in self._events:
@ -226,14 +258,14 @@ class Sphinx(object):
try:
visit, depart = val
except ValueError:
raise ExtensionError('Value for key %r must be a (visit, depart) '
'function tuple' % key)
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
@ -241,28 +273,42 @@ class Sphinx(object):
if depart:
setattr(translator, 'depart_'+node.__name__, depart)
def add_directive(self, name, func, content, arguments, **options):
func.content = content
func.arguments = arguments
func.options = options
directives.register_directive(name, func)
def add_directive(self, name, obj, content=None, arguments=None, **options):
if isinstance(obj, clstypes) and issubclass(obj, Directive):
if content or arguments or options:
raise ExtensionError('when adding directive classes, no '
'additional arguments may be given')
directives.register_directive(name, directive_dwim(obj))
else:
obj.content = content
obj.arguments = arguments
obj.options = options
directives.register_directive(name, obj)
def add_role(self, name, role):
roles.register_canonical_role(name, role)
roles.register_local_role(name, role)
def add_generic_role(self, name, nodeclass):
# don't use roles.register_generic_role because it uses
# register_canonical_role
role = roles.GenericRole(name, nodeclass)
roles.register_local_role(name, role)
def add_description_unit(self, directivename, rolename, indextemplate='',
parse_node=None, ref_nodeclass=None):
additional_xref_types[directivename] = (rolename, indextemplate, parse_node)
directives.register_directive(directivename, desc_directive)
roles.register_canonical_role(rolename, xfileref_role)
additional_xref_types[directivename] = (rolename, indextemplate,
parse_node)
directives.register_directive(directivename,
directive_dwim(GenericDesc))
roles.register_local_role(rolename, xfileref_role)
if ref_nodeclass is not None:
innernodetypes[rolename] = ref_nodeclass
def add_crossref_type(self, directivename, rolename, indextemplate='',
ref_nodeclass=None):
additional_xref_types[directivename] = (rolename, indextemplate, None)
directives.register_directive(directivename, target_directive)
roles.register_canonical_role(rolename, xfileref_role)
directives.register_directive(directivename, directive_dwim(Target))
roles.register_local_role(rolename, xfileref_role)
if ref_nodeclass is not None:
innernodetypes[rolename] = ref_nodeclass
@ -270,9 +316,25 @@ 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
def add_autodocumenter(self, cls):
from sphinx.ext import autodoc
autodoc.add_documenter(cls)
self.add_directive('auto' + cls.objtype, autodoc.AutoDirective)
def add_autodoc_attrgetter(self, type, getter):
from sphinx.ext import autodoc
autodoc.AutoDirective._special_attrgetters[type] = getter
class TemplateBridge(object):
"""
@ -280,11 +342,15 @@ class TemplateBridge(object):
that renders templates given a template name and a context.
"""
def init(self, builder):
def init(self, builder, theme=None, dirs=None):
"""
Called by the builder to initialize the template system. *builder*
is the builder object; you'll probably want to look at the value of
``builder.config.templates_path``.
Called by the builder to initialize the template system.
*builder* is the builder object; you'll probably want to look at the
value of ``builder.config.templates_path``.
*theme* is a :class:`sphinx.theming.Theme` object or None; in the latter
case, *dirs* can be list of fixed directories to look for templates.
"""
raise NotImplementedError('must be implemented in subclasses')
@ -298,7 +364,14 @@ class TemplateBridge(object):
def render(self, template, context):
"""
Called by the builder to render a *template* with a specified
context (a Python dictionary).
Called by the builder to render a template given as a filename with a
specified context (a Python dictionary).
"""
raise NotImplementedError('must be implemented in subclasses')
def render_string(self, template, context):
"""
Called by the builder to render a template given as a string with a
specified context (a Python dictionary).
"""
raise NotImplementedError('must be implemented in subclasses')

File diff suppressed because it is too large Load Diff

384
sphinx/builders/__init__.py Normal file
View File

@ -0,0 +1,384 @@
# -*- 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, term_width_line
# 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 = ''
# builder's output format, or '' if no document output is produced
format = ''
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 create_template_bridge(self):
"""
Return the template bridge configured.
"""
if self.config.template_bridge:
self.templates = self.app.import_object(
self.config.template_bridge, 'template_bridge setting')()
else:
from sphinx.jinja2glue import BuiltinTemplateLoader
self.templates = BuiltinTemplateLoader()
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 old_status_iterator(self, iterable, summary, colorfunc=darkgreen):
l = 0
for item in iterable:
if l == 0:
self.info(bold(summary), nonl=1)
l = 1
self.info(colorfunc(item) + ' ', nonl=1)
yield item
if l == 1:
self.info()
# new version with progress info
def status_iterator(self, iterable, summary, colorfunc=darkgreen, length=0):
if length == 0:
for item in self.old_status_iterator(iterable, summary, colorfunc):
yield item
return
l = 0
summary = bold(summary)
for item in iterable:
l += 1
self.info(term_width_line('%s[%3d%%] %s' %
(summary, 100*l/length,
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(
'no matching candidate for image URI %r' % node['uri'],
'%s:%s' % (node.source, getattr(node, 'line', '')))
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 = set()
# while reading, collect all warnings from docutils
warnings = []
self.env.set_warnfunc(lambda *args: warnings.append(args))
self.info(bold('updating environment: '), nonl=1)
msg, length, iterator = self.env.update(self.config, self.srcdir,
self.doctreedir, self.app)
self.info(msg)
for docname in self.status_iterator(iterator, 'reading sources... ',
purple, length):
updated_docnames.add(docname)
# nothing further to do, the environment has already
# done the reading
for warning in warnings:
self.warn(*warning)
self.env.set_warnfunc(self.warn)
doccount = len(updated_docnames)
self.info(bold('looking for now-outdated files... '), nonl=1)
for docname in self.env.check_dependents(updated_docnames):
updated_docnames.add(docname)
outdated = len(updated_docnames) - doccount
if outdated:
self.info('%d found' % outdated)
else:
self.info('none found')
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, list(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(lambda *args: warnings.append(args))
for docname in self.status_iterator(
sorted(docnames), 'writing output... ', darkgreen, len(docnames)):
doctree = self.env.get_and_resolve_doctree(docname, self)
self.write_doc(docname, doctree)
for warning in warnings:
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
def cleanup(self):
"""
Cleanup any resources. The default implementation does nothing.
"""
BUILTIN_BUILDERS = {
'html': ('html', 'StandaloneHTMLBuilder'),
'dirhtml': ('html', 'DirectoryHTMLBuilder'),
'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'),
}

156
sphinx/builders/changes.py Normal file
View File

@ -0,0 +1,156 @@
# -*- 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, copy_static_entry
from sphinx.theming import Theme
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.create_template_bridge()
Theme.init_themes(self)
self.theme = Theme('default')
self.templates.init(self, self.theme)
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 version %s.' % version))
return
self.info(bold('writing summary file...'))
for type, docname, lineno, module, descname, content in \
self.env.versionchanges[version]:
if isinstance(descname, tuple):
descname = descname[0]
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()
themectx = dict(('theme_' + key, val) for (key, val) in
self.theme.get_options({}).iteritems())
copy_static_entry(path.join(package_dir, 'themes', 'default',
'static', 'default.css_t'),
path.join(self.outdir, 'default.css_t'),
self, themectx)
copy_static_entry(path.join(package_dir, 'themes', 'basic',
'static', 'basic.css'),
path.join(self.outdir, 'basic.css'), self)
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

836
sphinx/builders/html.py Normal file
View File

@ -0,0 +1,836 @@
# -*- 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 posixpath
import cPickle as pickle
from os import path
try:
from hashlib import md5
except ImportError:
# 2.4 compatibility
from md5 import md5
from docutils import nodes
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, copy_static_entry
from sphinx.errors import SphinxError
from sphinx.search import js_index
from sphinx.theming import Theme
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'
format = '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):
# a hash of all config values that, if changed, cause a full rebuild
self.config_hash = ''
self.tags_hash = ''
# section numbers for headings in the currently visited document
self.secnumbers = {}
self.init_templates()
self.init_highlighter()
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_templates(self):
Theme.init_themes(self)
self.theme = Theme(self.config.html_theme)
self.create_template_bridge()
self.templates.init(self, self.theme)
def init_highlighter(self):
# determine Pygments style and create the highlighter
if self.config.pygments_style is not None:
style = self.config.pygments_style
elif self.theme:
style = self.theme.get_confstr('theme', 'pygments_style', 'none')
else:
style = 'sphinx'
self.highlighter = PygmentsBridge('html', style)
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 get_outdated_docs(self):
cfgdict = dict((name, self.config[name])
for (name, desc) in self.config.values.iteritems()
if desc[1] == 'html')
self.config_hash = md5(str(cfgdict)).hexdigest()
self.tags_hash = md5(str(sorted(self.tags))).hexdigest()
old_config_hash = old_tags_hash = ''
try:
fp = open(path.join(self.outdir, '.buildinfo'))
version = fp.readline()
if version.rstrip() != '# Sphinx build info version 1':
raise ValueError
fp.readline() # skip commentary
cfg, old_config_hash = fp.readline().strip().split(': ')
if cfg != 'config':
raise ValueError
tag, old_tags_hash = fp.readline().strip().split(': ')
if tag != 'tags':
raise ValueError
fp.close()
except ValueError:
self.warn('unsupported build info format in %r, building all' %
path.join(self.outdir, '.buildinfo'))
except Exception:
pass
if old_config_hash != self.config_hash or \
old_tags_hash != self.tags_hash:
for docname in self.env.found_docs:
yield docname
return
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 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')))
if self.config.html_style is not None:
stylename = self.config.html_style
elif self.theme:
stylename = self.theme.get_confstr('theme', 'stylesheet')
else:
stylename = 'default.css'
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,
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__,
style = stylename,
rellinks = rellinks,
builder = self.name,
parents = [],
logo = logo,
favicon = favicon,
)
if self.theme:
self.globalcontext.update(
('theme_' + key, val) for (key, val) in
self.theme.get_options(
self.config.html_theme_options).iteritems())
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)
# local TOC and global TOC tree
toc = self.render_partial(self.env.get_toc_for(docname))['fragment']
return dict(
parents = parents,
prev = prev,
next = next,
title = title,
meta = meta,
body = body,
metatags = metatags,
rellinks = rellinks,
sourcename = sourcename,
toc = toc,
# 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):
destination = StringOutput(encoding='utf-8')
doctree.settings = self.docsettings
self.secnumbers = self.env.toc_secnumbers.get(docname, {})
self.imgpath = relative_uri(self.get_target_uri(docname), '_images')
self.post_process_images(doctree)
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)
ignore = self.env.config['modindex_common_prefix']
ignore = sorted(ignore, key=len, reverse=True)
for i in ignore:
if mn.startswith(i):
mn = mn[len(i):]
stripped = i
break
else:
stripped = ''
if fl != mn[0].lower() and mn[0] != '_':
# heading
letter = mn[0].upper()
if letter not in letters:
modindexentries.append(['', False, 0, False,
letter, '', [], False, ''])
letters.append(letter)
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, stripped])
else:
num_toplevels += 1
cg += 1
modindexentries.append([mn, False, cg, (tn != mn), fn, sy, pl,
dep, stripped])
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
# As some parts of the module names may have been stripped, those
# names have changed, thus it is necessary to sort the entries.
if ignore:
def sorthelper(entry):
name = entry[0]
if name == '':
# heading
name = entry[4]
return name.lower()
modindexentries.sort(key=sorthelper)
letters.sort()
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(self.highlighter.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
if self.theme:
staticdirnames = [path.join(themepath, 'static')
for themepath in self.theme.get_dirchain()[::-1]]
else:
staticdirnames = []
staticdirnames += [path.join(self.confdir, spath)
for spath in self.config.html_static_path]
for staticdirname in staticdirnames:
if not path.isdir(staticdirname):
self.warn('static directory %r does not exist' % staticdirname)
continue
for filename in os.listdir(staticdirname):
if filename.startswith('.'):
continue
fullname = path.join(staticdirname, filename)
targetname = path.join(self.outdir, '_static', filename)
copy_static_entry(fullname, targetname, self,
self.globalcontext)
# 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))
# write build info file
fp = open(path.join(self.outdir, '.buildinfo'), 'w')
try:
fp.write('# Sphinx build info version 1\n'
'# This file hashes the configuration used when building'
' these files. When it is not found, a full rebuild will'
' be done.\nconfig: %s\ntags: %s\n' %
(self.config_hash, self.tags_hash))
finally:
fp.close()
self.info('done')
# dump the search index
self.handle_finish()
def cleanup(self):
# clean up theme stuff
if self.theme:
self.theme.cleanup()
def post_process_images(self, doctree):
"""
Pick the best candiate for an image and link down-scaled images to
their high res version.
"""
Builder.post_process_images(self, doctree)
for node in doctree.traverse(nodes.image):
if not node.has_key('scale') or \
isinstance(node.parent, nodes.reference):
# docutils does unfortunately not preserve the
# ``target`` attribute on images, so we need to check
# the parent node here.
continue
uri = node['uri']
reference = nodes.reference()
if uri in self.images:
reference['refuri'] = posixpath.join(self.imgpath,
self.images[uri])
else:
reference['refuri'] = uri
node.replace_self(reference)
reference.append(node)
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)
def _get_local_toctree(self, docname, collapse=True):
return self.render_partial(self.env.get_toctree_for(
docname, self, collapse))['fragment']
def get_outfilename(self, pagename):
return path.join(self.outdir, os_path(pagename) + self.out_suffix)
# --------- 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['toctree'] = lambda **kw: self._get_local_toctree(pagename, **kw)
ctx.update(addctx)
self.app.emit('html-page-context', pagename, templatename,
ctx, event_arg)
output = self.templates.render(templatename, ctx)
if not outfilename:
outfilename = self.get_outfilename(pagename)
# outfilename's path is in general different from self.outdir
ensuredir(path.dirname(outfilename))
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 DirectoryHTMLBuilder(StandaloneHTMLBuilder):
"""
A StandaloneHTMLBuilder that creates all HTML pages as "index.html" in
a directory given by their pagename, so that generated URLs don't have
``.html`` in them.
"""
name = 'dirhtml'
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 get_outfilename(self, pagename):
if pagename == 'index' or pagename.endswith(SEP + 'index'):
outfilename = path.join(self.outdir, os_path(pagename)
+ self.out_suffix)
else:
outfilename = path.join(self.outdir, os_path(pagename),
'index' + self.out_suffix)
return outfilename
class SerializingHTMLBuilder(StandaloneHTMLBuilder):
"""
An abstract builder that serializes the generated HTML.
"""
#: 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.config_hash = ''
self.tags_hash = ''
self.theme = None # no theme necessary
self.templates = None # no template bridge necessary
self.init_translator_class()
self.init_highlighter()
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:
raise SphinxError(
'The module simplejson (or json in Python >= 2.6) '
'is not available. The JSONHTMLBuilder builder will not work.')
SerializingHTMLBuilder.init(self)

250
sphinx/builders/htmlhelp.py Normal file
View File

@ -0,0 +1,250 @@
# -*- 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)
def istoctree(node):
return 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):
# XXX: better title?
write_param('Name', '[%d] %s' % (i, ref))
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()

203
sphinx/builders/latex.py Normal file
View File

@ -0,0 +1,203 @@
# -*- 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'
format = '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 get_relative_uri(self, from_, to, typ=None):
# ignore source path
return self.get_target_uri(to, typ)
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):
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
self.config.latex_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('toctree contains ref to nonexisting '
'file %r' % includefile,
self.builder.env.doc2path(docname))
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['docname'] = indexfile
for docname in appendices:
appendix = self.env.get_doctree(docname)
appendix['docname'] = docname
largetree.append(appendix)
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()
# copy additional files
if self.config.latex_additional_files:
self.info(bold('copying additional files...'), nonl=1)
for filename in self.config.latex_additional_files:
self.info(' '+filename, nonl=1)
shutil.copyfile(path.join(self.confdir, filename),
path.join(self.outdir, path.basename(filename)))
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')

View File

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
"""
sphinx.linkcheck
~~~~~~~~~~~~~~~~
sphinx.builders.linkcheck
~~~~~~~~~~~~~~~~~~~~~~~~~
The CheckExternalLinksBuilder class.
:copyright: 2008 by Georg Brandl, Thomas Lamb.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import socket
@ -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
@ -84,20 +84,28 @@ class CheckExternalLinksBuilder(Builder):
self.good.add(uri)
elif r == 2:
self.info(' - ' + red('broken: ') + s)
self.broken[uri] = (r, s)
self.write_entry('broken', docname, lineno, uri + ': ' + s)
self.broken[uri] = (r, s)
if self.app.quiet:
self.warn('broken link: %s' % uri,
'%s:%s' % (self.env.doc2path(docname), lineno))
else:
self.info(' - ' + purple('redirected') + ' to ' + s)
self.write_entry('redirected', docname,
lineno, uri + ' to ' + s)
self.redirected[uri] = (r, s)
self.write_entry('redirected', docname, lineno, uri + ' to ' + s)
elif len(uri) == 0 or uri[0:7] == 'mailto:' or uri[0:4] == 'ftp:':
return
else:
self.info(uri + ' - ' + red('malformed!'))
self.warn(uri + ' - ' + red('malformed!'))
self.write_entry('malformed', docname, lineno, uri)
if self.app.quiet:
self.warn('malformed link: %s' % uri,
'%s:%s' % (self.env.doc2path(docname), lineno))
self.app.statuscode = 1
return
if self.broken:
self.app.statuscode = 1
def write_entry(self, what, docname, line, uri):
output = open(path.join(self.outdir, 'output.txt'), 'a')

263
sphinx/builders/qthelp.py Normal file
View File

@ -0,0 +1,263 @@
# -*- 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(
r'(?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

70
sphinx/builders/text.py Normal file
View File

@ -0,0 +1,70 @@
# -*- 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'
format = '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))
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

222
sphinx/cmdline.py Normal file
View File

@ -0,0 +1,222 @@
# -*- coding: utf-8 -*-
"""
sphinx.cmdline
~~~~~~~~~~~~~~
sphinx-build command-line handling.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import sys
import getopt
import traceback
from os import path
from docutils.utils import SystemMessage
from sphinx import __version__
from sphinx.errors import SphinxError
from sphinx.application import Sphinx
from sphinx.util import Tee, format_exception_cut_frames, save_traceback
from sphinx.util.console import darkred, nocolor, color_terminal
def usage(argv, msg=None):
if msg:
print >>sys.stderr, msg
print >>sys.stderr
print >>sys.stderr, """\
Sphinx v%s
Usage: %s [options] sourcedir outdir [filenames...]
Options: -b <builder> -- builder to use; default is html
-a -- write all files; default is to only write \
new and changed files
-E -- don't use a saved environment, always read all files
-t <tag> -- include "only" blocks with <tag>
-d <path> -- path for the cached environment and doctree files
(default: outdir/.doctrees)
-c <path> -- path where configuration file (conf.py) is located
(default: same as sourcedir)
-C -- use no config file at all, only -D options
-D <setting=value> -- override a setting in configuration
-A <name=value> -- pass a value into the templates, for HTML builder
-g <path> -- auto-generate docs with sphinx.ext.autosummary
for autosummary directives in sources found in path
-N -- do not do colored output
-q -- no output on stdout, just warnings on stderr
-Q -- no output at all, not even warnings
-w <file> -- write warnings (and errors) to given file
-W -- turn warnings into errors
-P -- run Pdb on exception
Modi:
* without -a and without filenames, write new and changed files.
* with -a, write all files.
* with filenames, write these.""" % (__version__, argv[0])
def main(argv):
if not sys.stdout.isatty() or not color_terminal():
# Windows' poor cmd box doesn't understand ANSI sequences
nocolor()
try:
opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:g:NEqQWw:P')
allopts = set(opt[0] for opt in opts)
srcdir = confdir = path.abspath(args[0])
if not path.isdir(srcdir):
print >>sys.stderr, 'Error: Cannot find source directory.'
return 1
if not path.isfile(path.join(srcdir, 'conf.py')) and \
'-c' not in allopts and '-C' not in allopts:
print >>sys.stderr, ('Error: Source directory doesn\'t '
'contain conf.py file.')
return 1
outdir = path.abspath(args[1])
if not path.isdir(outdir):
print >>sys.stderr, 'Making output directory...'
os.makedirs(outdir)
except (IndexError, getopt.error):
usage(argv)
return 1
filenames = args[2:]
err = 0
for filename in filenames:
if not path.isfile(filename):
print >>sys.stderr, 'Cannot find file %r.' % filename
err = 1
if err:
return 1
buildername = all_files = None
freshenv = warningiserror = use_pdb = False
status = sys.stdout
warning = sys.stderr
error = sys.stderr
warnfile = None
confoverrides = {}
htmlcontext = {}
tags = []
doctreedir = path.join(outdir, '.doctrees')
for opt, val in opts:
if opt == '-b':
buildername = val
elif opt == '-a':
if filenames:
usage(argv, 'Cannot combine -a option and filenames.')
return 1
all_files = True
elif opt == '-t':
tags.append(val)
elif opt == '-d':
doctreedir = path.abspath(val)
elif opt == '-c':
confdir = path.abspath(val)
if not path.isfile(path.join(confdir, 'conf.py')):
print >>sys.stderr, ('Error: Configuration directory '
'doesn\'t contain conf.py file.')
return 1
elif opt == '-C':
confdir = None
elif opt == '-D':
try:
key, val = val.split('=')
except ValueError:
print >>sys.stderr, ('Error: -D option argument must be '
'in the form name=value.')
return 1
try:
val = int(val)
except ValueError:
pass
confoverrides[key] = val
elif opt == '-A':
try:
key, val = val.split('=')
except ValueError:
print >>sys.stderr, ('Error: -A option argument must be '
'in the form name=value.')
return 1
try:
val = int(val)
except ValueError:
pass
htmlcontext[key] = val
elif opt == '-g':
# XXX XXX XXX
source_filenames = [path.join(srcdir, f)
for f in os.listdir(srcdir) if f.endswith('.rst')]
if val is None:
print >>sys.stderr, \
'Error: you must provide a destination directory ' \
'for autodoc generation.'
return 1
p = path.abspath(val)
from sphinx.ext.autosummary.generate import generate_autosummary_docs
generate_autosummary_docs(source_filenames, p)
elif opt == '-N':
nocolor()
elif opt == '-E':
freshenv = True
elif opt == '-q':
status = None
elif opt == '-Q':
status = None
warning = None
elif opt == '-W':
warningiserror = True
elif opt == '-w':
warnfile = val
elif opt == '-P':
use_pdb = True
confoverrides['html_context'] = htmlcontext
if warning and warnfile:
warnfp = open(warnfile, 'w')
warning = Tee(warning, warnfp)
error = warning
try:
app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername,
confoverrides, status, warning, freshenv,
warningiserror, tags)
app.build(all_files, filenames)
return app.statuscode
except KeyboardInterrupt:
if use_pdb:
import pdb
print >>error, darkred('Interrupted while building, '
'starting debugger:')
traceback.print_exc()
pdb.post_mortem(sys.exc_info()[2])
return 1
except Exception, err:
if use_pdb:
import pdb
print >>error, darkred('Exception occurred while building, '
'starting debugger:')
traceback.print_exc()
pdb.post_mortem(sys.exc_info()[2])
else:
if isinstance(err, SystemMessage):
print >>error, darkred('reST markup error:')
print >>error, err.args[0].encode('ascii', 'backslashreplace')
elif isinstance(err, SphinxError):
print >>error, darkred('%s:' % err.category)
print >>error, err
else:
print >>error, darkred('Exception occurred:')
print >>error, format_exception_cut_frames().rstrip()
tbpath = save_traceback()
print >>error, darkred('The full traceback has been saved '
'in %s, if you want to report the '
'issue to the author.' % tbpath)
print >>error, ('Please also report this if it was a user '
'error, so that a better error message '
'can be provided next time.')
print >>error, ('Send reports to sphinx-dev@googlegroups.com. '
'Thanks!')
return 1

View File

@ -5,102 +5,121 @@
Build configuration file handling.
:copyright: 2008 by Georg Brandl.
:license: BSD license.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
from os import path
from sphinx.util import make_filename
class Config(object):
"""Configuration file abstraction."""
# the values are: (default, needs fresh doctrees if changed)
# the values are: (default, what needs to be rebuilt if changed)
# If you add a value here, don't forget to include it in the
# quickstart.py file template as well as in the docs!
config_values = dict(
# general options
project = ('Python', True),
copyright = ('', False),
version = ('', True),
release = ('', True),
today = ('', True),
today_fmt = (None, True), # the real default is locale-dependent
project = ('Python', 'env'),
copyright = ('', 'html'),
version = ('', 'env'),
release = ('', 'env'),
today = ('', 'env'),
today_fmt = (None, 'env'), # the real default is locale-dependent
language = (None, True),
locale_dirs = ([], True),
language = (None, 'env'),
locale_dirs = ([], 'env'),
master_doc = ('contents', True),
source_suffix = ('.rst', True),
source_encoding = ('utf-8', True),
unused_docs = ([], True),
exclude_dirs = ([], True),
exclude_trees = ([], True),
exclude_dirnames = ([], True),
default_role = (None, True),
add_function_parentheses = (True, True),
add_module_names = (True, True),
show_authors = (False, True),
pygments_style = ('sphinx', False),
highlight_language = ('python', False),
templates_path = ([], False),
template_bridge = (None, False),
keep_warnings = (False, True),
master_doc = ('contents', 'env'),
source_suffix = ('.rst', 'env'),
source_encoding = ('utf-8', 'env'),
unused_docs = ([], 'env'),
exclude_dirs = ([], 'env'),
exclude_trees = ([], 'env'),
exclude_dirnames = ([], 'env'),
default_role = (None, 'env'),
add_function_parentheses = (True, 'env'),
add_module_names = (True, 'env'),
trim_footnote_reference_space = (False, 'env'),
show_authors = (False, 'env'),
pygments_style = (None, 'html'),
highlight_language = ('python', 'env'),
templates_path = ([], 'html'),
template_bridge = (None, 'html'),
keep_warnings = (False, 'env'),
modindex_common_prefix = ([], 'html'),
rst_epilog = (None, 'env'),
# HTML options
html_theme = ('default', 'html'),
html_theme_path = ([], 'html'),
html_theme_options = ({}, 'html'),
html_title = (lambda self: '%s v%s documentation' %
(self.project, self.release),
False),
html_short_title = (lambda self: self.html_title, False),
html_style = ('default.css', False),
html_logo = (None, False),
html_favicon = (None, False),
html_static_path = ([], False),
html_last_updated_fmt = (None, False), # the real default is locale-dependent
html_use_smartypants = (True, False),
html_translator_class = (None, False),
html_sidebars = ({}, False),
html_additional_pages = ({}, False),
html_use_modindex = (True, False),
html_use_index = (True, False),
html_split_index = (False, False),
html_copy_source = (True, False),
html_use_opensearch = ('', False),
html_file_suffix = (None, False),
html_show_sphinx = (True, False),
html_context = ({}, False),
'html'),
html_short_title = (lambda self: self.html_title, 'html'),
html_style = (None, 'html'),
html_logo = (None, 'html'),
html_favicon = (None, 'html'),
html_static_path = ([], 'html'),
# the real default is locale-dependent
html_last_updated_fmt = (None, 'html'),
html_use_smartypants = (True, 'html'),
html_translator_class = (None, 'html'),
html_sidebars = ({}, 'html'),
html_additional_pages = ({}, 'html'),
html_use_modindex = (True, 'html'),
html_add_permalinks = (True, 'html'),
html_use_index = (True, 'html'),
html_split_index = (False, 'html'),
html_copy_source = (True, 'html'),
html_show_sourcelink = (True, 'html'),
html_use_opensearch = ('', 'html'),
html_file_suffix = (None, 'html'),
html_link_suffix = (None, 'html'),
html_show_sphinx = (True, 'html'),
html_context = ({}, 'html'),
# HTML help only options
htmlhelp_basename = ('pydoc', False),
htmlhelp_basename = (lambda self: make_filename(self.project), None),
# Qt help only options
qthelp_basename = (lambda self: make_filename(self.project), None),
# LaTeX options
latex_documents = ([], False),
latex_logo = (None, False),
latex_appendices = ([], False),
latex_use_parts = (False, False),
latex_use_modindex = (True, False),
latex_documents = ([], None),
latex_logo = (None, None),
latex_appendices = ([], None),
latex_use_parts = (False, None),
latex_use_modindex = (True, None),
# paper_size and font_size are still separate values
# so that you can give them easily on the command line
latex_paper_size = ('letter', False),
latex_font_size = ('10pt', False),
latex_elements = ({}, False),
latex_paper_size = ('letter', None),
latex_font_size = ('10pt', None),
latex_elements = ({}, None),
latex_additional_files = ([], None),
# now deprecated - use latex_elements
latex_preamble = ('', False),
latex_preamble = ('', None),
)
def __init__(self, dirname, filename, overrides):
def __init__(self, dirname, filename, overrides, tags):
self.overrides = overrides
self.values = Config.config_values.copy()
config = {'__file__': path.join(dirname, filename)}
olddir = os.getcwd()
try:
os.chdir(dirname)
execfile(config['__file__'], config)
finally:
os.chdir(olddir)
config = {}
if dirname is not None:
config['__file__'] = path.join(dirname, filename)
config['tags'] = tags
olddir = os.getcwd()
try:
os.chdir(dirname)
execfile(config['__file__'], config)
finally:
os.chdir(olddir)
self._raw_config = config
# these two must be preinitialized because extensions can add their
# own config values
@ -109,7 +128,12 @@ class Config(object):
def init_values(self):
config = self._raw_config
config.update(self.overrides)
for valname, value in self.overrides.iteritems():
if '.' in valname:
realvalname, key = valname.split('.', 1)
config.setdefault(realvalname, {})[key] = value
else:
config[valname] = value
for name in config:
if name in self.values:
self.__dict__[name] = config[name]
@ -121,7 +145,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

View File

@ -5,10 +5,23 @@
Handlers for additional ReST directives.
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from docutils.parsers.rst import directives
from docutils.parsers.rst.directives import images
# import and register directives
from sphinx.directives.desc import *
from sphinx.directives.code import *
from sphinx.directives.other import *
# allow units for the figure's "figwidth"
try:
images.Figure.option_spec['figwidth'] = \
directives.length_or_percentage_or_unitless
except AttributeError:
images.figure.options['figwidth'] = \
directives.length_or_percentage_or_unitless

View File

@ -3,10 +3,11 @@
sphinx.directives.code
~~~~~~~~~~~~~~~~~~~~~~
:copyright: 2007-2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import sys
import codecs
from os import path
@ -15,85 +16,161 @@ from docutils import nodes
from docutils.parsers.rst import directives
from sphinx import addnodes
from sphinx.util import parselinenos
from sphinx.util.compat import Directive, directive_dwim
# ------ highlight directive --------------------------------------------------------
class Highlight(Directive):
"""
Directive to set the highlighting language for code blocks, as well
as the threshold for line numbers.
"""
def highlightlang_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
if 'linenothreshold' in options:
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
option_spec = {
'linenothreshold': directives.unchanged,
}
def run(self):
if 'linenothreshold' in self.options:
try:
linenothreshold = int(self.options['linenothreshold'])
except Exception:
linenothreshold = 10
else:
linenothreshold = sys.maxint
return [addnodes.highlightlang(lang=self.arguments[0].strip(),
linenothreshold=linenothreshold)]
class CodeBlock(Directive):
"""
Directive for a code block with special highlighting or line numbering
settings.
"""
has_content = True
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
option_spec = {
'linenos': directives.flag,
}
def run(self):
code = u'\n'.join(self.content)
literal = nodes.literal_block(code, code)
literal['language'] = self.arguments[0]
literal['linenos'] = 'linenos' in self.options
return [literal]
class LiteralInclude(Directive):
"""
Like ``.. include:: :literal:``, but only warns if the include file is
not found, and does not raise errors. Also has several options for
selecting what to include.
"""
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
option_spec = {
'linenos': directives.flag,
'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,
}
def run(self):
document = self.state.document
filename = self.arguments[0]
if not document.settings.file_insertion_enabled:
return [document.reporter.warning('File insertion disabled',
line=self.lineno)]
env = document.settings.env
if filename.startswith('/') or filename.startswith(os.sep):
rel_fn = filename[1:]
else:
docdir = path.dirname(env.doc2path(env.docname, base=None))
rel_fn = path.normpath(path.join(docdir, filename))
fn = path.join(env.srcdir, rel_fn)
if 'pyobject' in self.options and 'lines' in self.options:
return [document.reporter.warning(
'Cannot use both "pyobject" and "lines" options',
line=self.lineno)]
encoding = self.options.get('encoding', env.config.source_encoding)
try:
linenothreshold = int(options['linenothreshold'])
except Exception:
linenothreshold = 10
else:
linenothreshold = sys.maxint
return [addnodes.highlightlang(lang=arguments[0].strip(),
linenothreshold=linenothreshold)]
f = codecs.open(fn, 'rU', encoding)
lines = f.readlines()
f.close()
except (IOError, OSError):
return [document.reporter.warning(
'Include file %r not found or reading it failed' % filename,
line=self.lineno)]
except UnicodeError:
return [document.reporter.warning(
'Encoding %r used for reading included file %r seems to '
'be wrong, try giving an :encoding: option' %
(encoding, filename))]
highlightlang_directive.content = 0
highlightlang_directive.arguments = (1, 0, 0)
highlightlang_directive.options = {'linenothreshold': directives.unchanged}
directives.register_directive('highlight', highlightlang_directive)
directives.register_directive('highlightlang', highlightlang_directive) # old name
objectname = self.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 [document.reporter.warning(
'Object named %r not found in include file %r' %
(objectname, filename), line=self.lineno)]
else:
lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]
linespec = self.options.get('lines')
if linespec is not None:
try:
linelist = parselinenos(linespec, len(lines))
except ValueError, err:
return [document.reporter.warning(str(err), line=self.lineno)]
lines = [lines[i] for i in linelist]
# ------ code-block directive -------------------------------------------------------
startafter = self.options.get('start-after')
endbefore = self.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
def codeblock_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
code = u'\n'.join(content)
literal = nodes.literal_block(code, code)
literal['language'] = arguments[0]
literal['linenos'] = 'linenos' in options
return [literal]
codeblock_directive.content = 1
codeblock_directive.arguments = (1, 0, 0)
codeblock_directive.options = {'linenos': directives.flag}
directives.register_directive('code-block', codeblock_directive)
directives.register_directive('sourcecode', codeblock_directive)
# ------ literalinclude directive ---------------------------------------------------
def literalinclude_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
"""Like .. include:: :literal:, but only warns if the include file is not found."""
if not state.document.settings.file_insertion_enabled:
return [state.document.reporter.warning('File insertion disabled', line=lineno)]
env = state.document.settings.env
rel_fn = arguments[0]
source_dir = path.dirname(path.abspath(state_machine.input_lines.source(
lineno - state_machine.input_offset - 1)))
fn = path.normpath(path.join(source_dir, rel_fn))
encoding = options.get('encoding', env.config.source_encoding)
try:
f = codecs.open(fn, 'r', encoding)
text = f.read()
f.close()
except (IOError, OSError):
retnode = state.document.reporter.warning(
'Include file %r not found or reading it failed' % arguments[0], line=lineno)
except UnicodeError:
retnode = 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:
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:
if self.options.get('language', ''):
retnode['language'] = self.options['language']
if 'linenos' in self.options:
retnode['linenos'] = True
state.document.settings.env.note_dependency(rel_fn)
return [retnode]
document.settings.env.note_dependency(rel_fn)
return [retnode]
literalinclude_directive.options = {'linenos': directives.flag,
'language': directives.unchanged,
'encoding': directives.encoding}
literalinclude_directive.content = 0
literalinclude_directive.arguments = (1, 0, 0)
directives.register_directive('literalinclude', literalinclude_directive)
directives.register_directive('highlight', directive_dwim(Highlight))
directives.register_directive('highlightlang', directive_dwim(Highlight)) # old
directives.register_directive('code-block', directive_dwim(CodeBlock))
directives.register_directive('sourcecode', directive_dwim(CodeBlock))
directives.register_directive('literalinclude', directive_dwim(LiteralInclude))

File diff suppressed because it is too large Load Diff

View File

@ -3,248 +3,329 @@
sphinx.directives.other
~~~~~~~~~~~~~~~~~~~~~~~
:copyright: 2007-2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
import posixpath
from docutils import nodes
from docutils.parsers.rst import directives
from sphinx import addnodes
from sphinx.util import patfilter
from sphinx.roles import caption_ref_re
from sphinx.locale import pairindextypes
from sphinx.util.compat import make_admonition
from sphinx.util import patfilter, ws_re, caption_ref_re, url_re, docname_join
from sphinx.util.compat import Directive, directive_dwim, make_admonition
# ------ the TOC tree ---------------------------------------------------------------
class TocTree(Directive):
"""
Directive to notify Sphinx about the hierarchical structure of the docs,
and to include a table-of-contents like tree in the current document.
"""
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
has_content = True
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
option_spec = {
'maxdepth': int,
'glob': directives.flag,
'hidden': directives.flag,
'numbered': directives.flag,
}
ret = []
subnode = addnodes.toctree()
includefiles = []
includetitles = {}
all_docnames = env.found_docs.copy()
# don't add the currently visited file in catch-all patterns
all_docnames.remove(env.docname)
for entry in content:
if not entry:
continue
if not glob:
# look for explicit titles and documents ("Some Title <document>").
m = caption_ref_re.match(entry)
if m:
docname = m.group(2)
includetitles[docname] = m.group(1)
def run(self):
env = self.state.document.settings.env
suffix = env.config.source_suffix
glob = 'glob' in self.options
ret = []
# (title, ref) pairs, where ref may be a document, or an external link,
# and title may be None if the document's title is to be used
entries = []
includefiles = []
includetitles = {}
all_docnames = env.found_docs.copy()
# don't add the currently visited file in catch-all patterns
all_docnames.remove(env.docname)
for entry in self.content:
if not entry:
continue
if not glob:
# look for explicit titles ("Some Title <document>")
m = caption_ref_re.match(entry)
if m:
ref = m.group(2)
title = m.group(1)
docname = ref
else:
ref = docname = entry
title = None
# remove suffixes (backwards compatibility)
if docname.endswith(suffix):
docname = docname[:-len(suffix)]
# absolutize filenames
docname = docname_join(env.docname, docname)
if url_re.match(ref) or ref == 'self':
entries.append((title, ref))
elif docname not in env.found_docs:
ret.append(self.state.document.reporter.warning(
'toctree references unknown document %r' % docname,
line=self.lineno))
else:
entries.append((title, docname))
includefiles.append(docname)
else:
docname = entry
# remove suffixes (backwards compatibility)
if docname.endswith(suffix):
docname = docname[:-len(suffix)]
# absolutize filenames
docname = posixpath.normpath(posixpath.join(dirname, 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))
docnames = sorted(patfilter(all_docnames, patname))
for docname in docnames:
all_docnames.remove(docname) # don't include it again
includefiles.append(docname)
if not docnames:
ret.append(state.document.reporter.warning(
'toctree glob pattern %r didn\'t match any documents' % entry,
line=lineno))
subnode['includefiles'] = includefiles
subnode['includetitles'] = includetitles
subnode['maxdepth'] = options.get('maxdepth', -1)
subnode['glob'] = glob
ret.append(subnode)
return ret
toctree_directive.content = 1
toctree_directive.options = {'maxdepth': int, 'glob': directives.flag}
directives.register_directive('toctree', toctree_directive)
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
entries.append((None, docname))
includefiles.append(docname)
if not docnames:
ret.append(self.state.document.reporter.warning(
'toctree glob pattern %r didn\'t match any documents'
% entry, line=self.lineno))
subnode = addnodes.toctree()
subnode['parent'] = env.docname
# entries contains all entries (self references, external links etc.)
subnode['entries'] = entries
# includefiles only entries that are documents
subnode['includefiles'] = includefiles
subnode['maxdepth'] = self.options.get('maxdepth', -1)
subnode['glob'] = glob
subnode['hidden'] = 'hidden' in self.options
subnode['numbered'] = 'numbered' in self.options
ret.append(subnode)
return ret
# ------ section metadata ----------------------------------------------------------
class Module(Directive):
"""
Directive to mark description of a new module.
"""
def module_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
env = state.document.settings.env
modname = arguments[0].strip()
noindex = 'noindex' in options
env.currmodule = modname
env.note_module(modname, options.get('synopsis', ''),
options.get('platform', ''),
'deprecated' in options)
modulenode = addnodes.module()
modulenode['modname'] = modname
modulenode['synopsis'] = options.get('synopsis', '')
targetnode = nodes.target('', '', ids=['module-' + modname])
state.document.note_explicit_target(targetnode)
ret = [modulenode, targetnode]
if 'platform' in options:
modulenode['platform'] = options['platform']
node = nodes.paragraph()
node += nodes.emphasis('', _('Platforms: '))
node += nodes.Text(options['platform'], options['platform'])
ret.append(node)
# the synopsis isn't printed; in fact, it is only used in the modindex currently
if not noindex:
indextext = _('%s (module)') % modname
inode = addnodes.index(entries=[('single', indextext,
'module-' + modname, modname)])
ret.insert(0, inode)
return ret
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
option_spec = {
'platform': lambda x: x,
'synopsis': lambda x: x,
'noindex': directives.flag,
'deprecated': directives.flag,
}
module_directive.arguments = (1, 0, 0)
module_directive.options = {'platform': lambda x: x,
'synopsis': lambda x: x,
'noindex': directives.flag,
'deprecated': directives.flag}
directives.register_directive('module', module_directive)
def currentmodule_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
# This directive is just to tell people that we're documenting
# stuff in module foo, but links to module foo won't lead here.
env = state.document.settings.env
modname = arguments[0].strip()
if modname == 'None':
env.currmodule = None
else:
def run(self):
env = self.state.document.settings.env
modname = self.arguments[0].strip()
noindex = 'noindex' in self.options
env.currmodule = modname
return []
currentmodule_directive.arguments = (1, 0, 0)
directives.register_directive('currentmodule', currentmodule_directive)
env.note_module(modname, self.options.get('synopsis', ''),
self.options.get('platform', ''),
'deprecated' in self.options)
modulenode = addnodes.module()
modulenode['modname'] = modname
modulenode['synopsis'] = self.options.get('synopsis', '')
targetnode = nodes.target('', '', ids=['module-' + modname], ismod=True)
self.state.document.note_explicit_target(targetnode)
ret = [modulenode, targetnode]
if 'platform' in self.options:
platform = self.options['platform']
modulenode['platform'] = platform
node = nodes.paragraph()
node += nodes.emphasis('', _('Platforms: '))
node += nodes.Text(platform, platform)
ret.append(node)
# the synopsis isn't printed; in fact, it is only used in the
# modindex currently
if not noindex:
indextext = _('%s (module)') % modname
inode = addnodes.index(entries=[('single', indextext,
'module-' + modname, modname)])
ret.insert(0, inode)
return ret
def author_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
# Show authors only if the show_authors option is on
env = state.document.settings.env
if not env.config.show_authors:
return []
para = nodes.paragraph()
emph = nodes.emphasis()
para += emph
if name == 'sectionauthor':
text = _('Section author: ')
elif name == 'moduleauthor':
text = _('Module author: ')
else:
text = _('Author: ')
emph += nodes.Text(text, text)
inodes, messages = state.inline_text(arguments[0], lineno)
emph.extend(inodes)
return [para] + messages
class CurrentModule(Directive):
"""
This directive is just to tell Sphinx that we're documenting
stuff in module foo, but links to module foo won't lead here.
"""
author_directive.arguments = (1, 0, 1)
directives.register_directive('sectionauthor', author_directive)
directives.register_directive('moduleauthor', author_directive)
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
option_spec = {}
# ------ index markup --------------------------------------------------------------
indextypes = [
'single', 'pair', 'triple',
]
def index_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
arguments = arguments[0].split('\n')
env = state.document.settings.env
targetid = 'index-%s' % env.index_num
env.index_num += 1
targetnode = nodes.target('', '', ids=[targetid])
state.document.note_explicit_target(targetnode)
indexnode = addnodes.index()
indexnode['entries'] = ne = []
for entry in arguments:
entry = entry.strip()
for type in pairindextypes:
if entry.startswith(type+':'):
value = entry[len(type)+1:].strip()
value = pairindextypes[type] + '; ' + value
ne.append(('pair', value, targetid, value))
break
def run(self):
env = self.state.document.settings.env
modname = self.arguments[0].strip()
if modname == 'None':
env.currmodule = None
else:
for type in indextypes:
env.currmodule = modname
return []
class Author(Directive):
"""
Directive to give the name of the author of the current document
or section. Shown in the output only if the show_authors option is on.
"""
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {}
def run(self):
env = self.state.document.settings.env
if not env.config.show_authors:
return []
para = nodes.paragraph()
emph = nodes.emphasis()
para += emph
if self.name == 'sectionauthor':
text = _('Section author: ')
elif self.name == 'moduleauthor':
text = _('Module author: ')
else:
text = _('Author: ')
emph += nodes.Text(text, text)
inodes, messages = self.state.inline_text(self.arguments[0],
self.lineno)
emph.extend(inodes)
return [para] + messages
class Program(Directive):
"""
Directive to name the program for which options are documented.
"""
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {}
def run(self):
env = self.state.document.settings.env
program = ws_re.sub('-', self.arguments[0].strip())
if program == 'None':
env.currprogram = None
else:
env.currprogram = program
return []
class Index(Directive):
"""
Directive to add entries to the index.
"""
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {}
indextypes = [
'single', 'pair', 'triple',
]
def run(self):
arguments = self.arguments[0].split('\n')
env = self.state.document.settings.env
targetid = 'index-%s' % env.index_num
env.index_num += 1
targetnode = nodes.target('', '', ids=[targetid])
self.state.document.note_explicit_target(targetnode)
indexnode = addnodes.index()
indexnode['entries'] = ne = []
for entry in arguments:
entry = entry.strip()
for type in pairindextypes:
if entry.startswith(type+':'):
value = entry[len(type)+1:].strip()
ne.append((type, value, targetid, value))
value = pairindextypes[type] + '; ' + value
ne.append(('pair', value, targetid, value))
break
# shorthand notation for single entries
else:
for value in entry.split(','):
ne.append(('single', value.strip(), targetid, value.strip()))
return [indexnode, targetnode]
index_directive.arguments = (1, 0, 1)
directives.register_directive('index', index_directive)
# ------ versionadded/versionchanged -----------------------------------------------
def version_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
node = addnodes.versionmodified()
node['type'] = name
node['version'] = arguments[0]
if len(arguments) == 2:
inodes, messages = state.inline_text(arguments[1], lineno+1)
node.extend(inodes)
if content:
state.nested_parse(content, content_offset, node)
ret = [node] + messages
else:
ret = [node]
env = state.document.settings.env
env.note_versionchange(node['type'], node['version'], node, lineno)
return ret
version_directive.arguments = (1, 1, 1)
version_directive.content = 1
directives.register_directive('deprecated', version_directive)
directives.register_directive('versionadded', version_directive)
directives.register_directive('versionchanged', version_directive)
for type in self.indextypes:
if entry.startswith(type+':'):
value = entry[len(type)+1:].strip()
ne.append((type, value, targetid, value))
break
# shorthand notation for single entries
else:
for value in entry.split(','):
value = value.strip()
if not value:
continue
ne.append(('single', value, targetid, value))
return [indexnode, targetnode]
# ------ see also ------------------------------------------------------------------
class VersionChange(Directive):
"""
Directive to describe a change/addition/deprecation in a specific version.
"""
def seealso_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
seealsonode = make_admonition(
addnodes.seealso, name, [_('See also')], options, content,
lineno, content_offset, block_text, state, state_machine)
if arguments:
argnodes, msgs = state.inline_text(arguments[0], lineno)
para = nodes.paragraph()
para += argnodes
seealsonode[1:1] = [para] + msgs
return [seealsonode]
has_content = True
required_arguments = 1
optional_arguments = 1
final_argument_whitespace = True
option_spec = {}
seealso_directive.content = 1
seealso_directive.arguments = (0, 1, 1)
directives.register_directive('seealso', seealso_directive)
def run(self):
node = addnodes.versionmodified()
node.document = self.state.document
node['type'] = self.name
node['version'] = self.arguments[0]
if len(self.arguments) == 2:
inodes, messages = self.state.inline_text(self.arguments[1],
self.lineno+1)
node.extend(inodes)
if self.content:
self.state.nested_parse(self.content, self.content_offset, node)
ret = [node] + messages
else:
ret = [node]
env = self.state.document.settings.env
env.note_versionchange(node['type'], node['version'], node, self.lineno)
return ret
# ------ production list (for the reference) ---------------------------------------
class SeeAlso(Directive):
"""
An admonition mentioning things to look at as reference.
"""
has_content = True
required_arguments = 0
optional_arguments = 1
final_argument_whitespace = True
option_spec = {}
def run(self):
ret = make_admonition(
addnodes.seealso, self.name, [_('See also')], self.options,
self.content, self.lineno, self.content_offset, self.block_text,
self.state, self.state_machine)
if self.arguments:
argnodes, msgs = self.state.inline_text(self.arguments[0],
self.lineno)
para = nodes.paragraph()
para += argnodes
para += msgs
ret[0].insert(1, para)
return ret
token_re = re.compile('`([a-z_]+)`')
@ -267,116 +348,223 @@ def token_xrefs(text, env):
retnodes.append(nodes.Text(text[pos:], text[pos:]))
return retnodes
def productionlist_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
env = state.document.settings.env
node = addnodes.productionlist()
messages = []
i = 0
class ProductionList(Directive):
"""
Directive to list grammar productions.
"""
for rule in arguments[0].split('\n'):
if i == 0 and ':' not in rule:
# production group
continue
i += 1
try:
name, tokens = rule.split(':', 1)
except ValueError:
break
subnode = addnodes.production()
subnode['tokenname'] = name.strip()
if subnode['tokenname']:
idname = 'grammar-token-%s' % subnode['tokenname']
if idname not in state.document.ids:
subnode['ids'].append(idname)
state.document.note_implicit_target(subnode, subnode)
env.note_reftarget('token', subnode['tokenname'], idname)
subnode.extend(token_xrefs(tokens, env))
node.append(subnode)
return [node] + messages
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {}
productionlist_directive.content = 0
productionlist_directive.arguments = (1, 0, 1)
directives.register_directive('productionlist', productionlist_directive)
def run(self):
env = self.state.document.settings.env
node = addnodes.productionlist()
messages = []
i = 0
# ------ glossary directive ---------------------------------------------------------
def glossary_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
"""Glossary with cross-reference targets for :term: roles."""
env = state.document.settings.env
node = addnodes.glossary()
state.nested_parse(content, content_offset, node)
# the content should be definition lists
dls = [child for child in node if isinstance(child, nodes.definition_list)]
# now, extract definition terms to enable cross-reference creation
for dl in dls:
dl['classes'].append('glossary')
for li in dl.children:
if not li.children or not isinstance(li[0], nodes.term):
for rule in self.arguments[0].split('\n'):
if i == 0 and ':' not in rule:
# production group
continue
termtext = li.children[0].astext()
new_id = 'term-' + nodes.make_id(termtext)
if new_id in env.gloss_entries:
new_id = 'term-' + str(len(env.gloss_entries))
env.gloss_entries.add(new_id)
li[0]['names'].append(new_id)
li[0]['ids'].append(new_id)
state.document.settings.env.note_reftarget('term', termtext.lower(),
new_id)
# add an index entry too
indexnode = addnodes.index()
indexnode['entries'] = [('single', termtext, new_id, termtext)]
li.insert(0, indexnode)
return [node]
glossary_directive.content = 1
glossary_directive.arguments = (0, 0, 0)
directives.register_directive('glossary', glossary_directive)
i += 1
try:
name, tokens = rule.split(':', 1)
except ValueError:
break
subnode = addnodes.production()
subnode['tokenname'] = name.strip()
if subnode['tokenname']:
idname = 'grammar-token-%s' % subnode['tokenname']
if idname not in self.state.document.ids:
subnode['ids'].append(idname)
self.state.document.note_implicit_target(subnode, subnode)
env.note_reftarget('token', subnode['tokenname'], idname)
subnode.extend(token_xrefs(tokens, env))
node.append(subnode)
return [node] + messages
# ------ miscellaneous markup -------------------------------------------------------
class TabularColumns(Directive):
"""
Directive to give an explicit tabulary column definition to LaTeX.
"""
def centered_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
if not arguments:
return []
subnode = addnodes.centered()
inodes, messages = state.inline_text(arguments[0], lineno)
subnode.extend(inodes)
return [subnode] + messages
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {}
centered_directive.arguments = (1, 0, 1)
directives.register_directive('centered', centered_directive)
def run(self):
node = addnodes.tabular_col_spec()
node['spec'] = self.arguments[0]
return [node]
def acks_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
node = addnodes.acks()
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('.. acks content is not a list',
line=lineno)]
return [node]
class Glossary(Directive):
"""
Directive to create a glossary with cross-reference targets
for :term: roles.
"""
acks_directive.content = 1
acks_directive.arguments = (0, 0, 0)
directives.register_directive('acks', acks_directive)
has_content = True
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
option_spec = {}
def run(self):
env = self.state.document.settings.env
node = addnodes.glossary()
node.document = self.state.document
self.state.nested_parse(self.content, self.content_offset, node)
# the content should be definition lists
dls = [child for child in node
if isinstance(child, nodes.definition_list)]
# now, extract definition terms to enable cross-reference creation
for dl in dls:
dl['classes'].append('glossary')
for li in dl.children:
if not li.children or not isinstance(li[0], nodes.term):
continue
termtext = li.children[0].astext()
new_id = 'term-' + nodes.make_id(termtext)
if new_id in env.gloss_entries:
new_id = 'term-' + str(len(env.gloss_entries))
env.gloss_entries.add(new_id)
li[0]['names'].append(new_id)
li[0]['ids'].append(new_id)
env.note_reftarget('term', termtext.lower(), new_id)
# add an index entry too
indexnode = addnodes.index()
indexnode['entries'] = [('single', termtext, new_id, termtext)]
li.insert(0, indexnode)
return [node]
def tabularcolumns_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
# support giving explicit tabulary column definition to latex
node = addnodes.tabular_col_spec()
node['spec'] = arguments[0]
return [node]
class Centered(Directive):
"""
Directive to create a centered line of bold text.
"""
tabularcolumns_directive.content = 0
tabularcolumns_directive.arguments = (1, 0, 1)
directives.register_directive('tabularcolumns', tabularcolumns_directive)
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {}
def run(self):
if not self.arguments:
return []
subnode = addnodes.centered()
inodes, messages = self.state.inline_text(self.arguments[0],
self.lineno)
subnode.extend(inodes)
return [subnode] + messages
class Acks(Directive):
"""
Directive for a list of names.
"""
has_content = True
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
option_spec = {}
def run(self):
node = addnodes.acks()
node.document = self.state.document
self.state.nested_parse(self.content, self.content_offset, node)
if len(node.children) != 1 or not isinstance(node.children[0],
nodes.bullet_list):
return [self.state.document.reporter.warning(
'.. acks content is not a list', line=self.lineno)]
return [node]
class HList(Directive):
"""
Directive for a list that gets compacted horizontally.
"""
has_content = True
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
option_spec = {
'columns': int,
}
def run(self):
ncolumns = self.options.get('columns', 2)
node = nodes.paragraph()
node.document = self.state.document
self.state.nested_parse(self.content, self.content_offset, node)
if len(node.children) != 1 or not isinstance(node.children[0],
nodes.bullet_list):
return [self.state.document.reporter.warning(
'.. hlist content is not a list', line=self.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]
class Only(Directive):
"""
Directive to only include text if the given tag(s) are enabled.
"""
has_content = True
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {}
def run(self):
node = addnodes.only()
node.document = self.state.document
node.line = self.lineno
node['expr'] = self.arguments[0]
self.state.nested_parse(self.content, self.content_offset, node)
return [node]
directives.register_directive('toctree', directive_dwim(TocTree))
directives.register_directive('module', directive_dwim(Module))
directives.register_directive('currentmodule', directive_dwim(CurrentModule))
directives.register_directive('sectionauthor', directive_dwim(Author))
directives.register_directive('moduleauthor', directive_dwim(Author))
directives.register_directive('program', directive_dwim(Program))
directives.register_directive('index', directive_dwim(Index))
directives.register_directive('deprecated', directive_dwim(VersionChange))
directives.register_directive('versionadded', directive_dwim(VersionChange))
directives.register_directive('versionchanged', directive_dwim(VersionChange))
directives.register_directive('seealso', directive_dwim(SeeAlso))
directives.register_directive('productionlist', directive_dwim(ProductionList))
directives.register_directive('tabularcolumns', directive_dwim(TabularColumns))
directives.register_directive('glossary', directive_dwim(Glossary))
directives.register_directive('centered', directive_dwim(Centered))
directives.register_directive('acks', directive_dwim(Acks))
directives.register_directive('hlist', directive_dwim(HList))
directives.register_directive('only', directive_dwim(Only))
# register the standard rst class directive under a different name

File diff suppressed because it is too large Load Diff

48
sphinx/errors.py Normal file
View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
"""
sphinx.errors
~~~~~~~~~~~~~
Contains SphinxError and a few subclasses (in an extra module to avoid
circular import problems).
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
class SphinxError(Exception):
"""
Base class for Sphinx errors that are shown to the user in a nicer
way than normal exceptions.
"""
category = 'Sphinx error'
class SphinxWarning(SphinxError):
"""Raised for warnings if warnings are treated as errors."""
category = 'Warning, treated as error'
class ExtensionError(SphinxError):
"""Raised if something's wrong with the configuration."""
category = 'Extension error'
def __init__(self, message, orig_exc=None):
super(ExtensionError, self).__init__(message)
self.orig_exc = orig_exc
def __repr__(self):
if self.orig_exc:
return '%s(%r, %r)' % (self.__class__.__name__,
self.message, self.orig_exc)
return '%s(%r)' % (self.__class__.__name__, self.message)
def __str__(self):
parent_str = super(ExtensionError, self).__str__()
if self.orig_exc:
return '%s (exception: %s)' % (parent_str, self.orig_exc)
return parent_str
class ThemeError(SphinxError):
category = 'Theme error'

View File

@ -5,6 +5,6 @@
Contains Sphinx features not activated by default.
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,8 @@
Check Python modules and C API for coverage. Mostly written by Josip
Dzolonga for the Google Highly Open Participation contest.
:copyright: 2008 by Josip Dzolonga, Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
@ -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
@ -53,17 +53,17 @@ class CoverageBuilder(Builder):
self.c_ignorexps = {}
for (name, exps) in self.config.coverage_ignore_c_items.iteritems():
self.c_ignorexps[name] = compile_regex_list('coverage_ignore_c_items',
exps, self.warn)
self.mod_ignorexps = compile_regex_list('coverage_ignore_modules',
self.config.coverage_ignore_modules,
self.warn)
self.cls_ignorexps = compile_regex_list('coverage_ignore_classes',
self.config.coverage_ignore_classes,
self.warn)
self.fun_ignorexps = compile_regex_list('coverage_ignore_functions',
self.config.coverage_ignore_functions,
self.warn)
self.c_ignorexps[name] = compile_regex_list(
'coverage_ignore_c_items', exps, self.warn)
self.mod_ignorexps = compile_regex_list(
'coverage_ignore_modules', self.config.coverage_ignore_modules,
self.warn)
self.cls_ignorexps = compile_regex_list(
'coverage_ignore_classes', self.config.coverage_ignore_classes,
self.warn)
self.fun_ignorexps = compile_regex_list(
'coverage_ignore_functions', self.config.coverage_ignore_functions,
self.warn)
def get_outdated_docs(self):
return 'coverage overview'
@ -128,7 +128,8 @@ class CoverageBuilder(Builder):
try:
mod = __import__(mod_name, fromlist=['foo'])
except ImportError, err:
self.warn('module %s could not be imported: %s' % (mod_name, err))
self.warn('module %s could not be imported: %s' %
(mod_name, err))
self.py_undoc[mod_name] = {'error': err}
continue
@ -168,7 +169,8 @@ class CoverageBuilder(Builder):
attrs = []
for attr_name, attr in inspect.getmembers(obj, inspect.ismethod):
for attr_name, attr in inspect.getmembers(
obj, inspect.ismethod):
if attr_name[0] == '_':
# starts with an underscore, ignore it
continue

View File

@ -6,13 +6,14 @@
Mimic doctest by automatically executing code snippets and checking
their results.
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
import sys
import time
import codecs
import StringIO
from os import path
# circumvent relative import
@ -21,7 +22,8 @@ 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.compat import Directive
from sphinx.util.console import bold
blankline_re = re.compile(r'^\s*<BLANKLINE>', re.MULTILINE)
@ -29,63 +31,77 @@ doctestopt_re = re.compile(r'#\s*doctest:.+$', re.MULTILINE)
# set up the necessary directives
def test_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
# use ordinary docutils nodes for test code: they get special attributes
# so that our builder recognizes them, and the other builders are happy.
code = '\n'.join(content)
test = None
if name == 'doctest':
if '<BLANKLINE>' in code:
# convert <BLANKLINE>s to ordinary blank lines for presentation
test = code
code = blankline_re.sub('', code)
if doctestopt_re.search(code):
if not test:
class TestDirective(Directive):
"""
Base class for doctest-related directives.
"""
has_content = True
required_arguments = 0
optional_arguments = 1
final_argument_whitespace = True
def run(self):
# use ordinary docutils nodes for test code: they get special attributes
# so that our builder recognizes them, and the other builders are happy.
code = '\n'.join(self.content)
test = None
if self.name == 'doctest':
if '<BLANKLINE>' in code:
# convert <BLANKLINE>s to ordinary blank lines for presentation
test = code
code = doctestopt_re.sub('', code)
nodetype = nodes.literal_block
if name == 'testsetup' or 'hide' in options:
nodetype = nodes.comment
if arguments:
groups = [x.strip() for x in arguments[0].split(',')]
else:
groups = ['default']
node = nodetype(code, code, testnodetype=name, groups=groups)
node.line = lineno
if test is not None:
# only save if it differs from code
node['test'] = test
if name == 'testoutput':
# don't try to highlight output
node['language'] = 'none'
node['options'] = {}
if name in ('doctest', 'testoutput') and 'options' in options:
# parse doctest-like output comparison flags
option_strings = options['options'].replace(',', ' ').split()
for option in option_strings:
if (option[0] not in '+-' or option[1:] not in
doctest.OPTIONFLAGS_BY_NAME):
# XXX warn?
continue
flag = doctest.OPTIONFLAGS_BY_NAME[option[1:]]
node['options'][flag] = (option[0] == '+')
return [node]
code = blankline_re.sub('', code)
if doctestopt_re.search(code):
if not test:
test = code
code = doctestopt_re.sub('', code)
nodetype = nodes.literal_block
if self.name == 'testsetup' or 'hide' in self.options:
nodetype = nodes.comment
if self.arguments:
groups = [x.strip() for x in self.arguments[0].split(',')]
else:
groups = ['default']
node = nodetype(code, code, testnodetype=self.name, groups=groups)
node.line = self.lineno
if test is not None:
# only save if it differs from code
node['test'] = test
if self.name == 'testoutput':
# don't try to highlight output
node['language'] = 'none'
node['options'] = {}
if self.name in ('doctest', 'testoutput') and 'options' in self.options:
# parse doctest-like output comparison flags
option_strings = self.options['options'].replace(',', ' ').split()
for option in option_strings:
if (option[0] not in '+-' or option[1:] not in
doctest.OPTIONFLAGS_BY_NAME):
# XXX warn?
continue
flag = doctest.OPTIONFLAGS_BY_NAME[option[1:]]
node['options'][flag] = (option[0] == '+')
return [node]
# need to have individual functions for each directive due to different
# options they accept
class TestsetupDirective(TestDirective):
option_spec = {}
def testsetup_directive(*args):
return test_directive(*args)
class DoctestDirective(TestDirective):
option_spec = {
'hide': directives.flag,
'options': directives.unchanged,
}
def doctest_directive(*args):
return test_directive(*args)
class TestcodeDirective(TestDirective):
option_spec = {
'hide': directives.flag,
}
def testcode_directive(*args):
return test_directive(*args)
def testoutput_directive(*args):
return test_directive(*args)
class TestoutputDirective(TestDirective):
option_spec = {
'hide': directives.flag,
'options': directives.unchanged,
}
parser = doctest.DocTestParser()
@ -98,9 +114,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':
@ -169,7 +188,8 @@ class DocTestBuilder(Builder):
date = time.strftime('%Y-%m-%d %H:%M:%S')
self.outfile = file(path.join(self.outdir, 'output.txt'), 'w')
self.outfile = codecs.open(path.join(self.outdir, 'output.txt'),
'w', encoding='utf-8')
self.outfile.write('''\
Results of doctest builder run on %s
==================================%s
@ -179,6 +199,12 @@ Results of doctest builder run on %s
self.info(text, nonl=True)
self.outfile.write(text)
def _warn_out(self, text):
self.info(text, nonl=True)
if self.app.quiet:
self.warn(text)
self.outfile.write(text)
def get_target_uri(self, docname, typ=None):
return ''
@ -200,6 +226,9 @@ Doctest summary
self.setup_failures, s(self.setup_failures)))
self.outfile.close()
if self.total_failures or self.setup_failures:
self.app.statuscode = 1
sys.path[0:0] = self.config.doctest_path
def write(self, build_docnames, updated_docnames, method='update'):
@ -229,8 +258,12 @@ Doctest summary
return isinstance(node, (nodes.literal_block, nodes.comment)) \
and node.has_key('testnodetype')
for node in doctree.traverse(condition):
code = TestCode(node.has_key('test') and node['test'] or node.astext(),
type=node.get('testnodetype', 'doctest'),
source = node.has_key('test') and node['test'] or node.astext()
if not source:
self.warn('no code/output in %s block at %s:%s' %
(node.get('testnodetype', 'doctest'),
self.env.doc2path(docname), node.line))
code = TestCode(source, type=node.get('testnodetype', 'doctest'),
lineno=node.line, options=node.get('options'))
node_groups = node.get('groups', ['default'])
if '*' in node_groups:
@ -243,10 +276,16 @@ 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
self._out('\nDocument: %s\n----------%s\n' % (docname, '-'*len(docname)))
self._out('\nDocument: %s\n----------%s\n' %
(docname, '-'*len(docname)))
for group in groups.itervalues():
self.test_group(group, self.env.doc2path(docname, base=None))
# Separately count results from setup code
@ -265,7 +304,8 @@ Doctest summary
ns = {}
examples = []
for setup in group.setup:
examples.append(doctest.Example(setup.code, '', lineno=setup.lineno))
examples.append(doctest.Example(setup.code, '',
lineno=setup.lineno))
if examples:
# simulate a doctest with the setup code
setup_doctest = doctest.DocTest(examples, {},
@ -274,7 +314,7 @@ Doctest summary
setup_doctest.globs = ns
old_f = self.setup_runner.failures
self.type = 'exec' # the snippet may contain multiple statements
self.setup_runner.run(setup_doctest, out=self._out,
self.setup_runner.run(setup_doctest, out=self._warn_out,
clear_globs=False)
if self.setup_runner.failures > old_f:
# don't run the group
@ -284,8 +324,6 @@ Doctest summary
test = parser.get_doctest(code[0].code, {},
group.name, filename, code[0].lineno)
if not test.examples:
self._out('WARNING: no examples in doctest block at '
+ filename + ', line %s\n' % code[0].lineno)
continue
for example in test.examples:
# apply directive's comparison options
@ -307,18 +345,16 @@ Doctest summary
# DocTest.__init__ copies the globs namespace, which we don't want
test.globs = ns
# also don't clear the globs namespace after running the doctest
self.test_runner.run(test, out=self._out, clear_globs=False)
self.test_runner.run(test, out=self._warn_out, clear_globs=False)
def setup(app):
app.add_directive('testsetup', testsetup_directive, 1, (0, 1, 1))
app.add_directive('doctest', doctest_directive, 1, (0, 1, 1),
hide=directives.flag, options=directives.unchanged)
app.add_directive('testcode', testcode_directive, 1, (0, 1, 1),
hide=directives.flag)
app.add_directive('testoutput', testoutput_directive, 1, (0, 1, 1),
hide=directives.flag, options=directives.unchanged)
app.add_directive('testsetup', TestsetupDirective)
app.add_directive('doctest', DoctestDirective)
app.add_directive('testcode', TestcodeDirective)
app.add_directive('testoutput', TestoutputDirective)
app.add_builder(DocTestBuilder)
# 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)

185
sphinx/ext/graphviz.py Normal file
View File

@ -0,0 +1,185 @@
# -*- coding: utf-8 -*-
"""
sphinx.ext.graphviz
~~~~~~~~~~~~~~~~~~~
Allow graphviz-formatted graphs to be included in Sphinx-generated
documents inline.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import re
import sys
import posixpath
from os import path
from subprocess import Popen, PIPE
try:
from hashlib import sha1 as sha
except ImportError:
from sha import sha
from docutils import nodes
from sphinx.errors import SphinxError
from sphinx.util import ensuredir
from sphinx.util.compat import Directive
mapname_re = re.compile(r'<map id="(.*?)"')
class GraphvizError(SphinxError):
category = 'Graphviz error'
class graphviz(nodes.General, nodes.Element):
pass
class Graphviz(Directive):
"""
Directive to insert arbitrary dot markup.
"""
has_content = True
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
option_spec = {}
def run(self):
node = graphviz()
node['code'] = '\n'.join(self.content)
node['options'] = []
return [node]
class GraphvizSimple(Directive):
"""
Directive to insert arbitrary dot markup.
"""
has_content = True
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
option_spec = {}
def run(self):
node = graphviz()
node['code'] = '%s %s {\n%s\n}\n' % \
(self.name, self.arguments[0], '\n'.join(self.content))
node['options'] = []
return [node]
def render_dot(self, code, options, format, prefix='graphviz'):
"""
Render graphviz code into a PNG or PDF output file.
"""
hashkey = code.encode('utf-8') + str(options) + \
str(self.builder.config.graphviz_dot_args)
fname = '%s-%s.%s' % (prefix, sha(hashkey).hexdigest(), format)
if hasattr(self.builder, 'imgpath'):
# HTML
relfn = posixpath.join(self.builder.imgpath, fname)
outfn = path.join(self.builder.outdir, '_images', fname)
else:
# LaTeX
relfn = fname
outfn = path.join(self.builder.outdir, fname)
if path.isfile(outfn):
return relfn
if hasattr(self.builder, '_graphviz_warned_dot') or \
hasattr(self.builder, '_graphviz_warned_ps2pdf'):
return None
ensuredir(path.dirname(outfn))
dot_args = [self.builder.config.graphviz_dot]
dot_args.extend(self.builder.config.graphviz_dot_args)
dot_args.extend(options)
dot_args.extend(['-T' + format, '-o' + outfn])
if format == 'png':
dot_args.extend(['-Tcmapx', '-o%s.map' % outfn])
try:
p = Popen(dot_args, stdout=PIPE, stdin=PIPE, stderr=PIPE)
except OSError, err:
if err.errno != 2: # No such file or directory
raise
self.builder.warn('dot command %r cannot be run (needed for graphviz '
'output), check the graphviz_dot setting' %
self.builder.config.graphviz_dot)
self.builder._graphviz_warned_dot = True
return None
# graphviz expects UTF-8 by default
if isinstance(code, unicode):
code = code.encode('utf-8')
stdout, stderr = p.communicate(code)
if p.returncode != 0:
raise GraphvizError('dot exited with error:\n[stderr]\n%s\n'
'[stdout]\n%s' % (stderr, stdout))
return relfn
def render_dot_html(self, node, code, options, prefix='graphviz', imgcls=None):
try:
fname = render_dot(self, code, options, 'png', prefix)
except GraphvizError, exc:
self.builder.warn('dot code %r: ' % code + str(exc))
raise nodes.SkipNode
self.body.append(self.starttag(node, 'p', CLASS='graphviz'))
if fname is None:
self.body.append(self.encode(code))
else:
mapfile = open(path.join(self.builder.outdir, fname) + '.map', 'rb')
imgmap = mapfile.readlines()
mapfile.close()
imgcss = imgcls and 'class="%s"' % imgcls or ''
if len(imgmap) == 2:
# nothing in image map (the lines are <map> and </map>)
self.body.append('<img src="%s" alt="%s" %s/>\n' %
(fname, self.encode(code).strip(), imgcss))
else:
# has a map: get the name of the map and connect the parts
mapname = mapname_re.match(imgmap[0]).group(1)
self.body.append('<img src="%s" alt="%s" usemap="#%s" %s/>\n' %
(fname, self.encode(code).strip(),
mapname, imgcss))
self.body.extend(imgmap)
self.body.append('</p>\n')
raise nodes.SkipNode
def html_visit_graphviz(self, node):
render_dot_html(self, node, node['code'], node['options'])
def render_dot_latex(self, node, code, options, prefix='graphviz'):
try:
fname = render_dot(self, code, options, 'pdf', prefix)
except GraphvizError, exc:
self.builder.warn('dot code %r: ' % code + str(exc))
raise nodes.SkipNode
if fname is not None:
self.body.append('\\includegraphics{%s}' % fname)
raise nodes.SkipNode
def latex_visit_graphviz(self, node):
render_dot_latex(self, node, node['code'], node['options'])
def setup(app):
app.add_node(graphviz,
html=(html_visit_graphviz, None),
latex=(latex_visit_graphviz, None))
app.add_directive('graphviz', Graphviz)
app.add_directive('graph', GraphvizSimple)
app.add_directive('digraph', GraphvizSimple)
app.add_config_value('graphviz_dot', 'dot', 'html')
app.add_config_value('graphviz_dot_args', [], 'html')

View File

@ -13,26 +13,36 @@
This stuff is only included in the built docs for unstable versions.
The argument for ``ifconfig`` is a plain Python expression, evaluated in the
namespace of the project configuration (that is, all variables from ``conf.py``
are available.)
namespace of the project configuration (that is, all variables from
``conf.py`` are available.)
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from docutils import nodes
from sphinx.util.compat import Directive
class ifconfig(nodes.Element): pass
def ifconfig_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
node = ifconfig()
node.line = lineno
node['expr'] = arguments[0]
state.nested_parse(content, content_offset, node)
return [node]
class IfConfig(Directive):
has_content = True
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {}
def run(self):
node = ifconfig()
node.document = self.state.document
node.line = self.lineno
node['expr'] = self.arguments[0]
self.state.nested_parse(self.content, self.content_offset, node)
return [node]
def process_ifconfig_nodes(app, doctree, docname):
@ -58,5 +68,5 @@ def process_ifconfig_nodes(app, doctree, docname):
def setup(app):
app.add_node(ifconfig)
app.add_directive('ifconfig', ifconfig_directive, 1, (1, 0, 1))
app.add_directive('ifconfig', IfConfig)
app.connect('doctree-resolved', process_ifconfig_nodes)

View File

@ -0,0 +1,367 @@
"""
sphinx.ext.inheritance_diagram
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Defines a docutils directive for inserting inheritance diagrams.
Provide the directive with one or more classes or modules (separated
by whitespace). For modules, all of the classes in that module will
be used.
Example::
Given the following classes:
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
class E(B): pass
.. inheritance-diagram: D E
Produces a graph like the following:
A
/ \
B C
/ \ /
E D
The graph is inserted as a PNG+image map into HTML and a PDF in
LaTeX.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import re
import sys
import inspect
import subprocess
try:
from hashlib import md5
except ImportError:
from md5 import md5
from docutils import nodes
from docutils.parsers.rst import directives
from sphinx.roles import xfileref_role
from sphinx.ext.graphviz import render_dot_html, render_dot_latex
from sphinx.util.compat import Directive
class_sig_re = re.compile(r'''^([\w.]*\.)? # module names
(\w+) \s* $ # class/final module name
''', re.VERBOSE)
class InheritanceException(Exception):
pass
class InheritanceGraph(object):
"""
Given a list of classes, determines the set of classes that they inherit
from all the way to the root "object", and then is able to generate a
graphviz dot graph from them.
"""
def __init__(self, class_names, currmodule, show_builtins=False):
"""
*class_names* is a list of child classes to show bases from.
If *show_builtins* is True, then Python builtins will be shown
in the graph.
"""
self.class_names = class_names
self.classes = self._import_classes(class_names, currmodule)
self.all_classes = self._all_classes(self.classes)
if len(self.all_classes) == 0:
raise InheritanceException('No classes found for '
'inheritance diagram')
self.show_builtins = show_builtins
def _import_class_or_module(self, name, currmodule):
"""
Import a class using its fully-qualified *name*.
"""
try:
path, base = class_sig_re.match(name).groups()
except ValueError:
raise InheritanceException('Invalid class or module %r specified '
'for inheritance diagram' % name)
fullname = (path or '') + base
path = (path and path.rstrip('.') or '')
# two possibilities: either it is a module, then import it
try:
module = __import__(fullname)
todoc = sys.modules[fullname]
except ImportError:
# else it is a class, then import the module
if not path:
if currmodule:
# try the current module
path = currmodule
else:
raise InheritanceException(
'Could not import class %r specified for '
'inheritance diagram' % base)
try:
module = __import__(path)
todoc = getattr(sys.modules[path], base)
except (ImportError, AttributeError):
raise InheritanceException(
'Could not import class or module %r specified for '
'inheritance diagram' % (path + '.' + base))
# If a class, just return it
if inspect.isclass(todoc):
return [todoc]
elif inspect.ismodule(todoc):
classes = []
for cls in todoc.__dict__.values():
if inspect.isclass(cls) and cls.__module__ == todoc.__name__:
classes.append(cls)
return classes
raise InheritanceException('%r specified for inheritance diagram is '
'not a class or module' % name)
def _import_classes(self, class_names, currmodule):
"""
Import a list of classes.
"""
classes = []
for name in class_names:
classes.extend(self._import_class_or_module(name, currmodule))
return classes
def _all_classes(self, classes):
"""
Return a list of all classes that are ancestors of *classes*.
"""
all_classes = {}
def recurse(cls):
all_classes[cls] = None
for c in cls.__bases__:
if c not in all_classes:
recurse(c)
for cls in classes:
recurse(cls)
return all_classes.keys()
def class_name(self, cls, parts=0):
"""
Given a class object, return a fully-qualified name. This
works for things I've tested in matplotlib so far, but may not
be completely general.
"""
module = cls.__module__
if module == '__builtin__':
fullname = cls.__name__
else:
fullname = '%s.%s' % (module, cls.__name__)
if parts == 0:
return fullname
name_parts = fullname.split('.')
return '.'.join(name_parts[-parts:])
def get_all_class_names(self):
"""
Get all of the class names involved in the graph.
"""
return [self.class_name(x) for x in self.all_classes]
# These are the default attrs for graphviz
default_graph_attrs = {
'rankdir': 'LR',
'size': '"8.0, 12.0"',
}
default_node_attrs = {
'shape': 'box',
'fontsize': 10,
'height': 0.25,
'fontname': 'Vera Sans, DejaVu Sans, Liberation Sans, '
'Arial, Helvetica, sans',
'style': '"setlinewidth(0.5)"',
}
default_edge_attrs = {
'arrowsize': 0.5,
'style': '"setlinewidth(0.5)"',
}
def _format_node_attrs(self, attrs):
return ','.join(['%s=%s' % x for x in attrs.items()])
def _format_graph_attrs(self, attrs):
return ''.join(['%s=%s;\n' % x for x in attrs.items()])
def generate_dot(self, name, parts=0, urls={}, env=None,
graph_attrs={}, node_attrs={}, edge_attrs={}):
"""
Generate a graphviz dot graph from the classes that
were passed in to __init__.
*name* is the name of the graph.
*urls* is a dictionary mapping class names to HTTP URLs.
*graph_attrs*, *node_attrs*, *edge_attrs* are dictionaries containing
key/value pairs to pass on as graphviz properties.
"""
g_attrs = self.default_graph_attrs.copy()
n_attrs = self.default_node_attrs.copy()
e_attrs = self.default_edge_attrs.copy()
g_attrs.update(graph_attrs)
n_attrs.update(node_attrs)
e_attrs.update(edge_attrs)
if env:
g_attrs.update(env.config.inheritance_graph_attrs)
n_attrs.update(env.config.inheritance_node_attrs)
e_attrs.update(env.config.inheritance_edge_attrs)
res = []
res.append('digraph %s {\n' % name)
res.append(self._format_graph_attrs(g_attrs))
for cls in self.all_classes:
if not self.show_builtins and cls in __builtins__.values():
continue
name = self.class_name(cls, parts)
# Write the node
this_node_attrs = n_attrs.copy()
url = urls.get(self.class_name(cls))
if url is not None:
this_node_attrs['URL'] = '"%s"' % url
res.append(' "%s" [%s];\n' %
(name, self._format_node_attrs(this_node_attrs)))
# Write the edges
for base in cls.__bases__:
if not self.show_builtins and base in __builtins__.values():
continue
base_name = self.class_name(base, parts)
res.append(' "%s" -> "%s" [%s];\n' %
(base_name, name,
self._format_node_attrs(e_attrs)))
res.append('}\n')
return ''.join(res)
class inheritance_diagram(nodes.General, nodes.Element):
"""
A docutils node to use as a placeholder for the inheritance diagram.
"""
pass
class InheritanceDiagram(Directive):
"""
Run when the inheritance_diagram directive is first encountered.
"""
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {
'parts': directives.nonnegative_int,
}
def run(self):
node = inheritance_diagram()
node.document = self.state.document
env = self.state.document.settings.env
class_names = self.arguments[0].split()
# Create a graph starting with the list of classes
try:
graph = InheritanceGraph(class_names, env.currmodule)
except InheritanceException, err:
return [node.document.reporter.warning(err.args[0],
line=self.lineno)]
# Create xref nodes for each target of the graph's image map and
# add them to the doc tree so that Sphinx can resolve the
# references to real URLs later. These nodes will eventually be
# removed from the doctree after we're done with them.
for name in graph.get_all_class_names():
refnodes, x = xfileref_role(
'class', ':class:`%s`' % name, name, 0, self.state)
node.extend(refnodes)
# Store the graph object so we can use it to generate the
# dot file later
node['graph'] = graph
# Store the original content for use as a hash
node['parts'] = self.options.get('parts', 0)
node['content'] = ' '.join(class_names)
return [node]
def get_graph_hash(node):
return md5(node['content'] + str(node['parts'])).hexdigest()[-10:]
def html_visit_inheritance_diagram(self, node):
"""
Output the graph for HTML. This will insert a PNG with clickable
image map.
"""
graph = node['graph']
parts = node['parts']
graph_hash = get_graph_hash(node)
name = 'inheritance%s' % graph_hash
# Create a mapping from fully-qualified class names to URLs.
urls = {}
for child in node:
if child.get('refuri') is not None:
urls[child['reftitle']] = child.get('refuri')
elif child.get('refid') is not None:
urls[child['reftitle']] = '#' + child.get('refid')
dotcode = graph.generate_dot(name, parts, urls, env=self.builder.env)
render_dot_html(self, node, dotcode, [], 'inheritance', 'inheritance')
raise nodes.SkipNode
def latex_visit_inheritance_diagram(self, node):
"""
Output the graph for LaTeX. This will insert a PDF.
"""
graph = node['graph']
parts = node['parts']
graph_hash = get_graph_hash(node)
name = 'inheritance%s' % graph_hash
dotcode = graph.generate_dot(name, parts, urls, env=self.builder.env,
graph_attrs={'size': '"6.0,6.0"'})
render_dot_latex(self, node, dotcode, [], 'inheritance')
raise nodes.SkipNode
def skip(self, node):
raise nodes.SkipNode
def setup(app):
app.setup_extension('sphinx.ext.graphviz')
app.add_node(
inheritance_diagram,
latex=(latex_visit_inheritance_diagram, None),
html=(html_visit_inheritance_diagram, None),
text=(skip, None))
app.add_directive('inheritance-diagram', InheritanceDiagram)
app.add_config_value('inheritance_graph_attrs', {}, False),
app.add_config_value('inheritance_node_attrs', {}, False),
app.add_config_value('inheritance_edge_attrs', {}, False),

View File

@ -20,8 +20,8 @@
also be specified individually, e.g. if the docs should be buildable
without Internet access.
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import time
@ -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):
@ -125,7 +125,7 @@ def missing_reference(app, env, node, contnode):
if target not in env.intersphinx_inventory:
return None
type, proj, version, uri = env.intersphinx_inventory[target]
print "Intersphinx hit:", target, uri
# print "Intersphinx hit:", target, uri
newnode = nodes.reference('', '')
newnode['refuri'] = uri + '#' + target
newnode['reftitle'] = '(in %s v%s)' % (proj, version)

View File

@ -6,8 +6,8 @@
Set up everything for use of JSMath to display math in HTML
via JavaScript.
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from docutils import nodes
@ -32,7 +32,8 @@ def html_visit_displaymath(self, node):
if i == 0:
# necessary to e.g. set the id property correctly
if node['number']:
self.body.append('<span class="eqno">(%s)</span>' % node['number'])
self.body.append('<span class="eqno">(%s)</span>' %
node['number'])
self.body.append(self.starttag(node, 'div', CLASS='math'))
else:
# but only once!

View File

@ -5,13 +5,15 @@
Set up math support in source files and LaTeX/text output.
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from docutils import nodes, utils
from docutils.parsers.rst import directives
from sphinx.util.compat import Directive
class math(nodes.Inline, nodes.TextElement):
pass
@ -45,22 +47,33 @@ def eq_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
node['docname'] = inliner.document.settings.env.docname
return [node], []
def math_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
latex = '\n'.join(content)
if arguments and arguments[0]:
latex = arguments[0] + '\n\n' + latex
node = displaymath()
node['latex'] = latex
node['label'] = options.get('label', None)
node['nowrap'] = 'nowrap' in options
node['docname'] = state.document.settings.env.docname
ret = [node]
if node['label']:
tnode = nodes.target('', '', ids=['equation-' + node['label']])
state.document.note_explicit_target(tnode)
ret.insert(0, tnode)
return ret
class MathDirective(Directive):
has_content = True
required_arguments = 0
optional_arguments = 1
final_argument_whitespace = True
option_spec = {
'label': directives.unchanged,
'nowrap': directives.flag,
}
def run(self):
latex = '\n'.join(self.content)
if self.arguments and self.arguments[0]:
latex = self.arguments[0] + '\n\n' + latex
node = displaymath()
node['latex'] = latex
node['label'] = self.options.get('label', None)
node['nowrap'] = 'nowrap' in self.options
node['docname'] = self.state.document.settings.env.docname
ret = [node]
if node['label']:
tnode = nodes.target('', '', ids=['equation-' + node['label']])
self.state.document.note_explicit_target(tnode)
ret.insert(0, tnode)
return ret
def latex_visit_math(self, node):
@ -134,6 +147,5 @@ def setup(app, htmlinlinevisitors, htmldisplayvisitors):
html=(html_visit_eqref, html_depart_eqref))
app.add_role('math', math_role)
app.add_role('eq', eq_role)
app.add_directive('math', math_directive, 1, (0, 1, 1),
label=directives.unchanged, nowrap=directives.flag)
app.add_directive('math', MathDirective)
app.connect('doctree-resolved', number_equations)

View File

@ -5,16 +5,15 @@
Render math in HTML via dvipng.
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
import shlex
import shutil
import tempfile
import posixpath
from os import path
from os import path, getcwd, chdir
from subprocess import Popen, PIPE
try:
from hashlib import sha1 as sha
@ -23,8 +22,9 @@ except ImportError:
from docutils import nodes
from sphinx.errors import SphinxError
from sphinx.util import ensuredir
from sphinx.application import SphinxError
from sphinx.util.png import read_png_depth, write_png_depth
from sphinx.ext.mathbase import setup as mathbase_setup, wrap_displaymath
class MathExtError(SphinxError):
@ -75,9 +75,17 @@ def render_math(self, math):
"""
use_preview = self.builder.config.pngmath_use_preview
shasum = "%s.png" % sha(math).hexdigest()
shasum = "%s.png" % sha(math.encode('utf-8')).hexdigest()
relfn = posixpath.join(self.builder.imgpath, 'math', shasum)
outfn = path.join(self.builder.outdir, '_images', 'math', shasum)
if path.isfile(outfn):
depth = read_png_depth(outfn)
return relfn, depth
# if latex or dvipng has failed once, don't bother to try again
if hasattr(self.builder, '_mathpng_warned_latex') or \
hasattr(self.builder, '_mathpng_warned_dvipng'):
return None, None
latex = DOC_HEAD + self.builder.config.pngmath_latex_preamble
latex += (use_preview and DOC_BODY_PREVIEW or DOC_BODY) % math
@ -96,28 +104,39 @@ def render_math(self, math):
tf.write(latex)
tf.close()
ltx_args = shlex.split(self.builder.config.pngmath_latex)
ltx_args += ['--interaction=nonstopmode', '--output-directory=' + tempdir,
'math.tex']
# build latex command; old versions of latex don't have the
# --output-directory option, so we have to manually chdir to the
# temp dir to run it.
ltx_args = [self.builder.config.pngmath_latex, '--interaction=nonstopmode']
# add custom args from the config file
ltx_args.extend(self.builder.config.pngmath_latex_args)
ltx_args.append('math.tex')
curdir = getcwd()
chdir(tempdir)
try:
p = Popen(ltx_args, stdout=PIPE, stderr=PIPE)
except OSError, err:
if err.errno != 2: # No such file or directory
raise
if not hasattr(self.builder, '_mathpng_warned_latex'):
try:
p = Popen(ltx_args, stdout=PIPE, stderr=PIPE)
except OSError, err:
if err.errno != 2: # No such file or directory
raise
self.builder.warn('LaTeX command %r cannot be run (needed for math '
'display), check the pngmath_latex setting' %
self.builder.config.pngmath_latex)
self.builder._mathpng_warned_latex = True
return relfn, None
return None, None
finally:
chdir(curdir)
stdout, stderr = p.communicate()
if p.returncode != 0:
raise MathExtError('latex exited with error:\n[stderr]\n%s\n[stdout]\n%s'
% (stderr, stdout))
raise MathExtError('latex exited with error:\n[stderr]\n%s\n'
'[stdout]\n%s' % (stderr, stdout))
ensuredir(path.dirname(outfn))
# use some standard dvipng arguments
dvipng_args = shlex.split(self.builder.config.pngmath_dvipng)
dvipng_args = [self.builder.config.pngmath_dvipng]
dvipng_args += ['-o', outfn, '-T', 'tight', '-z9']
# add custom ones from config value
dvipng_args.extend(self.builder.config.pngmath_dvipng_args)
@ -130,22 +149,22 @@ def render_math(self, math):
except OSError, err:
if err.errno != 2: # No such file or directory
raise
if not hasattr(self.builder, '_mathpng_warned_dvipng'):
self.builder.warn('dvipng command %r cannot be run (needed for math '
'display), check the pngmath_dvipng setting' %
self.builder.config.pngmath_dvipng)
self.builder._mathpng_warned_dvipng = True
return relfn, None
self.builder.warn('dvipng command %r cannot be run (needed for math '
'display), check the pngmath_dvipng setting' %
self.builder.config.pngmath_dvipng)
self.builder._mathpng_warned_dvipng = True
return None, None
stdout, stderr = p.communicate()
if p.returncode != 0:
raise MathExtError('dvipng exited with error:\n[stderr]\n%s\n[stdout]\n%s'
% (stderr, stdout))
raise MathExtError('dvipng exited with error:\n[stderr]\n%s\n'
'[stdout]\n%s' % (stderr, stdout))
depth = None
if use_preview:
for line in stdout.splitlines():
m = depth_re.match(line)
if m:
depth = int(m.group(1))
write_png_depth(outfn, depth)
break
return relfn, depth
@ -161,10 +180,28 @@ def cleanup_tempdir(app, exc):
pass
def html_visit_math(self, node):
fname, depth = render_math(self, '$'+node['latex']+'$')
self.body.append('<img src="%s" alt="%s" %s/>' %
(fname, self.encode(node['latex']),
depth and 'style="vertical-align: %dpx" ' % (-depth) or ''))
try:
fname, depth = render_math(self, '$'+node['latex']+'$')
except MathExtError, exc:
sm = nodes.system_message(str(exc), type='WARNING', level=2,
backrefs=[], source=node['latex'])
sm.walkabout(self)
self.builder.warn('display latex %r: ' % node['latex'] + str(exc))
raise nodes.SkipNode
if fname is None:
# something failed -- use text-only as a bad substitute
self.body.append('<span class="math">%s</span>' %
self.encode(node['latex']).strip())
else:
if depth is None:
self.body.append(
'<img class="math" src="%s" alt="%s"/>' %
(fname, self.encode(node['latex']).strip()))
else:
self.body.append(
'<img class="math" src="%s" alt="%s" '
'style="vertical-align: %dpx"/>' %
(fname, self.encode(node['latex']).strip(), -depth))
raise nodes.SkipNode
def html_visit_displaymath(self, node):
@ -172,13 +209,25 @@ def html_visit_displaymath(self, node):
latex = node['latex']
else:
latex = wrap_displaymath(node['latex'], None)
fname, depth = render_math(self, latex)
try:
fname, depth = render_math(self, latex)
except MathExtError, exc:
sm = nodes.system_message(str(exc), type='WARNING', level=2,
backrefs=[], source=node['latex'])
sm.walkabout(self)
self.builder.warn('inline latex %r: ' % node['latex'] + str(exc))
raise nodes.SkipNode
self.body.append(self.starttag(node, 'div', CLASS='math'))
self.body.append('<p>')
if node['number']:
self.body.append('<span class="eqno">(%s)</span>' % node['number'])
self.body.append('<img src="%s" alt="%s" />\n</div>' %
(fname, self.encode(node['latex'])))
if fname is None:
# something failed -- use text-only as a bad substitute
self.body.append('<span class="math">%s</span>' %
self.encode(node['latex']).strip())
else:
self.body.append('<img src="%s" alt="%s" />\n</div>' %
(fname, self.encode(node['latex']).strip()))
self.body.append('</p>')
raise nodes.SkipNode
@ -188,6 +237,7 @@ def setup(app):
app.add_config_value('pngmath_dvipng', 'dvipng', False)
app.add_config_value('pngmath_latex', 'latex', False)
app.add_config_value('pngmath_use_preview', False, False)
app.add_config_value('pngmath_dvipng_args', [], False)
app.add_config_value('pngmath_dvipng_args', ['-gamma 1.5', '-D 110'], False)
app.add_config_value('pngmath_latex_args', [], False)
app.add_config_value('pngmath_latex_preamble', '', False)
app.connect('build-finished', cleanup_tempdir)

View File

@ -9,8 +9,8 @@
Usage: Set the `refcount_file` config value to the path to the reference
count data file.
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from os import path
@ -55,7 +55,8 @@ class Refcounts(dict):
refcount = None
else:
refcount = int(refcount)
# Update the entry with the new parameter or the result information.
# Update the entry with the new parameter or the result
# information.
if arg:
entry.args.append((arg, type, refcount))
else:
@ -81,7 +82,8 @@ class Refcounts(dict):
if entry.result_refs is None:
rc += "Always NULL."
else:
rc += (entry.result_refs and "New" or "Borrowed") + " reference."
rc += (entry.result_refs and "New" or "Borrowed") + \
" reference."
node.insert(0, refcount(rc, rc))

147
sphinx/ext/todo.py Normal file
View File

@ -0,0 +1,147 @@
# -*- coding: utf-8 -*-
"""
sphinx.ext.todo
~~~~~~~~~~~~~~~
Allow todos to be inserted into your documentation. Inclusion of todos can
be switched of by a configuration variable. The todolist directive collects
all todos of your project and lists them along with a backlink to the
original location.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from docutils import nodes
from sphinx.util.compat import Directive, make_admonition
class todo_node(nodes.Admonition, nodes.Element): pass
class todolist(nodes.General, nodes.Element): pass
class Todo(Directive):
"""
A todo entry, displayed (if configured) in the form of an admonition.
"""
has_content = True
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
option_spec = {}
def run(self):
env = self.state.document.settings.env
targetid = "todo-%s" % env.index_num
env.index_num += 1
targetnode = nodes.target('', '', ids=[targetid])
ad = make_admonition(todo_node, self.name, [_('Todo')], self.options,
self.content, self.lineno, self.content_offset,
self.block_text, self.state, self.state_machine)
# Attach a list of all todos to the environment,
# the todolist works with the collected todo nodes
if not hasattr(env, 'todo_all_todos'):
env.todo_all_todos = []
env.todo_all_todos.append({
'docname': env.docname,
'lineno': self.lineno,
'todo': ad[0].deepcopy(),
'target': targetnode,
})
return [targetnode] + ad
class TodoList(Directive):
"""
A list of all todo entries.
"""
has_content = False
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = False
option_spec = {}
def run(self):
# Simply insert an empty todolist node which will be replaced later
# when process_todo_nodes is called
return [todolist('')]
def process_todo_nodes(app, doctree, fromdocname):
if not app.config['todo_include_todos']:
for node in doctree.traverse(todo_node):
node.parent.remove(node)
# Replace all todolist nodes with a list of the collected todos.
# Augment each todo with a backlink to the original location.
env = app.builder.env
if not hasattr(env, 'todo_all_todos'):
env.todo_all_todos = []
for node in doctree.traverse(todolist):
if not app.config['todo_include_todos']:
node.replace_self([])
continue
content = []
for todo_info in env.todo_all_todos:
para = nodes.paragraph()
filename = env.doc2path(todo_info['docname'], base=None)
description = (
_('(The original entry is located in %s, line %d and '
'can be found ') % (filename, todo_info['lineno']))
para += nodes.Text(description, description)
# Create a reference
newnode = nodes.reference('', '')
innernode = nodes.emphasis(_('here'), _('here'))
newnode['refdocname'] = todo_info['docname']
newnode['refuri'] = app.builder.get_relative_uri(
fromdocname, todo_info['docname'])
newnode['refuri'] += '#' + todo_info['target']['refid']
newnode.append(innernode)
para += newnode
para += nodes.Text('.)', '.)')
# Insert into the todolist
content.append(todo_info['todo'])
content.append(para)
node.replace_self(content)
def purge_todos(app, env, docname):
if not hasattr(env, 'todo_all_todos'):
return
env.todo_all_todos = [todo for todo in env.todo_all_todos
if todo['docname'] != docname]
def visit_todo_node(self, node):
self.visit_admonition(node)
def depart_todo_node(self, node):
self.depart_admonition(node)
def setup(app):
app.add_config_value('todo_include_todos', False, False)
app.add_node(todolist)
app.add_node(todo_node,
html=(visit_todo_node, depart_todo_node),
latex=(visit_todo_node, depart_todo_node),
text=(visit_todo_node, depart_todo_node))
app.add_directive('todo', Todo)
app.add_directive('todolist', TodoList)
app.connect('doctree-resolved', process_todo_nodes)
app.connect('env-purge-doc', purge_todos)

View File

@ -5,8 +5,8 @@
Highlight code blocks using Pygments.
:copyright: 2007-2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import sys
@ -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):
"""
@ -47,12 +49,15 @@ else:
Number: '#208050',
})
class NoneStyle(Style):
"""Style without any styling."""
lexers = dict(
none = TextLexer(),
python = PythonLexer(),
pycon = PythonConsoleLexer(),
# the python3 option exists as of Pygments 0.12, but it doesn't
# do any harm in previous versions
# the python3 option exists as of Pygments 1.0,
# but it doesn't do any harm in previous versions
pycon3 = PythonConsoleLexer(python3=True),
rest = RstLexer(),
c = CLexer(),
@ -81,22 +86,33 @@ 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:
return
if stylename == 'sphinx':
if stylename is None or stylename == 'sphinx':
style = SphinxStyle
elif stylename == 'none':
style = NoneStyle
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 +186,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 +202,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

View File

@ -1,210 +0,0 @@
# -*- coding: utf-8 -*-
"""
sphinx.htmlhelp
~~~~~~~~~~~~~~~
Build HTML help support files.
Adapted from the original Doc/tools/prechm.py.
:copyright: 2007-2008 by Georg Brandl.
:license: BSD.
"""
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
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):
if refs:
f.write('<LI> ')
item = object_sitemap % (cgi.escape(title), refs[0])
f.write(item.encode('ascii', 'xmlcharrefreplace'))
for ref in refs[1:]:
f.write(object_sitemap % ('[Link]', ref))
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()

102
sphinx/jinja2glue.py Normal file
View File

@ -0,0 +1,102 @@
# -*- 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
from pprint import pformat
from jinja2 import FileSystemLoader, BaseLoader, TemplateNotFound, \
contextfunction
from jinja2.sandbox import SandboxedEnvironment
from sphinx.util import mtimes_of_files
from sphinx.application import TemplateBridge
def _tobool(val):
if isinstance(val, basestring):
return val.lower() in ('true', '1', 'yes', 'on')
return bool(val)
def accesskey(context, key):
"""Helper to output each access key only once."""
if '_accesskeys' not in context:
context.vars['_accesskeys'] = {}
if key not in context.vars['_accesskeys']:
context.vars['_accesskeys'][key] = 1
return 'accesskey="%s"' % key
return ''
class BuiltinTemplateLoader(TemplateBridge, BaseLoader):
"""
Interfaces the rendering environment of jinja2 for use in Sphinx.
"""
# TemplateBridge interface
def init(self, builder, theme=None, dirs=None):
# create a chain of paths to search
if theme:
# the theme's own dir and its bases' dirs
chain = theme.get_dirchain()
# then the theme parent paths
chain.extend(theme.themepath)
elif dirs:
chain = list(dirs)
else:
chain = []
# prepend explicit template paths
self.templatepathlen = len(builder.config.templates_path)
if builder.config.templates_path:
chain[0:0] = [path.join(builder.confdir, tp)
for tp in builder.config.templates_path]
# store it for use in newest_template_mtime
self.pathchain = chain
# make the paths into loaders
self.loaders = map(FileSystemLoader, chain)
use_i18n = builder.translator is not None
extensions = use_i18n and ['jinja2.ext.i18n'] or []
self.environment = SandboxedEnvironment(loader=self,
extensions=extensions)
self.environment.filters['tobool'] = _tobool
self.environment.globals['debug'] = contextfunction(pformat)
self.environment.globals['accesskey'] = contextfunction(accesskey)
if use_i18n:
self.environment.install_gettext_translations(builder.translator)
def render(self, template, context):
return self.environment.get_template(template).render(context)
def render_string(self, source, context):
return self.environment.from_string(source).render(context)
def newest_template_mtime(self):
return max(mtimes_of_files(self.pathchain, '.html'))
# Loader interface
def get_source(self, environment, template):
loaders = self.loaders
# exclamation mark starts search from theme
if template.startswith('!'):
loaders = loaders[self.templatepathlen:]
template = template[1:]
for loader in loaders:
try:
return loader.get_source(environment, template)
except TemplateNotFound:
pass
raise TemplateNotFound(template)

View File

@ -5,8 +5,8 @@
Locale utilities.
:copyright: 2008 by Georg Brandl.
:license: BSD.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
_ = lambda x: x

View File

@ -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": {"Search Results": "V\u00fdsledky hled\u00e1n\u00ed", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "", "Getting search index...": "", "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 finished, found %s page(s) matching the search query.": ""}});
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\u0159ipravuji vyhled\u00e1v\u00e1n\u00ed....", "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 \u017e\u00e1dn\u00fd dokument. Ujist\u011bte se pros\u00edm, \u017ee v\u0161echna slova jsou spr\u00e1vn\u011b a \u017ee jste vybral dostatek kategori\u00ed.", "Search finished, found %s page(s) matching the search query.": "Vyhled\u00e1v\u00e1n\u00ed skon\u010dilo, nalezeno %s stran.", ", in ": ", v", "Permalink to this headline": "Trval\u00fd odkaz na tento nadpis", "Searching": "Hled\u00e1m", "Permalink to this definition": "Trval\u00fd odkaz na tuto definici", "Hide Search Matches": "Skr\u00fdt v\u00fdsledky vyhled\u00e1v\u00e1n\u00ed", "Search Results": "V\u00fdsledky hled\u00e1n\u00ed"}});

View File

@ -7,8 +7,8 @@ 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-09-06 19:10+0200\n"
"POT-Creation-Date: 2008-11-27 18:39+0100\n"
"PO-Revision-Date: 2009-01-24 18:39+0000\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 && "
@ -18,223 +18,244 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 0.9.3\n"
#: sphinx/builder.py:391
#, python-format
msgid "%b %d, %Y"
msgstr "%d.%m.%Y"
#: sphinx/builder.py:410 sphinx/templates/defindex.html:21
msgid "General Index"
msgstr "Rejstřík indexů"
#: sphinx/builder.py:410
msgid "index"
msgstr "index"
#: sphinx/builder.py:412 sphinx/htmlhelp.py:155
#: sphinx/templates/defindex.html:19 sphinx/templates/modindex.html:2
#: sphinx/templates/modindex.html:13
msgid "Global Module Index"
msgstr "Rejstřík modulů"
#: sphinx/builder.py:412
msgid "modules"
msgstr "moduly"
#: sphinx/builder.py:448
msgid "next"
msgstr "další"
#: sphinx/builder.py:455
msgid "previous"
msgstr "předchozí"
#: sphinx/builder.py:1092
msgid "Builtins"
msgstr "Vestavěné funkce"
#: sphinx/builder.py:1094
msgid "Module level"
msgstr "Úroveň modulů"
#: sphinx/environment.py:108 sphinx/latexwriter.py:129
#: sphinx/environment.py:104 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%d.%m.%Y"
#: sphinx/htmlwriter.py:73 sphinx/static/doctools.js:143
msgid "Permalink to this definition"
msgstr "Trvalý odkaz na tuto definici"
#: sphinx/htmlwriter.py:379 sphinx/static/doctools.js:136
msgid "Permalink to this headline"
msgstr "Trvalý odkaz na tento nadpis"
#: sphinx/latexwriter.py:143
msgid "Release"
msgstr "Vydání"
#: sphinx/latexwriter.py:188
msgid "Module index"
msgstr "Rejstřík modulů"
#: sphinx/latexwriter.py:190 sphinx/templates/genindex-single.html:2
#: sphinx/environment.py:300 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:126 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Index"
#: sphinx/roles.py:52 sphinx/directives/desc.py:514
#: sphinx/environment.py:301 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Rejstřík modulů "
#: sphinx/environment.py:302 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Vyhledávací stránka"
#: sphinx/roles.py:53 sphinx/directives/desc.py:580
#, python-format
msgid "environment variable; %s"
msgstr "promměná prostředí, %s"
#: sphinx/roles.py:59
#: sphinx/roles.py:60
#, python-format
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
#: sphinx/textwriter.py:151
#: sphinx/builders/changes.py:64
msgid "Builtins"
msgstr "Vestavěné funkce "
#: sphinx/builders/changes.py:66
msgid "Module level"
msgstr "Úroveň modulů"
#: sphinx/builders/html.py:118
#, python-format
msgid "Platform: %s"
msgstr "Platforma: %s"
msgid "%b %d, %Y"
msgstr "%d.%m.%Y"
#: sphinx/textwriter.py:353
msgid "[image]"
msgstr "[obrázek]"
#: sphinx/builders/html.py:137 sphinx/templates/defindex.html:21
msgid "General Index"
msgstr "Rejstřík indexů"
#: sphinx/directives/desc.py:26
#: sphinx/builders/html.py:137
msgid "index"
msgstr "index"
#: sphinx/builders/html.py:139 sphinx/builders/htmlhelp.py:182
#: sphinx/builders/qthelp.py:131 sphinx/templates/defindex.html:19
#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
msgid "Global Module Index"
msgstr "Celkový rejstřík modulů"
#: sphinx/builders/html.py:139
msgid "modules"
msgstr "moduly"
#: sphinx/builders/html.py:179
msgid "next"
msgstr "další"
#: sphinx/builders/html.py:186
msgid "previous"
msgstr "předchozí"
#: sphinx/builders/latex.py:155 sphinx/builders/pdf.py:162
msgid " (in "
msgstr "(v"
#: sphinx/directives/desc.py:25
#, python-format
msgid "%s() (built-in function)"
msgstr "%s() (vestavěná funkce)"
#: sphinx/directives/desc.py:27 sphinx/directives/desc.py:41
#: sphinx/directives/desc.py:53
#: sphinx/directives/desc.py:26 sphinx/directives/desc.py:42
#: sphinx/directives/desc.py:54
#, python-format
msgid "%s() (in module %s)"
msgstr "%s() (v modulu %s)"
#: sphinx/directives/desc.py:30
#: sphinx/directives/desc.py:29
#, python-format
msgid "%s (built-in variable)"
msgstr "%s() (vestavěná proměnná)"
#: sphinx/directives/desc.py:31 sphinx/directives/desc.py:65
#: sphinx/directives/desc.py:30 sphinx/directives/desc.py:78
#, python-format
msgid "%s (in module %s)"
msgstr "%s() (v modulu %s)"
#: sphinx/directives/desc.py:33
#, python-format
msgid "%s (built-in class)"
msgstr "%s () (vestavěná proměnná)"
#: sphinx/directives/desc.py:34
#, python-format
msgid "%s (class in %s)"
msgstr "%s() (třída v %s)"
#: sphinx/directives/desc.py:45
#: sphinx/directives/desc.py:46
#, python-format
msgid "%s() (%s.%s method)"
msgstr "%s() (metoda %s.%s)"
#: sphinx/directives/desc.py:47
#: sphinx/directives/desc.py:48
#, python-format
msgid "%s() (%s method)"
msgstr "%s() (metoda %s)"
#: sphinx/directives/desc.py:57
#: sphinx/directives/desc.py:58
#, python-format
msgid "%s() (%s.%s static method)"
msgstr "%s() (statická metoda %s.%s)"
#: sphinx/directives/desc.py:59
#: sphinx/directives/desc.py:60
#, python-format
msgid "%s() (%s static method)"
msgstr "%s() (statická metoda %s)"
#: sphinx/directives/desc.py:69
#: sphinx/directives/desc.py:82
#, python-format
msgid "%s (%s.%s attribute)"
msgstr "%s() (atribut %s.%s)"
#: sphinx/directives/desc.py:71
#: sphinx/directives/desc.py:84
#, python-format
msgid "%s (%s attribute)"
msgstr "%s() (atribut %s)"
#: sphinx/directives/desc.py:73
#: sphinx/directives/desc.py:86
#, python-format
msgid "%s (C function)"
msgstr "%s (C funkce)"
#: sphinx/directives/desc.py:75
#: sphinx/directives/desc.py:88
#, python-format
msgid "%s (C member)"
msgstr "%s (člen C)"
#: sphinx/directives/desc.py:77
#: sphinx/directives/desc.py:90
#, python-format
msgid "%s (C macro)"
msgstr "%s (C makro)"
#: sphinx/directives/desc.py:79
#: sphinx/directives/desc.py:92
#, python-format
msgid "%s (C type)"
msgstr "%s (C typ)"
#: sphinx/directives/desc.py:81
#: sphinx/directives/desc.py:94
#, python-format
msgid "%s (C variable)"
msgstr "%s (C proměnná)"
#: sphinx/directives/desc.py:99
#: sphinx/directives/desc.py:112
msgid "Raises"
msgstr "Vyvolá"
#: sphinx/directives/desc.py:103
#: sphinx/directives/desc.py:116
msgid "Variable"
msgstr "Proměnná"
#: sphinx/directives/desc.py:106
#: sphinx/directives/desc.py:119
msgid "Returns"
msgstr "Vrací"
#: sphinx/directives/desc.py:113
#: sphinx/directives/desc.py:128
msgid "Return type"
msgstr "Typ navrácené hodnoty"
#: sphinx/directives/desc.py:140
#: sphinx/directives/desc.py:213
#, fuzzy
msgid "Parameter"
msgstr "Parametry"
#: sphinx/directives/desc.py:217
msgid "Parameters"
msgstr "Parametry"
#: sphinx/directives/desc.py:402
#: sphinx/directives/desc.py:465
#, python-format
msgid "command line option; %s"
msgstr "parametry příkazového řádku; %s"
msgid "%scommand line option; %s"
msgstr "%s parametry příkazového řádku; %s"
#: sphinx/directives/other.py:102
#: sphinx/directives/other.py:101
msgid "Platforms: "
msgstr "Platformy: "
#: sphinx/directives/other.py:107
#: sphinx/directives/other.py:106
#, python-format
msgid "%s (module)"
msgstr "%s (module)"
#: sphinx/directives/other.py:147
#: sphinx/directives/other.py:146
msgid "Section author: "
msgstr "Autor sekce: "
#: sphinx/directives/other.py:149
#: sphinx/directives/other.py:148
msgid "Module author: "
msgstr "Autor modulu: "
#: sphinx/directives/other.py:151
#: sphinx/directives/other.py:150
msgid "Author: "
msgstr "Autor: "
#: sphinx/directives/other.py:233
#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Viz také"
#: sphinx/ext/autodoc.py:442
#, python-format
msgid " Bases: %s"
msgstr ""
#: sphinx/ext/autodoc.py:566 sphinx/ext/autodoc.py:583
#, python-format
msgid "alias of :class:`%s`"
msgstr ""
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr "Todo"
#: sphinx/ext/todo.py:75
#, python-format
msgid "(The original entry is located in %s, line %d and can be found "
msgstr "(Původní záznam je v %s, řádka %d a lze jej nalézt"
#: sphinx/ext/todo.py:81
msgid "here"
msgstr "zde"
#: sphinx/locale/__init__.py:15
msgid "Attention"
msgstr "Výstraha"
@ -318,33 +339,50 @@ msgstr "příkaz"
msgid "built-in function"
msgstr "vestavěná funkce"
#: sphinx/static/doctools.js:172
#: sphinx/static/doctools.js:139 sphinx/writers/html.py:425
msgid "Permalink to this headline"
msgstr "Trvalý odkaz na tento nadpis"
#: sphinx/static/doctools.js:145 sphinx/writers/html.py:80
msgid "Permalink to this definition"
msgstr "Trvalý odkaz na tuto definici"
#: sphinx/static/doctools.js:174
msgid "Hide Search Matches"
msgstr ""
msgstr "Skrýt výsledky vyhledávání"
#: sphinx/static/searchtools.js:242
#, fuzzy
#: sphinx/static/searchtools.js:274
msgid "Searching"
msgstr "hledej"
msgstr "Hledám"
#: sphinx/static/searchtools.js:246
msgid "Getting search index..."
msgstr ""
#: sphinx/static/searchtools.js:279
msgid "Preparing search..."
msgstr "Připravuji vyhledávání...."
#: sphinx/static/searchtools.js:384 sphinx/templates/search.html:18
#: sphinx/static/searchtools.js:338
msgid "module, in "
msgstr "modul, v"
#: sphinx/static/searchtools.js:347
msgid ", in "
msgstr ", v"
#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:25
msgid "Search Results"
msgstr "Výsledky hledání"
#: sphinx/static/searchtools.js:386
#: 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 ""
"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:389
#: sphinx/static/searchtools.js:457
#, 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"
@ -362,10 +400,6 @@ msgstr "Celkový obsah"
msgid "lists all sections and subsections"
msgstr "seznam všech sekcí a podsekcí"
#: sphinx/templates/defindex.html:16
msgid "Search page"
msgstr "Vyhledávací stránka"
#: sphinx/templates/defindex.html:17
msgid "search this documentation"
msgstr "prohledej tuto dokumentaci"
@ -409,27 +443,23 @@ msgstr "Obsah"
msgid "Previous topic"
msgstr "Přechozí téma"
#: sphinx/templates/layout.html:47
#: sphinx/templates/layout.html:48
msgid "previous chapter"
msgstr "předchozí kapitola"
#: sphinx/templates/layout.html:50
#: sphinx/templates/layout.html:51
msgid "Next topic"
msgstr "Další téma"
#: sphinx/templates/layout.html:51
#: sphinx/templates/layout.html:53
msgid "next chapter"
msgstr "další kapitola"
#: sphinx/templates/layout.html:55
#: sphinx/templates/layout.html:58
msgid "This Page"
msgstr "Tato stránka"
#: sphinx/templates/layout.html:59
msgid "Suggest Change"
msgstr "Návrh změnu"
#: sphinx/templates/layout.html:60 sphinx/templates/layout.html:62
#: sphinx/templates/layout.html:61
msgid "Show Source"
msgstr "Ukázat zdroj"
@ -437,60 +467,49 @@ msgstr "Ukázat zdroj"
msgid "Quick search"
msgstr "Rychlé vyhledávání"
#: sphinx/templates/layout.html:71
msgid "Keyword search"
msgstr "Hledání dle klíče"
#: sphinx/templates/layout.html:73
#: sphinx/templates/layout.html:74
msgid "Go"
msgstr "hledej"
#: sphinx/templates/layout.html:78
msgid "Enter a module, class or function name."
#, fuzzy
msgid "Enter search terms or a module, class or function name."
msgstr "Zadej jméno modulu, třídy nebo funkce."
#: sphinx/templates/layout.html:118
#: sphinx/templates/layout.html:115
#, python-format
msgid "Search within %(docstitle)s"
msgstr "Hledání uvnitř %(docstitle)s"
#: sphinx/templates/layout.html:127
#: sphinx/templates/layout.html:124
msgid "About these documents"
msgstr "O těchto dokumentech"
#: sphinx/templates/layout.html:129
msgid "Global table of contents"
msgstr "Celkový obsah"
#: sphinx/templates/layout.html:130
msgid "Global index"
msgstr "Celkový index"
#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
#: sphinx/templates/layout.html:127 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Hledání"
#: sphinx/templates/layout.html:133
#: sphinx/templates/layout.html:129
msgid "Copyright"
msgstr "Veškerá práva vyhrazena"
#: sphinx/templates/layout.html:178
#: sphinx/templates/layout.html:174
#, 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:176
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Copyright %(copyright)s."
#: sphinx/templates/layout.html:183
#: sphinx/templates/layout.html:179
#, 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
#: sphinx/templates/layout.html:182
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
@ -499,15 +518,7 @@ msgstr ""
"Vytvořeno pomocí <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s."
#: sphinx/templates/modindex.html:15
msgid "Most popular modules:"
msgstr "Nejpopulárnější moduly:"
#: sphinx/templates/modindex.html:24
msgid "Show modules only available on these platforms"
msgstr "Zobrazit moduly dostupné na této platformě"
#: sphinx/templates/modindex.html:56
#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "Zastaralé"
@ -516,33 +527,29 @@ msgstr "Zastaralé"
msgid "Search %(docstitle)s"
msgstr "Prohledat %(docstitle)s"
#: sphinx/templates/page.html:8
#: sphinx/templates/search.html:9
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."
"Please activate JavaScript to enable the search\n"
" functionality."
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
#: sphinx/templates/search.html:14
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."
" 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
#: sphinx/templates/search.html:21
msgid "search"
msgstr "hledej"
#: sphinx/templates/search.html:20
#: sphinx/templates/search.html:27
msgid "Your search did not match any results."
msgstr "Nic jsme nenašli."
@ -574,3 +581,40 @@ msgstr "Změny API"
msgid "Other changes"
msgstr "Ostatní změny"
#: sphinx/writers/latex.py:173
msgid "Release"
msgstr "Vydání"
#: sphinx/writers/text.py:166
#, python-format
msgid "Platform: %s"
msgstr "Platforma: %s"
#: sphinx/writers/text.py:427
msgid "[image]"
msgstr "[obrázek]"
#~ msgid "Suggest Change"
#~ msgstr "Návrh změnu"
#~ msgid "Keyword search"
#~ msgstr "Hledání dle klíče"
#~ msgid "Most popular modules:"
#~ msgstr "Nejpopulárnější moduly:"
#~ msgid "Show modules only available on these platforms"
#~ msgstr "Zobrazit moduly dostupné na této platformě"
#~ 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."

View File

@ -1 +1 @@
Documentation.addTranslations({"locale": "de", "plural_expr": "(n != 1)", "messages": {"Search Results": "Suchergebnisse", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "Es wurden keine Dokumente gefunden. Haben Sie alle Suchworte richtig geschrieben und gen\u00fcgend Kategorien ausgew\u00e4hlt?", "Getting search index...": "Suchindex wird geladen...", "Permalink to this headline": "Permalink zu dieser \u00dcberschrift", "Searching": "Suchen...", "Permalink to this definition": "Permalink zu dieser Definition", "Hide Search Matches": "Suchergebnisse ausblenden", "Search finished, found %s page(s) matching the search query.": "Suche beendet, %s Seite(n) mit Ergebnissen wurden gefunden."}});
Documentation.addTranslations({"locale": "de", "plural_expr": "(n != 1)", "messages": {"module, in ": "Modul, in ", "Preparing search...": "Suche wird vorbereitet...", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "Es wurden keine Dokumente gefunden. Haben Sie alle Suchworte richtig geschrieben und gen\u00fcgend Kategorien ausgew\u00e4hlt?", "Search finished, found %s page(s) matching the search query.": "Suche beendet, %s Seite(n) mit Ergebnissen wurden gefunden.", ", in ": ", in ", "Permalink to this headline": "Permalink zu dieser \u00dcberschrift", "Searching": "Suchen...", "Permalink to this definition": "Permalink zu dieser Definition", "Hide Search Matches": "Suchergebnisse ausblenden", "Search Results": "Suchergebnisse"}});

View File

@ -7,7 +7,7 @@ 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-09-06 19:13+0200\n"
"PO-Revision-Date: 2009-01-24 18:43+0000\n"
"Last-Translator: Horst Gutmann <zerok@zerokspot.com>\n"
"Language-Team: de <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
@ -16,223 +16,243 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 0.9.3\n"
#: sphinx/builder.py:391
#, python-format
msgid "%b %d, %Y"
msgstr "%d. %m. %Y"
#: sphinx/builder.py:410 sphinx/templates/defindex.html:21
msgid "General Index"
msgstr "Allgemeiner Index"
#: sphinx/builder.py:410
msgid "index"
msgstr "Index"
#: sphinx/builder.py:412 sphinx/htmlhelp.py:155
#: 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:412
msgid "modules"
msgstr "Module"
#: sphinx/builder.py:448
msgid "next"
msgstr "weiter"
#: sphinx/builder.py:455
msgid "previous"
msgstr "zurück"
#: sphinx/builder.py:1092
msgid "Builtins"
msgstr "Builtins"
#: sphinx/builder.py:1094
msgid "Module level"
msgstr "Modulebene"
#: sphinx/environment.py:108 sphinx/latexwriter.py:129
#: sphinx/environment.py:104 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%d. %m. %Y"
#: sphinx/htmlwriter.py:73 sphinx/static/doctools.js:143
msgid "Permalink to this definition"
msgstr "Permalink zu dieser Definition"
#: sphinx/htmlwriter.py:379 sphinx/static/doctools.js:136
msgid "Permalink to this headline"
msgstr "Permalink zu dieser Überschrift"
#: sphinx/latexwriter.py:143
msgid "Release"
msgstr "Release"
#: sphinx/latexwriter.py:188
msgid "Module index"
msgstr "Modulindex"
#: sphinx/latexwriter.py:190 sphinx/templates/genindex-single.html:2
#: sphinx/environment.py:300 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:126 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Stichwortverzeichnis"
#: sphinx/roles.py:52 sphinx/directives/desc.py:514
#: sphinx/environment.py:301 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Modulindex"
#: sphinx/environment.py:302 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Suche"
#: sphinx/roles.py:53 sphinx/directives/desc.py:580
#, python-format
msgid "environment variable; %s"
msgstr "Umgebungsvariable; %s"
#: sphinx/roles.py:59
#: sphinx/roles.py:60
#, python-format
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
#: sphinx/textwriter.py:151
#: sphinx/builders/changes.py:64
msgid "Builtins"
msgstr "Builtins"
#: sphinx/builders/changes.py:66
msgid "Module level"
msgstr "Modulebene"
#: sphinx/builders/html.py:118
#, python-format
msgid "Platform: %s"
msgstr "Plattform: %s"
msgid "%b %d, %Y"
msgstr "%d. %m. %Y"
#: sphinx/textwriter.py:353
msgid "[image]"
msgstr "[Bild]"
#: sphinx/builders/html.py:137 sphinx/templates/defindex.html:21
msgid "General Index"
msgstr "Allgemeiner Index"
#: sphinx/directives/desc.py:26
#: sphinx/builders/html.py:137
msgid "index"
msgstr "Index"
#: sphinx/builders/html.py:139 sphinx/builders/htmlhelp.py:182
#: sphinx/builders/qthelp.py:131 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:139
msgid "modules"
msgstr "Module"
#: sphinx/builders/html.py:179
msgid "next"
msgstr "weiter"
#: sphinx/builders/html.py:186
msgid "previous"
msgstr "zurück"
#: sphinx/builders/latex.py:155 sphinx/builders/pdf.py:162
msgid " (in "
msgstr " (in "
#: sphinx/directives/desc.py:25
#, python-format
msgid "%s() (built-in function)"
msgstr "%s() (eingebaute Funktion)"
#: sphinx/directives/desc.py:27 sphinx/directives/desc.py:41
#: sphinx/directives/desc.py:53
#: sphinx/directives/desc.py:26 sphinx/directives/desc.py:42
#: sphinx/directives/desc.py:54
#, python-format
msgid "%s() (in module %s)"
msgstr "%s() (in Modul %s)"
#: sphinx/directives/desc.py:30
#: sphinx/directives/desc.py:29
#, python-format
msgid "%s (built-in variable)"
msgstr "%s (eingebaute Variable)"
#: sphinx/directives/desc.py:31 sphinx/directives/desc.py:65
#: sphinx/directives/desc.py:30 sphinx/directives/desc.py:78
#, python-format
msgid "%s (in module %s)"
msgstr "%s (in Modul %s)"
#: sphinx/directives/desc.py:33
#, python-format
msgid "%s (built-in class)"
msgstr "%s (eingebaute Klasse)"
#: sphinx/directives/desc.py:34
#, python-format
msgid "%s (class in %s)"
msgstr "%s (Klasse in %s)"
#: sphinx/directives/desc.py:45
#: sphinx/directives/desc.py:46
#, python-format
msgid "%s() (%s.%s method)"
msgstr "%s() (Methode von %s.%s)"
#: sphinx/directives/desc.py:47
#: sphinx/directives/desc.py:48
#, python-format
msgid "%s() (%s method)"
msgstr "%s() (Methode von %s)"
#: sphinx/directives/desc.py:57
#: sphinx/directives/desc.py:58
#, python-format
msgid "%s() (%s.%s static method)"
msgstr "%s() (statische Methode von %s.%s)"
#: sphinx/directives/desc.py:59
#: sphinx/directives/desc.py:60
#, python-format
msgid "%s() (%s static method)"
msgstr "%s() (statische Methode von %s)"
#: sphinx/directives/desc.py:69
#: sphinx/directives/desc.py:82
#, python-format
msgid "%s (%s.%s attribute)"
msgstr "%s (Attribut von %s.%s)"
#: sphinx/directives/desc.py:71
#: sphinx/directives/desc.py:84
#, python-format
msgid "%s (%s attribute)"
msgstr "%s (Attribut von %s)"
#: sphinx/directives/desc.py:73
#: sphinx/directives/desc.py:86
#, python-format
msgid "%s (C function)"
msgstr "%s (C-Funktion)"
#: sphinx/directives/desc.py:75
#: sphinx/directives/desc.py:88
#, python-format
msgid "%s (C member)"
msgstr "%s (C-Member)"
#: sphinx/directives/desc.py:77
#: sphinx/directives/desc.py:90
#, python-format
msgid "%s (C macro)"
msgstr "%s (C-Makro)"
#: sphinx/directives/desc.py:79
#: sphinx/directives/desc.py:92
#, python-format
msgid "%s (C type)"
msgstr "%s (C-Typ)"
#: sphinx/directives/desc.py:81
#: sphinx/directives/desc.py:94
#, python-format
msgid "%s (C variable)"
msgstr "%s (C-Variable)"
#: sphinx/directives/desc.py:99
#: sphinx/directives/desc.py:112
msgid "Raises"
msgstr "Verursacht:"
#: sphinx/directives/desc.py:103
#: sphinx/directives/desc.py:116
msgid "Variable"
msgstr "Variable"
#: sphinx/directives/desc.py:106
#: sphinx/directives/desc.py:119
msgid "Returns"
msgstr "Rückgabe"
#: sphinx/directives/desc.py:113
#: sphinx/directives/desc.py:128
msgid "Return type"
msgstr "Rückgabetyp"
#: sphinx/directives/desc.py:140
#: sphinx/directives/desc.py:213
msgid "Parameter"
msgstr "Parameter"
#: sphinx/directives/desc.py:217
msgid "Parameters"
msgstr "Parameter"
#: sphinx/directives/desc.py:402
#: sphinx/directives/desc.py:465
#, python-format
msgid "command line option; %s"
msgstr "Kommandozeilenoption; %s"
msgid "%scommand line option; %s"
msgstr "%sKommandozeilenoption; %s"
#: sphinx/directives/other.py:102
#: sphinx/directives/other.py:101
msgid "Platforms: "
msgstr "Plattformen: "
#: sphinx/directives/other.py:107
#: sphinx/directives/other.py:106
#, python-format
msgid "%s (module)"
msgstr "%s (Modul)"
#: sphinx/directives/other.py:147
#: sphinx/directives/other.py:146
msgid "Section author: "
msgstr "Autor des Abschnitts: "
#: sphinx/directives/other.py:149
#: sphinx/directives/other.py:148
msgid "Module author: "
msgstr "Autor des Moduls: "
#: sphinx/directives/other.py:151
#: sphinx/directives/other.py:150
msgid "Author: "
msgstr "Autor: "
#: sphinx/directives/other.py:233
#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Siehe auch"
#: sphinx/ext/autodoc.py:442
#, python-format
msgid " Bases: %s"
msgstr " Basisklassen: %s"
#: sphinx/ext/autodoc.py:566 sphinx/ext/autodoc.py:583
#, python-format
msgid "alias of :class:`%s`"
msgstr "Alias von :class:`%s`"
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr "Zu tun"
#: sphinx/ext/todo.py:75
#, python-format
msgid "(The original entry is located in %s, line %d and can be found "
msgstr "(Der Eintrag steht in %s, Zeile %s, siehe "
#: sphinx/ext/todo.py:81
msgid "here"
msgstr "hier"
#: sphinx/locale/__init__.py:15
msgid "Attention"
msgstr "Achtung"
@ -316,30 +336,47 @@ msgstr "Statement"
msgid "built-in function"
msgstr "eingebaute Funktion"
#: sphinx/static/doctools.js:172
#: sphinx/static/doctools.js:139 sphinx/writers/html.py:425
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"
#: sphinx/static/searchtools.js:242
#, fuzzy
#: sphinx/static/searchtools.js:274
msgid "Searching"
msgstr "Suchen..."
#: sphinx/static/searchtools.js:246
msgid "Getting search index..."
msgstr "Suchindex wird geladen..."
#: sphinx/static/searchtools.js:279
msgid "Preparing search..."
msgstr "Suche wird vorbereitet..."
#: sphinx/static/searchtools.js:384 sphinx/templates/search.html:18
#: sphinx/static/searchtools.js:338
msgid "module, in "
msgstr "Modul, in "
#: sphinx/static/searchtools.js:347
msgid ", in "
msgstr ", in "
#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:25
msgid "Search Results"
msgstr "Suchergebnisse"
#: sphinx/static/searchtools.js:386
#: 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 "Es wurden keine Dokumente gefunden. Haben Sie alle Suchworte richtig geschrieben und genügend Kategorien ausgewählt?"
msgstr ""
"Es wurden keine Dokumente gefunden. Haben Sie alle Suchworte richtig "
"geschrieben und genügend Kategorien ausgewählt?"
#: sphinx/static/searchtools.js:389
#: 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."
@ -360,10 +397,6 @@ msgstr "Vollständiges Inhaltsverzeichnis"
msgid "lists all sections and subsections"
msgstr "Liste aller Kapitel und Unterkapitel"
#: sphinx/templates/defindex.html:16
msgid "Search page"
msgstr "Suche"
#: sphinx/templates/defindex.html:17
msgid "search this documentation"
msgstr "Durchsuche diese Dokumentation"
@ -407,27 +440,23 @@ msgstr "Inhalt"
msgid "Previous topic"
msgstr "Vorheriges Thema"
#: sphinx/templates/layout.html:47
#: sphinx/templates/layout.html:48
msgid "previous chapter"
msgstr "vorheriges Kapitel"
#: sphinx/templates/layout.html:50
#: sphinx/templates/layout.html:51
msgid "Next topic"
msgstr "Nächstes Thema"
#: sphinx/templates/layout.html:51
#: sphinx/templates/layout.html:53
msgid "next chapter"
msgstr "nächstes Kapitel"
#: sphinx/templates/layout.html:55
#: sphinx/templates/layout.html:58
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:61
msgid "Show Source"
msgstr "Quelltext anzeigen"
@ -435,60 +464,48 @@ msgstr "Quelltext anzeigen"
msgid "Quick search"
msgstr "Schnellsuche"
#: sphinx/templates/layout.html:71
msgid "Keyword search"
msgstr "Stichwortsuche"
#: sphinx/templates/layout.html:73
#: sphinx/templates/layout.html:74
msgid "Go"
msgstr "Los"
#: sphinx/templates/layout.html:78
msgid "Enter a module, class or function name."
msgstr "Gib einen Modul-, Klassen- oder Funktionsnamen an."
msgid "Enter search terms or a module, class or function name."
msgstr "Geben Sie einen Modul-, Klassen- oder Funktionsnamen einn."
#: sphinx/templates/layout.html:118
#: sphinx/templates/layout.html:115
#, python-format
msgid "Search within %(docstitle)s"
msgstr "Suche in %(docstitle)s"
#: sphinx/templates/layout.html:127
#: sphinx/templates/layout.html:124
msgid "About these documents"
msgstr "Über diese Dokumentation"
#: sphinx/templates/layout.html:129
msgid "Global table of contents"
msgstr "Globales Inhaltsverzeichnis"
#: sphinx/templates/layout.html:130
msgid "Global index"
msgstr "Globale Stichwortverzeichnis"
#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
#: sphinx/templates/layout.html:127 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Suche"
#: sphinx/templates/layout.html:133
#: sphinx/templates/layout.html:129
msgid "Copyright"
msgstr "Copyright"
#: sphinx/templates/layout.html:178
#: sphinx/templates/layout.html:174
#, 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:176
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Copyright %(copyright)s."
#: sphinx/templates/layout.html:183
#: sphinx/templates/layout.html:179
#, 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:182
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
@ -497,15 +514,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"
@ -514,34 +523,25 @@ msgstr "Veraltet"
msgid "Search %(docstitle)s"
msgstr "Suche in %(docstitle)s"
#: sphinx/templates/page.html:8
#: sphinx/templates/search.html:9
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."
"Please activate JavaScript to enable the search\n"
" functionality."
msgstr "Bitte aktivieren Sie JavaScript, wenn Sie die Suchfunktion nutzen wollen."
#: sphinx/templates/search.html:7
#: sphinx/templates/search.html:14
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."
msgstr ""
"Von hier aus kannst du die Dokumentation durchsuchen. Gib deine "
"Suchbegriffe in das untenstehende Feld ein und klicke auf \"suchen\". "
"Bitte beachte, dass die Suchfunktion automatisch nach all diesen Worten "
"suchen wird. Seiten, die nicht alle Worte enthalten, werden nicht in der "
"Ergebnisliste erscheinen."
" containing fewer words won't appear in the result list."
msgstr "Von hier aus können Sie die Dokumentation durchsuchen. Geben Sie Ihre Suchbegriffe in das untenstehende Feld ein und klicken Sie auf \"Suchen\". Bitte beachten Sie, dass die Suchfunktion automatisch nach all diesen Worten suchen wird. Seiten, die nicht alle Worte enthalten, werden nicht in der Ergebnisliste erscheinen."
#: sphinx/templates/search.html:14
#: sphinx/templates/search.html:21
msgid "search"
msgstr "suchen"
#: sphinx/templates/search.html:20
#: sphinx/templates/search.html:27
msgid "Your search did not match any results."
msgstr "Deine Suche ergab leider keine Treffer."
@ -573,3 +573,16 @@ 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]"

View File

@ -1 +1 @@
Documentation.addTranslations({"locale": "es", "plural_expr": "(n != 1)", "messages": {"Search Results": "Resultados de la b\u00fasqueda", "Preparing search...": "Preparando la b\u00fasqueda", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "La b\u00fasqueda no dio ning\u00fan resultado. Por favor aseg\u00farese que escribi\u00f3 todas las palabras correctamente y que ha seleccionado suficientes categor\u00edas", "Search finished, found %s page(s) matching the search query.": "B\u00fasqueda finalizada, se han encontrado %s p\u00e1gina(s) que concuerdan con su consulta", "Permalink to this headline": "Enlazar permanentemente con este t\u00edtulo", "Searching": "Buscando", "Permalink to this definition": "Enlazar permanentemente con esta definici\u00f3n", "Hide Search Matches": "Coincidencias de la b\u00fasqueda"}});
Documentation.addTranslations({"locale": "es", "plural_expr": "(n != 1)", "messages": {"module, in ": "m\u00f3dulo", "Preparing search...": "Preparando la b\u00fasqueda", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "La b\u00fasqueda no dio ning\u00fan resultado. Por favor aseg\u00farese que escribi\u00f3 todas las palabras correctamente y que ha seleccionado suficientes categor\u00edas", "Search finished, found %s page(s) matching the search query.": "B\u00fasqueda finalizada, se han encontrado %s p\u00e1gina(s) que concuerdan con su consulta", ", in ": "", "Permalink to this headline": "Enlazar permanentemente con este t\u00edtulo", "Searching": "Buscando", "Permalink to this definition": "Enlazar permanentemente con esta definici\u00f3n", "Hide Search Matches": "Coincidencias de la b\u00fasqueda", "Search Results": "Resultados de la b\u00fasqueda"}});

View File

@ -1,4 +1,4 @@
# Translations template for Sphinx.
# Spanish translations for Sphinx.
# Copyright (C) 2008 ORGANIZATION
# This file is distributed under the same license as the Sphinx project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2008.
@ -8,240 +8,256 @@ 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-10-23 22:11+0200\n"
"PO-Revision-Date: 2009-01-24 18:39+0000\n"
"Last-Translator: Guillem Borrell <guillem@torroja.dmt.upm.es>\n"
"Language-Team: LANGUAGE <LL@li.org>\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.3\n"
#: sphinx/builder.py:400
#, python-format
msgid "%b %d, %Y"
msgstr "%d %b, %Y"
#: sphinx/builder.py:419 sphinx/templates/defindex.html:21
msgid "General Index"
msgstr "Índice General"
#: sphinx/builder.py:419
msgid "index"
msgstr "índice"
#: sphinx/builder.py:421 sphinx/htmlhelp.py:155
#: 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:421
msgid "modules"
msgstr "módulos"
#: sphinx/builder.py:457
msgid "next"
msgstr "siguiente"
#: sphinx/builder.py:464
msgid "previous"
msgstr "anterior"
#: sphinx/builder.py:1108
#, fuzzy
msgid "Builtins"
msgstr "Funciones de base"
#: sphinx/builder.py:1110
#, fuzzy
msgid "Module level"
msgstr "Módulos"
#: sphinx/environment.py:107 sphinx/latexwriter.py:129
#, python-format, fuzzy
#: sphinx/environment.py:104 sphinx/writers/latex.py:170
#, fuzzy, python-format
msgid "%B %d, %Y"
msgstr "%d de %B de %Y"
#: sphinx/environment.py:270 sphinx/latexwriter.py:190
#: sphinx/templates/genindex-single.html:2
#: sphinx/environment.py:300 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:126 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Índice"
#: sphinx/environment.py:271 sphinx/latexwriter.py:188
#: sphinx/environment.py:301 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Índice de Módulos"
#: sphinx/environment.py:272 sphinx/templates/defindex.html:16
#: sphinx/environment.py:302 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Página de Búsqueda"
#: sphinx/htmlwriter.py:73 sphinx/static/doctools.js:145
msgid "Permalink to this definition"
msgstr "Enlazar permanentemente con esta definición"
#: sphinx/htmlwriter.py:375 sphinx/static/doctools.js:139
msgid "Permalink to this headline"
msgstr "Enlazar permanentemente con este título"
#: sphinx/latexwriter.py:143
#, fuzzy
msgid "Release"
msgstr "Versión"
#: sphinx/roles.py:52 sphinx/directives/desc.py:514
#: sphinx/roles.py:53 sphinx/directives/desc.py:580
#, python-format
msgid "environment variable; %s"
msgstr "variables de entorno; %s"
#: sphinx/roles.py:59
#: sphinx/roles.py:60
#, python-format
msgid "Python Enhancement Proposals!PEP %s"
msgstr "Python Enhancement Proposals!PEP %s"
#: sphinx/textwriter.py:151
#: 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:118
#, python-format
msgid "Platform: %s"
msgstr "Plataforma: %s"
msgid "%b %d, %Y"
msgstr "%d %b, %Y"
#: sphinx/textwriter.py:353
msgid "[image]"
msgstr "[imagen]"
#: sphinx/builders/html.py:137 sphinx/templates/defindex.html:21
msgid "General Index"
msgstr "Índice General"
#: sphinx/directives/desc.py:26
#, python-format, fuzzy
#: sphinx/builders/html.py:137
msgid "index"
msgstr "índice"
#: sphinx/builders/html.py:139 sphinx/builders/htmlhelp.py:182
#: sphinx/builders/qthelp.py:131 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:139
msgid "modules"
msgstr "módulos"
#: sphinx/builders/html.py:179
msgid "next"
msgstr "siguiente"
#: sphinx/builders/html.py:186
msgid "previous"
msgstr "anterior"
#: sphinx/builders/latex.py:155 sphinx/builders/pdf.py:162
msgid " (in "
msgstr ""
#: sphinx/directives/desc.py:25
#, fuzzy, python-format
msgid "%s() (built-in function)"
msgstr "%s() (función de base)"
#: sphinx/directives/desc.py:27 sphinx/directives/desc.py:41
#: sphinx/directives/desc.py:53
#: sphinx/directives/desc.py:26 sphinx/directives/desc.py:42
#: sphinx/directives/desc.py:54
#, python-format
msgid "%s() (in module %s)"
msgstr "%s() (en el módulo %s)"
#: sphinx/directives/desc.py:30
#, python-format, fuzzy
#: sphinx/directives/desc.py:29
#, fuzzy, python-format
msgid "%s (built-in variable)"
msgstr "%s (variable de base)"
#: sphinx/directives/desc.py:31 sphinx/directives/desc.py:65
#: sphinx/directives/desc.py:30 sphinx/directives/desc.py:78
#, python-format
msgid "%s (in module %s)"
msgstr "%s (en el módulo %s)"
#: sphinx/directives/desc.py:33
#, fuzzy, python-format
msgid "%s (built-in class)"
msgstr "%s (variable de base)"
#: sphinx/directives/desc.py:34
#, python-format
msgid "%s (class in %s)"
msgstr "%s (clase en %s)"
#: sphinx/directives/desc.py:45
#: sphinx/directives/desc.py:46
#, python-format
msgid "%s() (%s.%s method)"
msgstr "%s() (%s.%s método)"
#: sphinx/directives/desc.py:47
#: sphinx/directives/desc.py:48
#, python-format
msgid "%s() (%s method)"
msgstr "%s() (%s método)"
#: sphinx/directives/desc.py:57
#: sphinx/directives/desc.py:58
#, python-format
msgid "%s() (%s.%s static method)"
msgstr "%s() (%s.%s método estático)"
#: sphinx/directives/desc.py:59
#: sphinx/directives/desc.py:60
#, python-format
msgid "%s() (%s static method)"
msgstr "%s() (%s método estático)"
#: sphinx/directives/desc.py:69
#: sphinx/directives/desc.py:82
#, python-format
msgid "%s (%s.%s attribute)"
msgstr "%s (%s.%s atributo)"
#: sphinx/directives/desc.py:71
#: sphinx/directives/desc.py:84
#, python-format
msgid "%s (%s attribute)"
msgstr "%s (%s atributo)"
#: sphinx/directives/desc.py:73
#: sphinx/directives/desc.py:86
#, python-format
msgid "%s (C function)"
msgstr "%s (función C)"
#: sphinx/directives/desc.py:75
#: sphinx/directives/desc.py:88
#, python-format
msgid "%s (C member)"
msgstr "%s (miembro C)"
#: sphinx/directives/desc.py:77
#: sphinx/directives/desc.py:90
#, python-format
msgid "%s (C macro)"
msgstr "%s (macro C)"
#: sphinx/directives/desc.py:79
#: sphinx/directives/desc.py:92
#, python-format
msgid "%s (C type)"
msgstr "%s (tipo C)"
#: sphinx/directives/desc.py:81
#: sphinx/directives/desc.py:94
#, python-format
msgid "%s (C variable)"
msgstr "%s (variable C)"
#: sphinx/directives/desc.py:99
#: sphinx/directives/desc.py:112
msgid "Raises"
msgstr "Muestra"
#: sphinx/directives/desc.py:103
#: sphinx/directives/desc.py:116
msgid "Variable"
msgstr "Variable"
#: sphinx/directives/desc.py:106
#: sphinx/directives/desc.py:119
msgid "Returns"
msgstr "Devuelve"
#: sphinx/directives/desc.py:113
#: sphinx/directives/desc.py:128
#, fuzzy
msgid "Return type"
msgstr "Tipo del argumento devuelto"
#: sphinx/directives/desc.py:140
#: sphinx/directives/desc.py:213
#, fuzzy
msgid "Parameter"
msgstr "Parámetros"
#: sphinx/directives/desc.py:217
msgid "Parameters"
msgstr "Parámetros"
#: sphinx/directives/desc.py:402
#, python-format
msgid "command line option; %s"
msgstr "Opciones en línea de comandos; %s"
#: sphinx/directives/desc.py:465
#, fuzzy, python-format
msgid "%scommand line option; %s"
msgstr "%sOpciones en línea de comandos; %s"
#: sphinx/directives/other.py:102
#: sphinx/directives/other.py:101
msgid "Platforms: "
msgstr "Plataformas:"
#: sphinx/directives/other.py:107
#: sphinx/directives/other.py:106
#, python-format
msgid "%s (module)"
msgstr "%s (módulo)"
#: sphinx/directives/other.py:147
#: sphinx/directives/other.py:146
msgid "Section author: "
msgstr "Autor de la sección"
#: sphinx/directives/other.py:149
#: sphinx/directives/other.py:148
msgid "Module author: "
msgstr "Autor del módulo"
#: sphinx/directives/other.py:151
#: sphinx/directives/other.py:150
msgid "Author: "
msgstr "Autor:"
#: sphinx/directives/other.py:233
#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Ver también"
#: sphinx/ext/autodoc.py:442
#, python-format
msgid " Bases: %s"
msgstr ""
#: sphinx/ext/autodoc.py:566 sphinx/ext/autodoc.py:583
#, python-format
msgid "alias of :class:`%s`"
msgstr ""
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr ""
#: sphinx/ext/todo.py:75
#, python-format
msgid "(The original entry is located in %s, line %d and can be found "
msgstr ""
#: sphinx/ext/todo.py:81
msgid "here"
msgstr ""
#: sphinx/locale/__init__.py:15
msgid "Attention"
msgstr "Atención"
@ -326,6 +342,14 @@ msgstr "sentencia"
msgid "built-in function"
msgstr "función de base"
#: sphinx/static/doctools.js:139 sphinx/writers/html.py:425
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"
@ -339,20 +363,34 @@ msgstr "Buscando"
msgid "Preparing search..."
msgstr "Preparando la búsqueda"
#: sphinx/static/searchtools.js:401 sphinx/templates/search.html:18
#: sphinx/static/searchtools.js:338
#, fuzzy
msgid "module, in "
msgstr "módulo"
#: sphinx/static/searchtools.js:347
msgid ", in "
msgstr ""
#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:25
msgid "Search Results"
msgstr "Resultados de la búsqueda"
#: sphinx/static/searchtools.js:403
#: 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 búsqueda no dio ningún resultado. Por favor asegúrese que escribió todas las palabras correctamente y que ha seleccionado suficientes categorías"
msgstr ""
"La búsqueda no dio ningún resultado. Por favor asegúrese que escribió "
"todas las palabras correctamente y que ha seleccionado suficientes "
"categorías"
#: sphinx/static/searchtools.js:405
#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr "Búsqueda finalizada, se han encontrado %s página(s) que concuerdan con su consulta"
msgstr ""
"Búsqueda finalizada, se han encontrado %s página(s) que concuerdan con su"
" consulta"
#: sphinx/templates/defindex.html:2
msgid "Overview"
@ -413,27 +451,23 @@ msgstr "Contenidos"
msgid "Previous topic"
msgstr "Tema anterior"
#: sphinx/templates/layout.html:47
#: sphinx/templates/layout.html:48
msgid "previous chapter"
msgstr "Capítulo anterior"
#: sphinx/templates/layout.html:50
#: sphinx/templates/layout.html:51
msgid "Next topic"
msgstr "Próximo tema"
#: sphinx/templates/layout.html:51
#: sphinx/templates/layout.html:53
msgid "next chapter"
msgstr "Próximo capítulo"
#: sphinx/templates/layout.html:55
#: sphinx/templates/layout.html:58
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:61
msgid "Show Source"
msgstr "Enseñar el código"
@ -441,75 +475,58 @@ msgstr "Enseñar el código"
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:74
msgid "Go"
msgstr "Ir a"
#: sphinx/templates/layout.html:78
msgid "Enter a module, class or function name."
#, 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:118
#: sphinx/templates/layout.html:115
#, python-format
msgid "Search within %(docstitle)s"
msgstr "Buscar en %(docstitle)s"
#: sphinx/templates/layout.html:127
#: sphinx/templates/layout.html:124
msgid "About these documents"
msgstr "Sobre este documento"
#: sphinx/templates/layout.html:129
msgid "Global table of contents"
msgstr "Índice General"
#: sphinx/templates/layout.html:130
msgid "Global index"
msgstr "Índice Global"
#: sphinx/templates/layout.html:131 sphinx/templates/search.html:2
#: sphinx/templates/layout.html:127 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Búsqueda"
#: sphinx/templates/layout.html:133
#: sphinx/templates/layout.html:129
msgid "Copyright"
msgstr "Copyright"
#: sphinx/templates/layout.html:178
#: sphinx/templates/layout.html:174
#, 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:176
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr "&copy; Copyright %(copyright)s."
#: sphinx/templates/layout.html:183
#: sphinx/templates/layout.html:179
#, 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:182
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s."
msgstr "Creado con <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> %(sphinx_version)s."
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"
@ -518,26 +535,30 @@ msgstr "Obsoleto"
msgid "Search %(docstitle)s"
msgstr "Buscar en %(docstitle)s"
#: sphinx/templates/page.html:8
#: sphinx/templates/search.html:9
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."
"Please activate JavaScript to enable the search\n"
" functionality."
msgstr ""
#: sphinx/templates/search.html:7
#: sphinx/templates/search.html:14
#, 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 less words won't appear in the result list."
msgstr "Este es el diálogo de búsqueda. Introduce los términos en el diálogo siguiente y pulsa \"buscar\". El asistente buscará automáticamente todas las palabras. Las páginas que contengan menos palabras no aparecerán en la lista de resultados."
" containing fewer words won't appear in the result list."
msgstr ""
"Este es el diálogo de búsqueda. Introduce los términos en el diálogo "
"siguiente y pulsa \"buscar\". El asistente buscará automáticamente todas"
" las palabras. Las páginas que contengan menos palabras no aparecerán en"
" la lista de resultados."
#: sphinx/templates/search.html:14
#: sphinx/templates/search.html:21
msgid "search"
msgstr "buscar"
#: sphinx/templates/search.html:20
#: sphinx/templates/search.html:27
msgid "Your search did not match any results."
msgstr "Tu consulta no obtuvo ningún resultado"
@ -569,3 +590,17 @@ 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]"

View File

@ -0,0 +1 @@
Documentation.addTranslations({"locale": "fi", "plural_expr": "(n != 1)", "messages": {"module, in ": "", "Preparing search...": "Valmistellaan etsint\u00e4\u00e4...", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "Ei l\u00f6ytynyt yht\u00e4\u00e4n. Tarkista hakuehdot, sanahaku, ei sen osia", "Search finished, found %s page(s) matching the search query.": "Etsint\u00e4 tehty, l\u00f6ydetty %s sivu(a).", ", in ": "", "Permalink to this headline": "", "Searching": "Etsit\u00e4\u00e4n", "Permalink to this definition": "", "Hide Search Matches": "Piilota l\u00f6ydetyt", "Search Results": "Etsinn\u00e4n tulos"}});

Binary file not shown.

View File

@ -0,0 +1,600 @@
# Finnish translations for Sphinx.
# Copyright (C) 2009 ORGANIZATION
# This file is distributed under the same license as the Sphinx project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
#
msgid ""
msgstr ""
"Project-Id-Version: Sphinx 0.6\n"
"Report-Msgid-Bugs-To: sphinx@awot.fi\n"
"POT-Creation-Date: 2009-01-24 18:39+0000\n"
"PO-Revision-Date: 2009-02-11 11:21+0200\n"
"Last-Translator: Jukka Inkeri <sphinx@awot.fi>\n"
"Language-Team: fi <sphinx@awot.fi>\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"
#: sphinx/environment.py:104 sphinx/writers/latex.py:170
#, python-format
msgid "%B %d, %Y"
msgstr "%d.%m.%Y"
#: sphinx/environment.py:300 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:126 sphinx/writers/latex.py:176
msgid "Index"
msgstr "Sisällysluettelo"
#: sphinx/environment.py:301 sphinx/writers/latex.py:175
msgid "Module Index"
msgstr "Moduuli sisällysluettelo"
#: sphinx/environment.py:302 sphinx/templates/defindex.html:16
msgid "Search Page"
msgstr "Etsi sivu"
#: sphinx/roles.py:53 sphinx/directives/desc.py:580
#, python-format
msgid "environment variable; %s"
msgstr ""
#: sphinx/roles.py:60
#, python-format
msgid "Python Enhancement Proposals!PEP %s"
msgstr ""
#: sphinx/builders/changes.py:64
msgid "Builtins"
msgstr ""
#: sphinx/builders/changes.py:66
msgid "Module level"
msgstr "Moduulitaso"
#: sphinx/builders/html.py:118
#, python-format
msgid "%b %d, %Y"
msgstr "%d.%m.%Y"
#: sphinx/builders/html.py:137 sphinx/templates/defindex.html:21
msgid "General Index"
msgstr "Yleinen sisällysluettelo"
#: sphinx/builders/html.py:137
msgid "index"
msgstr "hakemisto"
#: sphinx/builders/html.py:139 sphinx/builders/htmlhelp.py:182
#: sphinx/builders/qthelp.py:131 sphinx/templates/defindex.html:19
#: sphinx/templates/modindex.html:2 sphinx/templates/modindex.html:13
msgid "Global Module Index"
msgstr "Yleinen moduulien sisällysluettelo"
#: sphinx/builders/html.py:139
msgid "modules"
msgstr "moduulit"
#msgstr "osat"
#: sphinx/builders/html.py:179
msgid "next"
msgstr ">"
#: sphinx/builders/html.py:186
msgid "previous"
msgstr "<"
#: sphinx/builders/latex.py:155 sphinx/builders/pdf.py:162
msgid " (in "
msgstr ""
#: sphinx/directives/desc.py:25
#, python-format
msgid "%s() (built-in function)"
msgstr ""
#: sphinx/directives/desc.py:26 sphinx/directives/desc.py:42
#: sphinx/directives/desc.py:54
#, python-format
msgid "%s() (in module %s)"
msgstr ""
#: sphinx/directives/desc.py:29
#, python-format
msgid "%s (built-in variable)"
msgstr ""
#: sphinx/directives/desc.py:30 sphinx/directives/desc.py:78
#, python-format
msgid "%s (in module %s)"
msgstr ""
#: sphinx/directives/desc.py:33
#, python-format
msgid "%s (built-in class)"
msgstr ""
#: sphinx/directives/desc.py:34
#, python-format
msgid "%s (class in %s)"
msgstr ""
#: sphinx/directives/desc.py:46
#, python-format
msgid "%s() (%s.%s method)"
msgstr ""
#: sphinx/directives/desc.py:48
#, python-format
msgid "%s() (%s method)"
msgstr ""
#: sphinx/directives/desc.py:58
#, python-format
msgid "%s() (%s.%s static method)"
msgstr ""
#: sphinx/directives/desc.py:60
#, python-format
msgid "%s() (%s static method)"
msgstr ""
#: sphinx/directives/desc.py:82
#, python-format
msgid "%s (%s.%s attribute)"
msgstr ""
#: sphinx/directives/desc.py:84
#, python-format
msgid "%s (%s attribute)"
msgstr ""
#: sphinx/directives/desc.py:86
#, python-format
msgid "%s (C function)"
msgstr ""
#: sphinx/directives/desc.py:88
#, python-format
msgid "%s (C member)"
msgstr ""
#: sphinx/directives/desc.py:90
#, python-format
msgid "%s (C macro)"
msgstr ""
#: sphinx/directives/desc.py:92
#, python-format
msgid "%s (C type)"
msgstr ""
#: sphinx/directives/desc.py:94
#, python-format
msgid "%s (C variable)"
msgstr ""
#: sphinx/directives/desc.py:112
msgid "Raises"
msgstr ""
#: sphinx/directives/desc.py:116
msgid "Variable"
msgstr ""
#: sphinx/directives/desc.py:119
msgid "Returns"
msgstr ""
#: sphinx/directives/desc.py:128
msgid "Return type"
msgstr ""
#: sphinx/directives/desc.py:213
msgid "Parameter"
msgstr ""
#: sphinx/directives/desc.py:217
msgid "Parameters"
msgstr ""
#: sphinx/directives/desc.py:465
#, python-format
msgid "%scommand line option; %s"
msgstr ""
#: sphinx/directives/other.py:101
msgid "Platforms: "
msgstr "Ympäristö"
#: sphinx/directives/other.py:106
#, python-format
msgid "%s (module)"
msgstr "%s (moduuli)"
#: sphinx/directives/other.py:146
msgid "Section author: "
msgstr "Luvun kirjoittaja: "
#: sphinx/directives/other.py:148
msgid "Module author: "
msgstr "Moduulin kirjoittaja: "
#: sphinx/directives/other.py:150
msgid "Author: "
msgstr "Tekijä: "
#: sphinx/directives/other.py:249
msgid "See also"
msgstr "Katso myös"
#: sphinx/ext/autodoc.py:442
#, python-format
msgid " Bases: %s"
msgstr ""
#: sphinx/ext/autodoc.py:566 sphinx/ext/autodoc.py:583
#, python-format
msgid "alias of :class:`%s`"
msgstr ""
#: sphinx/ext/todo.py:31
msgid "Todo"
msgstr "Tehtävä vielä"
#: sphinx/ext/todo.py:75
#, python-format
msgid "(The original entry is located in %s, line %d and can be found "
msgstr ""
#: sphinx/ext/todo.py:81
msgid "here"
msgstr "tässä"
#: sphinx/locale/__init__.py:15
msgid "Attention"
msgstr "Huom"
#: sphinx/locale/__init__.py:16
msgid "Caution"
msgstr "Varoitus"
#: sphinx/locale/__init__.py:17
msgid "Danger"
msgstr "Vaara"
#: sphinx/locale/__init__.py:18
msgid "Error"
msgstr "Virhe"
#: sphinx/locale/__init__.py:19
msgid "Hint"
msgstr "Vihje"
#: sphinx/locale/__init__.py:20
msgid "Important"
msgstr "Tärkeä"
#: sphinx/locale/__init__.py:21
msgid "Note"
msgstr "Muista"
#: sphinx/locale/__init__.py:22
msgid "See Also"
msgstr "Katso myös"
#: sphinx/locale/__init__.py:23
msgid "Tip"
msgstr "Vihje"
#: sphinx/locale/__init__.py:24
msgid "Warning"
msgstr "Varoitus"
#: sphinx/locale/__init__.py:28
#, python-format
msgid "New in version %s"
msgstr "Uusi versiossa %s"
#: sphinx/locale/__init__.py:29
#, python-format
msgid "Changed in version %s"
msgstr "Muutettu versiossa %s"
#: sphinx/locale/__init__.py:30
#, python-format
msgid "Deprecated since version %s"
msgstr "Poistettu versiosta %s alkaen"
#: sphinx/locale/__init__.py:34
msgid "module"
msgstr "moduuli"
#msgstr "osa"
#: sphinx/locale/__init__.py:35
msgid "keyword"
msgstr ""
#msgstr "avainsana"
#: sphinx/locale/__init__.py:36
msgid "operator"
msgstr ""
#msgstr "operaattori"
#: sphinx/locale/__init__.py:37
msgid "object"
msgstr ""
#msgstr "objekti"
#: sphinx/locale/__init__.py:38
msgid "exception"
msgstr ""
#msgstr "poikkeus"
#: sphinx/locale/__init__.py:39
msgid "statement"
msgstr ""
#: sphinx/locale/__init__.py:40
msgid "built-in function"
msgstr ""
#: sphinx/static/doctools.js:139 sphinx/writers/html.py:425
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 "Piilota löydetyt"
#: sphinx/static/searchtools.js:274
msgid "Searching"
msgstr "Etsitään"
#: sphinx/static/searchtools.js:279
msgid "Preparing search..."
msgstr "Valmistellaan etsintää..."
#: sphinx/static/searchtools.js:338
msgid "module, in "
msgstr ""
#: sphinx/static/searchtools.js:347
msgid ", in "
msgstr ""
#: sphinx/static/searchtools.js:453 sphinx/templates/search.html:25
msgid "Search Results"
msgstr "Etsinnän tulos"
#: 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 "Ei löytynyt yhtään. Tarkista hakuehdot, sanahaku, ei sen osia"
#: sphinx/static/searchtools.js:457
#, python-format
msgid "Search finished, found %s page(s) matching the search query."
msgstr "Etsintä tehty, löydetty %s sivu(a)."
#: sphinx/templates/defindex.html:2
msgid "Overview"
msgstr "Yhteenveto"
#: sphinx/templates/defindex.html:11
msgid "Indices and tables:"
msgstr ""
#: sphinx/templates/defindex.html:14
msgid "Complete Table of Contents"
msgstr ""
#: sphinx/templates/defindex.html:15
msgid "lists all sections and subsections"
msgstr ""
#: sphinx/templates/defindex.html:17
msgid "search this documentation"
msgstr ""
#: sphinx/templates/defindex.html:20
msgid "quick access to all modules"
msgstr ""
#: sphinx/templates/defindex.html:22
msgid "all functions, classes, terms"
msgstr ""
#: sphinx/templates/genindex-single.html:5
#, python-format
msgid "Index &ndash; %(key)s"
msgstr ""
#: 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 "Hakemisto yhtenä luettelona"
#: sphinx/templates/genindex-split.html:7
msgid "Index pages by letter"
msgstr "Hakemisto aakkostus sivuttain"
#: sphinx/templates/genindex-split.html:15
msgid "can be huge"
msgstr "voi olla iso"
#: sphinx/templates/layout.html:9
msgid "Navigation"
msgstr "Navikointi"
#: sphinx/templates/layout.html:40
msgid "Table Of Contents"
msgstr "Sisällysluettelo"
#: sphinx/templates/layout.html:46
msgid "Previous topic"
msgstr "<<"
#: sphinx/templates/layout.html:48
msgid "previous chapter"
msgstr "<<"
#: sphinx/templates/layout.html:51
msgid "Next topic"
msgstr ">>"
#: sphinx/templates/layout.html:53
msgid "next chapter"
msgstr ">>"
#: sphinx/templates/layout.html:58
msgid "This Page"
msgstr "Tämä sivu"
#: sphinx/templates/layout.html:61
msgid "Show Source"
msgstr "Näytä lähdekoodina"
#: sphinx/templates/layout.html:71
msgid "Quick search"
msgstr "Pikahaku"
#: sphinx/templates/layout.html:74
msgid "Go"
msgstr "Siirry"
#: sphinx/templates/layout.html:78
msgid "Enter search terms or a module, class or function name."
msgstr "Anna etsittävä termi tai moduuli, luokka tai funktio"
#: sphinx/templates/layout.html:115
#, python-format
msgid "Search within %(docstitle)s"
msgstr ""
#: sphinx/templates/layout.html:124
msgid "About these documents"
msgstr "Tietoja tästä documentistä"
#: sphinx/templates/layout.html:127 sphinx/templates/search.html:2
#: sphinx/templates/search.html:5
msgid "Search"
msgstr "Etsi"
#: sphinx/templates/layout.html:129
msgid "Copyright"
msgstr ""
#msgstr "(c)"
#: sphinx/templates/layout.html:174
#, python-format
msgid "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
msgstr ""
#msgstr "&copy; <a href=\"%(path)s\">Copyright</a> %(copyright)s."
#msgstr "&copy; <a href=\"%(path)s\">kaikki pidätetään</A> %(copyright)."
#: sphinx/templates/layout.html:176
#, python-format
msgid "&copy; Copyright %(copyright)s."
msgstr ""
##msgstr "&copy; Copyright %(copyright)s."
#msgstr "&copy; %(copyright)."
#: sphinx/templates/layout.html:179
#, python-format
msgid "Last updated on %(last_updated)s."
msgstr ""
#msgstr "Viimeksi muutettu %(last_updated)."
#: sphinx/templates/layout.html:182
#, python-format
msgid ""
"Created using <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> "
"%(sphinx_version)s."
msgstr """
#msgstr "Tehty <a href=\"http://sphinx.pocoo.org/\">Sphinx</a> %(sphinx_version)"
#: sphinx/templates/modindex.html:36
msgid "Deprecated"
msgstr "Poistettu"
#: sphinx/templates/opensearch.xml:4
#, python-format
msgid "Search %(docstitle)s"
msgstr ""
#: sphinx/templates/search.html:9
msgid ""
"Please activate JavaScript to enable the search\n"
" functionality."
msgstr "Javascript pitää olla sallittu, jotta etsintä toimii."
#: sphinx/templates/search.html:14
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 "Anna hakusanat kokonaan, osasanoilla ei haeta."
#: sphinx/templates/search.html:21
msgid "search"
msgstr "etsi"
#: sphinx/templates/search.html:27
msgid "Your search did not match any results."
msgstr "Ei löytynyt ko. ehdoilla yhtään."
#: sphinx/templates/changes/frameset.html:5
#: sphinx/templates/changes/versionchanges.html:12
#, python-format
msgid "Changes in Version %(version)s &mdash; %(docstitle)s"
msgstr "Muutos versiosta %(version) &mdash; %(docstitle)"
#: sphinx/templates/changes/rstsource.html:5
#, python-format
msgid "%(filename)s &mdash; %(docstitle)s"
msgstr ""
#: sphinx/templates/changes/versionchanges.html:17
#, python-format
msgid "Automatically generated list of changes in version %(version)s"
msgstr "Automaattisesti luotu muutoshistoria alkaen versiosta %(version)"
#: sphinx/templates/changes/versionchanges.html:18
msgid "Library changes"
msgstr ""
#: sphinx/templates/changes/versionchanges.html:23
msgid "C API changes"
msgstr ""
#: sphinx/templates/changes/versionchanges.html:25
msgid "Other changes"
msgstr ""
#: sphinx/writers/latex.py:173
msgid "Release"
msgstr ""
#: sphinx/writers/text.py:166
#, python-format
msgid "Ympäristö: %s"
msgstr ""
#: sphinx/writers/text.py:427
msgid "[image]"
msgstr ""

View File

@ -1 +1 @@
Documentation.addTranslations({"locale": "fr", "plural_expr": "(n > 1)", "messages": {"Search Results": "R\u00e9sultats de la recherche", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "", "Getting search index...": "", "Permalink to this headline": "Lien permanent vers ce titre", "Searching": "rechercher", "Permalink to this definition": "Lien permanent vers cette d\u00e9finition", "Hide Search Matches": "", "Search finished, found %s page(s) matching the search query.": ""}});
Documentation.addTranslations({"locale": "fr", "plural_expr": "(n > 1)", "messages": {"module, in ": "module, dans", "Preparing search...": "Pr\u00e9paration de la recherche...", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "Votre recherche ne correspond \u00e0 aucun document. V\u00e9rifiez l'orthographe des termes de recherche et que vous avez s\u00e9lectionn\u00e9 suffisamment de cat\u00e9gories.", "Search finished, found %s page(s) matching the search query.": "La recherche est termin\u00e9e, %s page(s) correspond(ent) \u00e0 la requ\u00eate.", ", in ": ", dans", "Permalink to this headline": "Lien permanent vers ce titre", "Searching": "En cours de recherche", "Permalink to this definition": "Lien permanent vers cette d\u00e9finition", "Hide Search Matches": "Cacher les r\u00e9sultats de la recherche", "Search Results": "R\u00e9sultats de la recherche"}});

Some files were not shown because too many files have changed in this diff Show More