Navigation

- modules

- Sphinx 1.4.1 documentation »

Welcome

What users say:

“Cheers for a great tool that actually makes programmers want to write documentation!”

Sphinx is a tool that makes it easy to create intelligent and beautiful documentation, written by Georg Brandl and licensed under the BSD license.

It was originally created for the new Python documentation, and it has excellent facilities for the documentation of Python projects, but C/C++ is already supported as well, and it is planned to add special support for other languages as well. Of course, this site is also created from reStructuredText sources using Sphinx! The following features should be highlighted:

- Output formats: HTML (including Windows HTML Help), LaTeX (for printable PDF versions), ePub, Texinfo, manual pages, plain text

- Extensive cross-references: semantic markup and automatic links for functions, classes, citations, glossary terms and similar pieces of information

- Hierarchical structure: easy definition of a document tree, with automatic links to siblings, parents and children

- Automatic indices: general index as well as a language-specific module indices

- Code handling: automatic highlighting using the Pygments highlighter

- Extensions: automatic testing of code snippets, inclusion of docstrings from Python modules (API docs), and more

- Contributed extensions: more than 50 extensions contributed by users in a second repository; most of them installable from PyPI

Sphinx uses reStructuredText as its markup language, and many of its strengths come from the power and straightforwardness of reStructuredText and its parsing and translating suite, the Docutils.

Documentation

You can also download PDF/EPUB versions of the Sphinx documentation: a PDF version generated from the LaTeX Sphinx produces, and a EPUB version.

Examples

Links to documentation generated with Sphinx can be found on the Projects using Sphinx page.

For examples of how Sphinx source files look, use the “Show source” links on all pages of the documentation apart from this welcome page.

You may also be interested in the very nice tutorial on how to create a customized documentation using Sphinx written by the matplotlib developers.

There is a Japanese translation of this documentation, thanks to the Japanese Sphinx user group.

A Japanese book about Sphinx has been published by O'Reilly: Sphinxをはじめよう / Learning Sphinx.

Hosting

Need a place to host your Sphinx docs? readthedocs.org hosts a lot of Sphinx docs already, and integrates well with projects' source control. It also features a powerful built-in search that exceeds the possibilities of Sphinx' JavaScript-based offline search.

Contributor Guide

If you want to contribute to the project, this part of the documentation is for you.

- Sphinx Developer’s Guide

- Sphinx Authors

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- Sphinx 1.4.1 documentation »

Sphinx documentation contents

- Introduction

- Conversion from other systems

- Use with other systems

- Prerequisites

- Usage

- First Steps with Sphinx

- Install Sphinx

- Setting up the documentation sources

- Defining document structure

- Adding content

- Running the build

- Documenting objects

- Basic configuration

- Autodoc

- Intersphinx

- More topics to be covered

- Invocation of sphinx-quickstart

- Structure options

- Project basic options

- Extension options

- Makefile and Batchfile creation options

- Invocation of sphinx-build

- Makefile options

- Invocation of sphinx-apidoc

- reStructuredText Primer

- Paragraphs

- Inline markup

- Lists and Quote-like blocks

- Source Code

- Tables

- Hyperlinks

- Sections

- Explicit Markup

- Directives

- Images

- Footnotes

- Citations

- Substitutions

- Comments

- Source encoding

- Gotchas

- Sphinx Markup Constructs

- The TOC tree

- Paragraph-level markup

- Table-of-contents markup

- Glossary

- Grammar production displays

- Showing code examples

- Inline markup

- Miscellaneous markup

- Sphinx Domains

- What is a Domain?

- Basic Markup

- The Python Domain

- The C Domain

- The C++ Domain

- The Standard Domain

- The JavaScript Domain

- The reStructuredText domain

- More domains

- Available builders

- Serialization builder details

- The build configuration file

- General configuration

- Project information

- Options for internationalization

- Options for HTML output

- Options for Apple Help output

- Options for epub output

- Options for LaTeX output

- Options for text output

- Options for manual page output

- Options for Texinfo output

- Options for the linkcheck builder

- Options for the XML builder

- Internationalization

- Sphinx internationalization details

- Translating with sphinx-intl

- Using Transifex service for team translation

- Contributing to Sphinx reference translation

- HTML theming support

- Using a theme

- Builtin themes

- Creating themes

- Templating

- Do I need to use Sphinx’s templates to produce HTML?

- Jinja/Sphinx Templating Primer

- Working with the builtin templates

- Sphinx Extensions

- Builtin Sphinx extensions

- Third-party extensions

- Developing extensions for Sphinx

- Extension metadata

- APIs used for writing extensions

- Sphinx Web Support

- Web Support Quick Start

- The WebSupport Class

- Search Adapters

- Storage Backends

- Sphinx FAQ

- How do I...

- Using Sphinx with...

- Epub info

- Texinfo info

- Glossary

- Sphinx Developer’s Guide

- Bug Reports and Feature Requests

- Contributing to Sphinx

- Coding Guide

- Changes in Sphinx

- Release 1.4.2 (in development)

- Release 1.4.1 (released Apr 12, 2016)

- Release 1.4 (released Mar 28, 2016)

- Release 1.3.6 (released Feb 29, 2016)

- Release 1.3.5 (released Jan 24, 2016)

- Release 1.3.4 (released Jan 12, 2016)

- Release 1.3.3 (released Dec 2, 2015)

- Release 1.3.2 (released Nov 29, 2015)

- Release 1.3.1 (released Mar 17, 2015)

- Release 1.3 (released Mar 10, 2015)

- Release 1.3b3 (released Feb 24, 2015)

- Release 1.3b2 (released Dec 5, 2014)

- Release 1.3b1 (released Oct 10, 2014)

- Release 1.2.3 (released Sep 1, 2014)

- Release 1.2.2 (released Mar 2, 2014)

- Release 1.2.1 (released Jan 19, 2014)

- Release 1.2 (released Dec 10, 2013)

- Release 1.2 beta3 (released Oct 3, 2013)

- Release 1.2 beta2 (released Sep 17, 2013)

- Release 1.2 beta1 (released Mar 31, 2013)

- Release 1.1.3 (Mar 10, 2012)

- Release 1.1.2 (Nov 1, 2011) – 1.1.1 is a silly version number anyway!

- Release 1.1.1 (Nov 1, 2011)

- Release 1.1 (Oct 9, 2011)

- Release 1.0.8 (Sep 23, 2011)

- Release 1.0.7 (Jan 15, 2011)

- Release 1.0.6 (Jan 04, 2011)

- Release 1.0.5 (Nov 12, 2010)

- Release 1.0.4 (Sep 17, 2010)

- Release 1.0.3 (Aug 23, 2010)

- Release 1.0.2 (Aug 14, 2010)

- Release 1.0.1 (Jul 27, 2010)

- Release 1.0 (Jul 23, 2010)

- Previous versions

- Projects using Sphinx

- Documentation using the alabaster theme

- Documentation using the classic theme

- Documentation using a customized version of the classic theme

- Documentation using the sphinxdoc theme

- Documentation using another builtin theme

- Documentation using a custom theme/integrated in a site

- Homepages and other non-documentation sites

- Books produced using Sphinx

- Thesis using Sphinx

- Sphinx authors

Indices and tables

- Module Index

- Glossary

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Introduction

This is the documentation for the Sphinx documentation builder. Sphinx is a tool that translates a set of reStructuredText [http://docutils.sourceforge.net/rst.html] source files into various output formats, automatically producing cross-references, indices etc. That is, if you have a directory containing a bunch of reST-formatted documents (and possibly subdirectories of docs in there as well), Sphinx can generate a nicely-organized arrangement of HTML files (in some other directory) for easy browsing and navigation. But from the same source, it can also generate a LaTeX file that you can compile into a PDF version of the documents, or a PDF file directly using rst2pdf [https://github.com/rst2pdf/rst2pdf].

The focus is on hand-written documentation, rather than auto-generated API docs. Though there is support for that kind of docs as well (which is intended to be freely mixed with hand-written content), if you need pure API docs have a look at Epydoc [http://epydoc.sourceforge.net/], which also understands reST.

For a great “introduction” to writing docs in general – the whys and hows, see also Write the docs [http://write-the-docs.readthedocs.org/], written by Eric Holscher.

Conversion from other systems

This section is intended to collect helpful hints for those wanting to migrate to reStructuredText/Sphinx from other documentation systems.

- Gerard Flanagan has written a script to convert pure HTML to reST; it can be found at the Python Package Index [https://pypi.python.org/pypi/html2rest].

- For converting the old Python docs to Sphinx, a converter was written which can be found at the Python SVN repository [http://svn.python.org/projects/doctools/converter]. It contains generic code to convert Python-doc-style LaTeX markup to Sphinx reST.

- Marcin Wojdyr has written a script to convert Docbook to reST with Sphinx markup; it is at Google Code [https://github.com/wojdyr/db2rst].

- Christophe de Vienne wrote a tool to convert from Open/LibreOffice documents to Sphinx: odt2sphinx [https://pypi.python.org/pypi/odt2sphinx/].

- To convert different markups, Pandoc [http://pandoc.org/] is a very helpful tool.

Use with other systems

See the pertinent section in the FAQ list.

Prerequisites

Sphinx needs at least Python 2.6 or Python 3.3 to run, as well as the docutils [http://docutils.sourceforge.net/] and Jinja2 [http://jinja.pocoo.org/] libraries. Sphinx should work with docutils version 0.10 or some (not broken) SVN trunk snapshot. If you like to have source code highlighting support, you must also install the Pygments [http://pygments.org/] library.

Usage

See First Steps with Sphinx for an introduction. It also contains links to more advanced sections in this manual for the topics it discusses.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

First Steps with Sphinx

This document is meant to give a tutorial-like overview of all common tasks while using Sphinx.

The green arrows designate “more info” links leading to advanced sections about the described task.

Install Sphinx

Install Sphinx, either from a distribution package or from PyPI [https://pypi.python.org/pypi/Sphinx] with

$ pip install Sphinx

Setting up the documentation sources

The root directory of a Sphinx collection of reStructuredText document sources is called the source directory. This directory also contains the Sphinx configuration file conf.py, where you can configure all aspects of how Sphinx reads your sources and builds your documentation. [1]

Sphinx comes with a script called sphinx-quickstart that sets up a source directory and creates a default conf.py with the most useful configuration values from a few questions it asks you. Just run

$ sphinx-quickstart

and answer its questions. (Be sure to say yes to the “autodoc” extension.)

There is also an automatic “API documentation” generator called sphinx-apidoc; see Invocation of sphinx-apidoc for details.

Defining document structure

Let’s assume you’ve run sphinx-quickstart. It created a source directory with conf.py and a master document, index.rst (if you accepted the defaults). The main function of the master document is to serve as a welcome page, and to contain the root of the “table of contents tree” (or toctree). This is one of the main things that Sphinx adds to reStructuredText, a way to connect multiple files to a single hierarchy of documents.

reStructuredText directives

toctree is a reStructuredText directive, a very versatile piece of markup. Directives can have arguments, options and content.

Arguments are given directly after the double colon following the directive’s name. Each directive decides whether it can have arguments, and how many.

Options are given after the arguments, in form of a “field list”. The maxdepth is such an option for the toctree directive.

Content follows the options or arguments after a blank line. Each directive decides whether to allow content, and what to do with it.

A common gotcha with directives is that the first line of the content must be indented to the same level as the options are.

The toctree directive initially is empty, and looks like this:

.. toctree::
:maxdepth: 2

You add documents listing them in the content of the directive:

.. toctree::
:maxdepth: 2

intro
tutorial
...

This is exactly how the toctree for this documentation looks. The documents to include are given as document names, which in short means that you leave off the file name extension and use slashes as directory separators.

Read more about the toctree directive.

You can now create the files you listed in the toctree and add content, and their section titles will be inserted (up to the “maxdepth” level) at the place where the toctree directive is placed. Also, Sphinx now knows about the order and hierarchy of your documents. (They may contain toctree directives themselves, which means you can create deeply nested hierarchies if necessary.)

Adding content

In Sphinx source files, you can use most features of standard reStructuredText. There are also several features added by Sphinx. For example, you can add cross-file references in a portable way (which works for all output types) using the ref role.

For an example, if you are viewing the HTML version you can look at the source for this document – use the “Show Source” link in the sidebar.

See reStructuredText Primer for a more in-depth introduction to reStructuredText and Sphinx Markup Constructs for a full list of markup added by Sphinx.

Running the build

Now that you have added some files and content, let’s make a first build of the docs. A build is started with the sphinx-build program, called like this:

$ sphinx-build -b html sourcedir builddir

where sourcedir is the source directory, and builddir is the directory in which you want to place the built documentation. The -b option selects a builder; in this example Sphinx will build HTML files.

See Invocation of sphinx-quickstart for all options that sphinx-build supports.

However, sphinx-quickstart script creates a Makefile and a make.bat which make life even easier for you: with them you only need to run

$ make html

to build HTML docs in the build directory you chose. Execute make without an argument to see which targets are available.

How do I generate PDF documents?

make latexpdf runs the LaTeX builder and readily invokes the pdfTeX toolchain for you.

Documenting objects

One of Sphinx’s main objectives is easy documentation of objects (in a very general sense) in any domain. A domain is a collection of object types that belong together, complete with markup to create and reference descriptions of these objects.

The most prominent domain is the Python domain. To e.g. document the Python built-in function enumerate(), you would add this to one of your source files:

.. py:function:: enumerate(sequence[, start=0])

Return an iterator that yields tuples of an index and an item of the
*sequence*. (And so on.)

This is rendered like this:

enumerate(sequence[, start=0])

Return an iterator that yields tuples of an index and an item of the sequence. (And so on.)

The argument of the directive is the signature of the object you describe, the content is the documentation for it. Multiple signatures can be given, each in its own line.

The Python domain also happens to be the default domain, so you don’t need to prefix the markup with the domain name:

.. function:: enumerate(sequence[, start=0])

...

does the same job if you keep the default setting for the default domain.

There are several more directives for documenting other types of Python objects, for example py:class or py:method. There is also a cross-referencing role for each of these object types. This markup will create a link to the documentation of enumerate():

The :py:func:`enumerate` function can be used for ...

And here is the proof: A link to enumerate().

Again, the py: can be left out if the Python domain is the default one. It doesn’t matter which file contains the actual documentation for enumerate(); Sphinx will find it and create a link to it.

Each domain will have special rules for how the signatures can look like, and make the formatted output look pretty, or add specific features like links to parameter types, e.g. in the C/C++ domains.

See Sphinx Domains for all the available domains and their directives/roles.

Basic configuration

Earlier we mentioned that the conf.py file controls how Sphinx processes your documents. In that file, which is executed as a Python source file, you assign configuration values. For advanced users: since it is executed by Sphinx, you can do non-trivial tasks in it, like extending sys.path or importing a module to find out the version you are documenting.

The config values that you probably want to change are already put into the conf.py by sphinx-quickstart and initially commented out (with standard Python syntax: a # comments the rest of the line). To change the default value, remove the hash sign and modify the value. To customize a config value that is not automatically added by sphinx-quickstart, just add an additional assignment.

Keep in mind that the file uses Python syntax for strings, numbers, lists and so on. The file is saved in UTF-8 by default, as indicated by the encoding declaration in the first line. If you use non-ASCII characters in any string value, you need to use Python Unicode strings (like project = u'Exposé').

See The build configuration file for documentation of all available config values.

Autodoc

When documenting Python code, it is common to put a lot of documentation in the source files, in documentation strings. Sphinx supports the inclusion of docstrings from your modules with an extension (an extension is a Python module that provides additional features for Sphinx projects) called “autodoc”.

In order to use autodoc, you need to activate it in conf.py by putting the string 'sphinx.ext.autodoc' into the list assigned to the extensions config value. Then, you have a few additional directives at your disposal.

For example, to document the function io.open(), reading its signature and docstring from the source file, you’d write this:

.. autofunction:: io.open

You can also document whole classes or even modules automatically, using member options for the auto directives, like

.. automodule:: io
:members:

autodoc needs to import your modules in order to extract the docstrings. Therefore, you must add the appropriate path to sys.path in your conf.py.

Warning

autodoc imports the modules to be documented. If any modules have side effects on import, these will be executed by autodoc when sphinx-build is run.

If you document scripts (as opposed to library modules), make sure their main routine is protected by a if __name__ == '__main__' condition.

See sphinx.ext.autodoc for the complete description of the features of autodoc.

Intersphinx

Many Sphinx documents including the Python documentation [https://docs.python.org/3] are published on the internet. When you want to make links to such documents from your documentation, you can do it with sphinx.ext.intersphinx.

In order to use intersphinx, you need to activate it in conf.py by putting the string 'sphinx.ext.intersphinx' into the extensions list and set up the intersphinx_mapping config value.

For example, to link to io.open() in the Python library manual, you need to setup your intersphinx_mapping like:

intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}

And now, you can write a cross-reference like :py:func:`io.open`. Any cross-reference that has no matching target in the current documentation set, will be looked up in the documentation sets configured in intersphinx_mapping (this needs access to the URL in order to download the list of valid targets). Intersphinx also works for some other domains’ roles including :ref:, however it doesn’t work for :doc: as that is non-domain role.

See sphinx.ext.intersphinx for the complete description of the features of intersphinx.

More topics to be covered

- Other extensions (math, viewcode, doctest)

- Static files

- Selecting a theme

- Templating

- Using extensions

- Writing extensions

Footnotes

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Invocation of sphinx-quickstart

The sphinx-quickstart script generates a Sphinx documentation set. It is called like this:

$ sphinx-quickstart [options] [projectdir]

where projectdir is the Sphinx documentation set directory in which you want to place. If you omit projectdir, files are generated into current directory by default.

The sphinx-quickstart script has several options:

-q, --quiet

Quiet mode that will skips interactive wizard to specify options. This option requires -p, -a and -v options.

-h, --help, --version

Display usage summary or Sphinx version.

Structure options

--sep

If specified, separate source and build directories.

--dot=DOT

Inside the root directory, two more directories will be created; “_templates” for custom HTML templates and “_static” for custom stylesheets and other static files. You can enter another prefix (such as ”.”) to replace the underscore.

Project basic options

-p PROJECT, --project=PROJECT

Project name will be set. (see project).

-a AUTHOR, --author=AUTHOR

Author names. (see copyright).

-v VERSION

Version of project. (see version).

-r RELEASE, --release=RELEASE

Release of project. (see release).

-l LANGUAGE, --language=LANGUAGE

Document language. (see language).

--suffix=SUFFIX

Source file suffix. (see source_suffix).

--master=MASTER

Master document name. (see master_doc).

--epub

Use epub.

Extension options

--ext-autodoc

Enable sphinx.ext.autodoc extension.

--ext-doctest

Enable sphinx.ext.doctest extension.

--ext-intersphinx

Enable sphinx.ext.intersphinx extension.

--ext-todo

Enable sphinx.ext.todo extension.

--ext-coverage

Enable sphinx.ext.coverage extension.

--ext-imgmath

Enable sphinx.ext.imgmath extension.

--ext-mathjax

Enable sphinx.ext.mathjax extension.

--ext-ifconfig

Enable sphinx.ext.ifconfig extension.

--ext-viewcode

Enable sphinx.ext.viewcode extension.

Makefile and Batchfile creation options

--use-make-mode, --no-use-make-mode

Makefile/make.bat uses (or not use) make-mode. Default is not use.

--makefile, --no-makefile

Create (or not create) makefile.

--batchfile, --no-batchfile

Create (or not create) batchfile

New in version 1.3: Add various options for sphinx-quickstart invocation.

Invocation of sphinx-build

The sphinx-build script builds a Sphinx documentation set. It is called like this:

$ sphinx-build [options] sourcedir builddir [filenames]

where sourcedir is the source directory, and builddir is the directory in which you want to place the built documentation. Most of the time, you don’t need to specify any filenames.

The sphinx-build script has several options:

-b buildername

The most important option: it selects a builder. The most common builders are:

html

Build HTML pages. This is the default builder.

dirhtml

Build HTML pages, but with a single directory per document. Makes for prettier URLs (no .html) if served from a webserver.

singlehtml

Build a single HTML with the whole content.

htmlhelp, qthelp, devhelp, epub

Build HTML files with additional information for building a documentation collection in one of these formats.

applehelp

Build an Apple Help Book. Requires hiutil and codesign, which are not Open Source and presently only available on Mac OS X 10.6 and higher.

latex

Build LaTeX sources that can be compiled to a PDF document using pdflatex.

man

Build manual pages in groff format for UNIX systems.

texinfo

Build Texinfo files that can be processed into Info files using makeinfo.

text

Build plain text files.

gettext

Build gettext-style message catalogs (.pot files).

doctest

Run all doctests in the documentation, if the doctest extension is enabled.

linkcheck

Check the integrity of all external links.

xml

Build Docutils-native XML files.

pseudoxml

Build compact pretty-printed “pseudo-XML” files displaying the internal structure of the intermediate document trees.

See Available builders for a list of all builders shipped with Sphinx. Extensions can add their own builders.

-a

If given, always write all output files. The default is to only write output files for new and changed source files. (This may not apply to all builders.)

-E

Don’t use a saved environment (the structure caching all 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 only directives that only include their content if this tag is set.

New in version 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”. Normally, these files are put in a directory called .doctrees under the build directory; with this option you can select a different cache directory (the doctrees can be shared between all builders).

-j N

Distribute the build over N processes in parallel, to make building on multiprocessor machines more effective. Note that not all parts and not all builders of Sphinx can be parallelized.

New in version 1.2: This option should be considered experimental.

-c path

Don’t look for the conf.py in the source directory, but use the given configuration directory instead. Note that various other files and paths given by configuration values are expected to be relative to the configuration directory, so they will have to be present at this location too.

New in version 0.3.

-C

Don’t look for a configuration file; only take options via the -D option.

New in version 0.5.

-D setting=value

Override a configuration value set in the conf.py file. The value must be a number, string, list or dictionary value.

For lists, you can separate elements with a comma like this: -D html_theme_path=path1,path2.

For dictionary values, supply the setting name and key like this: -D latex_elements.docclass=scrartcl.

For boolean values, use 0 or 1 as the value.

Changed in version 0.6: The value can now be a dictionary value.

Changed in version 1.3: The value can now also be a list value.

-A name=value

Make the name assigned to value in the HTML templates.

New in version 0.5.

-n

Run in nit-picky mode. Currently, this generates warnings for all missing references. See the config value nitpick_ignore for a way to exclude some references as “known missing”.

-N

Do not emit colored output.

-v

Increase verbosity (loglevel). This option can be given up to three times to get more debug logging output. It implies -T.

New in version 1.2.

-q

Do not output anything on standard output, only write warnings and errors to standard error.

-Q

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.

-T

Display the full traceback when an unhandled exception occurs. Otherwise, only a summary is displayed and the traceback information is saved to a file for further analysis.

New in version 1.2.

-P

(Useful for debugging only.) Run the Python debugger, pdb, if an unhandled exception occurs while building.

-h, --help, --version

Display usage summary or Sphinx version.

New in version 1.2.

You can also give one or more filenames on the command line after the source and build directories. Sphinx will then try to build only these output files (and their dependencies).

Makefile options

The Makefile and make.bat files created by sphinx-quickstart usually run sphinx-build only with the -b and -d options. However, they support the following variables to customize behavior:

PAPER

The value for latex_paper_size.

SPHINXBUILD

The command to use instead of sphinx-build.

BUILDDIR

The build directory to use instead of the one chosen in sphinx-quickstart.

SPHINXOPTS

Additional options for sphinx-build.

Invocation of sphinx-apidoc

The sphinx-apidoc generates completely automatic API documentation for a Python package. It is called like this:

$ sphinx-apidoc [options] -o outputdir packagedir [pathnames]

where packagedir is the path to the package to document, and outputdir is the directory where the generated sources are placed. Any pathnames given are paths to be excluded ignored during generation.

Warning

sphinx-apidoc generates reST files that use sphinx.ext.autodoc to document all found modules. If any modules have side effects on import, these will be executed by autodoc when sphinx-build is run.

If you document scripts (as opposed to library modules), make sure their main routine is protected by a if __name__ == '__main__' condition.

The sphinx-apidoc script has several options:

-o outputdir

Gives the directory in which to place the generated output.

-f, --force

Normally, sphinx-apidoc does not overwrite any files. Use this option to force the overwrite of all files that it generates.

-n, --dry-run

With this option given, no files will be written at all.

-s suffix

This option selects the file name suffix of output files. By default, this is rst.

-d maxdepth

This sets the maximum depth of the table of contents, if one is generated.

-l, --follow-links

This option makes sphinx-apidoc follow symbolic links when recursing the filesystem to discover packages and modules. You may need it if you want to generate documentation from a source directory managed by collective.recipe.omelette [https://pypi.python.org/pypi/collective.recipe.omelette/]. By default, symbolic links are skipped.

New in version 1.2.

-T, --no-toc

This prevents the generation of a table-of-contents file modules.rst. This has no effect when --full is given.

-F, --full

This option makes sphinx-apidoc create a full Sphinx project, using the same mechanism as sphinx-quickstart. Most configuration values are set to default values, but you can influence the most important ones using the following options.

-M

This option makes sphinx-apidoc put module documentation before submodule documentation.

-H project

Sets the project name to put in generated files (see project).

-A author

Sets the author name(s) to put in generated files (see copyright).

-V version

Sets the project version to put in generated files (see version).

-R release

Sets the project release to put in generated files (see release).

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

reStructuredText Primer

This section is a brief introduction to reStructuredText (reST) concepts and syntax, intended to provide authors with enough information to author documents productively. Since reST was designed to be a simple, unobtrusive markup language, this will not take too long.

See also

The authoritative reStructuredText User Documentation [http://docutils.sourceforge.net/rst.html]. The “ref” links in this document link to the description of the individual constructs in the reST reference.

Paragraphs

The paragraph (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#paragraphs]) is the most basic block in a reST document. Paragraphs are simply chunks of text separated by one or more blank lines. As in Python, indentation is significant in reST, so all lines of the same paragraph must be left-aligned to the same level of indentation.

Inline markup

The standard reST inline markup is quite simple: use

- one asterisk: *text* for emphasis (italics),

- two asterisks: **text** for strong emphasis (boldface), and

- backquotes: ``text`` for code samples.

If asterisks or backquotes appear in running text and could be confused with inline markup delimiters, they have to be escaped with a backslash.

Be aware of some restrictions of this markup:

- it may not be nested,

- content may not start or end with whitespace: * text* is wrong,

- it must be separated from surrounding text by non-word characters. Use a backslash escaped space to work around that: thisis\ *one*\ word.

These restrictions may be lifted in future versions of the docutils.

reST also allows for custom “interpreted text roles”, which signify that the enclosed text should be interpreted in a specific way. Sphinx uses this to provide semantic markup and cross-referencing of identifiers, as described in the appropriate section. The general syntax is :rolename:`content`.

Standard reST provides the following roles:

- emphasis [http://docutils.sourceforge.net/docs/ref/rst/roles.html#emphasis] – alternate spelling for *emphasis*

- strong [http://docutils.sourceforge.net/docs/ref/rst/roles.html#strong] – alternate spelling for **strong**

- literal [http://docutils.sourceforge.net/docs/ref/rst/roles.html#literal] – alternate spelling for ``literal``

- subscript [http://docutils.sourceforge.net/docs/ref/rst/roles.html#subscript] – subscript text

- superscript [http://docutils.sourceforge.net/docs/ref/rst/roles.html#superscript] – superscript text

- title-reference [http://docutils.sourceforge.net/docs/ref/rst/roles.html#title-reference] – for titles of books, periodicals, and other materials

See Inline markup for roles added by Sphinx.

Lists and Quote-like blocks

List markup (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#bullet-lists]) is natural: just place an asterisk at the start of a paragraph and indent properly. The same goes for numbered lists; they can also be autonumbered using a # sign:

* This is a bulleted list.
* It has two items, the second
item uses two lines.

1. This is a numbered list.
2. It has two items too.

#. This is a numbered list.
#. It has two items too.

Nested lists are possible, but be aware that they must be separated from the parent list items by blank lines:

* this is
* a list

* with a nested list
* and some subitems

* and here the parent list continues

Definition lists (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#definition-lists]) are created as follows:

term (up to a line of text)
Definition of the term, which must be indented

and can even consist of multiple paragraphs

next term
Description.

Note that the term cannot have more than one line of text.

Quoted paragraphs (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#block-quotes]) are created by just indenting them more than the surrounding paragraphs.

Line blocks (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#line-blocks]) are a way of preserving line breaks:

| These lines are
| broken exactly like in
| the source file.

There are also several more special blocks available:

- field lists (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#field-lists])

- option lists (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#option-lists])

- quoted literal blocks (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#quoted-literal-blocks])

- doctest blocks (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#doctest-blocks])

Source Code

Literal code blocks (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#literal-blocks]) are introduced by ending a paragraph with the special marker ::. The literal block must be indented (and, like all paragraphs, separated from the surrounding ones by blank lines):

This is a normal text paragraph. The next paragraph is a code sample::

It is not processed in any way, except
that the indentation is removed.

It can span multiple lines.

This is a normal text paragraph again.

The handling of the :: marker is smart:

- If it occurs as a paragraph of its own, that paragraph is completely left out of the document.

- If it is preceded by whitespace, the marker is removed.

- If it is preceded by non-whitespace, the marker is replaced by a single colon.

That way, the second sentence in the above example’s first paragraph would be rendered as “The next paragraph is a code sample:”.

Tables

Two forms of tables are supported. For grid tables (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#grid-tables]), you have to “paint” the cell grid yourself. They look like this:

+------------------------+------------+----------+----------+
| Header row, column 1   | Header 2   | Header 3 | Header 4 |
| (header rows optional) |            |          |          |
+========================+============+==========+==========+
| body row 1, column 1   | column 2   | column 3 | column 4 |
+------------------------+------------+----------+----------+
| body row 2             | ...        | ...      |          |
+------------------------+------------+----------+----------+

Simple tables (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#simple-tables]) are easier to write, but limited: they must contain more than one row, and the first column cannot contain multiple lines. They look like this:

=====  =====  =======
A      B      A and B
=====  =====  =======
False  False  False
True   False  False
False  True   False
True   True   True
=====  =====  =======

Hyperlinks

External links

Use `Link text <http://example.com/>`_ for inline web links. If the link text should be the web address, you don’t need special markup at all, the parser finds links and mail addresses in ordinary text.

You can also separate the link and the target definition (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#hyperlink-targets]), like this:

This is a paragraph that contains `a link`_.

.. _a link: http://example.com/

Internal links

Internal linking is done via a special reST role provided by Sphinx, see the section on specific markup, Cross-referencing arbitrary locations.

Sections

Section headers (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#sections]) are created by underlining (and optionally overlining) the section title with a punctuation character, at least as long as the text:

=================
This is a heading
=================

Normally, there are no heading levels assigned to certain characters as the structure is determined from the succession of headings. However, this convention is used in Python’s Style Guide for documentating [https://docs.python.org/devguide/documenting.html#style-guide] which you may follow:

- # with overline, for parts

- * with overline, for chapters

- =, for sections

- -, for subsections

- ^, for subsubsections

- ", for paragraphs

Of course, you are free to use your own marker characters (see the reST documentation), and use a deeper nesting level, but keep in mind that most target formats (HTML, LaTeX) have a limited supported nesting depth.

Explicit Markup

“Explicit markup” (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#explicit-markup-blocks]) is used in reST for most constructs that need special handling, such as footnotes, specially-highlighted paragraphs, comments, and generic directives.

An explicit markup block begins with a line starting with .. followed by whitespace and is terminated by the next paragraph at the same level of indentation. (There needs to be a blank line between explicit markup and normal paragraphs. This may all sound a bit complicated, but it is intuitive enough when you write it.)

Directives

A directive (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#directives]) is a generic block of explicit markup. Besides roles, it is one of the extension mechanisms of reST, and Sphinx makes heavy use of it.

Docutils supports the following directives:

- Admonitions: attention [http://docutils.sourceforge.net/docs/ref/rst/directives.html#attention], caution [http://docutils.sourceforge.net/docs/ref/rst/directives.html#caution], danger [http://docutils.sourceforge.net/docs/ref/rst/directives.html#danger], error [http://docutils.sourceforge.net/docs/ref/rst/directives.html#error], hint [http://docutils.sourceforge.net/docs/ref/rst/directives.html#hint], important [http://docutils.sourceforge.net/docs/ref/rst/directives.html#important], note [http://docutils.sourceforge.net/docs/ref/rst/directives.html#note], tip [http://docutils.sourceforge.net/docs/ref/rst/directives.html#tip], warning [http://docutils.sourceforge.net/docs/ref/rst/directives.html#warning] and the generic admonition [http://docutils.sourceforge.net/docs/ref/rst/directives.html#admonitions]. (Most themes style only “note” and “warning” specially.)

- Images:

- image [http://docutils.sourceforge.net/docs/ref/rst/directives.html#image] (see also Images below)

- figure [http://docutils.sourceforge.net/docs/ref/rst/directives.html#figure] (an image with caption and optional legend)

- Additional body elements:

- contents [http://docutils.sourceforge.net/docs/ref/rst/directives.html#table-of-contents] (a local, i.e. for the current file only, table of contents)

- container [http://docutils.sourceforge.net/docs/ref/rst/directives.html#container] (a container with a custom class, useful to generate an outer <div> in HTML)

- rubric [http://docutils.sourceforge.net/docs/ref/rst/directives.html#rubric] (a heading without relation to the document sectioning)

- topic [http://docutils.sourceforge.net/docs/ref/rst/directives.html#topic], sidebar [http://docutils.sourceforge.net/docs/ref/rst/directives.html#sidebar] (special highlighted body elements)

- parsed-literal [http://docutils.sourceforge.net/docs/ref/rst/directives.html#parsed-literal] (literal block that supports inline markup)

- epigraph [http://docutils.sourceforge.net/docs/ref/rst/directives.html#epigraph] (a block quote with optional attribution line)

- highlights [http://docutils.sourceforge.net/docs/ref/rst/directives.html#highlights], pull-quote [http://docutils.sourceforge.net/docs/ref/rst/directives.html#pull-quote] (block quotes with their own class attribute)

- compound [http://docutils.sourceforge.net/docs/ref/rst/directives.html#compound-paragraph] (a compound paragraph)

- Special tables:

- table [http://docutils.sourceforge.net/docs/ref/rst/directives.html#table] (a table with title)

- csv-table [http://docutils.sourceforge.net/docs/ref/rst/directives.html#csv-table] (a table generated from comma-separated values)

- list-table [http://docutils.sourceforge.net/docs/ref/rst/directives.html#list-table] (a table generated from a list of lists)

- Special directives:

- raw [http://docutils.sourceforge.net/docs/ref/rst/directives.html#raw-data-pass-through] (include raw target-format markup)

- include [http://docutils.sourceforge.net/docs/ref/rst/directives.html#include] (include reStructuredText from another file) – in Sphinx, when given an absolute include file path, this directive takes it as relative to the source directory

- class [http://docutils.sourceforge.net/docs/ref/rst/directives.html#class] (assign a class attribute to the next element) [1]

- HTML specifics:

- meta [http://docutils.sourceforge.net/docs/ref/rst/directives.html#meta] (generation of HTML <meta> tags)

- title [http://docutils.sourceforge.net/docs/ref/rst/directives.html#metadata-document-title] (override document title)

- Influencing markup:

- default-role [http://docutils.sourceforge.net/docs/ref/rst/directives.html#default-role] (set a new default role)

- role [http://docutils.sourceforge.net/docs/ref/rst/directives.html#role] (create a new role)

Since these are only per-file, better use Sphinx’s facilities for setting the default_role.

Do not use the directives sectnum [http://docutils.sourceforge.net/docs/ref/rst/directives.html#sectnum], header [http://docutils.sourceforge.net/docs/ref/rst/directives.html#header] and footer [http://docutils.sourceforge.net/docs/ref/rst/directives.html#footer].

Directives added by Sphinx are described in Sphinx Markup Constructs.

Basically, a directive consists of a name, arguments, options and content. (Keep this terminology in mind, it is used in the next chapter describing custom directives.) Looking at this example,

.. function:: foo(x)
foo(y, z)
:module: some.module.name

Return a line of text input from the user.

function is the directive name. It is given two arguments here, the remainder of the first line and the second line, as well as one option module (as you can see, options are given in the lines immediately following the arguments and indicated by the colons). Options must be indented to the same level as the directive content.

The directive content follows after a blank line and is indented relative to the directive start.

Images

reST supports an image directive (ref [http://docutils.sourceforge.net/docs/ref/rst/directives.html#image]), used like so:

.. image:: gnu.png
(options)

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:

.. image:: gnu.*

Sphinx then searches for all images matching the provided pattern and determines their type. Each builder then chooses the best image out of these candidates. For instance, if the file name gnu.* was given and two files gnu.pdf and gnu.png existed in the source tree, the LaTeX builder would choose the former, while the HTML builder would prefer the latter. Supported image types and choosing priority are defined at Available builders.

Note that image file names should not contain spaces.

Changed in version 0.4: Added the support for file names ending in an asterisk.

Changed in version 0.6: Image paths can now be absolute.

Footnotes

For footnotes (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#footnotes]), use [#name]_ to mark the footnote location, and add the footnote body at the bottom of the document after a “Footnotes” rubric heading, like so:

Lorem ipsum [#f1]_ dolor sit amet ... [#f2]_

.. rubric:: Footnotes

.. [#f1] Text of the first footnote.
.. [#f2] Text of the second footnote.

You can also explicitly number the footnotes ([1]_) or use auto-numbered footnotes without names ([#]_).

Citations

Standard reST citations (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#citations]) are supported, with the additional feature that they are “global”, i.e. all citations can be referenced from all files. Use them like so:

Lorem ipsum [Ref]_ dolor sit amet.

.. [Ref] Book or article reference, URL or whatever.

Citation usage is similar to footnote usage, but with a label that is not numeric or begins with #.

Substitutions

reST supports “substitutions” (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#substitution-definitions]), which are pieces of text and/or markup referred to in the text by |name|. They are defined like footnotes with explicit markup blocks, like this:

.. |name| replace:: replacement *text*

or this:

.. |caution| image:: warning.png
:alt: Warning!

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 rst_prolog or put them into a separate file and include it into all documents you want to use them in, using the include directive. (Be sure to give the include file a file name extension differing from that of other source files, to avoid Sphinx finding it as a standalone document.)

Sphinx defines some default substitutions, see Substitutions.

Comments

Every explicit markup block which isn’t a valid markup construct (like the footnotes above) is regarded as a comment (ref [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#comments]). 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

Since the easiest way to include special characters like em dashes or copyright signs in reST is to directly write them as Unicode characters, one has to specify an encoding. Sphinx assumes source files to be encoded in UTF-8 by default; you can change this with the source_encoding config value.

Gotchas

There are some problems one commonly runs into while authoring reST documents:

- Separation of inline markup: As said above, inline markup spans must be separated from the surrounding text by non-word characters, you have to use a backslash-escaped space to get around that. See the reference [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#substitution-definitions] for the details.

- No nested inline markup: Something like *see :func:`foo`* is not possible.

Footnotes

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Sphinx Markup Constructs

Sphinx adds a lot of new directives and interpreted text roles to standard reST markup [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html]. This section contains the reference material for these facilities.

- The TOC tree

- Special names

- Paragraph-level markup

- Table-of-contents markup

- Glossary

- Grammar production displays

- Showing code examples

- Line numbers

- Includes

- Caption and name

- Dedent

- Inline markup

- Cross-referencing syntax

- Cross-referencing anything

- Cross-referencing objects

- Cross-referencing arbitrary locations

- Cross-referencing documents

- Referencing downloadable files

- Cross-referencing figures by figure number

- Cross-referencing other items of interest

- Other semantic markup

- Substitutions

- Miscellaneous markup

- File-wide metadata

- Meta-information markup

- Index-generating markup

- Including content based on tags

- Tables

More markup is added by Sphinx Domains.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Markup Constructs »

The TOC tree

Since reST does not have facilities to interconnect several documents, or split documents into multiple output files, Sphinx uses a custom directive to add relations between the single files the documentation is made of, as well as tables of contents. The toctree directive is the central element.

Note

Simple “inclusion” of one file in another can be done with the include [http://docutils.sourceforge.net/docs/ref/rst/directives.html#include] directive.

.. toctree::

This directive inserts a “TOC tree” at the current location, using the individual TOCs (including “sub-TOC trees”) of the documents given in the directive body. Relative document names (not beginning with a slash) are relative to the document the directive occurs in, absolute names are relative to the source directory. A numeric maxdepth option may be given to indicate the depth of the tree; by default, all levels are included. [1]

Consider this example (taken from the Python docs’ library reference index):

.. toctree::
:maxdepth: 2

intro
strings
datatypes
numeric
(many more documents listed here)

This accomplishes two things:

- Tables of contents from all those documents are inserted, with a maximum depth of two, that means one nested heading. toctree directives in those documents are also taken into account.

- Sphinx knows that the relative order of the documents intro, 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.

Entries

Document titles in the toctree will be automatically read from the 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 cross-referencing 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.

Section numbering

If you want to have section numbers even in HTML output, give the toplevel toctree a numbered 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).

Numbering up to a specific depth is also possible, by giving the depth as a numeric argument to numbered.

Additional options

You can use caption option to provide a toctree caption and you can use name option to provide implicit target name that can be referenced by using ref:

.. toctree::
:caption: Table of Contents
:name: mastertoc

foo

If you want only the titles of documents in the tree to show up, not other headings of the same level, you can use the titlesonly option:

.. toctree::
:titlesonly:

foo
bar

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:

.. toctree::
:glob:

intro*
recipe/*
*

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.) [2]

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 cases where you want to have only one top-level toctree and hide all other lower level toctrees you can add the “includehidden” option to the top-level toctree entry:

.. toctree::
:includehidden:

doc_1
doc_2

All other toctree entries can then be eliminated by the “hidden” option.

In the end, all documents in the 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 be reachable through standard navigation.

Use exclude_patterns to explicitly exclude documents or directories from building completely. Use the “orphan” metadata to let a document be built, but notify Sphinx that it is not reachable via a toctree.

The “master document” (selected by master_doc) is the “root” of the TOC tree hierarchy. It can be used as the documentation’s main page, or as a “full table of contents” if you don’t give a maxdepth option.

Changed in version 0.3: Added “globbing” option.

Changed in version 0.6: Added “numbered” and “hidden” options as well as external links and support for “self” references.

Changed in version 1.0: Added “titlesonly” option.

Changed in version 1.1: Added numeric argument to “numbered”.

Changed in version 1.2: Added “includehidden” option.

Changed in version 1.3: Added “caption” and “name” option.

Special names

Sphinx reserves some document names for its own use; you should not try to create documents with these names – it will cause problems.

The special document names (and pages generated for them) are:

- genindex, modindex, search

These are used for the general index, the Python module index, and the search page, respectively.

The general index is populated with entries from modules, all index-generating object descriptions, and from index directives.

The Python module index contains one entry per py:module directive.

The search page contains a form that uses the generated JSON search index and JavaScript to full-text search the generated documents for search words; it should work on every major browser that supports modern JavaScript.

- every name beginning with _

Though only few such names are currently used by Sphinx, you should not create documents or document-containing directories with such names. (Using _ as a prefix for a custom template directory is fine.)

Warning

Be careful with unusual characters in filenames. Some formats may interpret these characters in unexpected ways:

- Do not use the colon : for HTML based formats. Links to other parts may not work.

- Do not use the plus + for the ePub format. Some resources may not be found.

Footnotes

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Markup Constructs »

Paragraph-level markup

These directives create short paragraphs and can be used inside information units as well as normal text:

.. note::

An especially important bit of information about an API that a user should be aware of when using whatever bit of API the note pertains to. The content of the directive should be written in complete sentences and include all appropriate punctuation.

Example:

.. note::

This function is not suitable for sending spam e-mails.

.. warning::

An important bit of information about an API that a user should be very aware of when using whatever bit of API the warning pertains to. The content of the directive should be written in complete sentences and include all appropriate punctuation. This differs from note in that it is recommended over note for information regarding security.

.. versionadded:: version

This directive documents the version of the project which added the described feature to the library or C API. When this applies to an entire module, it should be placed at the top of the module section before any prose.

The first argument must be given and is the version in question; you can add a second argument consisting of a brief explanation of the change.

Example:

.. versionadded:: 2.5
The *spam* parameter.

Note that there must be no blank line between the directive head and the explanation; this is to make these blocks visually continuous in the markup.

.. versionchanged:: version

Similar to versionadded, but describes when and what changed in the named feature in some way (new parameters, changed side effects, etc.).

.. deprecated:: version

Similar to versionchanged, but describes when the feature was deprecated. An explanation can also be given, for example to inform the reader what should be used instead. Example:

.. deprecated:: 3.1
Use :func:`spam` instead.

.. seealso::

Many sections include a list of references to module documentation or external documents. These lists are created using the seealso directive.

The seealso directive is typically placed in a section just before any subsections. For the HTML output, it is shown boxed off from the main flow of the text.

The content of the seealso directive should be a reST definition list. Example:

.. seealso::

Module :py:mod:`zipfile`
Documentation of the :py:mod:`zipfile` standard module.

`GNU tar manual, Basic Tar Format <http://link>`_
Documentation for tar archive files, including GNU tar extensions.

There’s also a “short form” allowed that looks like this:

.. seealso:: modules :py:mod:`zipfile`, :py:mod:`tarfile`

New in version 0.5: The short form.

.. rubric:: title

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” (or the selected language’s equivalent), this rubric is ignored by the LaTeX writer, since it is assumed to only contain footnote definitions and therefore would create an empty heading.

.. centered::

This directive creates a centered boldfaced line of text. Use it as follows:

.. centered:: LICENSE AGREEMENT

Deprecated since version 1.1: This presentation-only directive is a legacy from older versions. Use a rst-class directive instead and add an appropriate style.

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

New in version 0.6.

Table-of-contents markup

The toctree directive, which generates tables of contents of subdocuments, is described in The TOC tree.

For local tables of contents, use the standard reST contents directive [http://docutils.sourceforge.net/docs/ref/rst/directives.html#table-of-contents].

Glossary

.. glossary::

This directive must contain a reST definition-list-like markup with terms and definitions. The definitions will then be referencable with the term role. Example:

.. glossary::

environment
A structure where information about all documents under the root is
saved, and used for cross-referencing.  The environment is pickled
after the parsing stage, so that successive runs only need to read
and parse new and changed documents.

source directory
The directory which, including its subdirectories, contains all
source files for one Sphinx project.

In contrast to regular definition lists, multiple terms per entry are allowed, and inline markup is allowed in terms. You can link to all of the terms. For example:

.. glossary::

term 1
term 2
Definition of both terms.

(When the glossary is sorted, the first term determines the sort order.)

If you want to specify “grouping key” for general index entries, you can put a “key” as “term : key”. For example:

.. glossary::

term 1 : A
term 2 : B
Definition of both terms.

Note that “key” is used for grouping key as is. The “key” isn’t normalized; key “A” and “a” become different groups. The whole characters in “key” is used instead of a first character; it is used for “Combining Character Sequence” and “Surrogate Pairs” grouping key.

In i18n situation, you can specify “localized term : key” even if original text only have “term” part. In this case, translated “localized term” will be categorized in “key” group.

New in version 0.6: You can now give the glossary directive a :sorted: flag that will automatically sort the entries alphabetically.

Changed in version 1.1: Now supports multiple terms and inline markup in terms.

Changed in version 1.4: Index key for glossary term should be considered experimental.

Grammar production displays

Special markup is available for displaying the productions of a formal grammar. The markup is simple and does not attempt to model all aspects of BNF (or any derived forms), but provides enough to allow context-free grammars to be displayed in a way that causes uses of a symbol to be rendered as hyperlinks to the definition of the symbol. There is this directive:

.. productionlist:: [name]

This directive is used to enclose a group of productions. Each production is given on a single line and consists of a name, separated by a colon from the following definition. If the definition spans multiple lines, each continuation line must begin with a colon placed at the same column as in the first line.

The argument to productionlist serves to distinguish different sets of production lists that belong to different grammars.

Blank lines are not allowed within productionlist directive arguments.

The definition can contain token names which are marked as interpreted text (e.g. sum ::= `integer` "+" `integer`) – this generates cross-references to the productions of these tokens. Outside of the production list, you can reference to token productions using token.

Note that no further reST parsing is done in the production, so that you don’t have to escape * or | characters.

The following is an example taken from the Python Reference Manual:

.. productionlist::
try_stmt: try1_stmt | try2_stmt
try1_stmt: "try" ":" `suite`
: ("except" [`expression` ["," `target`]] ":" `suite`)+
: ["else" ":" `suite`]
: ["finally" ":" `suite`]
try2_stmt: "try" ":" `suite`
: "finally" ":" `suite`

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Markup Constructs »

Showing code examples

Examples of Python source code or interactive sessions are represented using standard reST literal blocks. They are started by a :: at the end of the preceding paragraph and delimited by indentation.

Representing an interactive session requires including the prompts and output along with the Python code. No special markup is required for interactive sessions. After the last line of input or output presented, there should not be an “unused” primary prompt; this is an example of what not to do:

>>> 1 + 1
2
>>>

Syntax highlighting is done with Pygments [http://pygments.org] and handled in a smart way:

- There is a “highlighting language” for each source file. Per default, this is 'python' as the majority of files will have to highlight Python snippets, but the doc-wide default can be set with the highlight_language config value.

- Within Python highlighting mode, interactive sessions are recognized 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:

.. highlight:: language

Example:

.. highlight:: c

This language is used until the next highlight directive is encountered.

- For documents that have to show snippets in different languages, there’s also a code-block directive that is given the highlighting language directly:

.. code-block:: language

Use it like this:

.. code-block:: ruby

Some Ruby code.

The directive’s alias name sourcecode works as well.

- The valid values for the highlighting language are:

- none (no highlighting)

- python (the default when highlight_language isn’t set)

- guess (let Pygments guess the lexer based on contents, only works with certain well-recognizable languages)

- rest

- c

- ... and any other lexer alias that Pygments supports [http://pygments.org/docs/lexers/].

- If highlighting with the selected language fails (i.e. Pygments emits an “Error” token), the block is not highlighted in any way.

Line numbers

Pygments can generate line numbers for code blocks. For automatically-highlighted blocks (those started by ::), line numbers must be switched on in a highlight directive, with the linenothreshold option:

.. highlight:: python
:linenothreshold: 5

This will produce line numbers for all code blocks longer than five lines.

For code-block blocks, a linenos flag option can be given to switch on line numbers for the individual block:

.. code-block:: ruby
:linenos:

Some more Ruby code.

The first line number can be selected with the lineno-start option. If present, linenos is automatically activated as well.

Additionally, an emphasize-lines option can be given to have Pygments emphasize particular lines:

.. code-block:: python
:emphasize-lines: 3,5

def some_function():
interesting = False
print 'This line is highlighted.'
print 'This one is not...'
print '...but this one is.'

Changed in version 1.1: emphasize-lines has been added.

Changed in version 1.3: lineno-start has been added.

Includes

.. literalinclude:: filename

Longer displays of verbatim text may be included by storing the example text in an external file containing only plain text. The file may be included using the literalinclude directive. [1] For example, to include the Python source file example.py, use:

.. literalinclude:: example.py

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.

Tabs in the input are expanded if you give a tab-width option with the desired tab width.

Like code-block, the directive supports the linenos flag option to switch on line numbers, the lineno-start option to select the first line number, the emphasize-lines option to emphasize particular lines, and a language option to select a language different from the current file’s standard language. Example with options:

.. literalinclude:: example.rb
:language: ruby
:emphasize-lines: 12,15-18
:linenos:

Include files are assumed to be encoded in the source_encoding. If the file has a different encoding, you can specify it with the encoding option:

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

When specifying particular parts of a file to display, it can be useful to display exactly which lines are being presented. This can be done using the lineno-match option.

You can prepend and/or append a line to the included code, using the prepend and append option, respectively. This is useful e.g. for highlighting PHP code that doesn’t include the <?php/?> markers.

If you want to show the diff of the code, you can specify the old file by giving a diff option:

.. literalinclude:: example.py
:diff: example.py.orig

This shows the diff between example.py and example.py.orig with unified diff format.

New in version 0.4.3: The encoding option.

New in version 0.6: The pyobject, lines, start-after and end-before options, as well as support for absolute filenames.

New in version 1.0: The prepend and append options, as well as tab-width.

New in version 1.3: The diff option. The lineno-match option.

Caption and name

New in version 1.3.

A caption option can be given to show that name before the code block. A name option can be provided implicit target name that can be referenced by using ref. For example:

.. code-block:: python
:caption: this.py
:name: this-py

print 'Explicit is better than implicit.'

literalinclude also supports the caption and name option. caption has a additional feature that if you leave the value empty, the shown filename will be exactly the one given as an argument.

Dedent

New in version 1.3.

A dedent option can be given to strip a precedence characters from the code block. For example:

.. literalinclude:: example.rb
:language: ruby
:dedent: 4
:lines: 10-15

code-block also supports the dedent option.

Footnotes

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Markup Constructs »

Inline markup

Sphinx uses interpreted text roles to insert semantic markup into documents. They are written as :rolename:`content`.

Note

The default role (`content`) has no special meaning by default. You are free to use it for anything you like, e.g. variable names; use the default_role config value to set it to a known role – the any role to find anything or the py:obj role to find Python objects are very useful for this.

See Sphinx Domains for roles added by domains.

Cross-referencing syntax

Cross-references are generated by many semantic interpreted text roles. Basically, you only need to write :role:`target`, and a link will be created to the item named target of the type indicated by role. The link’s text will be the same as target.

There are some additional facilities, however, that make cross-referencing roles more versatile:

- You may supply an explicit title and reference target, like in reST direct hyperlinks: :role:`title <target>` will refer to target, but the link text will be title.

- If you prefix the content with !, no reference/hyperlink will be created.

- If you prefix the content with ~, the link text will only be the last component of the target. For example, :py:meth:`~Queue.Queue.get` will refer to Queue.Queue.get but only display get as the link text. This does not work with all cross-reference roles, but is domain specific.

In HTML output, the link’s title attribute (that is e.g. shown as a tool-tip on mouse-hover) will always be the full target name.

Cross-referencing anything

:any:

New in version 1.3.

This convenience role tries to do its best to find a valid target for its reference text.

- First, it tries standard cross-reference targets that would be referenced by doc, ref or option.

Custom objects added to the standard domain by extensions (see add_object_type()) are also searched.

- Then, it looks for objects (targets) in all loaded domains. It is up to the domains how specific a match must be. For example, in the Python domain a reference of :any:`Builder` would match the sphinx.builders.Builder class.

If none or multiple targets are found, a warning will be emitted. In the case of multiple targets, you can change “any” to a specific role.

This role is a good candidate for setting default_role. If you do, you can write cross-references without a lot of markup overhead. For example, in this Python function documentation

.. function:: install()

This function installs a `handler` for every signal known by the
`signal` module.  See the section `about-signals` for more information.

there could be references to a glossary term (usually :term:`handler`), a Python module (usually :py:mod:`signal` or :mod:`signal`) and a section (usually :ref:`about-signals`).

The any role also works together with the intersphinx extension: when no local cross-reference is found, all object types of intersphinx inventories are also searched.

Cross-referencing objects

These roles are described with their respective domains:

- Python

- C

- C++

- JavaScript

- ReST

Cross-referencing arbitrary locations

:ref:

To support cross-referencing to arbitrary locations in any document, the standard reST labels are used. For this to work label names must be unique throughout the entire documentation. There are two ways in which you can refer to labels:

- If you place a label directly before a section title, you can reference to it with :ref:`label-name`. Example:

.. _my-reference-label:

Section to cross-reference
--------------------------

This is the text of the section.

It refers to the section itself, see :ref:`my-reference-label`.

The :ref: role would then generate a link to the section, with the link title being “Section to cross-reference”. This works just as well when section and reference are in different source files.

Automatic labels also work with figures: given

.. _my-figure:

.. figure:: whatever

Figure caption

a reference :ref:`my-figure` would insert a reference to the figure with link text “Figure caption”.

The same works for tables that are given an explicit caption using the table [http://docutils.sourceforge.net/docs/ref/rst/directives.html#table] directive.

- Labels that aren’t placed before a section title can still be referenced to, but you must give the link an explicit title, using this syntax: :ref:`Link title <label-name>`.

Using 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

New in version 0.6.

There is also a way to directly link to documents:

: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

New in version 0.6.

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

Cross-referencing figures by figure number

New in version 1.3.

:numref:

Link to the specified figures, tables and code-blocks; the standard reST labels are used. When you use this role, it will insert a reference to the figure with link text by its figure number like “Fig. 1.1”.

If an explicit link text is given (like usual: :numref:`Image of Sphinx (Fig. %s) <my-figure>`), the link caption will be the title of the reference. As a special character, %s will be replaced to figure number.

If numfig is False, figures are not numbered. so this role inserts not a reference but labels or link text.

Cross-referencing other items of interest

The following roles do possibly create a cross-reference, but do not refer to objects:

:envvar:

An environment variable. Index entries are generated. Also generates a link to the matching envvar directive, if it exists.

:token:

The name of a grammar token (used to create links between productionlist directives).

:keyword:

The name of a keyword in Python. This creates a link to a reference label with that name, if it exists.

:option:

A command-line option to an executable program. This generates a link to a option directive, if it exists.

The following role creates a cross-reference to a term in a glossary:

:term:

Reference to a term in a glossary. A glossary is created using the glossary directive containing a definition list with terms and definitions. It does not have to be in the same file as the term markup, for example the Python docs have one global glossary in the glossary.rst file.

If you use a term that’s not explained in a glossary, you’ll get a warning during build.

Other semantic markup

The following roles don’t do anything special except formatting the text in a different style:

: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)`.

New in version 0.6.

:command:

The name of an OS-level command, such as rm.

:dfn:

Mark the defining instance of a term in the text. (No index entries are generated.)

:file:

The name of a file or directory. Within the contents, you can use curly braces to indicate a “variable” part, for example:

... is installed in :file:`/usr/lib/python2.{x}/site-packages` ...

In the built documentation, the x will be displayed differently to indicate that it is to be replaced by the Python minor version.

:guilabel:

Labels presented as part of an interactive user interface should be marked using guilabel. This includes labels from text-based interfaces such as those created using curses or other text-based libraries. Any label used in the interface should be marked with this role, including button labels, window titles, field names, menu and menu selection names, and even values in selection lists.

Changed in version 1.0: An accelerator key for the GUI label can be included using an ampersand; this will be stripped and displayed underlined in the output (example: :guilabel:`&Cancel`). To include a literal ampersand, double it.

:kbd:

Mark a sequence of keystrokes. What form the key sequence takes may depend on platform- or application-specific conventions. When there are no relevant conventions, the names of modifier keys should be spelled out, to improve accessibility for new users and non-native speakers. For example, an xemacs key sequence may be marked like :kbd:`C-x C-f`, but without reference to a specific application or platform, the same sequence should be marked as :kbd:`Control-x Control-f`.

:mailheader:

The name of an RFC 822-style mail header. This markup does not imply that the header is being used in an email message, but can be used to refer to any header of the same “style.” This is also used for headers defined by the various MIME specifications. The header name should be entered in the same way it would normally be found in practice, with the camel-casing conventions being preferred where there is more than one common usage. For example: :mailheader:`Content-Type`.

:makevar:

The name of a make variable.

:manpage:

A reference to a Unix manual page including the section, e.g. :manpage:`ls(1)`.

:menuselection:

Menu selections should be marked using the menuselection role. This is used to mark a complete sequence of menu selections, including selecting submenus and choosing a specific operation, or any subsequence of such a sequence. The names of individual selections should be separated by -->.

For example, to mark the selection “Start > Programs”, use this markup:

:menuselection:`Start --> Programs`

When including a selection that includes some trailing indicator, such as the ellipsis some operating systems use to indicate that the command opens a dialog, the indicator should be omitted from the selection name.

menuselection also supports ampersand accelerators just like guilabel.

:mimetype:

The name of a MIME type, or a component of a MIME type (the major or minor portion, taken alone).

:newsgroup:

The name of a Usenet newsgroup.

:program:

The name of an executable program. This may differ from the file name for the executable for some platforms. In particular, the .exe (or other) extension should be omitted for Windows programs.

:regexp:

A regular expression. Quotes should not be included.

:samp:

A piece of literal text, such as code. Within the contents, you can use curly braces to indicate a “variable” part, as in file. For example, in :samp:`print 1+{variable}`, the part variable would be emphasized.

If you don’t need the “variable part” indication, use the standard ``code`` instead.

There is also an index role to generate index entries.

The following roles generate external links:

:pep:

A reference to a Python Enhancement Proposal. This generates appropriate index entries. The text “PEP number” is generated; in the HTML output, this text is a hyperlink to an online copy of the specified PEP. You can link to a specific section by saying :pep:`number#anchor`.

:rfc:

A reference to an Internet Request for Comments. This generates appropriate index entries. The text “RFC number” is generated; in the HTML output, this text is a hyperlink to an online copy of the specified RFC. You can link to a specific section by saying :rfc:`number#anchor`.

Note that there are no special roles for including hyperlinks as you can use the standard reST markup for that purpose.

Substitutions

The documentation system provides three substitutions that are defined by default. They are set in the build configuration file.

|release|

Replaced by the project release the documentation refers to. This is meant to be the full version string including alpha/beta/release candidate tags, e.g. 2.5.2b3. Set by release.

|version|

Replaced by the project version the documentation refers to. This is meant to consist only of the major and minor version parts, e.g. 2.5, even for version 2.5.1. Set by version.

|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 today_fmt and today.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Markup Constructs »

Miscellaneous markup

File-wide metadata

reST has the concept of “field lists”; these are a sequence of fields marked up like this:

:fieldname: Field content

A field list near the top of a file is parsed by docutils as the “docinfo” which is normally used to record the author, date of publication and other metadata. In Sphinx, a field list preceding any other markup is moved from the docinfo to the Sphinx environment as document metadata and is not displayed in the output; a field list appearing after the document title will be part of the docinfo as normal and will be displayed in the output.

At the moment, these metadata fields are recognized:

tocdepth

The maximum depth for a table of contents of this file.

New in version 0.4.

nocomments

If set, the web application won’t display a comment form for a page generated from this source file.

orphan

If set, warnings about this file not being included in any toctree will be suppressed.

New in version 1.0.

Meta-information markup

.. sectionauthor:: name <email>

Identifies the author of the current section. The argument should include the author’s name such that it can be used for presentation and email address. The domain name portion of the address should be lower case. Example:

.. sectionauthor:: Guido van Rossum <guido@python.org>

By default, this markup isn’t reflected in the output in any way (it helps keep track of contributions), but you can set the configuration value show_authors to True to make them produce a paragraph in the output.

.. codeauthor:: name <email>

The codeauthor directive, which can appear multiple times, names the authors of the described code, just like sectionauthor names the author(s) of a piece of documentation. It too only produces output if the show_authors configuration value is True.

Index-generating markup

Sphinx automatically creates index entries from all object descriptions (like functions, classes or attributes) like discussed in Sphinx Domains.

However, there is also explicit markup available, to make the index more comprehensive and enable index entries in documents where information is not mainly contained in information units, such as the language reference.

.. index:: <entries>

This directive contains one or more index entries. Each entry consists of a type and a value, separated by a colon.

For example:

.. index::
single: execution; context
module: __main__
module: sys
triple: module; search; path

The execution context
---------------------

...

This directive contains five entries, which will be converted to entries in the generated index which link to the exact location of the index statement (or, in case of offline media, the corresponding page number).

Since index directives generate cross-reference targets at their location in the source, it makes sense to put them before the thing they refer to – e.g. a heading, as in the example above.

The possible entry types are:

single

Creates a single index entry. Can be made a subentry by separating the subentry text with a semicolon (this notation is also used below to describe what entries are created).

pair

pair: loop; statement is a shortcut that creates two index entries, namely loop; statement and statement; loop.

triple

Likewise, triple: module; search; path is a shortcut that creates three index entries, which are module; search path, search; path, module and path; module search.

see

see: entry; other creates an index entry that refers from entry to other.

seealso

Like see, but inserts “see also” instead of “see”.

module, keyword, operator, object, exception, statement, builtin

These all create two index entries. For example, module: hashlib creates the entries module; hashlib and hashlib; module. (These are Python-specific and therefore deprecated.)

You can mark up “main” index entries by prefixing them with an exclamation mark. The references to “main” entries are emphasized in the generated index. For example, if two pages contain

.. index:: Python

and one page contains

.. index:: ! Python

then the backlink to the latter page is emphasized among the three backlinks.

For index directives containing only “single” entries, there is a shorthand notation:

.. index:: BNF, grammar, syntax, notation

This creates four index entries.

Changed in version 1.1: Added see and seealso types, as well as marking main entries.

:index:

While the index directive is a block-level markup and links to the beginning of the next paragraph, there is also a corresponding role that sets the link target directly where it is used.

The content of the role can be a simple phrase, which is then kept in the text and used as an index entry. It can also be a combination of text and index entry, styled like with explicit targets of cross-references. In that case, the “target” part can be a full entry as described for the directive above. For example:

This is a normal reST :index:`paragraph` that contains several
:index:`index entries <pair: index; entry>`.

New in version 1.1.

Including content based on tags

.. 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 conf.py, see here) are true. Boolean expressions, also using parentheses (like html and (latex or draft)) are supported.

The format and the name of the current builder (html, latex or text) are always set as a tag [1]. To make the distinction between format and name explicit, they are also added with the prefix format_ and builder_, e.g. the epub builder defines the tags html, epub, format_html and builder_epub.

These standard tags are set after the configuration file is read, so they are not available there.

All tags must follow the standard Python identifier syntax as set out in the Identifiers and keywords [https://docs.python.org/2/reference/lexical_analysis.html#identifiers] documentation. That is, a tag expression may only consist of tags that conform to the syntax of Python variables. In ASCII, this consists of the uppercase and lowercase letters A through Z, the underscore _ and, except for the first character, the digits 0 through 9.

New in version 0.6.

Changed in version 1.2: Added the name of the builder and the prefixes.

Tables

Use standard reStructuredText tables. They work fine in HTML output, however there are some gotchas when using tables in LaTeX: the column width is hard to determine correctly automatically. For this reason, the following directive exists:

.. tabularcolumns:: column spec

This directive gives a “column spec” for the next table occurring in the source file. The spec is the second argument to the LaTeX tabulary package’s environment (which Sphinx uses to translate tables). It can have values like

|l|l|l|

which means three left-adjusted, nonbreaking columns. For columns with longer text that should automatically be broken, use either the standard p{width} construct, or tabulary’s automatic specifiers:

The automatic width is determined by rendering the content in the table, and scaling them according to their share of the total width.

By default, Sphinx uses a table layout with L for every column.

New in version 0.3.

Warning

Tables that contain list-like elements such as object descriptions, blockquotes or any kind of lists cannot be set out of the box with tabulary. They are therefore set with the standard LaTeX tabular environment if you don’t give a tabularcolumns directive. If you do, the table will be set with tabulary, but you must use the p{width} construct for the columns that contain these elements.

Literal blocks do not work with tabulary at all, so tables containing a literal block are always set with tabular. Also, the verbatim environment used for literal blocks only works in p{width} columns, which means that by default, Sphinx generates such column specs for such tables. Use the tabularcolumns directive to get finer control over such tables.

Footnotes

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Sphinx Domains

New in version 1.0.

What is a Domain?

Originally, Sphinx was conceived for a single project, the documentation of the Python language. Shortly afterwards, it was made available for everyone as a documentation tool, but the documentation of Python modules remained deeply built in – the most fundamental directives, like function, were designed for Python objects. Since Sphinx has become somewhat popular, interest developed in using it for many different purposes: C/C++ projects, JavaScript, or even reStructuredText markup (like in this documentation).

While this was always possible, it is now much easier to easily support documentation of projects using different programming languages or even ones not supported by the main Sphinx distribution, by providing a domain for every such purpose.

A domain is a collection of markup (reStructuredText directives and roles) to describe and link to objects belonging together, e.g. elements of a programming language. Directive and role names in a domain have names like domain:name, e.g. py:function. Domains can also provide custom indices (like the Python Module Index).

Having domains means that there are no naming problems when one set of documentation wants to refer to e.g. C++ and Python classes. It also means that extensions that support the documentation of whole new languages are much easier to write.

This section describes what the domains that come with Sphinx provide. The domain API is documented as well, in the section Domain API.

Basic Markup

Most domains provide a number of object description directives, used to describe specific objects provided by modules. Each directive requires one or more signatures to provide basic information about what is being described, and the content should be the description. The basic version makes entries in the general index; if no index entry is desired, you can give the directive option flag :noindex:. An example using a Python domain directive:

.. py:function:: spam(eggs)
ham(eggs)

Spam or ham the foo.

This describes the two Python functions spam and ham. (Note that when signatures become too long, you can break them if you add a backslash to lines that are continued in the next line. Example:

.. py:function:: filterwarnings(action, message='', category=Warning, \
module='', lineno=0, append=False)
:noindex:

(This example also shows how to use the :noindex: flag.)

The domains also provide roles that link back to these object descriptions. For example, to link to one of the functions described in the example above, you could say

The function :py:func:`spam` does a similar thing.

As you can see, both directive and role names contain the domain name and the directive name.

Default Domain

To avoid having to writing the domain name all the time when you e.g. only describe Python objects, a default domain can be selected with either the config value primary_domain or this directive:

.. default-domain:: name

Select a new default domain. While the primary_domain selects a global default, this only has an effect within the same file.

If no other default is selected, the Python domain (named py) is the default one, mostly for compatibility with documentation written for older versions of Sphinx.

Directives and roles that belong to the default domain can be mentioned without giving the domain name, i.e.

.. function:: pyfunc()

Describes a Python function.

Reference to :func:`pyfunc`.

Cross-referencing syntax

For cross-reference roles provided by domains, the same facilities exist as for general cross-references. See Cross-referencing syntax.

In short:

- You may supply an explicit title and reference target: :role:`title <target>` will refer to target, but the link text will be title.

- If you prefix the content with !, no reference/hyperlink will be created.

- If you prefix the content with ~, the link text will only be the last component of the target. For example, :py:meth:`~Queue.Queue.get` will refer to Queue.Queue.get but only display get as the link text.

The Python Domain

The Python domain (name py) provides the following directives for module declarations:

.. py:module:: name

This directive marks the beginning of the description of a module (or package submodule, in which case the name should be fully qualified, including the package name). It does not create content (like e.g. py:class does).

This directive will also cause an entry in the global module index.

The platform option, if present, is a comma-separated list of the platforms on which the module is available (if it is available on all platforms, the option should be omitted). The keys are short identifiers; examples that are in use include “IRIX”, “Mac”, “Windows”, and “Unix”. It is important to use a key which has already been used when applicable.

The synopsis option should consist of one sentence describing the module’s purpose – it is currently only used in the Global Module Index.

The deprecated option can be given (with no value) to mark a module as deprecated; it will be designated as such in various locations then.

.. py:currentmodule:: name

This directive tells Sphinx that the classes, functions etc. documented from here are in the given module (like py:module), but it will not create index entries, an entry in the Global Module Index, or a link target for py:mod. This is helpful in situations where documentation for things in a module is spread over multiple files or sections – one location has the py:module directive, the others only py:currentmodule.

The following directives are provided for module and class contents:

.. py:function:: name(parameters)

Describes a module-level function. The signature should include the parameters as given in the Python function definition, see Python Signatures. For example:

.. py:function:: Timer.repeat(repeat=3, number=1000000)

For methods you should use py:method.

The description normally includes information about the parameters required and how they are used (especially whether mutable objects passed as parameters are modified), side effects, and possible exceptions.

This information can (in any py directive) optionally be given in a structured form, see Info field lists.

.. py:data:: name

Describes global data in a module, including both variables and values used as “defined constants.” Class and object attributes are not documented using this environment.

.. py:exception:: name

Describes an exception class. The signature can, but need not include parentheses with constructor arguments.

.. py:class:: name

.. py:class:: name(parameters)

Describes a class. The signature can optionally include parentheses with parameters which will be shown as the constructor arguments. See also Python Signatures.

Methods and attributes belonging to the class should be placed in this directive’s body. If they are placed outside, the supplied name should contain the class name so that cross-references still work. Example:

.. py:class:: Foo

.. py:method:: quux()

-- or --

.. py:class:: Bar

.. py:method:: Bar.quux()

The first way is the preferred one.

.. py:attribute:: name

Describes an object data attribute. The description should include information about the type of the data to be expected and whether it may be changed directly.

.. py:method:: name(parameters)

Describes an object method. The parameters should not include the self parameter. The description should include similar information to that described for function. See also Python Signatures and Info field lists.

.. py:staticmethod:: name(parameters)

Like py:method, but indicates that the method is a static method.

New in version 0.4.

.. py:classmethod:: name(parameters)

Like py:method, but indicates that the method is a class method.

New in version 0.6.

.. py:decorator:: name

.. py:decorator:: name(parameters)

Describes a decorator function. The signature should represent the usage as a decorator. For example, given the functions

def removename(func):
func.__name__ = ''
return func

def setnewname(name):
def decorator(func):
func.__name__ = name
return func
return decorator

the descriptions should look like this:

.. py:decorator:: removename

Remove name of the decorated function.

.. py:decorator:: setnewname(name)

Set name of the decorated function to *name*.

(as opposed to .. py:decorator:: removename(func).)

There is no py:deco role to link to a decorator that is marked up with this directive; rather, use the py:func role.

.. py:decoratormethod:: name

.. py:decoratormethod:: name(signature)

Same as py:decorator, but for decorators that are methods.

Refer to a decorator method using the py:meth role.

Python Signatures

Signatures of functions, methods and class constructors can be given like they would be written in Python.

Default values for optional arguments can be given (but if they contain commas, they will confuse the signature parser). Python 3-style argument annotations can also be given as well as return type annotations:

.. py:function:: compile(source : string, filename, symbol='file') -> ast object

For functions with optional parameters that don’t have default values (typically functions implemented in C extension modules without keyword argument support), you can use brackets to specify the optional parts:

compile(source[, filename[, symbol]])

It is customary to put the opening bracket before the comma.

Info field lists

New in version 0.4.

Inside Python object description directives, reST field lists with these fields are recognized and formatted nicely:

- param, parameter, arg, argument, key, keyword: Description of a parameter.

- type: Type of a parameter. Creates a link if possible.

- raises, raise, except, exception: That (and when) a specific exception is raised.

- var, ivar, cvar: Description of a variable.

- vartype: Type of a variable. Creates a link if possible.

- returns, return: Description of the return value.

- rtype: Return type. Creates a link if possible.

The field names must consist of one of these keywords and an argument (except for returns and rtype, which do not need an argument). This is best explained by an example:

.. py:function:: send_message(sender, recipient, message_body, [priority=1])

Send a message to a recipient

:param str sender: The person sending the message
:param str recipient: The recipient of the message
:param str message_body: The body of the message
:param priority: The priority of the message, can be a number 1-5
:type priority: integer or None
:return: the message id
:rtype: int
:raises ValueError: if the message_body exceeds 160 characters
:raises TypeError: if the message_body is not a basestring

This will render like this:

send_message(sender, recipient, message_body[, priority=1])

Send a message to a recipient

It is also possible to combine parameter type and description, if the type is a single word, like this:

:param int priority: The priority of the message, can be a number 1-5

Cross-referencing Python objects

The following roles refer to objects in modules and are possibly hyperlinked if a matching identifier is found:

:py:mod:

Reference a module; a dotted name may be used. This should also be used for package names.

:py:func:

Reference a Python function; dotted names may be used. The role text needs not include trailing parentheses to enhance readability; they will be added automatically by Sphinx if the add_function_parentheses config value is True (the default).

:py:data:

Reference a module-level variable.

:py:const:

Reference a “defined” constant. This may be a Python variable that is not intended to be changed.

:py:class:

Reference a class; a dotted name may be used.

:py:meth:

Reference a method of an object. The role text can include the type name and the method name; if it occurs within the description of a type, the type name can be omitted. A dotted name may be used.

:py:attr:

Reference a data attribute of an object.

:py:exc:

Reference an exception. A dotted name may be used.

:py:obj:

Reference an object of unspecified type. Useful e.g. as the default_role.

New in version 0.4.

The name enclosed in this markup can include a module name and/or a class name. For example, :py:func:`filter` could refer to a function named filter in the current module, or the built-in function of that name. In contrast, :py:func:`foo.filter` clearly refers to the filter function in the foo module.

Normally, names in these roles are searched first without any further qualification, then with the current module name prepended, then with the current module and class name (if any) prepended. If you prefix the name with a dot, this order is reversed. For example, in the documentation of Python’s codecs module, :py:func:`open` always refers to the built-in function, while :py:func:`.open` refers to codecs.open().

A similar heuristic is used to determine whether the name is an attribute of the currently documented class.

Also, if the name is prefixed with a dot, and no exact match is found, the target is taken as a suffix and all object names with that suffix are searched. For example, :py:meth:`.TarFile.close` references the tarfile.TarFile.close() function, even if the current module is not tarfile. Since this can get ambiguous, if there is more than one possible match, you will get a warning from Sphinx.

Note that you can combine the ~ and . prefixes: :py:meth:`~.TarFile.close` will reference the tarfile.TarFile.close() method, but the visible link caption will only be close().

The C Domain

The C domain (name c) is suited for documentation of C API.

.. c:function:: type name(signature)

Describes a C function. The signature should be given as in C, e.g.:

.. c:function:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)

This is also used to describe function-like preprocessor macros. The names of the arguments should be given so they may be used in the description.

Note that you don’t have to backslash-escape asterisks in the signature, as it is not parsed by the reST inliner.

.. c:member:: type name

Describes a C struct member. Example signature:

.. c:member:: PyObject* PyTypeObject.tp_bases

The text of the description should include the range of values allowed, how the value should be interpreted, and whether the value can be changed. References to structure members in text should use the member role.

.. c:macro:: name

Describes a “simple” C macro. Simple macros are macros which are used for code expansion, but which do not take arguments so cannot be described as functions. This is a simple C-language #define. Examples of its use in the Python documentation include PyObject_HEAD and Py_BEGIN_ALLOW_THREADS.

.. c:type:: name

Describes a C type (whether defined by a typedef or struct). The signature should just be the type name.

.. c:var:: type name

Describes a global C variable. The signature should include the type, such as:

.. c:var:: PyObject* PyClass_Type

Cross-referencing C constructs

The following roles create cross-references to C-language constructs if they are defined in the documentation:

:c:data:

Reference a C-language variable.

:c:func:

Reference a C-language function. Should include trailing parentheses.

:c:macro:

Reference a “simple” C macro, as defined above.

:c:type:

Reference a C-language type.

The C++ Domain

The C++ domain (name cpp) supports documenting C++ projects.

The following directives are available. All declarations can start with a visibility statement (public, private or protected).

.. cpp:class:: class specifier

Describe a class/struct, possibly with specification of inheritance, e.g.,:

.. cpp:class:: MyClass : public MyBase, MyOtherBase

The class can be directly declared inside a nested scope, e.g.,:

.. cpp:class:: OuterScope::MyClass : public MyBase, MyOtherBase

A template class can be declared:

.. cpp:class:: template<typename T, std::size_t N> std::array

or with a line break:

.. cpp:class:: template<typename T, std::size_t N> \
std::array

Full and partial template specialisations can be declared:

.. cpp::class:: template<> \
std::array<bool, 256>

.. cpp::class:: template<typename T> \
std::array<T, 42>

.. cpp:function:: (member) function prototype

Describe a function or member function, e.g.,:

.. cpp:function:: bool myMethod(int arg1, std::string arg2)

A function with parameters and types.

.. cpp:function:: bool myMethod(int, double)

A function with unnamed parameters.

.. cpp:function:: const T &MyClass::operator[](std::size_t i) const

An overload for the indexing operator.

.. cpp:function:: operator bool() const

A casting operator.

.. cpp:function:: constexpr void foo(std::string &bar[2]) noexcept

A constexpr function.

.. cpp:function:: MyClass::MyClass(const MyClass&) = default

A copy constructor with default implementation.

Function templates can also be described:

.. cpp:function:: template<typename U> \
void print(U &&u)

and function template specialisations:

.. cpp:function:: template<> \
void print(int i)

.. cpp:member:: (member) variable declaration

.. cpp:var:: (member) variable declaration

Describe a variable or member variable, e.g.,:

.. cpp:member:: std::string MyClass::myMember

.. cpp:var:: std::string MyClass::myOtherMember[N][M]

.. cpp:member:: int a = 42

Variable templates can also be described:

.. cpp:member:: template<class T> \
constexpr T pi = T(3.1415926535897932385)

.. cpp:type:: typedef declaration

.. cpp:type:: name

.. cpp:type:: type alias declaration

Describe a type as in a typedef declaration, a type alias declaration, or simply the name of a type with unspecified type, e.g.,:

.. cpp:type:: std::vector<int> MyList

A typedef-like declaration of a type.

.. cpp:type:: MyContainer::const_iterator

Declaration of a type alias with unspecified type.

.. cpp:type:: MyType = std::unordered_map<int, std::string>

Declaration of a type alias.

A type alias can also be templated:

.. cpp:type:: template<typename T> \
MyContainer = std::vector<T>

The example are rendered as follows.

typedef std::vector<int> MyList

A typedef-like declaration of a type.

type MyContainer::const_iterator

Declaration of a type alias with unspecified type.

using MyType = std::unordered_map<int, std::string>

Declaration of a type alias.

template<typename T>

using MyContainer = std::vector<T>

.. cpp:enum:: unscoped enum declaration

.. cpp:enum-struct:: scoped enum declaration

.. cpp:enum-class:: scoped enum declaration

Describe a (scoped) enum, possibly with the underlying type specified. Any enumerators declared inside an unscoped enum will be declared both in the enum scope and in the parent scope. Examples:

.. cpp:enum:: MyEnum

An unscoped enum.

.. cpp:enum:: MySpecificEnum : long

An unscoped enum with specified underlying type.

.. cpp:enum-class:: MyScopedEnum

A scoped enum.

.. cpp:enum-struct:: protected MyScopedVisibilityEnum : std::underlying_type<MySpecificEnum>::type

A scoped enum with non-default visibility, and with a specified underlying type.

.. cpp:enumerator:: name

.. cpp:enumerator:: name = constant

Describe an enumerator, optionally with its value defined, e.g.,:

.. cpp::enumerator:: MyEnum::myEnumerator

.. cpp::enumerator:: MyEnum::myOtherEnumerator = 42

Namespacing

Declarations in the C++ domain are as default placed in global scope. The current scope can be changed using three namespace directives. They manage a stack declarations where cpp:namespace resets the stack and changes a given scope. The cpp:namespace-push directive changes the scope to a given inner scope of the current one. The cpp:namespace-pop directive undos the most recent cpp:namespace-push directive.

.. cpp:namespace:: scope specification

Changes the current scope for the subsequent objects to the given scope, and resets the namespace directive stack. Note that the namespace does not need to correspond to C++ namespaces, but can end in names of classes, e.g.,:

.. cpp:namespace:: Namespace1::Namespace2::SomeClass::AnInnerClass

All subsequent objects will be defined as if their name were declared with the scope prepended. The subsequent cross-references will be searched for starting in the current scope.

Using NULL, 0, or nullptr as the scope will change to global scope.

A namespace declaration can also be templated, e.g.,:

.. cpp:class:: template<typename T> \
std::vector

.. cpp:namespace:: template<typename T> std::vector

.. cpp:function:: std::size_t size() const

declares size as a member function of the template class std::vector. Equivalently this could have been declared using:

.. cpp:class:: template<typename T> \
std::vector

.. cpp:function:: std::size_t size() const

or::

.. cpp:class:: template<typename T> \
std::vector

.. cpp:namespace-push:: scope specification

Change the scope relatively to the current scope. For example, after:

.. cpp:namespace:: A::B

.. cpp:namespace-push:: C::D

the current scope will be A::B::C::D.

.. cpp:namespace-pop::

Undo the previous cpp:namespace-push directive (not just pop a scope). For example, after:

.. cpp:namespace:: A::B

.. cpp:namespace-push:: C::D

.. cpp:namespace-pop::

the current scope will be A::B (not A::B::C).

If no previous cpp:namespace-push directive has been used, but only a cpp:namespace directive, then the current scope will be reset to global scope. That is, .. cpp:namespace:: A::B is equivalent to:

.. cpp:namespace:: nullptr

.. cpp:namespace-push:: A::B

Info field lists

The C++ directives support the following info fields (see also Info field lists):

- param, parameter, arg, argument: Description of a parameter.

- tparam: Description of a template parameter.

- returns, return: Description of a return value.

- throws, throw, exception: Description of a possibly thrown exception.

Cross-referencing

These roles link to the given declaration types:

:cpp:any:

:cpp:class:

:cpp:func:

:cpp:member:

:cpp:var:

:cpp:type:

:cpp:enum:

:cpp:enumerator:

Reference a C++ declaration by name (see below for details). The name must be properly qualified relative to the position of the link.

Note on References with Templates Parameters/Arguments

Sphinx’s syntax to give references a custom title can interfere with linking to template classes, if nothing follows the closing angle bracket, i.e. if the link looks like this: :cpp:class:`MyClass<int>`. This is interpreted as a link to int with a title of MyClass. In this case, please escape the opening angle bracket with a backslash, like this: :cpp:class:`MyClass\<int>`.

Note on References to Overloaded Functions

It is currently impossible to link to a specific version of an overloaded method. Currently the C++ domain is the first domain that has basic support for overloaded methods and until there is more data for comparison we don’t want to select a bad syntax to reference a specific overload. Currently Sphinx will link to the first overloaded version of the method / function.

Declarations without template parameters and template arguments

For linking to non-templated declarations the name must be a nested name, e.g., f or MyClass::f.

Templated declarations

Assume the following declarations.

class Wrapper

template<typename TOuter>

class Outer

template<typename TInner>

class Inner

In general the reference must include the template paraemter declarations, e.g., template\<typename TOuter> Wrapper::Outer (template<typename TOuter> Wrapper::Outer). Currently the lookup only succeed if the template parameter identifiers are equal strings. That is, template\<typename UOuter> Wrapper::Outer will not work.

The inner template class can not be directly referenced, unless the current namespace is changed or the following shorthand is used. If a template parameter list is omitted, then the lookup will assume either a template or a non-template, but not a partial template specialisation. This means the following references work.

- Wrapper::Outer (Wrapper::Outer)

- Wrapper::Outer::Inner (Wrapper::Outer::Inner)

- template\<typename TInner> Wrapper::Outer::Inner (template<typename TInner> Wrapper::Outer::Inner)

(Full) Template Specialisations

Assume the following declarations.

template<typename TOuter>

class Outer

template<typename TInner>

class Inner

template<>

class Outer<int>

template<typename TInner>

class Inner

template<>

class Inner<bool>

In general the reference must include a template parameter list for each template argument list. The full specialisation above can therefore be referenced with template\<> Outer\<int> (template<> Outer<int>) and template\<> template\<> Outer\<int>::Inner\<bool> (template<> template<> Outer<int>::Inner<bool>). As a shorthand the empty template parameter list can be omitted, e.g., Outer\<int> (Outer<int>) and Outer\<int>::Inner\<bool> (Outer<int>::Inner<bool>).

Partial Template Specialisations

Assume the following declaration.

template<typename T>

class Outer<T *>

References to partial specialisations must always include the template parameter lists, e.g., template\<typename T> Outer\<T*> (template<typename T> Outer<T*>). Currently the lookup only succeed if the template parameter identifiers are equal strings.

The Standard Domain

The so-called “standard” domain collects all markup that doesn’t warrant a domain of its own. Its directives and roles are not prefixed with a domain name.

The standard domain is also where custom object descriptions, added using the add_object_type() API, are placed.

There is a set of directives allowing documenting command-line programs:

.. option:: name args, name args, ...

Describes a command line argument or switch. Option argument names should be enclosed in angle brackets. Examples:

.. option:: dest_dir

Destination directory.

.. option:: -m <module>, --module <module>

Run a module as a script.

The directive will create cross-reference targets for the given options, referencable by option (in the example case, you’d use something like :option:`dest_dir`, :option:`-m`, or :option:`--module`).

cmdoption directive is a deprecated alias for the option directive.

.. envvar:: name

Describes an environment variable that the documented code or program uses or defines. Referencable by envvar.

.. program:: name

Like py:currentmodule, this directive produces no output. Instead, it serves to notify Sphinx that all following option directives document options for the program called name.

If you use program, you have to qualify the references in your option roles by the program name, so if you have the following situation

.. program:: rm

.. option:: -r

Work recursively.

.. program:: svn

.. option:: -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).

New in version 0.5.

There is also a very generic object description directive, which is not tied to any domain:

.. describe:: text

.. object:: text

This directive produces the same formatting as the specific ones provided by domains, but does not create index entries or cross-referencing targets. Example:

.. describe:: PAPER

You can set this variable to select a paper size.

The JavaScript Domain

The JavaScript domain (name js) provides the following directives:

.. js:function:: name(signature)

Describes a JavaScript function or method. If you want to describe arguments as optional use square brackets as documented for Python signatures.

You can use fields to give more details about arguments and their expected types, errors which may be thrown by the function, and the value being returned:

.. js:function:: $.getJSON(href, callback[, errback])

:param string href: An URI to the location of the resource.
:param callback: Gets called with the object.
:param errback:
Gets called in case the request fails. And a lot of other
text so we need multiple lines.
:throws SomeError: For whatever reason in that case.
:returns: Something.

This is rendered as:

$.getJSON(href, callback[, errback])

.. js:class:: name

Describes a constructor that creates an object. This is basically like a function but will show up with a class prefix:

.. js:class:: MyAnimal(name[, age])

:param string name: The name of the animal
:param number age: an optional age for the animal

This is rendered as:

class MyAnimal(name[, age])

.. js:data:: name

Describes a global variable or constant.

.. js:attribute:: object.name

Describes the attribute name of object.

These roles are provided to refer to the described objects:

:js:func:

:js:class:

:js:data:

:js:attr:

The reStructuredText domain

The reStructuredText domain (name rst) provides the following directives:

.. rst:directive:: name

Describes a reST directive. The name can be a single directive name or actual directive syntax (.. prefix and :: suffix) with arguments that will be rendered differently. For example:

.. rst:directive:: foo

Foo description.

.. rst:directive:: .. bar:: baz

Bar description.

will be rendered as:

.. foo::

Foo description.

.. bar:: baz

Bar description.

.. rst:role:: name

Describes a reST role. For example:

.. rst:role:: foo

Foo description.

will be rendered as:

:foo:

Foo description.

These roles are provided to refer to the described objects:

:rst:dir:

:rst:role:

More domains

The sphinx-contrib [https://bitbucket.org/birkenfeld/sphinx-contrib/] repository contains more domains available as extensions; currently Ada [https://pypi.python.org/pypi/sphinxcontrib-adadomain], CoffeeScript [https://pypi.python.org/pypi/sphinxcontrib-coffee], Erlang [https://pypi.python.org/pypi/sphinxcontrib-erlangdomain], HTTP [https://pypi.python.org/pypi/sphinxcontrib-httpdomain], Lasso [https://pypi.python.org/pypi/sphinxcontrib-lassodomain], MATLAB [https://pypi.python.org/pypi/sphinxcontrib-matlabdomain], PHP [https://pypi.python.org/pypi/sphinxcontrib-phpdomain], and Ruby [https://bitbucket.org/birkenfeld/sphinx-contrib/src/default/rubydomain] domains. Also available are domains for Chapel [https://pypi.python.org/pypi/sphinxcontrib-chapeldomain], Common Lisp [https://pypi.python.org/pypi/sphinxcontrib-cldomain], dqn [https://pypi.python.org/pypi/sphinxcontrib-dqndomain], Go [https://pypi.python.org/pypi/sphinxcontrib-golangdomain], Jinja [https://pypi.python.org/pypi/sphinxcontrib-jinjadomain], Operation [https://pypi.python.org/pypi/sphinxcontrib-operationdomain], and Scala [https://pypi.python.org/pypi/sphinxcontrib-scaladomain].

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Available builders

These are the built-in Sphinx builders. More builders can be added by extensions.

The builder’s “name” must be given to the -b command-line option of sphinx-build to select a builder.

class sphinx.builders.html.StandaloneHTMLBuilder[source]

This is the standard HTML builder. Its output is a directory with HTML files, complete with style sheets and optionally the reST sources. There are quite a few configuration values that customize the output of this builder, see the chapter Options for HTML output for details.

name = 'html'

format = 'html'

supported_image_types = ['image/svg+xml', 'image/png', 'image/gif', 'image/jpeg']

class sphinx.builders.html.DirectoryHTMLBuilder[source]

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

name = 'dirhtml'

format = 'html'

supported_image_types = ['image/svg+xml', 'image/png', 'image/gif', 'image/jpeg']

New in version 0.6.

class sphinx.builders.html.SingleFileHTMLBuilder[source]

This is an HTML builder that combines the whole project in one output file. (Obviously this only works with smaller projects.) The file is named like the master document. No indices will be generated.

name = 'singlehtml'

format = 'html'

supported_image_types = ['image/svg+xml', 'image/png', 'image/gif', 'image/jpeg']

New in version 1.0.

class sphinx.builders.htmlhelp.HTMLHelpBuilder[source]

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.

name = 'htmlhelp'

format = 'html'

supported_image_types = ['image/png', 'image/gif', 'image/jpeg']

class sphinx.builders.qthelp.QtHelpBuilder[source]

This builder produces the same output as the standalone HTML builder, but also generates Qt help [http://doc.qt.io/qt-4.8/qthelp-framework.html] collection support files that allow the Qt collection generator to compile them.

name = 'qthelp'

format = 'html'

supported_image_types = ['image/svg+xml', 'image/png', 'image/gif', 'image/jpeg']

class sphinx.builders.applehelp.AppleHelpBuilder[source]

This builder produces an Apple Help Book based on the same output as the standalone HTML builder.

If the source directory contains any .lproj folders, the one corresponding to the selected language will have its contents merged with the generated output. These folders will be ignored by all other documentation types.

In order to generate a valid help book, this builder requires the command line tool hiutil, which is only available on Mac OS X 10.6 and above. You can disable the indexing step by setting applehelp_disable_external_tools to True, in which case the output will not be valid until hiutil has been run on all of the .lproj folders within the bundle.

name = 'applehelp'

format = 'html'

supported_image_types = ['image/png', 'image/gif', 'image/jpeg', 'image/tiff', 'image/jp2', 'image/svg+xml']

New in version 1.3.

class sphinx.builders.devhelp.DevhelpBuilder[source]

This builder produces the same output as the standalone HTML builder, but also generates GNOME Devhelp [https://wiki.gnome.org/Apps/Devhelp] support file that allows the GNOME Devhelp reader to view them.

name = 'devhelp'

format = 'html'

supported_image_types = ['image/png', 'image/gif', 'image/jpeg']

class sphinx.builders.epub.EpubBuilder[source]

This builder produces the same output as the standalone HTML builder, but also generates an epub file for ebook readers. See Epub info for details about it. For definition of the epub format, have a look at http://idpf.org/epub or https://en.wikipedia.org/wiki/EPUB. The builder creates EPUB 2 files.

name = 'epub'

format = 'html'

supported_image_types = ['image/svg+xml', 'image/png', 'image/gif', 'image/jpeg']

class sphinx.builders.epub3.Epub3Builder[source]

This builder produces the same output as the standalone HTML builder, but also generates an epub file for ebook readers. See Epub info for details about it. For definition of the epub format, have a look at http://idpf.org/epub or https://en.wikipedia.org/wiki/EPUB. The builder creates EPUB 3 files.

This builder is still experimental because it can’t generate valid EPUB 3 files.

name = 'epub3'

format = 'html'

supported_image_types = ['image/svg+xml', 'image/png', 'image/gif', 'image/jpeg']

New in version 1.4.

class sphinx.builders.latex.LaTeXBuilder[source]

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 latex_documents configuration value. There are a few configuration values that customize the output of this builder, see the chapter Options for LaTeX output 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

name = 'latex'

format = 'latex'

supported_image_types = ['application/pdf', 'image/png', 'image/jpeg']

Note that a direct PDF builder using ReportLab is available in rst2pdf [https://github.com/rst2pdf/rst2pdf] version 0.12 or greater. You need to add 'rst2pdf.pdfbuilder' to your extensions to enable it, its name is pdf. Refer to the rst2pdf manual [http://ralsina.me/static/manual.pdf] for details.

class sphinx.builders.text.TextBuilder[source]

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.

name = 'text'

format = 'text'

supported_image_types = []

New in version 0.4.

class sphinx.builders.manpage.ManualPageBuilder[source]

This builder produces manual pages in the groff format. You have to specify which documents are to be included in which manual pages via the man_pages configuration value.

name = 'man'

format = 'man'

supported_image_types = []

New in version 1.0.

class sphinx.builders.texinfo.TexinfoBuilder[source]

This builder produces Texinfo files that can be processed into Info files by the makeinfo program. You have to specify which documents are to be included in which Texinfo files via the texinfo_documents configuration value.

The Info format is the basis of the on-line help system used by GNU Emacs and the terminal-based program info. See Texinfo info for more details. The Texinfo format is the official documentation system used by the GNU project. More information on Texinfo can be found at http://www.gnu.org/software/texinfo/.

name = 'texinfo'

format = 'texinfo'

supported_image_types = ['image/png', 'image/jpeg', 'image/gif']

New in version 1.1.

class sphinx.builders.html.SerializingHTMLBuilder[source]

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 concrete subclass of this builder serializing to the PHP serialization [https://pypi.python.org/pypi/phpserialize] 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'

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.

out_suffix

The suffix for all regular files.

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.

searchindex_filename

The filename for the search index Sphinx generates.

See Serialization builder details for details about the output format.

New in version 0.5.

class sphinx.builders.html.PickleHTMLBuilder[source]

This builder produces a directory with pickle files containing mostly HTML fragments and TOC information, for use of a web application (or custom postprocessing tool) that doesn’t use the standard HTML templates.

See Serialization builder details for details about the output format.

name = 'pickle'

The old name web still works as well.

format = 'html'

supported_image_types = ['image/svg+xml', 'image/png', 'image/gif', 'image/jpeg']

The file suffix is .fpickle. The global context is called globalcontext.pickle, the search index searchindex.pickle.

class sphinx.builders.html.JSONHTMLBuilder[source]

This builder produces a directory with JSON files containing mostly HTML fragments and TOC information, for use of a web application (or custom postprocessing tool) that doesn’t use the standard HTML templates.

See Serialization builder details for details about the output format.

name = 'json'

format = 'html'

supported_image_types = ['image/svg+xml', 'image/png', 'image/gif', 'image/jpeg']

The file suffix is .fjson. The global context is called globalcontext.json, the search index searchindex.json.

New in version 0.5.

class sphinx.builders.gettext.MessageCatalogBuilder[source]

This builder produces gettext-style message catalogs. Each top-level file or subdirectory grows a single .pot catalog template.

See the documentation on Internationalization for further reference.

name = u'gettext'

format = ''

supported_image_types = []

New in version 1.1.

class sphinx.builders.changes.ChangesBuilder[source]

This builder produces an HTML overview of all versionadded, versionchanged and deprecated directives for the current version. This is useful to generate a ChangeLog file, for example.

name = 'changes'

format = ''

supported_image_types = []

class sphinx.builders.dummy.DummyBuilder[source]

This builder produces no output. The input is only parsed and checked for consistency. This is useful for linting purposes.

name = 'dummy'

supported_image_types = []

New in version 1.4.

class sphinx.builders.linkcheck.CheckExternalLinksBuilder[source]

This builder scans all documents for external links, tries to open them with urllib2, and writes an overview which ones are broken and redirected to standard output and to output.txt in the output directory.

name = 'linkcheck'

format = ''

supported_image_types = []

class sphinx.builders.xml.XMLBuilder[source]

This builder produces Docutils-native XML files. The output can be transformed with standard XML tools such as XSLT processors into arbitrary final forms.

name = 'xml'

format = 'xml'

supported_image_types = []

New in version 1.2.

class sphinx.builders.xml.PseudoXMLBuilder[source]

This builder is used for debugging the Sphinx/Docutils “Reader to Transform to Writer” pipeline. It produces compact pretty-printed “pseudo-XML”, files where nesting is indicated by indentation (no end-tags). External attributes for all elements are output, and internal attributes for any leftover “pending” elements are also given.

name = 'pseudoxml'

format = 'pseudoxml'

supported_image_types = []

New in version 1.2.

Built-in Sphinx extensions that offer more builders are:

- doctest

- coverage

Serialization builder details

All serialization builders outputs one file per source file and a few special files. They also copy the reST source files in the directory _sources under the output directory.

The PickleHTMLBuilder is a builtin subclass that implements the pickle serialization interface.

The files per source file have the extensions of out_suffix, and are arranged in directories just as the source files are. They unserialize to a dictionary (or dictionary like structure) with these keys:

body

The HTML “body” (that is, the HTML rendering of the source file), as rendered by the HTML translator.

title

The title of the document, as HTML (may contain markup).

toc

The table of contents for the file, rendered as an HTML <ul>.

display_toc

A boolean that is True if the toc contains more than one entry.

current_page_name

The document name of the current file.

parents, prev and next

Information about related chapters in the TOC tree. Each relation is a dictionary with the keys link (HREF for the relation) and title (title of the related document, as HTML). parents is a list of relations, while prev and next are a single relation.

sourcename

The name of the source file under _sources.

The special files are located in the root output directory. They are:

SerializingHTMLBuilder.globalcontext_filename

A pickled dict with these keys:

project, copyright, release, version

The same values as given in the configuration file.

style

html_style.

last_updated

Date of last build.

builder

Name of the used builder, in the case of pickles this is always 'pickle'.

titles

A dictionary of all documents’ titles, as HTML strings.

SerializingHTMLBuilder.searchindex_filename
An index that can be used for searching the documentation. It is a pickled list with these entries:

- A list of indexed docnames.

- A list of document titles, as HTML strings, in the same order as the first list.

- A dict mapping word roots (processed by an English-language stemmer) to a list of integers, which are indices into the first list.

environment.pickle
The build environment. This is always a pickle file, independent of the builder and a copy of the environment that was used when the builder was started.

Todo

Document common members.

Unlike the other pickle files this pickle file requires that the sphinx package is available on unpickling.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

The build configuration file

The configuration directory must contain a file named conf.py. This file (containing Python code) is called the “build configuration file” and contains all configuration needed to customize Sphinx input and output behavior.

The configuration file is executed as Python code at build time (using execfile(), and with the current directory set to its containing directory), and therefore can execute arbitrarily complex code. Sphinx then reads simple names from the file’s namespace as its configuration.

Important points to note:

- If not otherwise documented, values must be strings, and their default is the empty string.

- The term “fully-qualified name” refers to a string that names an importable Python object inside a module; for example, the FQN "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.

- Since conf.py is read as a Python file, the usual rules apply for encodings and Unicode support: declare the encoding using an encoding cookie (a comment like # -*- coding: utf-8 -*-) and use Unicode string literals when you include non-ASCII characters in configuration values.

- The contents of the config namespace are pickled (so that Sphinx can find out when configuration changes), so it may not contain unpickleable values – 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 Including content based on tags). Use tags.has('tag') to query, tags.add('tag') and tags.remove('tag') to change. Only tags set via the -t command-line option or via tags.add('tag') can be queried using tags.has('tag'). Note that the current builder tag is not available in conf.py, as it is created after the builder is initialized.

General configuration

extensions

A list of strings that are module names of Sphinx extensions. These can be extensions coming with Sphinx (named sphinx.ext.*) or custom ones.

Note that you can extend sys.path within the conf file if your extensions live in another directory – but make sure you use absolute paths. If your extension path is relative to the configuration directory, use os.path.abspath() like so:

import sys, os

sys.path.append(os.path.abspath('sphinxext'))

extensions = ['extname']

That way, you can load an extension called extname from the subdirectory sphinxext.

The configuration file itself can be an extension; for that, you only need to provide a setup() function in it.

source_suffix

The file name extension, or list of extensions, of source files. Only files with this suffix will be read as sources. Default is '.rst'.

Changed in version 1.3: Can now be a list of extensions.

source_encoding

The encoding of all reST source files. The recommended encoding, and the default value, is 'utf-8-sig'.

New in version 0.5: Previously, Sphinx accepted only UTF-8 encoded sources.

source_parsers

If given, a dictionary of parser classes for different source suffices. The keys are the suffix, the values can be either a class or a string giving a fully-qualified name of a parser class. The parser class can be either docutils.parsers.Parser or sphinx.parsers.Parser. Files with a suffix that is not in the dictionary will be parsed with the default reStructuredText parser.

For example:

source_parsers = {'.md': 'some.markdown.module.Parser'}

New in version 1.3.

master_doc

The document name of the “master” document, that is, the document that contains the root toctree directive. Default is 'contents'.

exclude_patterns

A list of glob-style patterns that should be excluded when looking for source files. [1] They are matched against the source file names relative to the source directory, using slashes as directory separators on all platforms.

Example patterns:

- 'library/xml.rst' – ignores the library/xml.rst file (replaces entry in unused_docs)

- 'library/xml' – ignores the library/xml directory (replaces entry in exclude_trees)

- 'library/xml*' – ignores all files and directories starting with library/xml

- '**/.svn' – ignores all .svn directories (replaces entry in exclude_dirnames)

exclude_patterns is also consulted when looking for static files in html_static_path and html_extra_path.

New in version 1.0.

templates_path

A list of paths that contain extra templates (or templates that overwrite builtin/theme-specific templates). Relative paths are taken as relative to the configuration directory.

Changed in version 1.3: As these files are not meant to be built, they are automatically added to exclude_patterns.

template_bridge

A string with the fully-qualified name of a callable (or simply a class) that returns an instance of TemplateBridge. This instance is then used to render HTML documents, and possibly the output of other builders (currently the changes builder). (Note that the template bridge must be made theme-aware if HTML themes are to be used.)

rst_epilog

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

New in version 0.6.

rst_prolog

A string of reStructuredText that will be included at the beginning of every source file that is read.

New in version 1.0.

primary_domain

The name of the default domain. Can also be None to disable a default domain. The default is 'py'. Those objects in other domains (whether the domain name is given explicitly, or selected by a default-domain directive) will have the domain name explicitly prepended when named (e.g., when the default domain is C, Python functions will be named “Python function”, not just “function”).

New in version 1.0.

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 'py:obj' to make `filter` a cross-reference to the Python function “filter”. The default is None, which doesn’t reassign the default role.

The default role can always be set within individual documents using the standard reST default-role directive.

New in version 0.4.

keep_warnings

If true, keep warnings as “system message” paragraphs in the built documents. Regardless of this setting, warnings are always written to the standard error stream when sphinx-build is run.

The default is False, the pre-0.5 behavior was to always keep them.

New in version 0.5.

suppress_warnings

A list of warning types to suppress arbitrary warning messages.

Sphinx supports following warning types:

- app.add_node

- app.add_directive

- app.add_role

- app.add_generic_role

- app.add_source_parser

- image.data_uri

- image.nonlocal_uri

- ref.term

- ref.ref

- ref.numref

- ref.keyword

- ref.option

- ref.citation

- ref.doc

You can choose from these types.

Now, this option should be considered experimental.

New in version 1.4.

needs_sphinx

If set to a major.minor version string like '1.1', Sphinx will compare it with its version and refuse to build if it is too old. Default is no requirement.

New in version 1.0.

Changed in version 1.4: also accepts micro version string

needs_extensions

This value can be a dictionary specifying version requirements for extensions in extensions, e.g. needs_extensions = {'sphinxcontrib.something': '1.5'}. The version strings should be in the form major.minor. Requirements do not have to be specified for all extensions, only for those you want to check.

This requires that the extension specifies its version to Sphinx (see Developing extensions for Sphinx for how to do that).

New in version 1.3.

nitpicky

If true, Sphinx will warn about all references where the target cannot be found. Default is False. You can activate this mode temporarily using the -n command-line switch.

New in version 1.0.

nitpick_ignore

A list of (type, target) tuples (by default empty) that should be ignored when generating warnings in “nitpicky mode”. Note that type should include the domain name if present. Example entries would be ('py:func', 'int') or ('envvar', 'LD_LIBRARY_PATH').

New in version 1.1.

numfig

If true, figures, tables and code-blocks are automatically numbered if they have a caption. For now, it works only with the HTML builder. Default is False.

New in version 1.3.

numfig_format

A dictionary mapping 'figure', 'table' and 'code-block' to strings that are used for format of figure numbers. Default is to use 'Fig. %s' for 'figure', 'Table %s' for 'table' and 'Listing %s' for 'code-block'.

New in version 1.3.

numfig_secnum_depth

The scope of figure numbers, that is, the numfig feature numbers figures in which scope. 0 means “whole document”. 1 means “in a section”. Sphinx numbers like x.1, x.2, x.3... 2 means “in a subsection”. Sphinx numbers like x.x.1, x.x.2, x.x.3..., and so on. Default is 1.

New in version 1.3.

Project information

project

The documented project’s name.

copyright

A copyright statement in the style '2008, Author Name'.

version

The major project version, used as the replacement for |version|. For example, for the Python documentation, this may be something like 2.6.

release

The full project version, used as the replacement for |release| and e.g. in the HTML templates. For example, for the Python documentation, this may be something like 2.6.0rc1.

If you don’t need the separation provided between version and release, just set them both to the same value.

today

today_fmt

These values determine how to format the current date, used as the replacement for |today|.

- If you set today to a non-empty value, it is used.

- Otherwise, the current time is formatted using time.strftime() and the format given in today_fmt.

The default is no today and a today_fmt of '%B %d, %Y' (or, if translation is enabled with language, an equivalent format for the selected locale).

Changed in version 1.4: Format specification was changed from strftime to Locale Data Markup Language. strftime format is also supported for backward compatibility until Sphinx-1.5.

Changed in version 1.4.1: Format specification was changed again from Locale Data Markup Language to strftime. LDML format is also supported for backward compatibility until Sphinx-1.5.

highlight_language

The default language to highlight source code in. The default is 'python3'. The value should be a valid Pygments lexer name, see Showing code examples for more details.

New in version 0.5.

Changed in version 1.4: The default is now 'default'. It is similar to 'python3'; it is mostly a superset of 'python'. but it fallbacks to 'none' without warning if failed. 'python3' and other languages will emit warning if failed. If you prefer Python 2 only highlighting, you can set it back to 'python'.

highlight_options

A dictionary of options that modify how the lexer specified by highlight_language generates highlighted source code. These are lexer-specific; for the options understood by each, see the Pygments documentation [http://pygments.org/docs/lexers/].

New in version 1.3.

pygments_style

The style name to use for Pygments highlighting of source code. If not set, either the theme’s default style or 'sphinx' is selected for HTML output.

Changed in version 0.3: If the value is a fully-qualified name of a custom Pygments style class, this is then used as custom style.

add_function_parentheses

A boolean that decides whether parentheses are appended to function and method role text (e.g. the content of :func:`input`) to signify that the name is callable. Default is True.

add_module_names

A boolean that decides whether module names are prepended to all object names (for object types where a “module” of some kind is defined), e.g. for py:function directives. Default is True.

show_authors

A boolean that decides whether codeauthor and sectionauthor directives produce any output in the built files.

modindex_common_prefix

A list of prefixes that are ignored for sorting the Python 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 [].

New in version 0.6.

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.

New in version 0.6.

trim_doctest_flags

If true, doctest flags (comments looking like # doctest: FLAG, ...) at the ends of lines and <BLANKLINE> markers are removed for all code blocks showing interactive Python sessions (i.e. doctests). Default is True. See the extension doctest for more possibilities of including doctests.

New in version 1.0.

Changed in version 1.1: Now also removes <BLANKLINE>.

Options for internationalization

These options influence Sphinx’s Native Language Support. See the documentation on Internationalization for details.

language

The code for the language the docs are written in. Any text automatically generated by Sphinx will be in that language. Also, Sphinx will try to substitute individual paragraphs from your documents with the translation sets obtained from locale_dirs. Sphinx will search language-specific figures named by figure_language_filename and substitute them for original figures. In the LaTeX builder, a suitable language will be selected as an option for the Babel package. Default is None, which means that no translation will be done.

New in version 0.5.

Changed in version 1.4: Support figure substitution

Currently supported languages by Sphinx are:

- bn – Bengali

- ca – Catalan

- cs – Czech

- da – Danish

- de – German

- en – English

- es – Spanish

- et – Estonian

- eu – Basque

- fa – Iranian

- fi – Finnish

- fr – French

- he – Hebrew

- hr – Croatian

- hu – Hungarian

- id – Indonesian

- it – Italian

- ja – Japanese

- ko – Korean

- lt – Lithuanian

- lv – Latvian

- mk – Macedonian

- nb_NO – Norwegian Bokmal

- ne – Nepali

- nl – Dutch

- pl – Polish

- pt_BR – Brazilian Portuguese

- pt_PT – European Portuguese

- ru – Russian

- si – Sinhala

- sk – Slovak

- sl – Slovenian

- sv – Swedish

- tr – Turkish

- uk_UA – Ukrainian

- vi – Vietnamese

- zh_CN – Simplified Chinese

- zh_TW – Traditional Chinese

locale_dirs

New in version 0.5.

Directories in which to search for additional message catalogs (see language), relative to the source directory. The directories on this path are searched by the standard gettext module.

Internal messages are fetched from a text domain of sphinx; so if you add the directory ./locale to this setting, the message catalogs (compiled from .po format using msgfmt) must be in ./locale/language/LC_MESSAGES/sphinx.mo. The text domain of individual documents depends on gettext_compact.

The default is [].

gettext_compact

New in version 1.1.

If true, a document’s text domain is its docname if it is a top-level project file and its very base directory otherwise.

By default, the document markup/code.rst ends up in the markup text domain. With this option set to False, it is markup/code.

gettext_uuid

If true, Sphinx generates uuid information for version tracking in message catalogs. It is used for:

- Add uid line for each msgids in .pot files.

- Calculate similarity between new msgids and previously saved old msgids. This calculation takes a long time.

If you want to accelerate the calculation, you can use python-levenshtein 3rd-party package written in C by using pip install python-levenshtein.

The default is False.

New in version 1.3.

gettext_location

If true, Sphinx generates location information for messages in message catalogs.

The default is True.

New in version 1.3.

gettext_auto_build

If true, Sphinx builds mo file for each translation catalog files.

The default is True.

New in version 1.3.

gettext_additional_targets

To specify names to enable gettext extracting and translation applying for i18n additionally. You can specify below names:

For example: gettext_additional_targets = ['literal-block', 'image'].

The default is [].

New in version 1.3.

figure_language_filename

The filename format for language-specific figures. The default value is {root}.{language}{ext}. It will be expanded to dirname/filename.en.png from .. image:: dirname/filename.png.

New in version 1.4.

Options for HTML output

These options influence HTML as well as HTML Help output, and other builders that use Sphinx’s HTMLWriter class.

html_theme

The “theme” that the HTML output should use. See the section about theming. The default is 'alabaster'.

New in version 0.6.

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 this section.

New in version 0.6.

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.

New in version 0.6.

html_style

The style sheet to use for HTML pages. A file of that name must exist either in Sphinx’s static/ path, or in one of the custom paths given in 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.

html_title

The “title” for HTML documentation generated with Sphinx’s own templates. This is appended to the <title> tag of individual pages, and used in the navigation bar as the “topmost” element. It defaults to '<project> v<revision> documentation'.

html_short_title

A shorter “title” for the HTML docs. This is used in for links in the header and in the HTML Help docs. If not given, it defaults to the value of html_title.

New in version 0.4.

html_context

A dictionary of values to pass into the template engine’s context for all pages. Single values can also be put in this dictionary using the -A command-line option of sphinx-build.

New in version 0.5.

html_logo

If given, this must be the name of an image file (path relative to the configuration directory) that is the logo of the docs. It is placed at the top of the sidebar; its width should therefore not exceed 200 pixels. Default: None.

New in version 0.4.1: The image file will be copied to the _static directory of the output HTML, but only if the file does not already exist there.

html_favicon

If given, this must be the name of an image file (path relative to the configuration directory) that is the favicon of the docs. Modern browsers use this as the icon for tabs, windows and bookmarks. It should be a Windows-style icon file (.ico), which is 16x16 or 32x32 pixels large. Default: None.

New in version 0.4: The image file will be copied to the _static directory of the output HTML, but only if the file does not already exist there.

html_static_path

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’s _static directory after the theme’s static files, so a file named default.css will overwrite the theme’s default.css.

Changed in version 0.4: The paths in html_static_path can now contain subdirectories.

Changed in version 1.0: The entries in html_static_path can now be single files.

html_extra_path

A list of paths that contain extra files not directly related to the documentation, such as robots.txt or .htaccess. Relative paths are taken as relative to the configuration directory. They are copied to the output directory. They will overwrite any existing file of the same name.

As these files are not meant to be built, they are automatically added to exclude_patterns.

New in version 1.2.

Changed in version 1.4: The dotfiles in the extra directory will be copied to the output directory. And it refers exclude_patterns on copying extra files and directories, and ignores if path matches to patterns.

html_last_updated_fmt

If this is not None, a ‘Last updated on:’ timestamp is inserted at every page bottom, using the given strftime() format. The empty string is equivalent to '%b %d, %Y' (or a locale-dependent equivalent).

Changed in version 1.4: Format specification was changed from strftime to Locale Data Markup Language. strftime format is also supported for backward compatibility until Sphinx-1.5.

Changed in version 1.4.1: Format specification was changed again from Locale Data Markup Language to strftime. LDML format is also supported for backward compatibility until Sphinx-1.5.

html_use_smartypants

If true, SmartyPants [http://daringfireball.net/projects/smartypants/] will be used to convert quotes and dashes to typographically correct entities. Default: True.

html_add_permalinks

Sphinx will add “permalinks” for each heading and description environment as paragraph signs that become visible when the mouse hovers over them.

This value determines the text for the permalink; it defaults to "¶". Set it to None or the empty string to disable permalinks.

New in version 0.6: Previously, this was always activated.

Changed in version 1.1: This can now be a string to select the actual text of the link. Previously, only boolean values were accepted.

html_sidebars

Custom sidebar templates, must be a dictionary that maps document names to template names.

The keys can contain glob-style patterns [1], in which case all matching documents will get the specified sidebars. (A warning is emitted when a more than one glob-style pattern matches for any document.)

The values can be either lists or single strings.

- If a value is a list, it specifies the complete list of sidebar templates to include. If all or some of the default sidebars are to be included, they must be put into this list as well.

The default sidebars (for documents that don’t match any pattern) are: ['localtoc.html', 'relations.html', 'sourcelink.html', 'searchbox.html'].

- If a value is a single string, it specifies a custom sidebar to be added between the 'sourcelink.html' and 'searchbox.html' entries. This is for compatibility with Sphinx versions before 1.0.

Builtin sidebar templates that can be rendered are:

- localtoc.html – a fine-grained table of contents of the current document

- globaltoc.html – a coarse-grained table of contents for the whole documentation set, collapsed

- relations.html – two links to the previous and next documents

- sourcelink.html – a link to the source of the current document, if enabled in html_show_sourcelink

- searchbox.html – the “quick search” box

Example:

html_sidebars = {
'**': ['globaltoc.html', 'sourcelink.html', 'searchbox.html'],
'using/windows': ['windowssidebar.html', 'searchbox.html'],
}

This will render the custom template windowssidebar.html and the quick search box within the sidebar of the given document, and render the default sidebars for all other pages (except that the local TOC is replaced by the global TOC).

New in version 1.0: The ability to use globbing keys and to specify multiple sidebars.

Note that this value only has no effect if the chosen theme does not possess a sidebar, like the builtin scrolls and haiku themes.

html_additional_pages

Additional templates that should be rendered to HTML pages, must be a dictionary that maps document names to template names.

Example:

html_additional_pages = {
'download': 'customdownload.html',
}

This will render the template customdownload.html as the page download.html.

html_domain_indices

If true, generate domain-specific indices in addition to the general index. For e.g. the Python domain, this is the global module index. Default is True.

This value can be a bool or a list of index names that should be generated. To find out the index name for a specific index, look at the HTML file name. For example, the Python module index has the name 'py-modindex'.

New in version 1.0.

html_use_modindex

If true, add a module index to the HTML documents. Default is True.

Deprecated since version 1.0: Use html_domain_indices.

html_use_index

If true, add an index to the HTML documents. Default is True.

New in version 0.4.

html_split_index

If true, the index is generated twice: once as a single page with all the entries, and once as one page per starting letter. Default is False.

New in version 0.4.

html_copy_source

If true, the reST sources are included in the HTML build as _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.

html_show_sourcelink

If true (and html_copy_source is true as well), links to the reST sources will be added to the sidebar. The default is True.

New in version 0.6.

html_use_opensearch

If nonempty, an OpenSearch [http://www.opensearch.org/Home] description file will be output, and all pages will contain a <link> tag referring to it. Since OpenSearch doesn’t support relative URLs for its search page location, the value of this option must be the base URL from which these documents are served (without trailing slash), e.g. "https://docs.python.org". The default is ''.

html_file_suffix

This is the file name suffix for generated HTML files. The default is ".html".

New in version 0.4.

html_link_suffix

Suffix for generated links to HTML files. The default is whatever html_file_suffix is set to; it can be set differently (e.g. to support different web server setups).

New in version 0.6.

html_translator_class

A string with the fully-qualified name of a HTML Translator class, that is, a subclass of Sphinx’s HTMLTranslator, that is used to translate document trees to HTML. Default is None (use the builtin translator).

See also

set_translator()

html_show_copyright

If true, “(C) Copyright ...” is shown in the HTML footer. Default is True.

New in version 1.0.

html_show_sphinx

If true, “Created using Sphinx” is shown in the HTML footer. Default is True.

New in version 0.4.

html_output_encoding

Encoding of HTML output files. Default is 'utf-8'. Note that this encoding name must both be a valid Python encoding name and a valid HTML charset value.

New in version 1.0.

html_compact_lists

If true, list items containing only a single paragraph will not be rendered with a <p> element. This is standard docutils behavior. Default: True.

New in version 1.0.

html_secnumber_suffix

Suffix for section numbers. Default: ". ". Set to " " to suppress the final dot on section numbers.

New in version 1.0.

html_search_language

Language to be used for generating the HTML full-text search index. This defaults to the global language selected with language. If there is no support for this language, "en" is used which selects the English language.

Support is present for these languages:

- da – Danish

- nl – Dutch

- en – English

- fi – Finnish

- fr – French

- de – German

- hu – Hungarian

- it – Italian

- ja – Japanese

- no – Norwegian

- pt – Portuguese

- ro – Romanian

- ru – Russian

- es – Spanish

- sv – Swedish

- tr – Turkish

- zh – Chinese

Accelerating build speed

Each language (except Japanese) provides its own stemming algorithm. Sphinx uses a Python implementation by default. You can use a C implementation to accelerate building the index file.

- PorterStemmer [https://pypi.python.org/pypi/PorterStemmer] (en)

- PyStemmer [https://pypi.python.org/pypi/PyStemmer] (all languages)

New in version 1.1: With support for en and ja.

Changed in version 1.3: Added additional languages.

html_search_options

A dictionary with options for the search language support, empty by default. The meaning of these options depends on the language selected.

The English support has no options.

The Japanese support has these options:

Other option values depend on splitter value which you choose.

Options for 'mecab':

For example:

html_search_options = {
'type': 'mecab',
'dic_enc': 'utf-8',
'dict': '/path/to/mecab.dic',
'lib': '/path/to/libmecab.so',
}

Options for 'janome':

New in version 1.1.

Changed in version 1.4: html_search_options for Japanese is re-organized and any custom splitter can be used by type settings.

The Chinese support has these options:

- dict – the jieba dictionary path if want to use custom dictionary.

html_search_scorer

The name of a JavaScript file (relative to the configuration directory) that implements a search results scorer. If empty, the default will be used.

New in version 1.2.

html_scaled_image_link

If true, images itself links to the original image if it doesn’t have ‘target’ option or scale related options: ‘scale’, ‘width’, ‘height’. The default is True.

New in version 1.3.

htmlhelp_basename

Output file base name for HTML help builder. Default is 'pydoc'.

Options for Apple Help output

New in version 1.3.

These options influence the Apple Help output. This builder derives from the HTML builder, so the HTML options also apply where appropriate.

Note

Apple Help output will only work on Mac OS X 10.6 and higher, as it requires the hiutil and codesign command line tools, neither of which are Open Source.

You can disable the use of these tools using applehelp_disable_external_tools, but the result will not be a valid help book until the indexer is run over the .lproj folders within the bundle.

applehelp_bundle_name

The basename for the Apple Help Book. Defaults to the project name.

applehelp_bundle_id

The bundle ID for the help book bundle.

Warning

You must set this value in order to generate Apple Help.

applehelp_dev_region

The development region. Defaults to 'en-us', which is Apple’s recommended setting.

applehelp_bundle_version

The bundle version (as a string). Defaults to '1'.

applehelp_icon

The help bundle icon file, or None for no icon. According to Apple’s documentation, this should be a 16-by-16 pixel version of the application’s icon with a transparent background, saved as a PNG file.

applehelp_kb_product

The product tag for use with applehelp_kb_url. Defaults to '<project>-<release>'.

applehelp_kb_url

The URL for your knowledgebase server, e.g. https://example.com/kbsearch.py?p='product'&q='query'&l='lang'. Help Viewer will replace the values 'product', 'query' and 'lang' at runtime with the contents of applehelp_kb_product, the text entered by the user in the search box and the user’s system language respectively.

Defaults to None for no remote search.

applehelp_remote_url

The URL for remote content. You can place a copy of your Help Book’s Resources folder at this location and Help Viewer will attempt to use it to fetch updated content.

e.g. if you set it to https://example.com/help/Foo/ and Help Viewer wants a copy of index.html for an English speaking customer, it will look at https://example.com/help/Foo/en.lproj/index.html.

Defaults to None for no remote content.

applehelp_index_anchors

If True, tell the help indexer to index anchors in the generated HTML. This can be useful for jumping to a particular topic using the AHLookupAnchor function or the openHelpAnchor:inBook: method in your code. It also allows you to use help:anchor URLs; see the Apple documentation for more information on this topic.

applehelp_min_term_length

Controls the minimum term length for the help indexer. Defaults to None, which means the default will be used.

applehelp_stopwords

Either a language specification (to use the built-in stopwords), or the path to a stopwords plist, or None if you do not want to use stopwords. The default stopwords plist can be found at /usr/share/hiutil/Stopwords.plist and contains, at time of writing, stopwords for the following languages:

Defaults to language, or if that is not set, to en.

applehelp_locale

Specifies the locale to generate help for. This is used to determine the name of the .lproj folder inside the Help Book’s Resources, and is passed to the help indexer.

Defaults to language, or if that is not set, to en.

applehelp_title

Specifies the help book title. Defaults to '<project> Help'.

applehelp_codesign_identity

Specifies the identity to use for code signing, or None if code signing is not to be performed.

Defaults to the value of the environment variable CODE_SIGN_IDENTITY, which is set by Xcode for script build phases, or None if that variable is not set.

applehelp_codesign_flags

A list of additional arguments to pass to codesign when signing the help book.

Defaults to a list based on the value of the environment variable OTHER_CODE_SIGN_FLAGS, which is set by Xcode for script build phases, or the empty list if that variable is not set.

applehelp_indexer_path

The path to the hiutil program. Defaults to '/usr/bin/hiutil'.

applehelp_codesign_path

The path to the codesign program. Defaults to '/usr/bin/codesign'.

applehelp_disable_external_tools

If True, the builder will not run the indexer or the code signing tool, no matter what other settings are specified.

This is mainly useful for testing, or where you want to run the Sphinx build on a non-Mac OS X platform and then complete the final steps on OS X for some reason.

Defaults to False.

Options for epub output

These options influence the epub output. As this builder derives from the HTML builder, the HTML options also apply where appropriate. The actual values for some of the options is not really important, they just have to be entered into the Dublin Core metadata [http://dublincore.org/].

epub_basename

The basename for the epub file. It defaults to the project name.

epub_theme

The HTML theme for the epub output. Since the default themes are not optimized for small screen space, using the same theme for HTML and epub output is usually not wise. This defaults to 'epub', a theme designed to save visual space.

epub_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 this section.

New in version 1.2.

epub_title

The title of the document. It defaults to the html_title option but can be set independently for epub creation.

epub3_description

The description of the document. The default value is ''.

New in version 1.4.

epub_author

The author of the document. This is put in the Dublin Core metadata. The default value is 'unknown'.

epub3_contributor

The name of a person, organization, etc. that played a secondary role in the creation of the content of an EPUB Publication. The default value is 'unknown'.

New in version 1.4.

epub_language

The language of the document. This is put in the Dublin Core metadata. The default is the language option or 'en' if unset.

epub_publisher

The publisher of the document. This is put in the Dublin Core metadata. You may use any sensible string, e.g. the project homepage. The default value is 'unknown'.

epub_copyright

The copyright of the document. It defaults to the copyright option but can be set independently for epub creation.

epub_identifier

An identifier for the document. This is put in the Dublin Core metadata. For published documents this is the ISBN number, but you can also use an alternative scheme, e.g. the project homepage. The default value is 'unknown'.

epub_scheme

The publication scheme for the epub_identifier. This is put in the Dublin Core metadata. For published books the scheme is 'ISBN'. If you use the project homepage, 'URL' seems reasonable. The default value is 'unknown'.

epub_uid

A unique identifier for the document. This is put in the Dublin Core metadata. You may use a random string. The default value is 'unknown'.

epub_cover

The cover page information. This is a tuple containing the filenames of the cover image and the html template. The rendered html cover page is inserted as the first item in the spine in content.opf. If the template filename is empty, no html cover page is created. No cover at all is created if the tuple is empty. Examples:

epub_cover = ('_static/cover.png', 'epub-cover.html')
epub_cover = ('_static/cover.png', '')
epub_cover = ()

The default value is ().

New in version 1.1.

epub_guide

Meta data for the guide element of content.opf. This is a sequence of tuples containing the type, the uri and the title of the optional guide information. See the OPF documentation at http://idpf.org/epub for details. If possible, default entries for the cover and toc types are automatically inserted. However, the types can be explicitly overwritten if the default entries are not appropriate. Example:

epub_guide = (('cover', 'cover.html', u'Cover Page'),)

The default value is ().

epub_pre_files

Additional files that should be inserted before the text generated by Sphinx. It is a list of tuples containing the file name and the title. If the title is empty, no entry is added to toc.ncx. Example:

epub_pre_files = [
('index.html', 'Welcome'),
]

The default value is [].

epub_post_files

Additional files that should be inserted after the text generated by Sphinx. It is a list of tuples containing the file name and the title. This option can be used to add an appendix. If the title is empty, no entry is added to toc.ncx. The default value is [].

epub_exclude_files

A list of files that are generated/copied in the build directory but should not be included in the epub file. The default value is [].

epub_tocdepth

The depth of the table of contents in the file toc.ncx. It should be an integer greater than zero. The default value is 3. Note: A deeply nested table of contents may be difficult to navigate.

epub_tocdup

This flag determines if a toc entry is inserted again at the beginning of its nested toc listing. This allows easier navigation to the top of a chapter, but can be confusing because it mixes entries of different depth in one list. The default value is True.

epub_tocscope

This setting control the scope of the epub table of contents. The setting can have the following values:

- 'default' – include all toc entries that are not hidden (default)

- 'includehidden' – include all toc entries

New in version 1.2.

epub_fix_images

This flag determines if sphinx should try to fix image formats that are not supported by some epub readers. At the moment palette images with a small color table are upgraded. You need the Python Image Library (Pillow the successor of the PIL) installed to use this option. The default value is False because the automatic conversion may lose information.

New in version 1.2.

epub_max_image_width

This option specifies the maximum width of images. If it is set to a value greater than zero, images with a width larger than the given value are scaled accordingly. If it is zero, no scaling is performed. The default value is 0. You need the Python Image Library (Pillow) installed to use this option.

New in version 1.2.

epub_show_urls

Control whether to display URL addresses. This is very useful for readers that have no other means to display the linked URL. The settings can have the following values:

- 'inline' – display URLs inline in parentheses (default)

- 'footnote' – display URLs in footnotes

- 'no' – do not display URLs

The display of inline URLs can be customized by adding CSS rules for the class link-target.

New in version 1.2.

epub_use_index

If true, add an index to the epub document. It defaults to the html_use_index option but can be set independently for epub creation.

New in version 1.2.

epub3_page_progression_direction

The global direction in which the content flows. Allowed values are 'ltr' (left-to-right), 'rtl' (right-to-left) and 'default'. The default value is 'ltr'.

When the 'default' value is specified, the Author is expressing no preference and the Reading System may chose the rendering direction.

New in version 1.4.

Options for LaTeX output

These options influence LaTeX output.

latex_documents

This value determines how to group the document tree into LaTeX source files. It must be a list of tuples (startdocname, targetname, title, author, documentclass, toctree_only), where the items are:

- startdocname: document name that is the “root” of the LaTeX file. All documents referenced by it in TOC trees will be included in the LaTeX file too. (If you want only one LaTeX file, use your master_doc here.)

- targetname: file name of the LaTeX file in the output directory.

- title: LaTeX document title. Can be empty to use the title of the startdoc. This is inserted as LaTeX markup, so special characters like a backslash or ampersand must be represented by the proper LaTeX commands if they are to be inserted literally.

- author: Author for the LaTeX document. The same LaTeX markup caveat as for title applies. Use \and to separate multiple authors, as in: 'John \and Sarah'.

- documentclass: Normally, one of 'manual' or 'howto' (provided by Sphinx). Other document classes can be given, but they must include the “sphinx” package in order to define Sphinx’s custom LaTeX commands. “howto” documents will not get appendices. Also, howtos will have a simpler title page.

- toctree_only: Must be True or False. If true, the startdoc document itself is not included in the output, only the documents referenced by it via TOC trees. With this option, you can put extra stuff in the master document that shows up in the HTML, but not the LaTeX output.

New in version 1.2: In the past including your own document class required you to prepend the document class name with the string “sphinx”. This is not necessary anymore.

New in version 0.3: The 6th item toctree_only. Tuples with 5 items are still accepted.

latex_logo

If given, this must be the name of an image file (relative to the configuration directory) that is the logo of the docs. It is placed at the top of the title page. Default: None.

latex_toplevel_sectioning

This value determines the topmost sectioning unit. It should be chosen from part, chapter or section. The default is None; the topmost sectioning unit is switched by documentclass. section is used if documentclass will be howto, otherwise chapter will be used.

New in version 1.4.

latex_use_parts

If true, the topmost sectioning unit is parts, else it is chapters. Default: False.

New in version 0.3.

Deprecated since version 1.4: Use latex_toplevel_sectioning.

latex_appendices

A list of document names to append as an appendix to all manuals.

latex_domain_indices

If true, generate domain-specific indices in addition to the general index. For e.g. the Python domain, this is the global module index. Default is True.

This value can be a bool or a list of index names that should be generated, like for html_domain_indices.

New in version 1.0.

latex_use_modindex

If true, add a module index to LaTeX documents. Default is True.

Deprecated since version 1.0: Use latex_domain_indices.

latex_show_pagerefs

If true, add page references after internal references. This is very useful for printed copies of the manual. Default is False.

New in version 1.0.

latex_show_urls

Control whether to display URL addresses. This is very useful for printed copies of the manual. The setting can have the following values:

- 'no' – do not display URLs (default)

- 'footnote' – display URLs in footnotes

- 'inline' – display URLs inline in parentheses

New in version 1.0.

Changed in version 1.1: This value is now a string; previously it was a boolean value, and a true value selected the 'inline' display. For backwards compatibility, True is still accepted.

latex_elements

New in version 0.5.

A dictionary that contains LaTeX snippets that override those Sphinx usually puts into the generated .tex files.

Keep in mind that backslashes must be doubled in Python string literals to 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'.

'pointsize'

Point size option of the document class ('10pt', '11pt' or '12pt'), default '10pt'.

'babel'

“babel” package inclusion, default '\\usepackage{babel}'.

'fontpkg'

Font package inclusion, default '\\usepackage{times}' (which uses Times and Helvetica). You can set this to '' to use the Computer Modern fonts.

Changed in version 1.2: Defaults to '' when the language uses the Cyrillic script.

'fncychap'

Inclusion of the “fncychap” package (which makes fancy chapter titles), default '\\usepackage[Bjarne]{fncychap}' for English documentation, '\\usepackage[Sonny]{fncychap}' for internationalized docs (because the “Bjarne” style uses numbers spelled out in English). Other “fncychap” styles you can try include “Lenny”, “Glenn”, “Conny” and “Rejne”. You can also set this to '' to disable fncychap.

'passoptionstopackages'

“PassOptionsToPackage” call, default empty.

New in version 1.4.

'preamble'

Additional preamble content, default empty.

'figure_align'

Latex figure float alignment, default ‘htbp’ (here, top, bottom, page). Whenever an image doesn’t fit into the current page, it will be ‘floated’ into the next page but may be preceded by any other text. If you don’t like this behavior, use ‘H’ which will disable floating and position figures strictly in the order they appear in the source.

New in version 1.3.

'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}'.

'cmappkg'

“cmap” package inclusion, default '\\usepackage{cmap}'.

New in version 1.2.

'fontenc'

“fontenc” package inclusion, default '\\usepackage[T1]{fontenc}'.

'maketitle'

“maketitle” call, default '\\maketitle'. Override if you want to generate a differently-styled title page.

'releasename'

value that prefixes 'release' element on title page, default 'Release'.

'tableofcontents'

“tableofcontents” call, default '\\tableofcontents'. Override if you want to generate a different table of contents or put content between the title page and the TOC.

'transition'

Commands used to display transitions, default '\n\n\\bigskip\\hrule{}\\bigskip\n\n'. Override if you want to display transitions differently.

New in version 1.2.

'printindex'

“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' 'date' 'release' 'author' 'logo' 'makeindex' 'shorthandoff'

latex_docclass

A dictionary mapping 'howto' and 'manual' to names of real document classes that will be used as the base for the two Sphinx classes. Default is to use 'article' for 'howto' and 'report' for 'manual'.

New in version 1.0.

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.

New in version 0.6.

Changed in version 1.2: This overrides the files which is provided from Sphinx such as sphinx.sty.

latex_preamble

Additional LaTeX markup for the preamble.

Deprecated since version 0.5: Use the 'preamble' key in the latex_elements value.

latex_paper_size

The output paper size ('letter' or 'a4'). Default is 'letter'.

Deprecated since version 0.5: Use the 'papersize' key in the latex_elements value.

latex_font_size

The font size (‘10pt’, ‘11pt’ or ‘12pt’). Default is '10pt'.

Deprecated since version 0.5: Use the 'pointsize' key in the latex_elements value.

Options for text output

These options influence text output.

text_newlines

Determines which end-of-line character(s) are used in text output.

- 'unix': use Unix-style line endings (\n)

- 'windows': use Windows-style line endings (\r\n)

- 'native': use the line ending style of the platform the documentation is built on

Default: 'unix'.

New in version 1.1.

text_sectionchars

A string of 7 characters that should be used for underlining sections. The first character is used for first-level headings, the second for second-level headings and so on.

The default is '*=-~"+`'.

New in version 1.1.

Options for manual page output

These options influence manual page output.

man_pages

This value determines how to group the document tree into manual pages. It must be a list of tuples (startdocname, name, description, authors, section), where the items are:

- startdocname: document name that is the “root” of the manual page. All documents referenced by it in TOC trees will be included in the manual file too. (If you want one master manual page, use your master_doc here.)

- name: name of the manual page. This should be a short string without spaces or special characters. It is used to determine the file name as well as the name of the manual page (in the NAME section).

- description: description of the manual page. This is used in the NAME section.

- authors: A list of strings with authors, or a single string. Can be an empty string or list if you do not want to automatically generate an AUTHORS section in the manual page.

- section: The manual page section. Used for the output file name as well as in the manual page header.

New in version 1.0.

man_show_urls

If true, add URL addresses after links. Default is False.

New in version 1.1.

Options for Texinfo output

These options influence Texinfo output.

texinfo_documents

This value determines how to group the document tree into Texinfo source files. It must be a list of tuples (startdocname, targetname, title, author, dir_entry, description, category, toctree_only), where the items are:

- startdocname: document name that is the “root” of the Texinfo file. All documents referenced by it in TOC trees will be included in the Texinfo file too. (If you want only one Texinfo file, use your master_doc here.)

- targetname: file name (no extension) of the Texinfo file in the output directory.

- title: Texinfo document title. Can be empty to use the title of the startdoc. Inserted as Texinfo markup, so special characters like @ and {} will need to be escaped to be inserted literally.

- author: Author for the Texinfo document. Inserted as Texinfo markup. Use @* to separate multiple authors, as in: 'John@*Sarah'.

- dir_entry: The name that will appear in the top-level DIR menu file.

- description: Descriptive text to appear in the top-level DIR menu file.

- category: Specifies the section which this entry will appear in the top-level DIR menu file.

- toctree_only: Must be True or False. If true, the startdoc document itself is not included in the output, only the documents referenced by it via TOC trees. With this option, you can put extra stuff in the master document that shows up in the HTML, but not the Texinfo output.

New in version 1.1.

texinfo_appendices

A list of document names to append as an appendix to all manuals.

New in version 1.1.

texinfo_domain_indices

If true, generate domain-specific indices in addition to the general index. For e.g. the Python domain, this is the global module index. Default is True.

This value can be a bool or a list of index names that should be generated, like for html_domain_indices.

New in version 1.1.

texinfo_show_urls

Control how to display URL addresses.

- 'footnote' – display URLs in footnotes (default)

- 'no' – do not display URLs

- 'inline' – display URLs inline in parentheses

New in version 1.1.

texinfo_no_detailmenu

If true, do not generate a @detailmenu in the “Top” node’s menu containing entries for each sub-node in the document. Default is False.

New in version 1.2.

texinfo_elements

A dictionary that contains Texinfo snippets that override those Sphinx usually puts into the generated .texi files.

- Keys that you may want to override include:

'paragraphindent'

Number of spaces to indent the first line of each paragraph, default 2. Specify 0 for no indentation.

'exampleindent'

Number of spaces to indent the lines for examples or literal blocks, default 4. Specify 0 for no indentation.

'preamble'

Texinfo markup inserted near the beginning of the file.

'copying'

Texinfo markup inserted within the @copying block and displayed after the title. The default value consists of a simple title page identifying the project.

Keys that are set by other options and therefore should not be overridden are:

'author' 'body' 'date' 'direntry' 'filename' 'project' 'release' 'title'

New in version 1.1.

Options for the linkcheck builder

linkcheck_ignore

A list of regular expressions that match URIs that should not be checked when doing a linkcheck build. Example:

linkcheck_ignore = [r'http://localhost:\d+/']

New in version 1.1.

linkcheck_retries

The number of times the linkcheck builder will attempt to check a URL before declaring it broken. Defaults to 1 attempt.

New in version 1.4.

linkcheck_timeout

A timeout value, in seconds, for the linkcheck builder. Only works in Python 2.6 and higher. The default is to use Python’s global socket timeout.

New in version 1.1.

linkcheck_workers

The number of worker threads to use when checking links. Default is 5 threads.

New in version 1.1.

linkcheck_anchors

If true, check the validity of #anchors in links. Since this requires downloading the whole document, it’s considerably slower when enabled. Default is True.

New in version 1.2.

Options for the XML builder

xml_pretty

If true, pretty-print the XML. Default is True.

New in version 1.2.

Footnotes

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Internationalization

New in version 1.1.

Complementary to translations provided for Sphinx-generated messages such as navigation bars, Sphinx provides mechanisms facilitating document translations in itself. See the Options for internationalization for details on configuration.

Workflow visualization of translations in Sphinx. (The stick-figure is taken from an XKCD comic [http://xkcd.com/779/].)

- Sphinx internationalization details

- Translating with sphinx-intl

- Quick guide

- Translating

- Update your po files by new pot files

- Using Transifex service for team translation

- Contributing to Sphinx reference translation

Sphinx internationalization details

gettext [1] is an established standard for internationalization and localization. It naively maps messages in a program to a translated string. Sphinx uses these facilities to translate whole documents.

Initially project maintainers have to collect all translatable strings (also referred to as messages) to make them known to translators. Sphinx extracts these through invocation of sphinx-build -b gettext.

Every single element in the doctree will end up in a single message which results in lists being equally split into different chunks while large paragraphs will remain as coarsely-grained as they were in the original document. This grants seamless document updates while still providing a little bit of context for translators in free-text passages. It is the maintainer’s task to split up paragraphs which are too large as there is no sane automated way to do that.

After Sphinx successfully ran the MessageCatalogBuilder you will find a collection of .pot files in your output directory. These are catalog templates and contain messages in your original language only.

They can be delivered to translators which will transform them to .po files — so called message catalogs — containing a mapping from the original messages to foreign-language strings.

Gettext compiles them into a binary format known as binary catalogs through msgfmt for efficiency reasons. If you make these files discoverable with locale_dirs for your language, Sphinx will pick them up automatically.

An example: you have a document usage.rst in your Sphinx project. The gettext builder will put its messages into usage.pot. Imagine you have Spanish translations [2] on your hands in usage.po — for your builds to be translated you need to follow these instructions:

- Compile your message catalog to a locale directory, say locale, so it ends up in ./locale/es/LC_MESSAGES/usage.mo in your source directory (where es is the language code for Spanish.)

msgfmt "usage.po" -o "locale/es/LC_MESSAGES/usage.mo"

- Set locale_dirs to ["locale/"].

- Set language to es (also possible via -D).

- Run your desired build.

Translating with sphinx-intl

Quick guide

sphinx-intl [https://pypi.python.org/pypi/sphinx-intl] is a useful tool to work with Sphinx translation flow. This section describe a easy way to translate with sphinx-intl.

1. Install sphinx-intl [https://pypi.python.org/pypi/sphinx-intl] by pip install sphinx-intl or easy_install sphinx-intl.

2. Add configurations to your conf.py:

locale_dirs = ['locale/']   # path is example but recommended.
gettext_compact = False     # optional.

This case-study assumes that locale_dirs is set to ‘locale/’ and gettext_compact is set to False (the Sphinx document is already configured as such).

3. Extract document’s translatable messages into pot files:

$ make gettext

As a result, many pot files are generated under _build/locale directory.

4. Setup/Update your locale_dir:

$ sphinx-intl update -p _build/locale -l de -l ja

Done. You got these directories that contain po files:

- ./locale/de/LC_MESSAGES/

- ./locale/ja/LC_MESSAGES/

5. Translate your po files under ./locale/<lang>/LC_MESSAGES/.

6. make translated document.

You need a language parameter in conf.py or you may also specify the parameter on the command line:

$ make -e SPHINXOPTS="-D language='de'" html

Congratulations! You got the translated documentation in the _build/html directory.

New in version 1.3: sphinx-build that is invoked by make command will build po files into mo files.

If you are using 1.2.x or earlier, please invoke sphinx-intl build command before make command.

Translating

Translate po file under ./locale/de/LC_MESSAGES directory. The case of builders.po file for sphinx document:

# a5600c3d2e3d48fc8c261ea0284db79b
#: ../../builders.rst:4
msgid "Available builders"
msgstr "<FILL HERE BY TARGET LANGUAGE>"

Another case, msgid is multi-line text and contains reStructuredText syntax:

# 302558364e1d41c69b3277277e34b184
#: ../../builders.rst:9
msgid ""
"These are the built-in Sphinx builders. More builders can be added by "
":ref:`extensions <extensions>`."
msgstr ""
"FILL HERE BY TARGET LANGUAGE FILL HERE BY TARGET LANGUAGE FILL HERE "
"BY TARGET LANGUAGE :ref:`EXTENSIONS <extensions>` FILL HERE."

Please be careful not to break reST notation. Most po-editors will help you with that.

Update your po files by new pot files

If a document is updated, it is necessary to generate updated pot files and to apply differences to translated po files. In order to apply the updating difference of a pot file to po file, use the sphinx-intl update command.

$ sphinx-intl update -p _build/locale

Using Transifex service for team translation

Transifex [https://www.transifex.com/] is one of several services that allow collaborative translation via a web interface. It has a nifty Python-based command line client that makes it easy to fetch and push translations.

1. Install transifex-client [https://pypi.python.org/pypi/transifex-client]

You need tx command to upload resources (pot files).

$ pip install transifex-client

See also

Transifex Client v0.8 &mdash; Transifex documentation [http://docs.transifex.com/developer/client/]

2. Create your transifex [https://www.transifex.com/] account and create new project for your document

Currently, transifex does not allow for a translation project to have more than one version of the document, so you’d better include a version number in your project name.

For example:

3. Create config files for tx command

This process will create .tx/config in the current directory, as well as a ~/.transifexrc file that includes auth information.

$ tx init
Creating .tx folder...
Transifex instance [https://www.transifex.com]:
...
Please enter your transifex username: <transifex-username>
Password: <transifex-password>
...
Done.

4. Upload pot files to transifex service

Register pot files to .tx/config file:

$ cd /your/document/root
$ sphinx-intl update-txconfig-resources --pot-dir _build/locale \
--transifex-project-name sphinx-document-test_1_0

and upload pot files:

$ tx push -s
Pushing translations for resource sphinx-document-test_1_0.builders:
Pushing source file (locale/pot/builders.pot)
Resource does not exist.  Creating...
...
Done.

5. Forward the translation on transifex

6. Pull translated po files and make translated html

Get translated catalogs and build mo files (ex. for ‘de’):

$ cd /your/document/root
$ tx pull -l de
Pulling translations for resource sphinx-document-test_1_0.builders (...)
-> de: locale/de/LC_MESSAGES/builders.po
...
Done.

Invoke make html:

$ make -e SPHINXOPTS="-D language='de'" html

That’s all!

Tip

Translating locally and on Transifex

If you want to push all language’s po files, you can be done by using tx push -t command. Watch out! This operation overwrites translations in transifex.

In other words, if you have updated each in the service and local po files, it would take much time and effort to integrate them.

Contributing to Sphinx reference translation

The recommended way for new contributors to translate Sphinx reference is to join the translation team on Transifex.

There is sphinx translation page [https://www.transifex.com/sphinx-doc/sphinx-doc-1_3/] for Sphinx-1.3 documentation.

1. Login to transifex [https://www.transifex.com/] service.

2. Go to sphinx translation page [https://www.transifex.com/sphinx-doc/sphinx-doc-1_3/].

3. Click Request language and fill form.

4. Wait acceptance by transifex sphinx translation maintainers.

5. (after acceptance) translate on transifex.

Footnotes

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

HTML theming support

New in version 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 html_theme config value. With the 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 conf.py:

html_theme = "classic"
html_theme_options = {
"rightsidebar": "true",
"relbarbgcolor": "black"
}

That would give you the classic 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 static forms: either a directory (containing 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 html_theme_path. It gives a list of directories, relative to the directory containing conf.py, that can contain theme directories or zip files. For example, if you have a theme in the file blue.zip, you can put it right in the directory containing conf.py and use this configuration:

html_theme = "blue"
html_theme_path = ["."]

The third form provides your theme path dynamically to Sphinx if the setuptools package is installed. You can provide an entry point section called sphinx_themes in your setup.py file and write a get_path function that has to return the directory with themes in it:

# 'setup.py'

setup(
...
entry_points = {
'sphinx_themes': [
'path = your_package:get_path',
]
},
...
)

# 'your_package.py'

from os import path
package_dir = path.abspath(path.dirname(__file__))
template_path = path.join(package_dir, 'themes')

def get_path():
return template_path

New in version 1.2: ‘sphinx_themes’ entry_points feature.

Builtin themes

Sphinx comes with a selection of themes to choose from.

These themes are:

- basic – This is a basically unstyled layout used as the base for the other themes, and usable as the base for custom themes as well. The HTML contains all important elements like sidebar and relation bar. There are these options (which are inherited by the other themes):

- nosidebar (true or false): Don’t include the sidebar. Defaults to False.

- sidebarwidth (an integer): Width of the sidebar in pixels. (Do not include px in the value.) Defaults to 230 pixels.

- alabaster – Alabaster theme [https://pypi.python.org/pypi/alabaster] is a modified “Kr” Sphinx theme from @kennethreitz (especially as used in his Requests project), which was itself originally based on @mitsuhiko’s theme used for Flask & related projects. You can get options information at Alabaster theme [https://pypi.python.org/pypi/alabaster] page.

- sphinx_rtd_theme – Read the Docs Sphinx Theme [https://pypi.python.org/pypi/sphinx_rtd_theme]. This is a mobile-friendly sphinx theme that was made for readthedocs.org. View a working demo over on readthedocs.org. You can get options information at Read the Docs Sphinx Theme [https://pypi.python.org/pypi/sphinx_rtd_theme] page.

- classic – This is the classic theme, which looks like the Python 2 documentation [https://docs.python.org/2/]. 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.

- collapsiblesidebar (true or false): Add an experimental JavaScript snippet that makes the sidebar collapsible via a button on its side. Doesn’t work with “stickysidebar”. Defaults to False.

- externalrefs (true or false): Display external links differently from internal links. 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.

- sidebarbtncolor (CSS color): Background color for the sidebar collapse button (used when collapsiblesidebar is True).

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

- visitedlinkcolor (CSS color): Body color for visited links.

- 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 and sidebarwidth.

- scrolls – A more lightweight theme, based on the Jinja documentation [http://jinja.pocoo.org/]. The following color options are available:

- headerbordercolor

- subheadlinecolor

- linkcolor

- visitedlinkcolor

- admonitioncolor

- agogo – A theme created by Andi Albrecht. The following options are supported:

- bodyfont (CSS font family): Font for normal text.

- headerfont (CSS font family): Font for headings.

- pagewidth (CSS length): Width of the page content, default 70em.

- documentwidth (CSS length): Width of the document (without sidebar), default 50em.

- sidebarwidth (CSS length): Width of the sidebar, default 20em.

- bgcolor (CSS color): Background color.

- headerbg (CSS value for “background”): background for the header area, default a grayish gradient.

- footerbg (CSS value for “background”): background for the footer area, default a light gray gradient.

- linkcolor (CSS color): Body link color.

- headercolor1, headercolor2 (CSS color): colors for <h1> and <h2> headings.

- headerlinkcolor (CSS color): Color for the backreference link in headings.

- textalign (CSS text-align value): Text alignment for the body, default is justify.

- nature – A greenish theme. There are currently no options beyond nosidebar and sidebarwidth.

- pyramid – A theme from the Pyramid web framework project, designed by Blaise Laflamme. There are currently no options beyond nosidebar and sidebarwidth.

- haiku – A theme without sidebar inspired by the Haiku OS user guide [https://www.haiku-os.org/docs/userguide/en/contents.html]. The following options are supported:

- full_logo (true or false, default False): If this is true, the header will only show the html_logo. Use this for large logos. If this is false, the logo (if present) will be shown floating right, and the documentation title will be put in the header.

- textcolor, headingcolor, linkcolor, visitedlinkcolor, hoverlinkcolor (CSS colors): Colors for various body elements.

- traditional – A theme resembling the old Python documentation. There are currently no options beyond nosidebar and sidebarwidth.

- epub – A theme for the epub builder. This theme tries to save visual space which is a sparse resource on ebook readers. The following options are supported:

- relbar1 (true or false, default True): If this is true, the relbar1 block is inserted in the epub output, otherwise it is omitted.

- footer (true or false, default True): If this is true, the footer block is inserted in the epub output, otherwise it is omitted.

- bizstyle – A simple bluish theme. The following options are supported beyond nosidebar and sidebarwidth:

- rightsidebar (true or false): Put the sidebar on the right side. Defaults to False.

New in version 1.3: ‘alabaster’, ‘sphinx_rtd_theme’ and ‘bizstyle’ theme.

Changed in version 1.3: The ‘default’ theme has been renamed to ‘classic’. ‘default’ is still available, however it will emit notice a recommendation that using new ‘alabaster’ theme.

Creating themes

As said, themes are either a directory or a zipfile (whose name is the theme name), containing the following:

- A theme.conf file, see below.

- HTML templates, if needed.

- A static/ directory containing any static files that will be copied to the output static directory on build. These can be images, styles, script files.

The theme.conf file is in INI format [1] (readable by the standard Python ConfigParser module) and has the following structure:

[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 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 pygments_style config value.

- The options section contains pairs of variable names and default values. These options can be overridden by the user in html_theme_options and are accessible from all templates as theme_<name>.

Templating

The guide to 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 classic theme has a file static/classic.css_t which uses templating to put the color options into the stylesheet. When a documentation is built with the classic theme, the output directory will contain a _static/classic.css file where all template tags have been processed.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Templating

Sphinx uses the Jinja [http://jinja.pocoo.org] templating engine for its HTML templates. Jinja is a text-based engine, and inspired by Django templates, so anyone having used Django will already be familiar with it. It also has excellent documentation for those who need to make themselves familiar with it.

Do I need to use Sphinx’s templates to produce HTML?

No. You have several other options:

- You can write a TemplateBridge subclass that calls your template engine of choice, and set the template_bridge configuration value accordingly.

- You can write a custom builder that derives from StandaloneHTMLBuilder and calls your template engine of choice.

- You can use the PickleHTMLBuilder that produces pickle files with the page contents, and postprocess them using a custom tool, or use them in your Web application.

Jinja/Sphinx Templating Primer

The default templating language in Sphinx is Jinja. It’s Django/Smarty inspired and easy to understand. The most important concept in Jinja is template inheritance, which means that you can overwrite only specific blocks within a 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 structure the Sphinx quickstart generated for you.

Sphinx will look for templates in the folders of templates_path first, and if it can’t find the template it’s looking for there, it falls back 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’s basic theme provides base templates with a couple of blocks it will fill with data. These are located in the themes/basic subdirectory of the Sphinx installation directory, and used by all builtin Sphinx themes. Templates with the same name in the 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:

{% extends "!layout.html" %}
{% block rootrellink %}
<li><a href="http://project.invalid/">Project Homepage</a> &raquo;</li>
{{ super() }}
{% endblock %}

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 with 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.html template:

doctype

The doctype of the output format. By default this is XHTML 1.0 Transitional as this is the closest to what Sphinx and Docutils generate and it’s a good idea not to change it unless you want to switch to HTML 5 or a different but compatible XHTML doctype.

linktags

This block adds a couple of <link> tags to the head section of the template.

extrahead

This block is empty by default and can be used to add extra contents into the <head> tag of the generated HTML file. This is the right place to add references to JavaScript or extra CSS files.

relbar1 / relbar2

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 %}

rootrellink / relbaritems

Inside the relbar there are three sections: The rootrellink, the links from the documentation and the custom relbaritems. The rootrellink is a block that by default contains a list item pointing to the master document by default, the relbaritems is an empty block. If you override them to add extra links into the bar make sure that they are list items and end with the reldelim1.

document

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 and is empty by default, sidebar2 after the document and contains the default sidebar. If you want to swap the sidebar location override this and call the sidebar helper:

{% block sidebar1 %}{{ sidebar() }}{% endblock %}
{% block sidebar2 %}{% endblock %}

(The sidebar2 location for the sidebar is needed by the sphinxdoc.css stylesheet, for example.)

sidebarlogo

The logo location within the sidebar. Override this if you want to place some content at the top of the sidebar.

footer

The block for the footer div. If you want a custom footer or markup before or after it, override this one.

The following four blocks are only used for pages that do not have assigned a list of custom sidebars in the html_sidebars config value. Their use is deprecated in favor of separate sidebar templates, which can be included via html_sidebars.

sidebartoc

The table of contents within the sidebar.

Deprecated since version 1.0.

sidebarrel

The relation links (previous, next document) within the sidebar.

Deprecated since version 1.0.

sidebarsourcelink

The “Show source” link within the sidebar (normally only shown if this is enabled by html_show_sourcelink).

Deprecated since version 1.0.

sidebarsearch

The search box within the sidebar. Override this if you want to place some content at the bottom of the sidebar.

Deprecated since version 1.0.

Configuration Variables

Inside templates you can set a couple of variables used by the layout template using the {% set %} tag:

reldelim1

The delimiter for the items on the left side of the related bar. This defaults to ' &raquo;' Each item in the related bar ends with the value of this variable.

reldelim2

The delimiter for the items on the right side of the related bar. This defaults to ' |'. Each item except of the last one in the related bar ends with the value of this variable.

Overriding works like this:

{% extends "!layout.html" %}
{% set reldelim1 = ' &gt;' %}

script_files

Add additional script files here, like this:

{% set script_files = script_files + ["_static/myscript.js"] %}

css_files

Similar to script_files, for CSS files.

Helper Functions

Sphinx provides various Jinja functions as helpers in the template. You can use them to generate links or output multiply used elements.

pathto(document)

Return the path to a Sphinx document as a URL. Use this to refer to built documents.

pathto(file, 1)

Return the path to a file which is a filename relative to the root of the generated output. Use this to refer to static files.

hasdoc(document)

Check if a document with the name document exists.

sidebar()

Return the rendered sidebar.

relbar()

Return the rendered relation bar.

Global Variables

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.

builder

The name of the builder (e.g. html or htmlhelp).

copyright

The value of copyright.

docstitle

The title of the documentation (the value of html_title), except when the “single-file” builder is used, when it is set to None.

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.

favicon

The path to the HTML favicon in the static path, or ''.

file_suffix

The value of the builder’s out_suffix attribute, i.e. the file name extension that the output files will get. For a standard HTML builder, this is usually .html.

has_source

True if the reST document sources are copied (if html_copy_source is True).

language

The value of language.

last_updated

The build date.

logo

The path to the HTML logo image in the static path, or ''.

master_doc

The value of master_doc, for usage with pathto().

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 %}

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

parents

A list of parent documents for navigation, structured like the next item.

prev

Like next, but for the previous page.

project

The value of project.

release

The value of release.

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 general index and other indices, such as the Python module index. If you add something yourself, it must be a tuple (pagename, link title, accesskey, link text).

shorttitle

The value of html_short_title.

show_source

True if html_show_sourcelink is True.

sphinx_version

The version of Sphinx used to build.

style

The name of the main stylesheet, as given by the theme or html_style.

title

The title of the current document, as used in the <title> tag.

use_opensearch

The value of html_use_opensearch.

version

The value of 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 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:

meta

Document metadata (a dictionary), see File-wide metadata.

sourcename

The name of the copied source file for the current document. This is only nonempty if the html_copy_source value is True.

toc

The local table of contents for the current page, rendered as HTML bullet lists.

toctree

A callable yielding the global TOC tree containing the current page, rendered as HTML bullet lists. Optional keyword arguments:

- collapse (True by default): if true, all TOC entries that are not ancestors of the current page are collapsed

- maxdepth (defaults to the max depth selected in the toctree directive): the maximum depth of the tree; set it to -1 to allow unlimited depth

- titles_only (False by default): if true, put only toplevel document titles in the tree

- includehidden (False by default): if true, the TOC tree will also contain hidden entries.

page_source_suffix

The suffix of the file that was rendered. Since we support a list of source_suffix, this will allow you to properly link to the original source file.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Sphinx Extensions

Since many projects will need special features in their documentation, Sphinx allows to add “extensions” to the build process, each of which can modify almost any aspect of document processing.

This chapter describes the extensions bundled with Sphinx. For the API documentation on writing your own extension, see Developing extensions for Sphinx.

Builtin Sphinx extensions

These extensions are built in and can be activated by respective entries in the extensions configuration value:

- sphinx.ext.autodoc – Include documentation from docstrings

- Docstring preprocessing

- Skipping members

- sphinx.ext.autosectionlabel – Allow reference sections using its title

- sphinx.ext.autosummary – Generate autodoc summaries

- sphinx-autogen – generate autodoc stub pages

- Generating stub pages automatically

- Customizing templates

- sphinx.ext.coverage – Collect doc coverage stats

- sphinx.ext.doctest – Test snippets in the documentation

- Directives

- Configuration

- sphinx.ext.extlinks – Markup to shorten external links

- sphinx.ext.githubpages – Publish HTML docs in GitHub Pages

- sphinx.ext.graphviz – Add Graphviz graphs

- sphinx.ext.ifconfig – Include content based on configuration

- sphinx.ext.inheritance_diagram – Include inheritance diagrams

- sphinx.ext.intersphinx – Link to other projects’ documentation

- sphinx.ext.linkcode – Add external links to source code

- Math support in Sphinx

- sphinx.ext.imgmath – Render math as images

- sphinx.ext.mathjax – Render math via JavaScript

- sphinx.ext.jsmath – Render math via JavaScript

- sphinx.ext.napoleon – Support for NumPy and Google style docstrings

- Napoleon - Marching toward legible docstrings

- Getting Started

- Docstrings

- Docstring Sections

- Google vs NumPy

- Configuration

- sphinx.ext.todo – Support for todo items

- sphinx.ext.viewcode – Add links to highlighted source code

Third-party extensions

You can find several extensions contributed by users in the Sphinx Contrib [https://bitbucket.org/birkenfeld/sphinx-contrib] repository. It is open for anyone who wants to maintain an extension publicly; just send a short message asking for write permissions.

There are also several extensions hosted elsewhere. The Sphinx extension survey [http://sphinxext-survey.readthedocs.org/en/latest/] contains a comprehensive list.

If you write an extension that you think others will find useful or you think should be included as a part of Sphinx, please write to the project mailing list (join here [https://groups.google.com/forum/#!forum/sphinx-dev]).

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

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.autodoc – Include documentation from docstrings

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 sys.path – adapt your sys.path in the configuration file accordingly.

Warning

autodoc imports the modules to be documented. If any modules have side effects on import, these will be executed by autodoc when sphinx-build is run.

If you document scripts (as opposed to library modules), make sure their main routine is protected by a if __name__ == '__main__' condition.

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 hand-written documentation, this technique eases the pain of having to maintain two locations for documentation, while at the same time avoiding auto-generated-looking pure API documentation.

If you prefer NumPy [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt] or Google [https://google.github.io/styleguide/pyguide.html#Comments] style docstrings over reStructuredText, you can also enable the napoleon extension. napoleon is a preprocessor that converts your docstrings to correct reStructuredText before autodoc processes them.

autodoc provides several directives that are versions of the usual py:module, py:class and so forth. On parsing time, they import the corresponding module and extract the docstring of the given objects, inserting them into the page source under a suitable py:module, py:class etc. directive.

Note

Just as py:class respects the current py:module, autoclass will also do so. Likewise, automethod will respect the current py:class.

.. automodule::

.. autoclass::

.. autoexception::

Document a module, class or exception. All three directives will by default only insert the docstring of the object itself:

.. autoclass:: Noodle

will produce source like this:

.. class:: Noodle

Noodle's docstring.

The “auto” directives can also contain content of their own, it will be inserted into the resulting non-auto directive source after the docstring (but before any automatic member documentation).

Therefore, you can also mix automatic and non-automatic member documentation, like so:

.. autoclass:: Noodle
:members: eat, slurp

.. method:: boil(time=10)

Boil the noodle *time* minutes.

Options and advanced usage

- If you want to automatically document members, there’s a members option:

.. automodule:: noodle
:members:

will document all module members (recursively), and

.. autoclass:: Noodle
:members:

will document all non-private member functions and properties (that is, those whose name doesn’t start with _).

For modules, __all__ will be respected when looking for members; the order of the members will also be the order in __all__.

You can also give an explicit list of members; only these will then be documented:

.. autoclass:: Noodle
:members: eat, slurp

- If you want to make the members option (or other flag options described below) the default, see autodoc_default_flags.

- Members without docstrings will be left out, unless you give the undoc-members flag option:

.. automodule:: noodle
:members:
:undoc-members:

- “Private” members (that is, those named like _private or __private) will be included if the private-members flag option is given.

New in version 1.1.

- Python “special” members (that is, those named like __special__) will be included if the special-members flag option is given:

.. autoclass:: my.Class
:members:
:private-members:
:special-members:

would document both “private” and “special” members of the class.

New in version 1.1.

Changed in version 1.2: The option can now take arguments, i.e. the special members to document.

- For classes and exceptions, members inherited from base classes will be left out when documenting all members, unless you give the inherited-members flag option, in addition to members:

.. autoclass:: Noodle
:members:
:inherited-members:

This can be combined with undoc-members to document all available members of the class or module.

Note: this will lead to markup errors if the inherited members come from a module whose docstrings are not reST formatted.

New in version 0.3.

- It’s possible to override the signature for explicitly documented callable objects (functions, methods, classes) with the regular syntax that will override the signature gained from introspection:

.. autoclass:: Noodle(type)

.. automethod:: eat(persona)

This is useful if the signature from the method is hidden by a decorator.

New in version 0.4.

- The automodule, autoclass and 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 automodule, this will be inserted for every class that is documented in the module).

New in version 0.4.

- All autodoc directives support the noindex flag option that has the same effect as for standard py:function etc. directives: no index entries are generated for the documented object (and all autodocumented members).

New in version 0.4.

- automodule also recognizes the synopsis, platform and deprecated options that the standard py:module directive supports.

New in version 0.5.

- automodule and autoclass also has an member-order option that can be used to override the global value of autodoc_member_order for one directive.

New in version 0.6.

- The directives supporting member documentation also have a exclude-members option that can be used to exclude single member names from documentation, if all members are to be documented.

New in version 0.6.

- In an automodule directive with the members option set, only module members whose __module__ attribute is equal to the module name as given to automodule will be documented. This is to prevent documentation of imported classes or functions. Set the imported-members option if you want to prevent this behavior and document all available members. Note that attributes from imported modules will not be documented, because attribute documentation is discovered by parsing the source file of the current module.

New in version 1.2.

- Add a list of modules in the autodoc_mock_imports to prevent import errors to halt the building process when some external dependencies are not importable at build time.

New in version 1.3.

.. autofunction::

.. autodata::

.. automethod::

.. autoattribute::

These work exactly like autoclass etc., but do not offer the options used for automatic member documentation.

autodata and autoattribute support the annotation option. Without this option, the representation of the object will be shown in the documentation. When the option is given without arguments, only the name of the object will be printed:

.. autodata:: CD_DRIVE
:annotation:

You can tell sphinx what should be printed after the name:

.. autodata:: CD_DRIVE
:annotation: = your CD device name

For module data members and class attributes, documentation can either be put into a comment with special formatting (using a #: to start the comment instead of just #), or in a docstring after the definition. Comments need to be either on a line of their own before the definition, or immediately after the assignment on the same line. The latter form is restricted to one line only.

This means that in the following class definition, all attributes can be autodocumented:

class Foo:
"""Docstring for class Foo."""

#: Doc comment for class attribute Foo.bar.
#: It can have multiple lines.
bar = 1

flox = 1.5   #: Doc comment for Foo.flox. One line only.

baz = 2
"""Docstring for class attribute Foo.baz."""

def __init__(self):
#: Doc comment for instance attribute qux.
self.qux = 3

self.spam = 4
"""Docstring for instance attribute spam."""

Changed in version 0.6: autodata and autoattribute can now extract docstrings.

Changed in version 1.1: Comment docs are now allowed on the same line after an assignment.

Changed in version 1.2: autodata and autoattribute have an annotation option.

Note

If you document decorated functions or methods, keep in mind that autodoc retrieves its docstrings by importing the module and inspecting the __doc__ attribute of the given function or method. That means that if a decorator replaces the decorated function with another, it must copy the original __doc__ to the new function.

From Python 2.5, functools.wraps() can be used to create well-behaved decorating functions.

There are also new config values that you can set:

autoclass_content

This value selects what content will be inserted into the main body of an autoclass directive. The possible values are:

"class"

Only the class’ docstring is inserted. This is the default. You can still document __init__ as a separate method using automethod or the members option to autoclass.

"both"

Both the class’ and the __init__ method’s docstring are concatenated and inserted.

"init"

Only the __init__ method’s docstring is inserted.

New in version 0.3.

If the class has no __init__ method or if the __init__ method’s docstring is empty, but the class has a __new__ method’s docstring, it is used instead.

New in version 1.4.

autodoc_member_order

This value selects if automatically documented members are sorted alphabetical (value 'alphabetical'), by member type (value 'groupwise') or by source order (value 'bysource'). The default is alphabetical.

Note that for source order, the module must be a Python module with the source code available.

New in version 0.6.

Changed in version 1.0: Support for 'bysource'.

autodoc_default_flags

This value is a list of autodoc directive flags that should be automatically applied to all autodoc directives. The supported flags are 'members', 'undoc-members', 'private-members', 'special-members', 'inherited-members' and 'show-inheritance'.

If you set one of these flags in this config value, you can use a negated form, 'no-flag', in an autodoc directive, to disable it once. For example, if autodoc_default_flags is set to ['members', 'undoc-members'], and you write a directive like this:

.. automodule:: foo
:no-undoc-members:

the directive will be interpreted as if only :members: was given.

New in version 1.0.

autodoc_docstring_signature

Functions imported from C modules cannot be introspected, and therefore the signature for such functions cannot be automatically determined. However, it is an often-used convention to put the signature into the first line of the function’s docstring.

If this boolean value is set to True (which is the default), autodoc will look at the first line of the docstring for functions and methods, and if it looks like a signature, use the line as the signature and remove it from the docstring content.

New in version 1.1.

autodoc_mock_imports

This value contains a list of modules to be mocked up. This is useful when some external dependencies are not met at build time and break the building process.

New in version 1.3.

Docstring preprocessing

autodoc provides the following additional events:

autodoc-process-docstring(app, what, name, obj, options, lines)

New in version 0.4.

Emitted when autodoc has read and processed a docstring. lines is a list of strings – the lines of the processed docstring – that the event handler can modify in place to change what Sphinx puts into the output.

autodoc-process-signature(app, what, name, obj, options, signature, return_annotation)

New in version 0.5.

Emitted when autodoc has formatted a signature for an object. The event handler can return a new tuple (signature, return_annotation) to change what Sphinx puts into the output.

The sphinx.ext.autodoc module provides factory functions for commonly needed docstring processing in event autodoc-process-docstring:

sphinx.ext.autodoc.cut_lines(pre, post=0, what=None)[source]

Return a listener that removes the first pre and last post lines of every docstring. If what is a sequence of strings, only docstrings of a type in what will be processed.

Use like this (e.g. in the setup() function of conf.py):

from sphinx.ext.autodoc import cut_lines
app.connect('autodoc-process-docstring', cut_lines(4, what=['module']))

This can (and should) be used in place of automodule_skip_lines.

sphinx.ext.autodoc.between(marker, what=None, keepempty=False, exclude=False)[source]

Return a listener that either keeps, or if exclude is True excludes, lines between lines that match the marker regular expression. If no line matches, the resulting docstring would be empty, so no change will be made unless keepempty is true.

If what is a sequence of strings, only docstrings of a type in what will be processed.

Skipping members

autodoc allows the user to define a custom method for determining whether a member should be included in the documentation by using the following event:

autodoc-skip-member(app, what, name, obj, skip, options)

New in version 0.5.

Emitted when autodoc has to decide whether a member should be included in the documentation. The member is excluded if a handler returns True. It is included if the handler returns False.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.autosectionlabel – Allow reference sections using its title

New in version 1.4.

This extension allows you to refer sections its title. This affects to the reference role (ref).

For example:

A Plain Title
-------------

This is the text of the section.

It refers to the section title, see :ref:`A Plain Title`.

Internally, this extension generates the labels for each section. If same section names are used in whole of document, any one is used for a target.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.autosummary – Generate autodoc summaries

New in version 0.6.

This extension generates function/method/attribute summary lists, similar to those output e.g. by Epydoc and other API doc generation tools. This is especially useful when your docstrings are long and detailed, and putting each one of them on a separate page makes them easier to read.

The sphinx.ext.autosummary extension does this in two parts:

1. There is an autosummary directive for generating summary listings that contain links to the documented items, and short summary blurbs extracted from their docstrings.

2. Optionally, the convenience script sphinx-autogen or the new autosummary_generate config value can be used to generate short “stub” files for the entries listed in the autosummary directives. These files by default contain only the corresponding sphinx.ext.autodoc directive, but can be customized with templates.

.. autosummary::

Insert a table that contains links to documented items, and a short summary blurb (the first sentence of the docstring) for each of them.

The autosummary directive can also optionally serve as a toctree entry for the included items. Optionally, stub .rst files for these items can also be automatically generated.

For example,

.. currentmodule:: sphinx

.. autosummary::

environment.BuildEnvironment
util.relative_uri

produces a table like this:

Autosummary preprocesses the docstrings and signatures with the same autodoc-process-docstring and autodoc-process-signature hooks as autodoc.

Options

- If you want the autosummary table to also serve as a toctree entry, use the toctree option, for example:

.. autosummary::
:toctree: DIRNAME

sphinx.environment.BuildEnvironment
sphinx.util.relative_uri

The toctree option also signals to the sphinx-autogen script that stub pages should be generated for the entries listed in this directive. The option accepts a directory name as an argument; sphinx-autogen will by default place its output in this directory. If no argument is given, output is placed in the same directory as the file that contains the directive.

- If you don’t want the autosummary to show function signatures in the listing, include the nosignatures option:

.. autosummary::
:nosignatures:

sphinx.environment.BuildEnvironment
sphinx.util.relative_uri

- You can specify a custom template with the template option. For example,

.. autosummary::
:template: mytemplate.rst

sphinx.environment.BuildEnvironment

would use the template mytemplate.rst in your templates_path to generate the pages for all entries listed. See Customizing templates below.

New in version 1.0.

sphinx-autogen – generate autodoc stub pages

The sphinx-autogen script can be used to conveniently generate stub documentation pages for items included in autosummary listings.

For example, the command

$ sphinx-autogen -o generated *.rst

will read all autosummary tables in the *.rst files that have the :toctree: option set, and output corresponding stub pages in directory generated for all documented items. The generated pages by default contain text of the form:

sphinx.util.relative_uri
========================

.. autofunction:: sphinx.util.relative_uri

If the -o option is not given, the script will place the output files in the directories specified in the :toctree: options.

Generating stub pages automatically

If you do not want to create stub pages with sphinx-autogen, you can also use this new config value:

autosummary_generate

Boolean indicating whether to scan all found documents for autosummary directives, and to generate stub pages for each.

Can also be a list of documents for which stub pages should be generated.

The new files will be placed in the directories specified in the :toctree: options of the directives.

Customizing templates

New in version 1.0.

You can customize the stub page templates, in a similar way as the HTML Jinja templates, see Templating. (TemplateBridge is not supported.)

Note

If you find yourself spending much time tailoring the stub templates, this may indicate that it’s a better idea to write custom narrative documentation instead.

Autosummary uses the following template files:

- autosummary/base.rst – fallback template

- autosummary/module.rst – template for modules

- autosummary/class.rst – template for classes

- autosummary/function.rst – template for functions

- autosummary/attribute.rst – template for class attributes

- autosummary/method.rst – template for class methods

The following variables available in the templates:

name

Name of the documented object, excluding the module and class parts.

objname

Name of the documented object, excluding the module parts.

fullname

Full name of the documented object, including module and class parts.

module

Name of the module the documented object belongs to.

class

Name of the class the documented object belongs to. Only available for methods and attributes.

underline

A string containing len(full_name) * '='.

members

List containing names of all members of the module or class. Only available for modules and classes.

functions

List containing names of “public” functions in the module. Here, “public” here means that the name does not start with an underscore. Only available for modules.

classes

List containing names of “public” classes in the module. Only available for modules.

exceptions

List containing names of “public” exceptions in the module. Only available for modules.

methods

List containing names of “public” methods in the class. Only available for classes.

attributes

List containing names of “public” attributes in the class. Only available for classes.

Note

You can use the autosummary directive in the stub pages. Stub pages are generated also based on these directives.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.coverage – Collect doc coverage stats

This extension features one additional builder, the CoverageBuilder.

class sphinx.ext.coverage.CoverageBuilder[source]

To use this builder, activate the coverage extension in your configuration file and give -b coverage on the command line.

Todo

Write this section.

Several new configuration values can be used to specify what the builder should check:

coverage_ignore_modules

coverage_ignore_functions

coverage_ignore_classes

coverage_c_path

coverage_c_regexes

coverage_ignore_c_items

coverage_write_headline

Set to False to not write headlines.

New in version 1.1.

coverage_skip_undoc_in_source

Skip objects that are not documented in the source with a docstring. False by default.

New in version 1.1.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.doctest – Test snippets in the documentation

This extension allows you to test snippets in the documentation in a natural way. It works by collecting specially-marked up code blocks and running them as doctest tests.

Within one document, test code is partitioned in groups, where each group consists of:

- zero or more setup code blocks (e.g. importing the module to test)

- one or more test blocks

When building the docs with the doctest builder, groups are collected for each document and run one after the other, first executing setup code blocks, then the test blocks in the order they appear in the file.

There are two kinds of test blocks:

- doctest-style blocks mimic interactive sessions by interleaving Python code (including the interpreter prompt) and output.

- code-output-style blocks consist of an ordinary piece of Python code, and optionally, a piece of output for that code.

Directives

The group argument below is interpreted as follows: if it is empty, the block is assigned to the group named default. If it is *, the block is assigned to all groups (including the default group). Otherwise, it must be a comma-separated list of group names.

.. testsetup:: [group]

A setup code block. This code is not shown in the output for other builders, but executed before the doctests of the group(s) it belongs to.

.. testcleanup:: [group]

A cleanup code block. This code is not shown in the output for other builders, but executed after the doctests of the group(s) it belongs to.

New in version 1.1.

.. doctest:: [group]

A doctest-style code block. You can use standard doctest flags for controlling how actual output is compared with what you give as output. By default, these options are enabled: ELLIPSIS (allowing you to put ellipses in the expected output that match anything in the actual output), IGNORE_EXCEPTION_DETAIL (not comparing tracebacks), DONT_ACCEPT_TRUE_FOR_1 (by default, doctest accepts “True” in the output where “1” is given – this is a relic of pre-Python 2.2 times).

This directive supports two options:

- hide, a flag option, hides the doctest block in other builders. By default it is shown as a highlighted doctest block.

- options, a string option, can be used to give a comma-separated list of doctest flags that apply to each example in the tests. (You still can give explicit flags per example, with doctest comments, but they will show up in other builders too.)

Note that like with standard doctests, you have to use <BLANKLINE> to signal a blank line in the expected output. The <BLANKLINE> is removed when building presentation output (HTML, LaTeX etc.).

Also, you can give inline doctest options, like in doctest:

>>> datetime.date.now()   # doctest: +SKIP
datetime.date(2008, 1, 1)

They will be respected when the test is run, but stripped from presentation output.

.. testcode:: [group]

A code block for a code-output-style test.

This directive supports one option:

- hide, a flag option, hides the code block in other builders. By default it is shown as a highlighted code block.

Note

Code in a testcode block is always executed all at once, no matter how many statements it contains. Therefore, output will not be generated for bare expressions – use print. Example:

.. testcode::

1+1        # this will give no output!
print 2+2  # this will give output

.. testoutput::

4

Also, please be aware that since the doctest module does not support mixing regular output and an exception message in the same snippet, this applies to testcode/testoutput as well.

.. testoutput:: [group]

The corresponding output, or the exception message, for the last testcode block.

This directive supports two options:

- hide, a flag option, hides the output block in other builders. By default it is shown as a literal block without highlighting.

- options, a string option, can be used to give doctest flags (comma-separated) just like in normal doctest blocks.

Example:

.. testcode::

print 'Output     text.'

.. testoutput::
:hide:
:options: -ELLIPSIS, +NORMALIZE_WHITESPACE

Output text.

The following is an example for the usage of the directives. The test via doctest and the test via testcode and testoutput are equivalent.

The parrot module
=================

.. testsetup:: *

import parrot

The parrot module is a module about parrots.

Doctest example:

.. doctest::

>>> parrot.voom(3000)
This parrot wouldn't voom if you put 3000 volts through it!

Test-Output example:

.. testcode::

parrot.voom(3000)

This would output:

.. testoutput::

This parrot wouldn't voom if you put 3000 volts through it!

Configuration

The doctest extension uses the following configuration values:

doctest_path

A list of directories that will be added to sys.path when the doctest builder is used. (Make sure it contains absolute paths.)

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.

New in version 0.6.

doctest_global_cleanup

Python code that is treated like it were put in a testcleanup directive for every file that is tested, and for every group. You can use this to e.g. remove any temporary files that the tests leave behind.

New in version 1.1.

doctest_test_doctest_blocks

If this is a nonempty string (the default is 'default'), standard reST doctest blocks will be tested too. They will be assigned to the group name given.

reST doctest blocks are simply doctests put into a paragraph of their own, like so:

Some documentation text.

>>> print 1
1

Some more documentation text.

(Note that no special :: is used to introduce a doctest block; docutils recognizes them from the leading >>>. Also, no additional indentation is used, though it doesn’t hurt.)

If this value is left at its default value, the above snippet is interpreted by the doctest builder exactly like the following:

Some documentation text.

.. doctest::

>>> print 1
1

Some more documentation text.

This feature makes it easy for you to test doctests in docstrings included with the autodoc extension without marking them up with a special directive.

Note though that you can’t have blank lines in reST doctest blocks. They will be interpreted as one block ending and another one starting. Also, removal of <BLANKLINE> and # doctest: options only works in doctest blocks, though you may set trim_doctest_flags to achieve that in all code blocks with Python console content.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.extlinks – Markup to shorten external links

Module author: Georg Brandl

New in version 1.0.

This extension is meant to help with the common pattern of having many external links that point to URLs on one and the same site, e.g. links to bug trackers, version control web interfaces, or simply subpages in other websites. It does so by providing aliases to base URLs, so that you only need to give the subpage name when creating a link.

Let’s assume that you want to include many links to issues at the Sphinx tracker, at https://github.com/sphinx-doc/sphinx/issues/num. Typing this URL again and again is tedious, so you can use extlinks to avoid repeating yourself.

The extension adds one new config value:

extlinks

This config value must be a dictionary of external sites, mapping unique short alias names to a base URL and a prefix. For example, to create an alias for the above mentioned issues, you would add

extlinks = {'issue': ('https://github.com/sphinx-doc/sphinx/issues/%s',
'issue ')}

Now, you can use the alias name as a new role, e.g. :issue:`123`. This then inserts a link to https://github.com/sphinx-doc/sphinx/issues/123. As you can see, the target given in the role is substituted in the base URL in the place of %s.

The link caption depends on the second item in the tuple, the prefix:

- If the prefix is None, the link caption is the full URL.

- If the prefix is the empty string, the link caption is the partial URL given in the role content (123 in this case.)

- If the prefix is a non-empty string, the link caption is the partial URL, prepended by the prefix – in the above example, the link caption would be issue 123.

You can also use the usual “explicit title” syntax supported by other roles that generate links, i.e. :issue:`this issue <123>`. In this case, the prefix is not relevant.

Note

Since links are generated from the role in the reading stage, they appear as ordinary links to e.g. the linkcheck builder.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.githubpages – Publish HTML docs in GitHub Pages

New in version 1.4.

This extension creates .nojekyll file on generated HTML directory to publish the document on GitHub Pages.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.graphviz – Add Graphviz graphs

New in version 0.6.

This extension allows you to embed Graphviz [http://graphviz.org/] graphs in your documents.

It adds these directives:

.. 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 or SVG image (see graphviz_output_format). In LaTeX output, the code will be rendered to an embeddable PDF file.

You can also embed external dot files, by giving the file name as an argument to graphviz and no additional content:

.. graphviz:: external.dot

As for all file references in Sphinx, if the filename is absolute, it is taken as relative to the source directory.

Changed in version 1.1: Added support for external files.

.. 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";

Note

The graph name is passed unchanged to Graphviz. If it contains non-alphanumeric characters (e.g. a dash), you will have to double-quote it.

.. 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";

New in version 1.0: All three directives support an alt option that determines the image’s alternate text for HTML output. If not given, the alternate text defaults to the graphviz code.

New in version 1.1: All three directives support an inline flag that controls paragraph breaks in the output. When set, the graph is inserted into the current paragraph. If the flag is not given, paragraph breaks are introduced before and after the image (the default).

New in version 1.1: All three directives support a caption option that can be used to give a caption to the diagram. Naturally, diagrams marked as “inline” cannot have a caption.

Deprecated since version 1.4: inline option is deprecated. All three directives generate inline node by default. If caption is given, these generate block node instead.

Changed in version 1.4: All three directives support a graphviz_dot option that can be switch the dot command within the directive.

There are also these new config values:

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 sphinx-build command line via the -D option should be preferable, like this:

sphinx-build -b html -D graphviz_dot=C:\graphviz\bin\dot.exe . _build/html

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.

graphviz_output_format

The output format for Graphviz when building HTML files. This must be either 'png' or 'svg'; the default is 'png'. If 'svg' is used, in order to make the URL links work properly, an appropriate target attribute must be set, such as "_top" and "_blank". For example, the link in the following graph should work in the svg output:

.. graphviz::

digraph example {
a [label="sphinx", href="http://sphinx-doc.org", target="_top"];
b [label="other"];
a -> b;
}

New in version 1.0: Previously, output always was PNG.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.ifconfig – Include content based on configuration

This extension is quite simple, and features only one directive:

.. ifconfig::

Include content of the directive only if the Python expression given as an argument is True, evaluated in the namespace of the project’s configuration (that is, all registered variables from conf.py are available).

For example, one could write

.. ifconfig:: releaselevel in ('alpha', 'beta', 'rc')

This stuff is only included in the built docs for unstable versions.

To make a custom config value known to Sphinx, use add_config_value() in the setup function in conf.py, e.g.:

def setup(app):
app.add_config_value('releaselevel', '', 'env')

The second argument is the default value, the third should always be 'env' for such values (it selects if Sphinx re-reads the documents if the value changes).

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.inheritance_diagram – Include inheritance diagrams

New in version 0.6.

This extension allows you to include inheritance diagrams, rendered via the Graphviz extension.

It adds this 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 py: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.)

It also supports a private-bases flag option; if given, private base classes (those whose name starts with _) will be included.

Changed in version 1.1: Added private-bases option; previously, all bases were always included.

New config values are:

inheritance_graph_attrs

A dictionary of graphviz graph attributes for inheritance diagrams.

For example:

inheritance_graph_attrs = dict(rankdir="LR", size='"6.0, 8.0"',
fontsize=14, ratio='compress')

inheritance_node_attrs

A dictionary of graphviz node attributes for inheritance diagrams.

For example:

inheritance_node_attrs = dict(shape='ellipse', fontsize=14, height=0.75,
color='dodgerblue1', style='filled')

inheritance_edge_attrs

A dictionary of graphviz edge attributes for inheritance diagrams.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.intersphinx – Link to other projects’ documentation

New in version 0.5.

This extension can generate automatic links to the documentation of objects in other projects.

Usage is simple: whenever Sphinx encounters a cross-reference that has no matching target in the current documentation set, it looks for targets in the documentation sets configured in intersphinx_mapping. A reference like :py:class:`zipfile.ZipFile` can then link to the Python documentation for the ZipFile class, without you having to specify where it is located exactly.

When using the “new” format (see below), you can even force lookup in a foreign set by prefixing the link target appropriately. A link like :ref:`comparison manual <python:comparisons>` will then link to the label “comparisons” in the doc set “python”, if it exists.

Behind the scenes, this works as follows:

- Each Sphinx HTML build creates a file named objects.inv that contains a mapping from object names to URIs relative to the HTML set’s root.

- Projects using the Intersphinx extension can specify the location of such mapping files in the intersphinx_mapping config value. The mapping will then be used to resolve otherwise missing references to objects into links to the other documentation.

- By default, the mapping file is assumed to be at the same location as the rest of the documentation; however, the location of the mapping file can also be specified individually, e.g. if the docs should be buildable without Internet access.

To use intersphinx linking, add 'sphinx.ext.intersphinx' to your extensions config value, and use these new config values to activate linking:

intersphinx_mapping

This config value contains the locations and names of other projects that should be linked to in this documentation.

Relative local paths for target locations are taken as relative to the base of the built documentation, while relative local paths for inventory locations are taken as relative to the source directory.

When fetching remote inventory files, proxy settings will be read from the $HTTP_PROXY environment variable.

Old format for this config value

This is the format used before Sphinx 1.0. It is still recognized.

A dictionary mapping URIs to either None or an URI. The keys are the base URI of the foreign Sphinx documentation sets and can be local paths or HTTP URIs. The values indicate where the inventory file can be found: they can be None (at the same location as the base URI) or another local or HTTP URI.

New format for this config value

New in version 1.0.

A dictionary mapping unique identifiers to a tuple (target, inventory). Each target is the base URI of a foreign Sphinx documentation set and can be a local path or an HTTP URI. The inventory indicates where the inventory file can be found: it can be None (at the same location as the base URI) or another local or HTTP URI.

The unique identifier can be used to prefix cross-reference targets, so that it is clear which intersphinx set the target belongs to. A link like :ref:`comparison manual <python:comparisons>` will link to the label “comparisons” in the doc set “python”, if it exists.

Example

To add links to modules and objects in the Python standard library documentation, use:

intersphinx_mapping = {'python': ('https://docs.python.org/3.4', None)}

This will download the corresponding 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 re-downloaded whenever you do a full rebuild.

A second example, showing the meaning of a non-None value of the second tuple item:

intersphinx_mapping = {'python': ('https://docs.python.org/3.4',
'python-inv.txt')}

This will read the inventory from python-inv.txt in the source directory, but still generate links to the pages under https://docs.python.org/3.4. It is up to you to update the inventory file as new objects are added to the Python documentation.

Multiple target for the inventory

New in version 1.3.

Alternative files can be specified for each inventory. One can give a tuple for the second inventory tuple item as shown in the following example. This will read the inventory iterating through the (second) tuple items until the first successful fetch. The primary use case for this to specify mirror sites for server downtime of the primary inventory:

intersphinx_mapping = {'python': ('https://docs.python.org/3.4',
(None, 'python-inv.txt'))}

intersphinx_cache_limit

The maximum number of days to cache remote inventories. The default is 5, meaning five days. Set this to a negative value to cache inventories for unlimited time.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.linkcode – Add external links to source code

Module author: Pauli Virtanen

New in version 1.2.

This extension looks at your object descriptions (.. class::, .. function:: etc.) and adds external links to code hosted somewhere on the web. The intent is similar to the sphinx.ext.viewcode extension, but assumes the source code can be found somewhere on the Internet.

In your configuration, you need to specify a linkcode_resolve function that returns an URL based on the object.

linkcode_resolve

This is a function linkcode_resolve(domain, info), which should return the URL to source code corresponding to the object in given domain with given information.

The function should return None if no link is to be added.

The argument domain specifies the language domain the object is in. info is a dictionary with the following keys guaranteed to be present (dependent on the domain):

- py: module (name of the module), fullname (name of the object)

- c: names (list of names for the object)

- cpp: names (list of names for the object)

- javascript: object (name of the object), fullname (name of the item)

Example:

def linkcode_resolve(domain, info):
if domain != 'py':
return None
if not info['module']:
return None
filename = info['module'].replace('.', '/')
return "http://somesite/sourcerepo/%s.py" % filename

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

Math support in Sphinx

New in version 0.5.

Since mathematical notation isn’t natively supported by HTML in any way, Sphinx supports math in documentation with several extensions.

The basic math support is contained in sphinx.ext.mathbase. Other math support extensions should, if possible, reuse that support too.

Note

mathbase is not meant to be added to the extensions config value, instead, use either sphinx.ext.imgmath or sphinx.ext.mathjax 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 further translation is necessary when building LaTeX output.

Keep in mind that when you put math markup in Python docstrings read by autodoc, you either have to double all backslashes, or use Python raw strings (r"raw").

mathbase provides the following config values:

math_number_all

Set this option to True if you want all displayed math to be numbered. The default is False.

mathbase defines these new markup elements:

:math:

Role for inline math. Use like this:

Since Pythagoras, we know that :math:`a^2 + b^2 = c^2`.

.. math::

Directive for displayed math (math that takes the whole line for itself).

The directive supports multiple equations, which should be separated by a blank line:

.. math::

(a + b)^2 = a^2 + 2ab + b^2

(a - b)^2 = a^2 - 2ab + b^2

In addition, each single equation is set within a split environment, which means that you can have multiple aligned lines in an equation, aligned at & and separated by \\:

.. math::

(a + b)^2  &=  (a + b)(a + b) \\
&=  a^2 + 2ab + b^2

For more details, look into the documentation of the AmSMath LaTeX package [http://www.ams.org/publications/authors/tex/amslatex].

When the math is only one line of text, it can also be given as a directive argument:

.. math:: (a + b)^2 = a^2 + 2ab + b^2

Normally, equations are not numbered. If you want your equation to get a number, use the label option. When given, it selects an internal label for the equation, by which it can be cross-referenced, and causes an equation number to be issued. See eqref for an example. The numbering style depends on the output format.

There is also an option nowrap that prevents any wrapping of the given math in a math environment. When you give this option, you must make sure yourself that the math is properly set up. For example:

.. math::
:nowrap:

\begin{eqnarray}
y    & = & ax^2 + bx + c \\
f(x) & = & x^2 + 2xy + y^2
\end{eqnarray}

:eq:

Role for cross-referencing equations via their label. This currently works only within the same document. Example:

.. math:: e^{i\pi} + 1 = 0
:label: euler

Euler's identity, equation :eq:`euler`, was elected one of the most
beautiful mathematical formulas.

sphinx.ext.imgmath – Render math as images

New in version 1.4.

This extension renders math via LaTeX and dvipng [http://savannah.nongnu.org/projects/dvipng/] or dvisvgm [http://dvisvgm.bplaced.net/] into PNG or SVG images. This of course means that the computer where the docs are built must have both programs available.

There are various config values you can set to influence how the images are built:

imgmath_image_format

The output image format. The default is 'png'. It should be either 'png' or 'svg'.

imgmath_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 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 sphinx-build command line via the -D option should be preferable, like this:

sphinx-build -b html -D imgmath_latex=C:\tex\latex.exe . _build/html

This value should only contain the path to the latex executable, not further arguments; use imgmath_latex_args for that purpose.

imgmath_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. This option is only used when imgmath_image_format is set to 'png'.

imgmath_dvisvgm

The command name with which to invoke dvisvgm. The default is 'dvisvgm'; you may need to set this to a full path if dvisvgm is not in the executable search path. This option is only used when imgmath_image_format is 'svg'.

imgmath_latex_args

Additional arguments to give to latex, as a list. The default is an empty list.

imgmath_latex_preamble

Additional LaTeX code to put into the preamble of the short LaTeX files that are used to translate the math snippets. This is empty by default. Use it e.g. to add more packages whose commands you want to use in the math.

imgmath_dvipng_args

Additional arguments to give to dvipng, as a list. The default value is ['-gamma', '1.5', '-D', '110', '-bg', 'Transparent'] which makes the image a bit darker and larger then it is by default, and produces PNGs with a transparent background. This option is used only when imgmath_image_format is 'png'.

imgmath_dvisvgm_args

Additional arguments to give to dvisvgm, as a list. The default value is ['--no-fonts']. This option is used only when imgmath_image_format is 'svg'.

imgmath_use_preview

dvipng has the ability to determine the “depth” of the rendered text: for example, when typesetting a fraction inline, the baseline of surrounding text should not be flush with the bottom of the image, rather the image should extend a bit below the baseline. This is what TeX calls “depth”. When this is enabled, the images put into the HTML document will get a vertical-align style that correctly aligns the baselines.

Unfortunately, this only works when the preview-latex package [http://www.gnu.org/software/auctex/preview-latex.html] is installed. Therefore, the default for this option is False.

Currently this option is only used when imgmath_image_format is 'png'.

imgmath_add_tooltips

Default: True. If false, do not add the LaTeX code as an “alt” attribute for math images.

imgmath_font_size

The font size (in pt) of the displayed math. The default value is 12. It must be a positive integer.

sphinx.ext.mathjax – Render math via JavaScript

New in version 1.1.

This extension puts math as-is into the HTML files. The JavaScript package MathJax [https://www.mathjax.org/] is then loaded and transforms the LaTeX markup to readable math live in the browser.

Because MathJax (and the necessary fonts) is very large, it is not included in Sphinx.

mathjax_path

The path to the JavaScript file to include in the HTML files in order to load MathJax.

The default is the http:// URL that loads the JS files from the MathJax CDN [http://docs.mathjax.org/en/latest/start.html]. If you want MathJax to be available offline, you have to download it and set this value to a different path.

The path can be absolute or relative; if it is relative, it is relative to the _static directory of the built docs.

For example, if you put MathJax into the static path of the Sphinx docs, this value would be MathJax/MathJax.js. If you host more than one Sphinx documentation set on one server, it is advisable to install MathJax in a shared location.

You can also give a full http:// URL different from the CDN URL.

sphinx.ext.jsmath – Render math via JavaScript

This extension works just as the MathJax extension does, but uses the older package jsMath [http://www.math.union.edu/~dpvc/jsmath/]. It provides this config value:

jsmath_path

The path to the JavaScript file to include in the HTML files in order to load JSMath. There is no default.

The path can be absolute or relative; if it is relative, it is relative to the _static directory of the built docs.

For example, if you put JSMath into the static path of the Sphinx docs, this value would be jsMath/easy/load.js. If you host more than one Sphinx documentation set on one server, it is advisable to install jsMath in a shared location.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.napoleon – Support for NumPy and Google style docstrings

Module author: Rob Ruana

New in version 1.3.

Napoleon - Marching toward legible docstrings

Are you tired of writing docstrings that look like this:

:param path: The path of the file to wrap
:type path: str
:param field_storage: The :class:`FileStorage` instance to wrap
:type field_storage: FileStorage
:param temporary: Whether or not to delete the file when the File
instance is destructed
:type temporary: bool
:returns: A buffered writable file descriptor
:rtype: BufferedFileStorage

ReStructuredText [http://docutils.sourceforge.net/rst.html] is great, but it creates visually dense, hard to read docstrings [https://www.python.org/dev/peps/pep-0287/]. Compare the jumble above to the same thing rewritten according to the Google Python Style Guide [http://google.github.io/styleguide/pyguide.html]:

Args:
path (str): The path of the file to wrap
field_storage (FileStorage): The :class:`FileStorage` instance to wrap
temporary (bool): Whether or not to delete the file when the File
instance is destructed

Returns:
BufferedFileStorage: A buffered writable file descriptor

Much more legible, no?

Napoleon is a Sphinx Extensions that enables Sphinx to parse both NumPy [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt] and Google [http://google.github.io/styleguide/pyguide.html#Comments] style docstrings - the style recommended by Khan Academy [https://github.com/Khan/style-guides/blob/master/style/python.md#docstrings].

Napoleon is a pre-processor that parses NumPy [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt] and Google [http://google.github.io/styleguide/pyguide.html#Comments] style docstrings and converts them to reStructuredText before Sphinx attempts to parse them. This happens in an intermediate step while Sphinx is processing the documentation, so it doesn’t modify any of the docstrings in your actual source code files.

Getting Started

1. After setting up Sphinx to build your docs, enable napoleon in the Sphinx conf.py file:

# conf.py

# Add autodoc and napoleon to the extensions list
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']

2. Use sphinx-apidoc to build your API documentation:

$ sphinx-apidoc -f -o docs/source projectdir

Docstrings

Napoleon interprets every docstring that autodoc can find, including docstrings on: modules, classes, attributes, methods, functions, and variables. Inside each docstring, specially formatted Sections are parsed and converted to reStructuredText.

All standard reStructuredText formatting still works as expected.

Docstring Sections

All of the following section headers are supported:

- Args (alias of Parameters)

- Arguments (alias of Parameters)

- Attributes

- Example

- Examples

- Keyword Args (alias of Keyword Arguments)

- Keyword Arguments

- Methods

- Note

- Notes

- Other Parameters

- Parameters

- Return (alias of Returns)

- Returns

- Raises

- References

- See Also

- Todo

- Warning

- Warnings (alias of Warning)

- Warns

- Yield (alias of Yields)

- Yields

Google vs NumPy

Napoleon supports two styles of docstrings: Google [http://google.github.io/styleguide/pyguide.html#Comments] and NumPy [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt]. The main difference between the two styles is that Google uses indention to separate sections, whereas NumPy uses underlines.

Google style:

def func(arg1, arg2):
"""Summary line.

Extended description of function.

Args:
arg1 (int): Description of arg1
arg2 (str): Description of arg2

Returns:
bool: Description of return value

"""
return True

NumPy style:

def func(arg1, arg2):
"""Summary line.

Extended description of function.

Parameters
----------
arg1 : int
Description of arg1
arg2 : str
Description of arg2

Returns
-------
bool
Description of return value

"""
return True

NumPy style tends to require more vertical space, whereas Google style tends to use more horizontal space. Google style tends to be easier to read for short and simple docstrings, whereas NumPy style tends be easier to read for long and in-depth docstrings.

The Khan Academy [https://github.com/Khan/style-guides/blob/master/style/python.md#docstrings] recommends using Google style.

The choice between styles is largely aesthetic, but the two styles should not be mixed. Choose one style for your project and be consistent with it.

See also

For complete examples:

- Example Google Style Python Docstrings

- Example NumPy Style Python Docstrings

For Python type annotations, see PEP 484 [https://www.python.org/dev/peps/pep-0484/].

Configuration

Listed below are all the settings used by napoleon and their default values. These settings can be changed in the Sphinx conf.py file. Make sure that both “sphinx.ext.autodoc” and “sphinx.ext.napoleon” are enabled in conf.py:

# conf.py

# Add any Sphinx extension module names here, as strings
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']

# Napoleon settings
napoleon_google_docstring = True
napoleon_numpy_docstring = True
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = True
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = False
napoleon_use_param = True
napoleon_use_rtype = True

napoleon_google_docstring

True to parse Google style [http://google-styleguide.googlecode.com/svn/trunk/pyguide.html] docstrings. False to disable support for Google style docstrings. Defaults to True.

napoleon_numpy_docstring

True to parse NumPy style [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt] docstrings. False to disable support for NumPy style docstrings. Defaults to True.

napoleon_include_private_with_doc

True to include private members (like _membername) with docstrings in the documentation. False to fall back to Sphinx’s default behavior. Defaults to False.

If True:

def _included(self):
"""
This will be included in the docs because it has a docstring
"""
pass

def _skipped(self):
# This will NOT be included in the docs
pass

napoleon_include_special_with_doc

True to include special members (like __membername__) with docstrings in the documentation. False to fall back to Sphinx’s default behavior. Defaults to True.

If True:

def __str__(self):
"""
This will be included in the docs because it has a docstring
"""
return unicode(self).encode('utf-8')

def __unicode__(self):
# This will NOT be included in the docs
return unicode(self.__class__.__name__)

napoleon_use_admonition_for_examples

True to use the .. admonition:: directive for the Example and Examples sections. False to use the .. rubric:: directive instead. One may look better than the other depending on what HTML theme is used. Defaults to False.

This NumPy style [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt] snippet will be converted as follows:

Example
-------
This is just a quick example

If True:

.. admonition:: Example

This is just a quick example

If False:

.. rubric:: Example

This is just a quick example

napoleon_use_admonition_for_notes

True to use the .. admonition:: directive for Notes sections. False to use the .. rubric:: directive instead. Defaults to False.

Note

The singular Note section will always be converted to a .. note:: directive.

See also

napoleon_use_admonition_for_examples

napoleon_use_admonition_for_references

True to use the .. admonition:: directive for References sections. False to use the .. rubric:: directive instead. Defaults to False.

See also

napoleon_use_admonition_for_examples

napoleon_use_ivar

True to use the :ivar: role for instance variables. False to use the .. attribute:: directive instead. Defaults to False.

This NumPy style [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt] snippet will be converted as follows:

Attributes
----------
attr1 : int
Description of `attr1`

If True:

:ivar attr1: Description of `attr1`
:vartype attr1: int

If False:

.. attribute:: attr1

*int*

Description of `attr1`

napoleon_use_param

True to use a :param: role for each function parameter. False to use a single :parameters: role for all the parameters. Defaults to True.

This NumPy style [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt] snippet will be converted as follows:

Parameters
----------
arg1 : str
Description of `arg1`
arg2 : int, optional
Description of `arg2`, defaults to 0

If True:

:param arg1: Description of `arg1`
:type arg1: str
:param arg2: Description of `arg2`, defaults to 0
:type arg2: int, optional

If False:

:parameters: * **arg1** (*str*) --
Description of `arg1`
* **arg2** (*int, optional*) --
Description of `arg2`, defaults to 0

napoleon_use_rtype

True to use the :rtype: role for the return type. False to output the return type inline with the description. Defaults to True.

This NumPy style [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt] snippet will be converted as follows:

Returns
-------
bool
True if successful, False otherwise

If True:

:returns: True if successful, False otherwise
:rtype: bool

If False:

:returns: *bool* -- True if successful, False otherwise

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.todo – Support for todo items

Module author: Daniel Bültmann

New in version 0.5.

There are two additional directives when using this extension:

.. todo::

Use this directive like, for example, note.

It will only show up in the output if todo_include_todos is True.

New in version 1.3.2: This directive supports an class option that determines the class attribute for HTML output. If not given, the class defaults to admonition-todo.

.. todolist::

This directive is replaced by a list of all todo directives in the whole documentation, if todo_include_todos is True.

There is also an additional config value:

todo_include_todos

If this is True, todo and todolist produce output, else they produce nothing. The default is False.

todo_link_only

If this is True, todolist produce output without file path and line, The default is False.

New in version 1.4.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Extensions »

sphinx.ext.viewcode – Add links to highlighted source code

Module author: Georg Brandl

New in version 1.0.

This extension looks at your Python object descriptions (.. class::, .. function:: etc.) and tries to find the source files where the objects are contained. When found, a separate HTML page will be output for each module with a highlighted version of the source code, and a link will be added to all object descriptions that leads to the source code of the described object. A link back from the source to the description will also be inserted.

There is an additional config value:

viewcode_import

If this is True, viewcode extension will follow alias objects that imported from another module such as functions, classes and attributes. As side effects, this option else they produce nothing. The default is True.

Warning

viewcode_import imports the modules to be followed real location. If any modules have side effects on import, these will be executed by viewcode when sphinx-build is run.

If you document scripts (as opposed to library modules), make sure their main routine is protected by a if __name__ == '__main__' condition.

New in version 1.3.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Developing extensions for Sphinx

Since many projects will need special features in their documentation, Sphinx is designed to be extensible on several levels.

This is what you can do in an extension: First, you can add new builders 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.

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 extensions configuration value.

Extension metadata

New in version 1.3.

The setup() function can return a dictionary. This is treated by Sphinx as metadata of the extension. Metadata keys currently recognized are:

- 'version': a string that identifies the extension version. It is used for extension version requirement checking (see needs_extensions) and informational purposes. If not given, "unknown version" is substituted.

- 'parallel_read_safe': a boolean that specifies if parallel reading of source files can be used when the extension is loaded. It defaults to False, i.e. you have to explicitly specify your extension to be parallel-read-safe after checking that it is.

- 'parallel_write_safe': a boolean that specifies if parallel writing of output files can be used when the extension is loaded. Since extensions usually don’t negatively influence the process, this defaults to True.

APIs used for writing extensions

- Tutorial: Writing a simple extension

- Important objects

- Build Phases

- Extension Design

- The Setup Function

- The Node Classes

- The Directive Classes

- The Event Handlers

- Application API

- Extension setup

- Emitting events

- Producing messages / logging

- Sphinx core events

- Checking the Sphinx version

- The Config object

- The template bridge

- Exceptions

- Build environment API

- Builder API

- Docutils markup API

- Roles

- Directives

- ViewLists

- Parsing directive content as ReST

- Domain API

- Parser API

- Doctree node classes added by Sphinx

- Nodes for domain-specific object descriptions

- New admonition-like constructs

- Other paragraph-level nodes

- New inline nodes

- Special nodes

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Developing extensions for Sphinx »

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 extension, 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 to collect these in a central place. (A similar “todo” extension is distributed with Sphinx.)

Important objects

There are several key objects whose API you will use while writing an extension. These are:

Application

The application object (usually called app) is an instance of Sphinx. It controls most high-level functionality, such as the setup of extensions, event dispatching and producing output (logging).

If you have the environment object, the application is available as env.app.

Environment

The build environment object (usually called env) is an instance of BuildEnvironment. It is responsible for parsing the source documents, stores all metadata about the document collection and is serialized to disk after each build.

Its API provides methods to do with access to metadata, resolving references, etc. It can also be used by extensions to cache information that should persist for incremental rebuilds.

If you have the application or builder object, the environment is available as app.env or builder.env.

Builder

The builder object (usually called builder) is an instance of a specific subclass of Builder. Each builder class knows how to convert the parsed documents into an output format, or otherwise process them (e.g. check external links).

If you have the application object, the builder is available as app.builder.

Config

The config object (usually called config) provides the values of configuration values set in conf.py as attributes. It is an instance of Config.

The config is available as app.config or env.config.

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 of interest to 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 docutils, and the corresponding code is executed. The output of this phase is a doctree for each source file; 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.

There are nodes provided by docutils, which are documented in the docutils documentation [http://docutils.sourceforge.net/docs/ref/doctree.html]. Additional nodes are provided by Sphinx and documented here.

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 doctree-resolved event, to replace the todo and todolist nodes, and one for env-purge-doc (the reason for that will be covered later).

The Setup Function

The new elements are added in the extension’s setup function. Let us create a new Python module called todo.py and add the setup function:

def setup(app):
app.add_config_value('todo_include_todos', False, 'html')

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)

return {'version': '0.1'}   # identifies the version of our extension

The calls in this function refer to classes and functions not yet written. What the individual calls do is the following:

- 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 'html', HTML documents would be full rebuild if the config value changed its value. This is needed for config values that influence reading (build phase 1).

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

- add_directive() adds a new directive, given by name and class.

The handler functions are created later.

- Finally, 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 docutils.nodes. todo inherits from Admonition because it should be handled like a note or warning, todolist is just a “general” node.

Note

Many extensions will not have to create their own node classes and work fine with the nodes already provided by docutils [http://docutils.sourceforge.net/docs/ref/doctree.html] and Sphinx.

The Directive Classes

A directive class is a class deriving usually from docutils.parsers.rst.Directive. The directive interface is also covered in detail in the docutils documentation [http://docutils.sourceforge.net/docs/ref/rst/directives.html]; the important thing is that the class should have attributes that configure the allowed markup, and a run method that returns a list of nodes.

The todolist directive is quite simple:

from docutils.parsers.rst 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
from sphinx.locale import _

class TodoDirective(Directive):

# this enables content in the directive
has_content = True

def run(self):
env = self.state.document.settings.env

targetid = "todo-%d" % env.new_serialno('todo')
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.new_serialno which returns a new unique integer on each call 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 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 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 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.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Developing extensions for Sphinx »

Application API

Each Sphinx extension is a Python module with at least a setup() function. This function is called at initialization time with one argument, the application object representing the Sphinx process.

class sphinx.application.Sphinx[source]

This application object has the public API described in the following.

Extension setup

These methods are usually called in an extension’s setup() function.

Examples of using the Sphinx extension API can be seen in the sphinx.ext package.

Sphinx.setup_extension(name)[source]

Load the extension given by the module name. Use this if your extension needs the features provided by another extension.

Sphinx.add_builder(builder)[source]

Register a new builder. builder must be a class that inherits from Builder.

Sphinx.add_config_value(name, default, rebuild)[source]

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

Changed in version 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.

Changed in version 0.6: Changed rebuild from a simple boolean (equivalent to '' or 'env') to a string. However, booleans are still accepted and converted internally.

Sphinx.add_domain(domain)[source]

Make the given domain (which must be a class; more precisely, a subclass of Domain) known to Sphinx.

New in version 1.0.

Sphinx.override_domain(domain)[source]

Make the given domain class known to Sphinx, assuming that there is already a domain with its .name. The new domain must be a subclass of the existing one.

New in version 1.0.

Sphinx.add_index_to_domain(domain, index)[source]

Add a custom index class to the domain named domain. index must be a subclass of Index.

New in version 1.0.

Sphinx.add_event(name)[source]

Register an event called name. This is needed to be able to emit it.

Sphinx.set_translator(name, translator_class)[source]

Register or override a Docutils translator class. This is used to register a custom output translator or to replace a builtin translator. This allows extensions to use custom translator and define custom nodes for the translator (see add_node()).

This is a API version of html_translator_class for all other builders. Note that if html_translator_class is specified and this API is called for html related builders, API overriding takes precedence.

New in version 1.3.

Sphinx.add_node(node, **kwds)[source]

Register a Docutils node class. This is necessary for Docutils internals. It may also be used in the future to validate nodes in the parsed documents.

Node visitor functions for the Sphinx HTML, LaTeX, text and manpage writers can be given as keyword arguments: the keyword should be one or more of 'html', 'latex', 'text', 'man', 'texinfo' or any other supported translators, the value a 2-tuple of (visit, depart) methods. depart can be None if the visit function raises docutils.nodes.SkipNode. Example:

class math(docutils.nodes.Element): pass

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 on the node when encountered in a document to translate.

Changed in version 0.5: Added the support for keyword arguments giving visit functions.

Sphinx.add_enumerable_node(node, figtype, title_getter=None, **kwds)[source]

Register a Docutils node class as a numfig target. Sphinx numbers the node automatically. And then the users can refer it using numref.

figtype is a type of enumerable nodes. Each figtypes have individual numbering sequences. As a system figtypes, figure, table and code-block are defined. It is able to add custom nodes to these default figtypes. It is also able to define new custom figtype if new figtype is given.

title_getter is a getter function to obtain the title of node. It takes an instance of the enumerable node, and it must return its title as string. The title is used to the default title of references for ref. By default, Sphinx searches docutils.nodes.caption or docutils.nodes.title from the node as a title.

Other keyword arguments are used for node visitor functions. See the Sphinx.add_node() for details.

New in version 1.4.

Sphinx.add_directive(name, func, content, arguments, **options)[source]

Sphinx.add_directive(name, directiveclass)

Register a Docutils directive. name must be the prospective directive name. There are two possible ways to write a directive:

- In the docutils 0.4 style, obj 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. This style is deprecated.

- 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 must inherit from the class docutils.parsers.rst.Directive.

For example, the (already existing) 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 = directives.unchanged,
encoding = directives.encoding)

Changed in version 0.6: Docutils 0.5-style directive classes are now supported.

Sphinx.add_directive_to_domain(domain, name, func, content, arguments, **options)[source]

Sphinx.add_directive_to_domain(domain, name, directiveclass)

Like add_directive(), but the directive is added to the domain named domain.

New in version 1.0.

Sphinx.add_role(name, role)[source]

Register a Docutils role. name must be the role name that occurs in the source, role the role function (see the Docutils documentation [http://docutils.sourceforge.net/docs/howto/rst-roles.html] on details).

Sphinx.add_role_to_domain(domain, name, role)[source]

Like add_role(), but the role is added to the domain named domain.

New in version 1.0.

Sphinx.add_generic_role(name, nodeclass)[source]

Register a Docutils role that does nothing but wrap its contents in the node given by nodeclass.

New in version 0.6.

Sphinx.add_object_type(directivename, rolename, indextemplate='', parse_node=None, ref_nodeclass=None, objname='', doc_field_types=[])[source]

This method is a very convenient way to add a new object type that can be cross-referenced. It will do this:

- Create a new directive (called directivename) for documenting an object. It will automatically add index entries if indextemplate is nonempty; if given, it must contain exactly one instance of %s. See the example below for how the template will be interpreted.

- Create a new role (called rolename) to cross-reference to these object descriptions.

- If you provide parse_node, it must be a function that takes a string and a docutils node, and it must populate the node with children parsed from the string. It must then return the name of the item to be used in cross-referencing and index entries. See the conf.py file in the source for this documentation for an example.

- The objname (if not given, will default to directivename) names the type of object. It is used when listing objects, e.g. in search results.

For example, if you have this call in a custom Sphinx extension:

app.add_object_type('directive', 'dir', 'pair: %s; directive')

you can use this markup in your documents:

.. rst:directive:: function

Document a function.

<...>

See also the :rst:dir:`function` directive.

For the directive, an index entry will be generated as if you had prepended

.. index:: pair: function; directive

The reference node will be of class literal (so it will be rendered in a proportional font, as appropriate for code) unless you give the ref_nodeclass argument, which must be a docutils node class. Most useful are docutils.nodes.emphasis or docutils.nodes.strong – you can also use docutils.nodes.generated if you want no further text decoration. If the text should be treated as literal (e.g. no smart quote replacement), but not have typewriter styling, use sphinx.addnodes.literal_emphasis or sphinx.addnodes.literal_strong.

For the role content, you have the same syntactical possibilities as for standard Sphinx roles (see Cross-referencing syntax).

This method is also available under the deprecated alias add_description_unit.

Sphinx.add_crossref_type(directivename, rolename, indextemplate='', ref_nodeclass=None, objname='')[source]

This method is very similar to add_object_type() except that the directive it generates must be empty, and will produce no output.

That means that you can add semantic targets to your sources, and refer to them using custom roles instead of generic ones (like ref). Example call:

app.add_crossref_type('topic', 'topic', 'single: %s', docutils.nodes.emphasis)

Example usage:

.. topic:: application API

The application API
-------------------

<...>

See also :topic:`this section <application API>`.

(Of course, the element following the topic directive needn’t be a section.)

Sphinx.add_transform(transform)[source]

Add the standard docutils Transform subclass transform to the list of transforms that are applied after Sphinx parses a reST document.

Sphinx.add_javascript(filename)[source]

Add filename to the list of JavaScript files that the default HTML template will include. The filename must be relative to the HTML static path, see the docs for the config value. A full URI with scheme, like http://example.org/foo.js, is also supported.

New in version 0.5.

Sphinx.add_stylesheet(filename)[source]

Add filename to the list of CSS files that the default HTML template will include. Like for add_javascript(), the filename must be relative to the HTML static path, or a full URI with scheme.

New in version 1.0.

Sphinx.add_latex_package(packagename, options=None)[source]

Add packagename to the list of packages that LaTeX source code will include. If you provide options, it will be taken to usepackage declaration.

app.add_latex_package('mypackage')             # => \usepackage{mypackage}
app.add_latex_package('mypackage', 'foo,bar')  # => \usepackage[foo,bar]{mypackage}

New in version 1.3.

Sphinx.add_lexer(alias, lexer)[source]

Use lexer, which must be an instance of a Pygments lexer class, to highlight code blocks with the given language alias.

New in version 0.6.

Sphinx.add_autodocumenter(cls)[source]

Add cls as a new documenter class for the sphinx.ext.autodoc extension. It must be a subclass of 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 Documenter.

New in version 0.6.

Sphinx.add_autodoc_attrgetter(type, getter)[source]

Add getter, which must be a function with an interface compatible to the 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 getattr().

New in version 0.6.

Sphinx.add_search_language(cls)[source]

Add cls, which must be a subclass of sphinx.search.SearchLanguage, as a support language for building the HTML full-text search index. The class must have a lang attribute that indicates the language it should be used for. See html_search_language.

New in version 1.1.

Sphinx.add_source_parser(name, suffix, parser)[source]

Register a parser class for specified suffix.

New in version 1.4.

Sphinx.require_sphinx(version)[source]

Compare version (which must be a major.minor version string, e.g. '1.1') with the version of the running Sphinx, and abort the build when it is too old.

New in version 1.0.

Sphinx.connect(event, callback)[source]

Register callback to be called when event is emitted. For details on available core events and the arguments of callback functions, please see Sphinx core events.

The method returns a “listener ID” that can be used as an argument to disconnect().

Sphinx.disconnect(listener_id)[source]

Unregister callback listener_id.

exception sphinx.application.ExtensionError[source]

All these methods raise this exception if something went wrong with the extension API.

Emitting events

Sphinx.emit(event, *arguments)[source]

Emit event and pass arguments to the callback functions. Return the return values of all callbacks as a list. Do not emit core Sphinx events in extensions!

Sphinx.emit_firstresult(event, *arguments)[source]

Emit event and pass arguments to the callback functions. Return the result of the first callback that doesn’t return None.

New in version 0.5.

Producing messages / logging

The application object also provides support for emitting leveled messages.

Note

There is no “error” call: in Sphinx, errors are defined as things that stop the build; just raise an exception (sphinx.errors.SphinxError or a custom subclass) to do that.

Sphinx.warn(message, location=None, prefix='WARNING: ', type=None, subtype=None)[source]

Emit a warning.

If location is given, it should either be a tuple of (docname, lineno) or a string describing the location of the warning as well as possible.

prefix usually should not be changed.

type and subtype are used to suppress warnings with suppress_warnings.

Note

For warnings emitted during parsing, you should use BuildEnvironment.warn() since that will collect all warnings during parsing for later output.

Sphinx.info(message='', nonl=False)[source]

Emit an informational message.

If nonl is true, don’t emit a newline at the end (which implies that more info output will follow soon.)

Sphinx.verbose(message, *args, **kwargs)[source]

Emit a verbose informational message.

The message will only be emitted for verbosity levels >= 1 (i.e. at least one -v option was given).

The message can contain %-style interpolation placeholders, which is formatted with either the *args or **kwargs when output.

Sphinx.debug(message, *args, **kwargs)[source]

Emit a debug-level informational message.

The message will only be emitted for verbosity levels >= 2 (i.e. at least two -v options were given).

The message can contain %-style interpolation placeholders, which is formatted with either the *args or **kwargs when output.

Sphinx.debug2(message, *args, **kwargs)[source]

Emit a lowlevel debug-level informational message.

The message will only be emitted for verbosity level 3 (i.e. three -v options were given).

The message can contain %-style interpolation placeholders, which is formatted with either the *args or **kwargs when output.

Sphinx core events

These events are known to the core. The arguments shown are given to the registered event handlers. Use connect() in an extension’s setup function (note that conf.py can also have a setup function) to connect handlers to the events. Example:

def source_read_handler(app, docname, source):
print('do something here...')

def setup(app):
app.connect('source-read', source_read_handler)

builder-inited(app)

Emitted when the builder object has been created. It is available as app.builder.

env-get-outdated(app, env, added, changed, removed)

Emitted when the environment determines which source files have changed and should be re-read. added, changed and removed are sets of docnames that the environment has determined. You can return a list of docnames to re-read in addition to these.

New in version 1.1.

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.

New in version 0.5.

env-before-read-docs(app, env, docnames)

Emitted after the environment has determined the list of all added and changed files and just before it reads them. It allows extension authors to reorder the list of docnames (inplace) before processing, or add more docnames that Sphinx did not consider changed (but never add any docnames that are not in env.found_docs).

You can also remove document names; do this with caution since it will make Sphinx treat changed files as unchanged.

New in version 1.3.

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:`...`.

New in version 0.5.

doctree-read(app, doctree)

Emitted when a doctree has been parsed and read by the environment, and is about to be pickled. The doctree can be modified in-place.

missing-reference(app, env, node, contnode)

Emitted when a cross-reference to a Python module or object cannot be resolved. If the event handler can resolve the reference, it should return a new docutils node to be inserted in the document tree in place of the node node. Usually this node is a reference node containing contnode as a child.

New in version 0.5.

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

env-merge-info(env, docnames, other)

This event is only emitted when parallel reading of documents is enabled. It is emitted once for every subprocess that has read some documents.

You must handle this event in an extension that stores data in the environment in a custom location. Otherwise the environment in the main process will not be aware of the information stored in the subprocess.

other is the environment object from the subprocess, env is the environment from the main process. docnames is a set of document names that have been read in the subprocess.

For a sample of how to deal with this event, look at the standard sphinx.ext.todo extension. The implementation is often similar to that of env-purge-doc, only that information is not removed, but added to the main environment from the other environment.

New in version 1.3.

env-updated(app, env)

Emitted when the update() method of the build environment has completed, that is, the environment and all doctrees are now up-to-date.

You can return an iterable of docnames from the handler. These documents will then be considered updated, and will be (re-)written during the writing phase.

New in version 0.5.

Changed in version 1.3: The handlers’ return value is now used.

html-collect-pages(app)

Emitted when the HTML builder is starting to write non-document pages. You can add pages to write by returning an iterable from this event consisting of (pagename, context, templatename).

New in version 1.0.

html-page-context(app, pagename, templatename, context, doctree)

Emitted when the HTML builder has created a context dictionary to render a template with – this can be used to add custom elements to the context.

The pagename argument is the canonical name of the page being rendered, that is, without .html suffix and using slashes as path separators. The templatename is the name of the template to render, this will be 'page.html' for all pages from reST documents.

The context argument is a dictionary of values that are given to the template engine to render the page and can be modified to include custom values. Keys must be strings.

The doctree argument will be a doctree when the page is created from a reST documents; it will be None when the page is created from an HTML template alone.

You can return a string from the handler, it will then replace 'page.html' as the HTML template for this page.

New in version 0.4.

Changed in version 1.3: The return value can now specify a template name.

build-finished(app, exception)

Emitted when a build has finished, before Sphinx exits, usually used for cleanup. This event is emitted even when the build process raised an exception, given as the exception argument. The exception is reraised in the application after the event handlers have run. If the build process raised no exception, exception will be None. This allows to customize cleanup actions depending on the exception status.

New in version 0.5.

Checking the Sphinx version

Use this to adapt your extension to API changes in Sphinx.

sphinx.version_info

A tuple of five elements; for Sphinx version 1.2.1 beta 3 this would be (1, 2, 1, 'beta', 3).

New in version 1.2: Before version 1.2, check the string sphinx.__version__.

The Config object

class sphinx.config.Config[source]

The config object makes the values of all config values available as attributes.

It is available as the config attribute on the application and environment objects. For example, to get the value of language, use either app.config.language or env.config.language.

The template bridge

class sphinx.application.TemplateBridge[source]

This class defines the interface for a “template bridge”, that is, a class that renders templates given a template name and a context.

init(builder, theme=None, dirs=None)[source]

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 sphinx.theming.Theme object or None; in the latter case, dirs can be list of fixed directories to look for templates.

newest_template_mtime()[source]

Called by the builder to determine if output files are outdated because of template changes. Return the mtime of the newest template file that was changed. The default implementation returns 0.

render(template, context)[source]

Called by the builder to render a template given as a filename with a specified context (a Python dictionary).

render_string(template, context)[source]

Called by the builder to render a template given as a string with a specified context (a Python dictionary).

Exceptions

exception sphinx.errors.SphinxError[source]

This is the base class for “nice” exceptions. When such an exception is raised, Sphinx will abort the build and present the exception category and message to the user.

Extensions are encouraged to derive from this exception for their custom errors.

Exceptions not derived from SphinxError are treated as unexpected and shown to the user with a part of the traceback (and the full traceback saved in a temporary file).

category

Description of the exception “category”, used in converting the exception to a string (“category: message”). Should be set accordingly in subclasses.

exception sphinx.errors.ConfigError[source]

Used for erroneous values or nonsensical combinations of configuration values.

exception sphinx.errors.ExtensionError[source]

Used for errors in setting up extensions.

exception sphinx.errors.ThemeError[source]

Used for errors to do with themes.

exception sphinx.errors.VersionRequirementError[source]

Raised when the docs require a higher Sphinx version than the current one.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Developing extensions for Sphinx »

Build environment API

class sphinx.environment.BuildEnvironment[source]

Attributes

app

Reference to the Sphinx (application) object.

config

Reference to the Config object.

srcdir

Source directory.

confdir

Directory containing conf.py.

doctreedir

Directory for storing pickled doctrees.

found_docs

A set of all existing docnames.

metadata

Dictionary mapping docnames to “metadata” (see File-wide metadata).

titles

Dictionary mapping docnames to the docutils node for their main title.

docname

Returns the docname of the document currently being parsed.

Utility methods

warn(docname, msg, lineno=None, **kwargs)[source]

Emit a warning.

This differs from using app.warn() in that the warning may not be emitted instantly, but collected for emitting all warnings after the update of the environment.

warn_node(msg, node, **kwargs)[source]

Like warn(), but with source information taken from node.

doc2path(docname, base=True, suffix=None)[source]

Return the filename for the document name.

If base is True, return absolute path under self.srcdir. If base is None, return relative path to self.srcdir. If base is a path string, return absolute path under that. If suffix is not None, add it instead of config.source_suffix.

relfn2path(filename, docname=None)[source]

Return paths to a file referenced from a document, relative to documentation root and absolute.

In the input “filename”, absolute filenames are taken as relative to the source dir, while relative filenames are relative to the dir of the containing document.

note_dependency(filename)[source]

Add filename as a dependency of the current document.

This means that the document will be rebuilt if this file changes.

filename should be absolute or relative to the source directory.

new_serialno(category='')[source]

Return a serial number, e.g. for index entry targets.

The number is guaranteed to be unique in the current document.

note_reread()[source]

Add the current document to the list of documents that will automatically be re-read at the next build.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Developing extensions for Sphinx »

Builder API

Todo

Expand this.

class sphinx.builders.Builder[source]

This is the base class for all builders.

These methods are predefined and will be called from the application:

get_relative_uri(from_, to, typ=None)[source]

Return a relative URI between two source filenames.

May raise environment.NoUri if there’s no way to return a sensible URI.

build_all()[source]

Build all source files.

build_specific(filenames)[source]

Only rebuild as much as needed for changes in the filenames.

build_update()[source]

Only rebuild what was changed or added since last build.

build(docnames, summary=None, method='update')[source]

Main build method.

First updates the environment, and then calls write().

These methods can be overridden in concrete builder classes:

init()[source]

Load necessary templates and perform initialization. The default implementation does nothing.

get_outdated_docs()[source]

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.

get_target_uri(docname, typ=None)[source]

Return the target URI for a document name.

typ can be used to qualify the link characteristic for individual builders.

prepare_writing(docnames)[source]

A place where you can add logic before write_doc() is run

write_doc(docname, doctree)[source]

Where you actually write something to the filesystem.

finish()[source]

Finish the building process.

The default implementation does nothing.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Developing extensions for Sphinx »

Docutils markup API

This section describes the API for adding ReST markup elements (roles and directives).

Roles

Directives

Directives are handled by classes derived from docutils.parsers.rst.Directive. They have to be registered by an extension using Sphinx.add_directive() or Sphinx.add_directive_to_domain().

class docutils.parsers.rst.Directive[source]

The markup syntax of the new directive is determined by the follow five class attributes:

required_arguments = 0

Number of required directive arguments.

optional_arguments = 0

Number of optional arguments after the required arguments.

final_argument_whitespace = False

May the final argument contain whitespace?

option_spec = None

Mapping of option names to validator functions.

Option validator functions take a single parameter, the option argument (or None if not given), and should validate it or convert it to the proper form. They raise ValueError or TypeError to indicate failure.

There are several predefined and possibly useful validators in the docutils.parsers.rst.directives module.

has_content = False

May the directive have content?

New directives must implement the run() method:

run()[source]

This method must process the directive arguments, options and content, and return a list of Docutils/Sphinx nodes that will be inserted into the document tree at the point where the directive was encountered.

Instance attributes that are always set on the directive are:

name

The directive name (useful when registering the same directive class under multiple names).

arguments

The arguments given to the directive, as a list.

options

The options given to the directive, as a dictionary mapping option names to validated/converted values.

content

The directive content, if given, as a ViewList.

lineno

The absolute line number on which the directive appeared. This is not always a useful value; use srcline instead.

src

The source file of the directive.

srcline

The line number in the source file on which the directive appeared.

content_offset

Internal offset of the directive content. Used when calling nested_parse (see below).

block_text

The string containing the entire directive.

state

state_machine

The state and state machine which controls the parsing. Used for nested_parse.

ViewLists

Docutils represents document source lines in a class docutils.statemachine.ViewList. This is a list with extended functionality – for one, slicing creates views of the original list, and also the list contains information about the source line numbers.

The Directive.content attribute is a ViewList. If you generate content to be parsed as ReST, you have to create a ViewList yourself. Important for content generation are the following points:

- The constructor takes a list of strings (lines) and a source (document) name.

- The .append() method takes a line and a source name as well.

Parsing directive content as ReST

Many directives will contain more markup that must be parsed. To do this, use one of the following APIs from the Directive.run() method:

- self.state.nested_parse

- sphinx.util.nodes.nested_parse_with_titles() – this allows titles in the parsed content.

Both APIs parse the content into a given node. They are used like this:

node = docutils.nodes.paragraph()
# either
nested_parse_with_titles(self.state, self.result, node)
# or
self.state.nested_parse(self.result, 0, node)

If you don’t need the wrapping node, you can use any concrete node type and return node.children from the Directive.

See also

Creating directives [http://docutils.sourceforge.net/docs/howto/rst-directives.html]

HOWTO of the Docutils documentation

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Developing extensions for Sphinx »

Domain API

class sphinx.domains.Domain(env)[source]

A Domain is meant to be a group of “object” description directives for objects of a similar nature, and corresponding roles to create references to them. Examples would be Python modules, classes, functions etc., elements of a templating language, Sphinx roles and directives, etc.

Each domain has a separate storage for information about existing objects and how to reference them in self.data, which must be a dictionary. It also must implement several functions that expose the object information in a uniform way to parts of Sphinx that allow the user to reference or search for objects in a domain-agnostic way.

About self.data: since all object and cross-referencing information is stored on a BuildEnvironment instance, the domain.data object is also stored in the env.domaindata dict under the key domain.name. Before the build process starts, every active domain is instantiated and given the environment object; the domaindata dict must then either be nonexistent or a dictionary whose ‘version’ key is equal to the domain class’ data_version attribute. Otherwise, IOError is raised and the pickled environment is discarded.

clear_doc(docname)[source]

Remove traces of a document in the domain-specific inventories.

directive(name)[source]

Return a directive adapter class that always gives the registered directive its full name (‘domain:name’) as self.name.

get_objects()[source]

Return an iterable of “object descriptions”, which are tuples with five items:

- name – fully qualified name

- dispname – name to display when searching/linking

- type – object type, a key in self.object_types

- docname – the document where it is to be found

- anchor – the anchor name for the object

- priority – how “important” the object is (determines placement in search results)

- 1: default priority (placed before full-text matches)

- 0: object is important (placed before default-priority objects)

- 2: object is unimportant (placed after full-text matches)

- -1: object should not show up in search at all

get_type_name(type, primary=False)[source]

Return full name for given ObjType.

merge_domaindata(docnames, otherdata)[source]

Merge in data regarding docnames from a different domaindata inventory (coming from a subprocess in parallel builds).

process_doc(env, docname, document)[source]

Process a document after it is read by the environment.

resolve_any_xref(env, fromdocname, builder, target, node, contnode)[source]

Resolve the pending_xref node with the given target.

The reference comes from an “any” or similar role, which means that we don’t know the type. Otherwise, the arguments are the same as for resolve_xref().

The method must return a list (potentially empty) of tuples ('domain:role', newnode), where 'domain:role' is the name of a role that could have created the same reference, e.g. 'py:func'. newnode is what resolve_xref() would return.

New in version 1.3.

resolve_xref(env, fromdocname, builder, typ, target, node, contnode)[source]

Resolve the pending_xref node with the given typ and target.

This method should return a new node, to replace the xref node, containing the contnode which is the markup content of the cross-reference.

If no resolution can be found, None can be returned; the xref node will then given to the ‘missing-reference’ event, and if that yields no resolution, replaced by contnode.

The method can also raise sphinx.environment.NoUri to suppress the ‘missing-reference’ event being emitted.

role(name)[source]

Return a role adapter function that always gives the registered role its full name (‘domain:name’) as the first argument.

dangling_warnings = {}

role name -> a warning message if reference is missing

data_version = 0

data version, bump this when the format of self.data changes

directives = {}

directive name -> directive class

indices = []

a list of Index subclasses

initial_data = {}

data value for a fresh environment

label = ''

domain label: longer, more descriptive (used in messages)

name = ''

domain name: should be short, but unique

object_types = {}

type (usually directive) name -> ObjType instance

roles = {}

role name -> role callable

class sphinx.domains.ObjType(lname, *roles, **attrs)[source]

An ObjType is the description for a type of object that a domain can document. In the object_types attribute of Domain subclasses, object type names are mapped to instances of this class.

Constructor arguments:

- lname: localized name of the type (do not include domain name)

- roles: all the roles that can refer to an object of this type

- attrs: object attributes – currently only “searchprio” is known, which defines the object’s priority in the full-text search index, see Domain.get_objects().

class sphinx.domains.Index(domain)[source]

An Index is the description for a domain-specific index. To add an index to a domain, subclass Index, overriding the three name attributes:

- name is an identifier used for generating file names.

- localname is the section title for the index.

- shortname is a short name for the index, for use in the relation bar in HTML output. Can be empty to disable entries in the relation bar.

and providing a generate() method. Then, add the index class to your domain’s indices list. Extensions can add indices to existing domains using add_index_to_domain().

generate(docnames=None)[source]

Return entries for the index given by name. If docnames is given, restrict to entries referring to these docnames.

The return value is a tuple of (content, collapse), where collapse is a boolean that determines if sub-entries should start collapsed (for output formats that support collapsing sub-entries).

content is a sequence of (letter, entries) tuples, where letter is the “heading” for the given entries, usually the starting letter.

entries is a sequence of single entries, where a single entry is a sequence [name, subtype, docname, anchor, extra, qualifier, descr]. The items in this sequence have the following meaning:

- name – the name of the index entry to be displayed

- subtype – sub-entry related type: 0 – normal entry 1 – entry with sub-entries 2 – sub-entry

- docname – docname where the entry is located

- anchor – anchor for the entry within docname

- extra – extra info for the entry

- qualifier – qualifier for the description

- descr – description for the entry

Qualifier and description are not rendered e.g. in LaTeX output.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Developing extensions for Sphinx »

Parser API

class sphinx.parsers.Parser[source]

A base class of source parsers. The additonal parsers should inherits this class instead of docutils.parsers.Parser. Compared with docutils.parsers.Parser, this class improves accessibility to Sphinx APIs.

The subclasses can access following objects and functions:

self.app

The application object (sphinx.application.Sphinx)

self.config

The config object (sphinx.config.Config)

self.env

The environment object (sphinx.environment.BuildEnvironment)

self.warn()

Emit a warning. (Same as sphinx.application.Sphinx.warn())

self.info()

Emit a informational message. (Same as sphinx.application.Sphinx.info())

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Developing extensions for Sphinx »

Doctree node classes added by Sphinx

Nodes for domain-specific object descriptions

class sphinx.addnodes.desc(rawsource='', *children, **attributes)[source]

Node for object descriptions.

This node is similar to a “definition list” with one definition. It contains one or more desc_signature and a desc_content.

class sphinx.addnodes.desc_signature(rawsource='', text='', *children, **attributes)[source]

Node for object signatures.

The “term” part of the custom Sphinx definition list.

class sphinx.addnodes.desc_addname(rawsource='', text='', *children, **attributes)[source]

Node for additional name parts (module name, class name).

class sphinx.addnodes.desc_type(rawsource='', text='', *children, **attributes)[source]

Node for return types or object type names.

class sphinx.addnodes.desc_returns(rawsource='', text='', *children, **attributes)[source]

Node for a “returns” annotation (a la -> in Python).

class sphinx.addnodes.desc_name(rawsource='', text='', *children, **attributes)[source]

Node for the main object name.

class sphinx.addnodes.desc_parameterlist(rawsource='', text='', *children, **attributes)[source]

Node for a general parameter list.

class sphinx.addnodes.desc_parameter(rawsource='', text='', *children, **attributes)[source]

Node for a single parameter.

class sphinx.addnodes.desc_optional(rawsource='', text='', *children, **attributes)[source]

Node for marking optional parts of the parameter list.

class sphinx.addnodes.desc_annotation(rawsource='', text='', *children, **attributes)[source]

Node for signature annotations (not Python 3-style annotations).

class sphinx.addnodes.desc_content(rawsource='', *children, **attributes)[source]

Node for object description content.

This is the “definition” part of the custom Sphinx definition list.

New admonition-like constructs

class sphinx.addnodes.versionmodified(rawsource='', text='', *children, **attributes)[source]

Node for version change entries.

Currently used for “versionadded”, “versionchanged” and “deprecated” directives.

class sphinx.addnodes.seealso(rawsource='', *children, **attributes)[source]

Custom “see also” admonition.

Other paragraph-level nodes

class sphinx.addnodes.compact_paragraph(rawsource='', text='', *children, **attributes)[source]

Node for a compact paragraph (which never makes a <p> node).

New inline nodes

class sphinx.addnodes.index(rawsource='', text='', *children, **attributes)[source]

Node for index entries.

This node is created by the index directive and has one attribute, entries. Its value is a list of 4-tuples of (entrytype, entryname, target, ignored).

entrytype is one of “single”, “pair”, “double”, “triple”.

class sphinx.addnodes.pending_xref(rawsource='', *children, **attributes)[source]

Node for cross-references that cannot be resolved without complete information about all documents.

These nodes are resolved before writing output, in BuildEnvironment.resolve_references.

class sphinx.addnodes.literal_emphasis(rawsource='', text='', *children, **attributes)[source]

Node that behaves like emphasis, but further text processors are not applied (e.g. smartypants for HTML output).

class sphinx.addnodes.abbreviation(rawsource='', text='', *children, **attributes)[source]

Node for abbreviations with explanations.

class sphinx.addnodes.download_reference(rawsource='', text='', *children, **attributes)[source]

Node for download references, similar to pending_xref.

Special nodes

class sphinx.addnodes.only(rawsource='', *children, **attributes)[source]

Node for “only” directives (conditional inclusion based on tags).

class sphinx.addnodes.meta(rawsource='', *children, **attributes)[source]

Node for meta directive – same as docutils’ standard meta node, but pickleable.

class sphinx.addnodes.highlightlang(rawsource='', *children, **attributes)[source]

Inserted to set the highlight language and line number options for subsequent code blocks.

You should not need to generate the nodes below in extensions.

class sphinx.addnodes.glossary(rawsource='', *children, **attributes)[source]

Node to insert a glossary.

class sphinx.addnodes.toctree(rawsource='', *children, **attributes)[source]

Node for inserting a “TOC tree”.

class sphinx.addnodes.start_of_file(rawsource='', *children, **attributes)[source]

Node to mark start of a new file, used in the LaTeX builder only.

class sphinx.addnodes.productionlist(rawsource='', *children, **attributes)[source]

Node for grammar production lists.

Contains production nodes.

class sphinx.addnodes.production(rawsource='', text='', *children, **attributes)[source]

Node for a single grammar production rule.

class sphinx.addnodes.termsep(*args, **kw)[source]

Separates two terms within a <term> node.

Changed in version 1.4: sphinx.addnodes.termsep is deprecated. It will be removed at Sphinx-1.5.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Sphinx Web Support

New in version 1.1.

Sphinx provides a Python API to easily integrate Sphinx documentation into your web application. To learn more read the Web Support Quick Start.

- Web Support Quick Start

- Building Documentation Data

- Integrating Sphinx Documents Into Your Webapp

- Authentication

- Performing Searches

- Comments & Proposals

- Comment Moderation

- The WebSupport Class

- Methods

- Search Adapters

- BaseSearch Methods

- Storage Backends

- StorageBackend Methods

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Web Support »

Web Support Quick Start

Building Documentation Data

To make use of the web support package in your application you’ll need to build the data it uses. This data includes pickle files representing documents, search indices, and node data that is used to track where comments and other things are in a document. To do this you will need to create an instance of the WebSupport class and call its build() method:

from sphinx.websupport import WebSupport

support = WebSupport(srcdir='/path/to/rst/sources/',
builddir='/path/to/build/outdir',
search='xapian')

support.build()

This will read reStructuredText sources from srcdir and place the necessary data in builddir. The builddir will contain two sub-directories: one named “data” that contains all the data needed to display documents, search through documents, and add comments to documents. The other directory will be called “static” and contains static files that should be served from “/static”.

Note

If you wish to serve static files from a path other than “/static”, you can do so by providing the staticdir keyword argument when creating the WebSupport object.

Integrating Sphinx Documents Into Your Webapp

Now that the data is built, it’s time to do something useful with it. Start off by creating a WebSupport object for your application:

from sphinx.websupport import WebSupport

support = WebSupport(datadir='/path/to/the/data',
search='xapian')

You’ll only need one of these for each set of documentation you will be working with. You can then call its get_document() method to access individual documents:

contents = support.get_document('contents')

This will return a dictionary containing the following items:

- body: The main body of the document as HTML

- sidebar: The sidebar of the document as HTML

- relbar: A div containing links to related documents

- title: The title of the document

- css: Links to CSS files used by Sphinx

- script: JavaScript containing comment options

This dict can then be used as context for templates. The goal is to be easy to integrate with your existing templating system. An example using Jinja2 [http://jinja.pocoo.org/] is:

{%- extends "layout.html" %}

{%- block title %}
{{ document.title }}
{%- endblock %}

{% block css %}
{{ super() }}
{{ document.css|safe }}
<link rel="stylesheet" href="/static/websupport-custom.css" type="text/css">
{% endblock %}

{%- block script %}
{{ super() }}
{{ document.script|safe }}
{%- endblock %}

{%- block relbar %}
{{ document.relbar|safe }}
{%- endblock %}

{%- block body %}
{{ document.body|safe }}
{%- endblock %}

{%- block sidebar %}
{{ document.sidebar|safe }}
{%- endblock %}

Authentication

To use certain features such as voting, it must be possible to authenticate users. The details of the authentication are left to your application. Once a user has been authenticated you can pass the user’s details to certain WebSupport methods using the username and moderator keyword arguments. The web support package will store the username with comments and votes. The only caveat is that if you allow users to change their username you must update the websupport package’s data:

support.update_username(old_username, new_username)

username should be a unique string which identifies a user, and moderator should be a boolean representing whether the user has moderation privileges. The default value for moderator is False.

An example Flask [http://flask.pocoo.org/] function that checks whether a user is logged in and then retrieves a document is:

from sphinx.websupport.errors import *

@app.route('/<path:docname>')
def doc(docname):
username = g.user.name if g.user else ''
moderator = g.user.moderator if g.user else False
try:
document = support.get_document(docname, username, moderator)
except DocumentNotFoundError:
abort(404)
return render_template('doc.html', document=document)

The first thing to notice is that the docname is just the request path. This makes accessing the correct document easy from a single view. If the user is authenticated, then the username and moderation status are passed along with the docname to get_document(). The web support package will then add this data to the COMMENT_OPTIONS that are used in the template.

Note

This only works if your documentation is served from your document root. If it is served from another directory, you will need to prefix the url route with that directory, and give the docroot keyword argument when creating the web support object:

support = WebSupport(..., docroot='docs')

@app.route('/docs/<path:docname>')

Performing Searches

To use the search form built-in to the Sphinx sidebar, create a function to handle requests to the url ‘search’ relative to the documentation root. The user’s search query will be in the GET parameters, with the key q. Then use the get_search_results() method to retrieve search results. In Flask [http://flask.pocoo.org/] that would be like this:

@app.route('/search')
def search():
q = request.args.get('q')
document = support.get_search_results(q)
return render_template('doc.html', document=document)

Note that we used the same template to render our search results as we did to render our documents. That’s because get_search_results() returns a context dict in the same format that get_document() does.

Comments & Proposals

Now that this is done it’s time to define the functions that handle the AJAX calls from the script. You will need three functions. The first function is used to add a new comment, and will call the web support method add_comment():

@app.route('/docs/add_comment', methods=['POST'])
def add_comment():
parent_id = request.form.get('parent', '')
node_id = request.form.get('node', '')
text = request.form.get('text', '')
proposal = request.form.get('proposal', '')
username = g.user.name if g.user is not None else 'Anonymous'
comment = support.add_comment(text, node_id='node_id',
parent_id='parent_id',
username=username, proposal=proposal)
return jsonify(comment=comment)

You’ll notice that both a parent_id and node_id are sent with the request. If the comment is being attached directly to a node, parent_id will be empty. If the comment is a child of another comment, then node_id will be empty. Then next function handles the retrieval of comments for a specific node, and is aptly named get_data():

@app.route('/docs/get_comments')
def get_comments():
username = g.user.name if g.user else None
moderator = g.user.moderator if g.user else False
node_id = request.args.get('node', '')
data = support.get_data(node_id, username, moderator)
return jsonify(**data)

The final function that is needed will call process_vote(), and will handle user votes on comments:

@app.route('/docs/process_vote', methods=['POST'])
def process_vote():
if g.user is None:
abort(401)
comment_id = request.form.get('comment_id')
value = request.form.get('value')
if value is None or comment_id is None:
abort(400)
support.process_vote(comment_id, g.user.id, value)
return "success"

Comment Moderation

By default, all comments added through add_comment() are automatically displayed. If you wish to have some form of moderation, you can pass the displayed keyword argument:

comment = support.add_comment(text, node_id='node_id',
parent_id='parent_id',
username=username, proposal=proposal,
displayed=False)

You can then create a new view to handle the moderation of comments. It will be called when a moderator decides a comment should be accepted and displayed:

@app.route('/docs/accept_comment', methods=['POST'])
def accept_comment():
moderator = g.user.moderator if g.user else False
comment_id = request.form.get('id')
support.accept_comment(comment_id, moderator=moderator)
return 'OK'

Rejecting comments happens via comment deletion.

To perform a custom action (such as emailing a moderator) when a new comment is added but not displayed, you can pass callable to the WebSupport class when instantiating your support object:

def moderation_callback(comment):
"""Do something..."""

support = WebSupport(..., moderation_callback=moderation_callback)

The moderation callback must take one argument, which will be the same comment dict that is returned by add_comment().

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Web Support »

The WebSupport Class

class sphinx.websupport.WebSupport[source]

The main API class for the web support package. All interactions with the web support package should occur through this class.

The class takes the following keyword arguments:

srcdir

The directory containing reStructuredText source files.

builddir

The directory that build data and static files should be placed in. This should be used when creating a WebSupport object that will be used to build data.

datadir

The directory that the web support data is in. This should be used when creating a WebSupport object that will be used to retrieve data.

search

This may contain either a string (e.g. ‘xapian’) referencing a built-in search adapter to use, or an instance of a subclass of BaseSearch.

storage

This may contain either a string representing a database uri, or an instance of a subclass of StorageBackend. If this is not provided, a new sqlite database will be created.

moderation_callback

A callable to be called when a new comment is added that is not displayed. It must accept one argument: a dictionary representing the comment that was added.

staticdir

If static files are served from a location besides '/static', this should be a string with the name of that location (e.g. '/static_files').

docroot

If the documentation is not served from the base path of a URL, this should be a string specifying that path (e.g. 'docs').

Methods

WebSupport.build()[source]

Build the documentation. Places the data into the outdir directory. Use it like this:

support = WebSupport(srcdir, builddir, search='xapian')
support.build()

This will read reStructured text files from srcdir. Then it will build the pickles and search index, placing them into builddir. It will also save node data to the database.

WebSupport.get_document(docname, username='', moderator=False)[source]

Load and return a document from a pickle. The document will be a dict object which can be used to render a template:

support = WebSupport(datadir=datadir)
support.get_document('index', username, moderator)

In most cases docname will be taken from the request path and passed directly to this function. In Flask, that would be something like this:

@app.route('/<path:docname>')
def index(docname):
username = g.user.name if g.user else ''
moderator = g.user.moderator if g.user else False
try:
document = support.get_document(docname, username,
moderator)
except DocumentNotFoundError:
abort(404)
render_template('doc.html', document=document)

The document dict that is returned contains the following items to be used during template rendering.

- body: The main body of the document as HTML

- sidebar: The sidebar of the document as HTML

- relbar: A div containing links to related documents

- title: The title of the document

- css: Links to css files used by Sphinx

- script: Javascript containing comment options

This raises DocumentNotFoundError if a document matching docname is not found.

WebSupport.get_data(node_id, username=None, moderator=False)[source]

Get the comments and source associated with node_id. If username is given vote information will be included with the returned comments. The default CommentBackend returns a dict with two keys, source, and comments. source is raw source of the node and is used as the starting point for proposals a user can add. comments is a list of dicts that represent a comment, each having the following items:

WebSupport.add_comment(text, node_id='', parent_id='', displayed=True, username=None, time=None, proposal=None, moderator=False)[source]

Add a comment to a node or another comment. Returns the comment in the same format as get_comments(). If the comment is being attached to a node, pass in the node’s id (as a string) with the node keyword argument:

comment = support.add_comment(text, node_id=node_id)

If the comment is the child of another comment, provide the parent’s id (as a string) with the parent keyword argument:

comment = support.add_comment(text, parent_id=parent_id)

If you would like to store a username with the comment, pass in the optional username keyword argument:

comment = support.add_comment(text, node=node_id,
username=username)

WebSupport.process_vote(comment_id, username, value)[source]

Process a user’s vote. The web support package relies on the API user to perform authentication. The API user will typically receive a comment_id and value from a form, and then make sure the user is authenticated. A unique username must be passed in, which will also be used to retrieve the user’s past voting data. An example, once again in Flask:

@app.route('/docs/process_vote', methods=['POST'])
def process_vote():
if g.user is None:
abort(401)
comment_id = request.form.get('comment_id')
value = request.form.get('value')
if value is None or comment_id is None:
abort(400)
support.process_vote(comment_id, g.user.name, value)
return "success"

WebSupport.get_search_results(q)[source]

Perform a search for the query q, and create a set of search results. Then render the search results as html and return a context dict like the one created by get_document():

document = support.get_search_results(q)

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Web Support »

Search Adapters

To create a custom search adapter you will need to subclass the BaseSearch class. Then create an instance of the new class and pass that as the search keyword argument when you create the WebSupport object:

support = WebSupport(srcdir=srcdir,
builddir=builddir,
search=MySearch())

For more information about creating a custom search adapter, please see the documentation of the BaseSearch class below.

class sphinx.websupport.search.BaseSearch[source]

Defines an interface for search adapters.

BaseSearch Methods

The following methods are defined in the BaseSearch class. Some methods do not need to be overridden, but some (add_document() and handle_query()) must be overridden in your subclass. For a working example, look at the built-in adapter for whoosh.

BaseSearch.init_indexing(changed=[])[source]

Called by the builder to initialize the search indexer. changed is a list of pagenames that will be reindexed. You may want to remove these from the search index before indexing begins.

BaseSearch.finish_indexing()[source]

Called by the builder when writing has been completed. Use this to perform any finalization or cleanup actions after indexing is complete.

BaseSearch.feed(pagename, title, doctree)[source]

Called by the builder to add a doctree to the index. Converts the doctree to text and passes it to add_document(). You probably won’t want to override this unless you need access to the doctree. Override add_document() instead.

BaseSearch.add_document(pagename, title, text)[source]

Called by feed() to add a document to the search index. This method should should do everything necessary to add a single document to the search index.

pagename is name of the page being indexed. It is the combination of the source files relative path and filename, minus the extension. For example, if the source file is “ext/builders.rst”, the pagename would be “ext/builders”. This will need to be returned with search results when processing a query.

BaseSearch.query(q)[source]

Called by the web support api to get search results. This method compiles the regular expression to be used when extracting context, then calls handle_query(). You won’t want to override this unless you don’t want to use the included extract_context() method. Override handle_query() instead.

BaseSearch.handle_query(q)[source]

Called by query() to retrieve search results for a search query q. This should return an iterable containing tuples of the following format:

(<path>, <title>, <context>)

path and title are the same values that were passed to add_document(), and context should be a short text snippet of the text surrounding the search query in the document.

The extract_context() method is provided as a simple way to create the context.

BaseSearch.extract_context(text, length=240)[source]

Extract the context for the search query from the document’s full text.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

- Sphinx Web Support »

Storage Backends

To create a custom storage backend you will need to subclass the StorageBackend class. Then create an instance of the new class and pass that as the storage keyword argument when you create the WebSupport object:

support = WebSupport(srcdir=srcdir,
builddir=builddir,
storage=MyStorage())

For more information about creating a custom storage backend, please see the documentation of the StorageBackend class below.

class sphinx.websupport.storage.StorageBackend[source]

Defines an interface for storage backends.

StorageBackend Methods

StorageBackend.pre_build()[source]

Called immediately before the build process begins. Use this to prepare the StorageBackend for the addition of nodes.

StorageBackend.add_node(id, document, source)[source]

Add a node to the StorageBackend.

StorageBackend.post_build()[source]

Called after a build has completed. Use this to finalize the addition of nodes if needed.

StorageBackend.add_comment(text, displayed, username, time, proposal, node_id, parent_id, moderator)[source]

Called when a comment is being added.

StorageBackend.delete_comment(comment_id, username, moderator)[source]

Delete a comment.

Raises UserNotAuthorizedError if moderator is False and username doesn’t match the username on the comment.

StorageBackend.get_data(node_id, username, moderator)[source]

Called to retrieve all data for a node. This should return a dict with two keys, source and comments as described by WebSupport‘s get_data() method.

StorageBackend.process_vote(comment_id, username, value)[source]

Process a vote that is being cast. value will be either -1, 0, or 1.

StorageBackend.update_username(old_username, new_username)[source]

If a user is allowed to change their username this method should be called so that there is not stagnate data in the storage system.

StorageBackend.accept_comment(comment_id)[source]

Called when a moderator accepts a comment. After the method is called the comment should be displayed to all users.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Sphinx FAQ

This is a list of Frequently Asked Questions about Sphinx. Feel free to suggest new entries!

How do I...

... create PDF files without LaTeX?

You can use rst2pdf [https://github.com/rst2pdf/rst2pdf] version 0.12 or greater which comes with built-in Sphinx integration. See the Available builders section for details.

... get section numbers?

They are automatic in LaTeX output; for HTML, give a :numbered: option to the toctree directive where you want to start numbering.

... customize the look of the built HTML files?

Use themes, see HTML theming support.

... add global substitutions or includes?

Add them in the rst_epilog config value.

... display the whole TOC tree in the sidebar?

Use the toctree callable in a custom layout template, probably in the sidebartoc block.

... write my own extension?

See the extension tutorial.

... convert from my existing docs using MoinMoin markup?

The easiest way is to convert to xhtml, then convert xhtml to reST [http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py]. You’ll still need to mark up classes and such, but the headings and code examples come through cleanly.

... create HTML slides from Sphinx documents?

See the “Hieroglyph” package at https://github.com/nyergler/hieroglyph.

For many more extensions and other contributed stuff, see the sphinx-contrib [https://bitbucket.org/birkenfeld/sphinx-contrib/] repository.

Using Sphinx with...

Read the Docs

https://readthedocs.org is a documentation hosting service based around Sphinx. They will host sphinx documentation, along with supporting a number of other features including version support, PDF generation, and more. The Getting Started [http://read-the-docs.readthedocs.org/en/latest/getting_started.html] guide is a good place to start.

Epydoc

There’s a third-party extension providing an api role [http://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py] which refers to Epydoc’s API docs for a given identifier.

Doxygen

Michael Jones is developing a reST/Sphinx bridge to doxygen called breathe [https://github.com/michaeljones/breathe/tree/master].

SCons

Glenn Hutchings has written a SCons build script to build Sphinx documentation; it is hosted here: https://bitbucket.org/zondo/sphinx-scons

PyPI

Jannis Leidel wrote a setuptools command [https://pypi.python.org/pypi/Sphinx-PyPI-upload] that automatically uploads Sphinx documentation to the PyPI package documentation area at http://pythonhosted.org/.

GitHub Pages

Directories starting with underscores are ignored by default which breaks static files in Sphinx. GitHub’s preprocessor can be disabled [https://github.com/blog/572-bypassing-jekyll-on-github-pages] to support Sphinx HTML output properly.

MediaWiki

See https://bitbucket.org/kevindunn/sphinx-wiki/wiki/Home, a project by Kevin Dunn.

Google Analytics

You can use a custom layout.html template, like this:

{% extends "!layout.html" %}

{%- block extrahead %}
{{ super() }}
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'XXX account number XXX']);
_gaq.push(['_trackPageview']);
</script>
{% endblock %}

{% block footer %}
{{ super() }}
<div class="footer">This page uses <a href="http://analytics.google.com/">
Google Analytics</a> to collect statistics. You can disable it by blocking
the JavaScript coming from www.google-analytics.com.
<script type="text/javascript">
(function() {
var ga = document.createElement('script');
ga.src = ('https:' == document.location.protocol ?
'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
ga.setAttribute('async', 'true');
document.documentElement.firstChild.appendChild(ga);
})();
</script>
</div>
{% endblock %}

Epub info

The following list gives some hints for the creation of epub files:

- Split the text into several files. The longer the individual HTML files are, the longer it takes the ebook reader to render them. In extreme cases, the rendering can take up to one minute.

- Try to minimize the markup. This also pays in rendering time.

- For some readers you can use embedded or external fonts using the CSS @font-face directive. This is extremely useful for code listings which are often cut at the right margin. The default Courier font (or variant) is quite wide and you can only display up to 60 characters on a line. If you replace it with a narrower font, you can get more characters on a line. You may even use FontForge [http://fontforge.github.io/] and create narrow variants of some free font. In my case I get up to 70 characters on a line.

You may have to experiment a little until you get reasonable results.

- Test the created epubs. You can use several alternatives. The ones I am aware of are Epubcheck [https://code.google.com/archive/p/epubcheck], Calibre [http://calibre-ebook.com/], FBreader [https://fbreader.org/] (although it does not render the CSS), and Bookworm [http://www.oreilly.com/bookworm/index.html]. For bookworm you can download the source from https://code.google.com/archive/p/threepress and run your own local server.

- Large floating divs are not displayed properly. If they cover more than one page, the div is only shown on the first page. In that case you can copy the epub.css from the sphinx/themes/epub/static/ directory to your local _static/ directory and remove the float settings.

- Files that are inserted outside of the toctree directive must be manually included. This sometimes applies to appendixes, e.g. the glossary or the indices. You can add them with the epub_post_files option.

- The handling of the epub cover page differs from the reStructuredText procedure which automatically resolves image paths and puts the images into the _images directory. For the epub cover page put the image in the html_static_path directory and reference it with its full path in the epub_cover config option.

Texinfo info

There are two main programs for reading Info files, info and GNU Emacs. The info program has less features but is available in most Unix environments and can be quickly accessed from the terminal. Emacs provides better font and color display and supports extensive customization (of course).

Displaying Links

One noticeable problem you may encounter with the generated Info files is how references are displayed. If you read the source of an Info file, a reference to this section would look like:

* note Displaying Links: target-id

In the stand-alone reader, info, references are displayed just as they appear in the source. Emacs, on the other-hand, will by default replace *note: with see and hide the target-id. For example:

Displaying Links

The exact behavior of how Emacs displays references is dependent on the variable Info-hide-note-references. If set to the value of hide, Emacs will hide both the *note: part and the target-id. This is generally the best way to view Sphinx-based documents since they often make frequent use of links and do not take this limitation into account. However, changing this variable affects how all Info documents are displayed and most due take this behavior into account.

If you want Emacs to display Info files produced by Sphinx using the value hide for Info-hide-note-references and the default value for all other Info files, try adding the following Emacs Lisp code to your start-up file, ~/.emacs.d/init.el.

(defadvice info-insert-file-contents (after
sphinx-info-insert-file-contents
activate)
"Hack to make `Info-hide-note-references' buffer-local and
automatically set to `hide' iff it can be determined that this file
was created from a Texinfo file generated by Docutils or Sphinx."
(set (make-local-variable 'Info-hide-note-references)
(default-value 'Info-hide-note-references))
(save-excursion
(save-restriction
(widen) (goto-char (point-min))
(when (re-search-forward
"^Generated by \\(Sphinx\\|Docutils\\)"
(save-excursion (search-forward "\x1f" nil t)) t)
(set (make-local-variable 'Info-hide-note-references)
'hide)))))

Notes

The following notes may be helpful if you want to create Texinfo files:

- Each section corresponds to a different node in the Info file.

- Colons (:) cannot be properly escaped in menu entries and xrefs. They will be replaced with semicolons (;).

- Links to external Info files can be created using the somewhat official URI scheme info. For example:

info:Texinfo#makeinfo_options

which produces:

info:Texinfo#makeinfo_options

- Inline markup

The standard formatting for *strong* and _emphasis_ can result in ambiguous output when used to markup parameter names and other values. Since this is a fairly common practice, the default formatting has been changed so that emphasis and strong are now displayed like `literal's.

The standard formatting can be re-enabled by adding the following to your conf.py:

texinfo_elements = {'preamble': """
@definfoenclose strong,*,*
@definfoenclose emph,_,_
"""}

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Glossary

builder

A class (inheriting from 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 documentation, or build coverage information.

See Available builders for an overview over Sphinx’s built-in builders.

configuration directory

The directory containing conf.py. By default, this is the same as the source directory, but can be set differently with the -c command-line option.

directive

A reStructuredText markup element that allows marking a block of content with special meaning. Directives are supplied not only by docutils, but Sphinx and custom extensions can add their own. The basic directive syntax looks like this:

.. directivename:: argument ...
:option: value

Content of the directive.

See Directives for more information.

document name

Since reST source files can have different extensions (some people like .txt, some like .rst – the extension can be configured with source_suffix) and different OSes have different path separators, Sphinx abstracts them: document names are always relative to the source directory, the extension is stripped, and path separators are converted to slashes. All values, parameters and such referring to “documents” expect such document names.

Examples for document names are index, library/zipfile, or reference/datamodel/types. Note that there is no leading or trailing slash.

domain

A domain is a collection of markup (reStructuredText directives and roles) to describe and link to objects belonging together, e.g. elements of a programming language. Directive and role names in a domain have names like domain:name, e.g. py:function.

Having domains means that there are no naming problems when one set of documentation wants to refer to e.g. C++ and Python classes. It also means that extensions that support the documentation of whole new languages are much easier to write. For more information about domains, see the chapter Sphinx Domains.

environment

A structure where information about all documents under the root is saved, and used for cross-referencing. The environment is pickled after the parsing stage, so that successive runs only need to read and parse new and changed documents.

master document

The document that contains the root toctree directive.

object

The basic building block of Sphinx documentation. Every “object directive” (e.g. function or object) creates such a block; and most objects can be cross-referenced to.

role

A reStructuredText markup element that allows marking a piece of text. Like directives, roles are extensible. The basic syntax looks like this: :rolename:`content`. See Inline markup for details.

source directory

The directory which, including its subdirectories, contains all source files for one Sphinx project.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Sphinx Developer’s Guide

Abstract

This document describes the development process of Sphinx, a documentation system used by developers to document systems used by other developers to develop other systems that may also be documented using Sphinx.

The Sphinx source code is managed using Git and is hosted on Github.

git clone git://github.com/sphinx-doc/sphinx

Community

sphinx-users <sphinx-users@googlegroups.com>

Mailing list for user support.

sphinx-dev <sphinx-dev@googlegroups.com>

Mailing list for development related discussions.

#sphinx-doc on irc.freenode.net

IRC channel for development questions and user support.

Bug Reports and Feature Requests

If you have encountered a problem with Sphinx or have an idea for a new feature, please submit it to the issue tracker [https://github.com/sphinx-doc/sphinx/issues] on Github or discuss it on the sphinx-dev mailing list.

For bug reports, please include the output produced during the build process and also the log file Sphinx creates after it encounters an un-handled exception. The location of this file should be shown towards the end of the error message.

Including or providing a link to the source files involved may help us fix the issue. If possible, try to create a minimal project that produces the error and post that instead.

Contributing to Sphinx

The recommended way for new contributors to submit code to Sphinx is to fork the repository on Github and then submit a pull request after committing the changes. The pull request will then need to be approved by one of the core developers before it is merged into the main repository.

1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.

2. If you feel uncomfortable or uncertain about an issue or your changes, feel free to email sphinx-dev@googlegroups.com.

3. Fork the repository [https://github.com/sphinx-doc/sphinx] on Github to start making your changes to the master branch for next major version, or stable branch for next minor version.

4. Write a test which shows that the bug was fixed or that the feature works as expected.

5. Send a pull request and bug the maintainer until it gets merged and published. Make sure to add yourself to AUTHORS [https://github.com/sphinx-doc/sphinx/blob/master/AUTHORS] and the change to CHANGES [https://github.com/sphinx-doc/sphinx/blob/master/CHANGES].

Getting Started

These are the basic steps needed to start developing on Sphinx.

1. Create an account on Github.

2. Fork the main Sphinx repository (sphinx-doc/sphinx [https://github.com/sphinx-doc/sphinx]) using the Github interface.

3. Clone the forked repository to your machine.

git clone https://github.com/USERNAME/sphinx
cd sphinx

4. Checkout the appropriate branch.

For changes that should be included in the next minor release (namely bug fixes), use the stable branch.

git checkout stable

For new features or other substantial changes that should wait until the next major release, use the master branch.

5. Optional: setup a virtual environment.

virtualenv ~/sphinxenv
. ~/sphinxenv/bin/activate
pip install -e .

6. Create a new working branch. Choose any name you like.

git checkout -b feature-xyz

7. Hack, hack, hack.

For tips on working with the code, see the Coding Guide.

8. Test, test, test. Possible steps:

- Run the unit tests:

pip install -r test-reqs.txt
make test

- Build the documentation and check the output for different builders:

cd doc
make clean html latexpdf

- Run the unit tests under different Python environments using tox:

pip install tox
tox -v

- Add a new unit test in the tests directory if you can.

- For bug fixes, first add a test that fails without your changes and passes after they are applied.

- Tests that need a sphinx-build run should be integrated in one of the existing test modules if possible. New tests that to @with_app and then build_all for a few assertions are not good since the test suite should not take more than a minute to run.

9. Please add a bullet point to CHANGES if the fix or feature is not trivial (small doc updates, typo fixes). Then commit:

git commit -m '#42: Add useful new feature that does this.'

Github recognizes certain phrases that can be used to automatically update the issue tracker.

For example:

git commit -m 'Closes #42: Fix invalid markup in docstring of Foo.bar.'

would close issue #42.

10. Push changes in the branch to your forked repository on Github.

git push origin feature-xyz

11. Submit a pull request from your branch to the respective branch (master or stable) on sphinx-doc/sphinx using the Github interface.

12. Wait for a core developer to review your changes.

Core Developers

The core developers of Sphinx have write access to the main repository. They can commit changes, accept/reject pull requests, and manage items on the issue tracker.

You do not need to be a core developer or have write access to be involved in the development of Sphinx. You can submit patches or create pull requests from forked repositories and have a core developer add the changes for you.

The following are some general guidelines for core developers:

- Questionable or extensive changes should be submitted as a pull request instead of being committed directly to the main repository. The pull request should be reviewed by another core developer before it is merged.

- Trivial changes can be committed directly but be sure to keep the repository in a good working state and that all tests pass before pushing your changes.

- When committing code written by someone else, please attribute the original author in the commit message and any relevant CHANGES entry.

Locale updates

The parts of messages in Sphinx that go into builds are translated into several locales. The translations are kept as gettext .po files translated from the master template sphinx/locale/sphinx.pot.

Sphinx uses Babel [http://babel.edgewall.org] to extract messages and maintain the catalog files. It is integrated in setup.py:

- Use python setup.py extract_messages to update the .pot template.

- Use python setup.py update_catalog to update all existing language catalogs in sphinx/locale/*/LC_MESSAGES with the current messages in the template file.

- Use python setup.py compile_catalog to compile the .po files to binary .mo files and .js files.

When an updated .po file is submitted, run compile_catalog to commit both the source and the compiled catalogs.

When a new locale is submitted, add a new directory with the ISO 639-1 language identifier and put sphinx.po in there. Don’t forget to update the possible values for language in doc/config.rst.

The Sphinx core messages can also be translated on Transifex [https://www.transifex.com/]. There exists a client tool named tx in the Python package “transifex_client”, which can be used to pull translations in .po format from Transifex. To do this, go to sphinx/locale and then run tx pull -f -l LANG where LANG is an existing language identifier. It is good practice to run python setup.py update_catalog afterwards to make sure the .po file has the canonical Babel formatting.

Coding Guide

- Try to use the same code style as used in the rest of the project. See the Pocoo Styleguide [http://flask.pocoo.org/docs/styleguide/] for more information.

- For non-trivial changes, please update the CHANGES file. If your changes alter existing behavior, please document this.

- New features should be documented. Include examples and use cases where appropriate. If possible, include a sample that is displayed in the generated output.

- When adding a new configuration variable, be sure to document it and update sphinx/quickstart.py if it’s important enough.

- Use the included utils/check_sources.py script to check for common formatting issues (trailing whitespace, lengthy lines, etc).

- Add appropriate unit tests.

Debugging Tips

- Delete the build cache before building documents if you make changes in the code by running the command make clean or using the sphinx-build -E option.

- Use the sphinx-build -P option to run Pdb on exceptions.

- Use node.pformat() and node.asdom().toxml() to generate a printable representation of the document structure.

- Set the configuration variable keep_warnings to True so warnings will be displayed in the generated output.

- Set the configuration variable nitpicky to True so that Sphinx will complain about references without a known target.

- Set the debugging options in the Docutils configuration file [http://docutils.sourceforge.net/docs/user/config.html].

- JavaScript stemming algorithms in sphinx/search/*.py (except en.py) are generated by this modified snowballcode generator [https://github.com/shibukawa/snowball]. Generated JSX [http://jsx.github.io/] files are in this repository [https://github.com/shibukawa/snowball-stemmer.jsx]. You can get the resulting JavaScript files using the following command:

$ npm install
$ node_modules/.bin/grunt build # -> dest/*.global.js

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Changes in Sphinx

Release 1.4.2 (in development)

Features added

- Now suppress_warnings accepts following configurations (ref: #2451, #2466):

- app.add_node

- app.add_directive

- app.add_role

- app.add_generic_role

- app.add_source_parser

- image.data_uri

- image.nonlocal_uri

- #2453: LaTeX writer allows page breaks in topic contents; and their horizontal extent now fits in the line width (with shadow in margin). Also warning-type admonitions allow page breaks and their vertical spacing has been made more coherent with the one for hint-type notices (ref #2446).

- #2459: the framing of literal code-blocks in LaTeX output (and not only the code lines themselves) obey the indentation in lists or quoted blocks.

- #2343: the long source lines in code-blocks are wrapped (without modifying

the line numbering) in LaTeX output (ref #1534, #2304).

Bugs fixed

- #2370: the equations are slightly misaligned in LaTeX writer

- #1817, #2077: suppress pep8 warnings on conf.py generated by sphinx-quickstart

- #2407: building docs crash if document includes large data image URIs

- #2436: Sphinx does not check version by needs_sphinx if loading extensions failed

- #2397: Setup shorthandoff for turkish documents

- #2447: VerbatimBorderColor wrongly used also for captions of PDF

- #2456: C++, fix crash related to document merging (e.g., singlehtml and Latex builders).

- #2446: latex(pdf) sets local tables of contents (or more generally topic nodes) in unbreakable boxes, causes overflow at bottom

- #2476: Omit MathJax markers if :nowrap: is given

- #2465: latex builder fails in case no caption option is provided to toctree directive

- Sphinx crashes if self referenced toctree found

- #2481: spelling mistake for mecab search splitter. Thanks to Naoki Sato.

- #2309: Fix could not refer “indirect hyperlink targets” by ref-role

- intersphinx fails if mapping URL contains any port

- #2088: intersphinx crashes if the mapping URL requires basic auth

- #2304: auto line breaks in latexpdf codeblocks

- #1534: Word wrap long lines in Latex verbatim blocks

- #2460: too much white space on top of captioned literal blocks in PDF output

- Show error reason when multiple math extensions are loaded (ref: #2499)

- #2483: any figure number was not assigned if figure title contains only non text objects

- #2501: Unicode subscript numbers are normalized in LaTeX

- #2492: Figure directive with :figwidth: generates incorrect Latex-code

- The caption of figure is always put on center even if :align: was specified

- #2526: LaTeX writer crashes if the section having only images

- #2522: Sphinx touches mo files under installed directory that caused permission error.

Release 1.4.1 (released Apr 12, 2016)

Incompatible changes

- The default format of today_fmt and html_last_updated_fmt is back to strftime format again. Locale Date Markup Language is also supported for backward compatibility until Sphinx-1.5.

Translations

- Added Welsh translation, thanks to Geraint Palmer.

- Added Greek translation, thanks to Stelios Vitalis.

- Added Esperanto translation, thanks to Dinu Gherman.

- Added Hindi translation, thanks to Purnank H. Ghumalia.

- Added Romanian translation, thanks to Razvan Stefanescu.

Bugs fixed

- C++, added support for extern and thread_local.

- C++, type declarations are now using the prefixes typedef, using, and type, depending on the style of declaration.

- #2413: C++, fix crash on duplicate declarations

- #2394: Sphinx crashes when html_last_updated_fmt is invalid

- #2408: dummy builder not available in Makefile and make.bat

- #2412: hyperlink targets are broken in LaTeX builder

- figure directive crashes if non paragraph item is given as caption

- #2418: time formats no longer allowed in today_fmt

- #2395: Sphinx crashes if unicode character in image filename

- #2396: “too many values to unpack” in genindex-single

- #2405: numref link in PDF jumps to the wrong location

- #2414: missing number in PDF hyperlinks to code listings

- #2440: wrong import for gmtime. Thanks to Uwe L. Korn.

Release 1.4 (released Mar 28, 2016)

Incompatible changes

- Drop PorterStemmer package support. Use PyStemmer instead of PorterStemmer to accelerate stemming.

- sphinx_rtd_theme has become optional. Please install it manually. Refs #2087, #2086, #1845 and #2097. Thanks to Victor Zverovich.

- #2231: Use DUrole instead of DUspan for custom roles in LaTeX writer. It enables to take title of roles as an argument of custom macros.

- #2022: ‘Thumbs.db’ and ‘.DS_Store’ are added to exclude_patterns default values in conf.py that will be provided on sphinx-quickstart.

- #2027, #2208: The html_title accepts string values only. And The None value cannot be accepted.

- sphinx.ext.graphviz: show graph image in inline by default

- #2060, #2224: The manpage role now generate sphinx.addnodes.manpage node instead of sphinx.addnodes.literal_emphasis node.

- #2022: html_extra_path also copies dotfiles in the extra directory, and refers to exclude_patterns to exclude extra files and directories.

- #2300: enhance autoclass:: to use the docstring of __new__ if __init__ method’s is missing of empty

- #2251: Previously, under glossary directives, multiple terms for one definition are converted into single term node and the each terms in the term node are separated by termsep node. In new implementation, each terms are converted into individual term nodes and termsep node is removed. By this change, output layout of every builders are changed a bit.

- The default highlight language is now Python 3. This means that source code is highlighted as Python 3 (which is mostly a superset of Python 2), and no parsing is attempted to distinguish valid code. To get the old behavior back, add highlight_language = "python" to conf.py.

- Locale Date Markup Language [http://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns] like "MMMM dd, YYYY" is default format for today_fmt and html_last_updated_fmt. However strftime format like "%B %d, %Y" is also supported for backward compatibility until Sphinx-1.5. Later format will be disabled from Sphinx-1.5.

- #2327: latex_use_parts is deprecated now. Use latex_toplevel_sectioning instead.

- #2337: Use \url{URL} macro instead of \href{URL}{URL} in LaTeX writer.

- #1498: manpage writer: don’t make whole of item in definition list bold if it includes strong node.

- #582: Remove hint message from quick search box for html output.

- #2378: Sphinx now bundles newfloat.sty

Features added

- #2092: add todo directive support in napoleon package.

- #1962: when adding directives, roles or nodes from an extension, warn if such an element is already present (built-in or added by another extension).

- #1909: Add “doc” references to Intersphinx inventories.

- C++ type alias support (e.g., .. type:: T = int).

- C++ template support for classes, functions, type aliases, and variables (#1729, #1314).

- C++, added new scope management directives namespace-push and namespace-pop.

- #1970: Keyboard shortcuts to navigate Next and Previous topics

- Intersphinx: Added support for fetching Intersphinx inventories with URLs using HTTP basic auth.

- C++, added support for template parameter in function info field lists.

- C++, added support for pointers to member (function).

- #2113: Allow :class: option to code-block directive.

- #2192: Imgmath (pngmath with svg support).

- #2200: Support XeTeX and LuaTeX for the LaTeX builder.

- #1906: Use xcolor over color for fcolorbox where available for LaTeX output.

- #2216: Texinputs makefile improvements.

- #2170: Support for Chinese language search index.

- #2214: Add sphinx.ext.githubpages to publish the docs on GitHub Pages

- #1030: Make page reference names for latex_show_pagerefs translatable

- #2162: Add Sphinx.add_source_parser() to add source_suffix and source_parsers from extension

- #2207: Add sphinx.parsers.Parser class; a base class for new parsers

- #656: Add graphviz_dot option to graphviz directives to switch the dot command

- #1939: Added the dummy builder: syntax check without output.

- #2230: Add math_number_all option to number all displayed math in math extensions

- #2235: needs_sphinx supports micro version comparison

- #2282: Add “language” attribute to html tag in the “basic” theme

- #1779: Add EPUB 3 builder

- #1751: Add todo_link_only to avoid file path and line indication on todolist. Thanks to Francesco Montesano.

- #2199: Use imagesize package to obtain size of images.

- #1099: Add configurable retries to the linkcheck builder. Thanks to Alex Gaynor. Also don’t check anchors starting with !.

- #2300: enhance autoclass:: to use the docstring of __new__ if __init__ method’s is missing of empty

- #1858: Add Sphinx.add_enumerable_node() to add enumerable nodes for numfig feature

- #1286, #2099: Add sphinx.ext.autosectionlabel extension to allow reference sections using its title. Thanks to Tadhg O’Higgins.

- #1854: Allow to choose Janome for Japanese splitter.

- #1853: support custom text splitter on html search with language='ja'.

- #2320: classifier of glossary terms can be used for index entries grouping key. The classifier also be used for translation. See also Glossary.

- #2308: Define \tablecontinued macro to redefine the style of continued label for longtables.

- Select an image by similarity if multiple images are globbed by .. image:: filename.*

- #1921: Support figure substitutions by language and figure_language_filename

- #2245: Add latex_elements["passoptionstopackages"] option to call PassOptionsToPackages in early stage of preambles.

- #2340: Math extension: support alignment of multiple equations for MathJAX.

- #2338: Define \titleref macro to redefine the style of title-reference roles.

- Define \menuselection and \accelerator macros to redefine the style of menuselection roles.

- Define \crossref macro to redefine the style of references

- #2301: Texts in the classic html theme should be hyphenated.

- #2355: Define \termref macro to redefine the style of term roles.

- Add suppress_warnings to suppress arbitrary warning message (experimental)

- #2229: Fix no warning is given for unknown options

- #2327: Add latex_toplevel_sectioning to switch the top level sectioning of LaTeX document.

Bugs fixed

- #1913: C++, fix assert bug for enumerators in next-to-global and global scope.

- C++, fix parsing of ‘signed char’ and ‘unsigned char’ as types.

- C++, add missing support for ‘friend’ functions.

- C++, add missing support for virtual base classes (thanks to Rapptz).

- C++, add support for final classes.

- C++, fix parsing of types prefixed with ‘enum’.

- #2023: Dutch search support uses Danish stemming info.

- C++, add support for user-defined literals.

- #1804: Now html output wraps overflowed long-line-text in the sidebar. Thanks to Hassen ben tanfous.

- #2183: Fix porterstemmer causes make json to fail.

- #1899: Ensure list is sent to OptParse.

- #2164: Fix wrong check for pdftex inside sphinx.sty (for graphicx package option).

- #2165, #2218: Remove faulty and non-need conditional from sphinx.sty.

- Fix broken LaTeX code is generated if unknown language is given

- #1944: Fix rst_prolog breaks file-wide metadata

- #2074: make gettext should use canonical relative paths for .pot. Thanks to anatoly techtonik.

- #2311: Fix sphinx.ext.inheritance_diagram raises AttributeError

- #2251: Line breaks in .rst files are transferred to .pot files in a wrong way.

- #794: Fix date formatting in latex output is not localized

- Remove image/gif from supported_image_types of LaTeX writer (#2272)

- Fix ValueError is raised if LANGUAGE is empty string

- Fix unpack warning is shown when the directives generated from Sphinx.add_crossref_type is used

- The default highlight language is now default. This means that source code is highlighted as Python 3 (which is mostly a superset of Python 2) if possible. To get the old behavior back, add highlight_language = "python" to conf.py.

- #2329: Refresh environment forcely if source directory has changed.

- #2331: Fix code-blocks are filled by block in dvi; remove xcdraw option from xcolor package

- Fix the confval type checker emits warnings if unicode is given to confvals which expects string value

- #2360: Fix numref in LaTeX output is broken

- #2361: Fix additional paragraphs inside the “compound” directive are indented

- #2364: Fix KeyError ‘rootSymbol’ on Sphinx upgrade from older version.

- #2348: Move amsmath and amssymb to before fontpkg on LaTeX writer.

- #2368: Ignore emacs lock files like .#foo.rst by default.

- #2262: literal_block and its caption has been separated by pagebreak in LaTeX output.

- #2319: Fix table counter is overrided by code-block’s in LaTeX. Thanks to jfbu.

- Fix unpack warning if combinated with 3rd party domain extensions.

- #1153: Fix figures in sidebar causes latex build error.

- #2358: Fix user-preamble could not override the tocdepth definition.

- #2358: Redece tocdepth if part or chapter is used for top_sectionlevel.

- #2351: Fix footnote spacing

- #2363: Fix toctree() in templates generates broken links in SingleHTMLBuilder.

- #2366: Fix empty hyperref is generated on toctree in HTML builder.

Documentation

- #1757: Fix for usage of html_last_updated_fmt. Thanks to Ralf Hemmecke.

Release 1.3.6 (released Feb 29, 2016)

Features added

- #1873, #1876, #2278: Add page_source_suffix html context variable. This should be introduced with source_parsers feature. Thanks for Eric Holscher.

Bugs fixed

- #2265: Fix babel is used in spite of disabling it on latex_elements

- #2295: Avoid mutating dictionary errors while enumerating members in autodoc with Python 3

- #2291: Fix pdflatex “Counter too large” error from footnotes inside tables of contents

- #2292: Fix some footnotes disappear from LaTeX output

- #2287: sphinx.transforms.Locale always uses rst parser. Sphinx i18n feature should support parsers that specified source_parsers.

- #2290: Fix sphinx.ext.mathbase use of amsfonts may break user choice of math fonts

- #2324: Print a hint how to increase the recursion limit when it is hit.

- #1565, #2229: Revert new warning; the new warning will be triggered from version 1.4 on.

- #2329: Refresh environment forcely if source directory has changed.

- #2019: Fix the domain objects in search result are not escaped

Release 1.3.5 (released Jan 24, 2016)

Bugs fixed

- Fix line numbers was not shown on warnings in LaTeX and texinfo builders

- Fix filenames were not shown on warnings of citations

- Fix line numbers was not shown on warnings in LaTeX and texinfo builders

- Fix line numbers was not shown on warnings of indices

- #2026: Fix LaTeX builder raises error if parsed-literal includes links

- #2243: Ignore strange docstring types for classes, do not crash

- #2247: Fix #2205 breaks make html for definition list with classifiers that contains regular-expression like string

- #1565: Sphinx will now emit a warning that highlighting was skipped if the syntax is incorrect for code-block, literalinclude and so on.

- #2211: Fix paragraphs in table cell doesn’t work in Latex output

- #2253: :pyobject: option of literalinclude directive can’t detect indented body block when the block starts with blank or comment lines.

- Fix TOC is not shown when no :maxdepth: for toctrees (ref: #771)

- Fix warning message for :numref: if target is in orphaned doc (ref: #2244)

Release 1.3.4 (released Jan 12, 2016)

Bugs fixed

- #2134: Fix figure caption with reference causes latex build error

- #2094: Fix rubric with reference not working in Latex

- #2147: Fix literalinclude code in latex does not break in pages

- #1833: Fix email addresses is showed again if latex_show_urls is not None

- #2176: sphinx.ext.graphviz: use <object> instead of <img> to embed svg

- #967: Fix SVG inheritance diagram is not hyperlinked (clickable)

- #1237: Fix footnotes not working in definition list in LaTeX

- #2168: Fix raw directive does not work for text writer

- #2171: Fix cannot linkcheck url with unicode

- #2182: LaTeX: support image file names with more than 1 dots

- #2189: Fix previous sibling link for first file in subdirectory uses last file, not intended previous from root toctree

- #2003: Fix decode error under python2 (only) when make linkcheck is run

- #2186: Fix LaTeX output of mathbb in math

- #1480, #2188: LaTeX: Support math in section titles

- #2071: Fix same footnote in more than two section titles => LaTeX/PDF Bug

- #2040: Fix UnicodeDecodeError in sphinx-apidoc when author contains non-ascii characters

- #2193: Fix shutil.SameFileError if source directory and destination directory are same

- #2178: Fix unparseable C++ cross-reference when referencing a function with :cpp:any:

- #2206: Fix Sphinx latex doc build failed due to a footnotes

- #2201: Fix wrong table caption for tables with over 30 rows

- #2213: Set <blockquote> in the classic theme to fit with <p>

- #1815: Fix linkcheck does not raise an exception if warniserror set to true and link is broken

- #2197: Fix slightly cryptic error message for missing index.rst file

- #1894: Unlisted phony targets in quickstart Makefile

- #2125: Fix unifies behavior of collapsed fields (GroupedField and TypedField)

- #1408: Check latex_logo validity before copying

- #771: Fix latex output doesn’t set tocdepth

- #1820: On Windows, console coloring is broken with colorama version 0.3.3. Now sphinx use colorama>=0.3.5 to avoid this problem.

- #2072: Fix footnotes in chapter-titles do not appear in PDF output

- #1580: Fix paragraphs in longtable don’t work in Latex output

- #1366: Fix centered image not centered in latex

- #1860: Fix man page using :samp: with braces - font doesn’t reset

- #1610: Sphinx crashes in japanese indexing in some systems

- Fix Sphinx crashes if mecab initialization failed

- #2160: Fix broken TOC of PDFs if section includes an image

- #2172: Fix dysfunctional admonition py@lightbox in sphinx.sty. Thanks to jfbu.

- #2198,#2205: make gettext generate broken msgid for definition lists.

- #2062: Escape characters in doctests are treated incorrectly with Python 2.

- #2225: Fix if the option does not begin with dash, linking is not performed

- #2226: Fix math is not HTML-encoded when :nowrap: is given (jsmath, mathjax)

- #1601, #2220: ‘any’ role breaks extended domains behavior. Affected extensions doesn’t support resolve_any_xref and resolve_xref returns problematic node instead of None. sphinxcontrib-httpdomain is one of them.

- #2229: Fix no warning is given for unknown options

Release 1.3.3 (released Dec 2, 2015)

Bugs fixed

- #2177: Fix parallel hangs

- #2012: Fix exception occurred if numfig_format is invalid

- #2142: Provide non-minified JS code in sphinx/search/non-minified-js/*.js for source distribution on PyPI.

- #2148: Error while building devhelp target with non-ASCII document.

Release 1.3.2 (released Nov 29, 2015)

Features added

- #1935: Make “numfig_format” overridable in latex_elements.

Bugs fixed

- #1976: Avoid “2.0” version of Babel because it doesn’t work with Windows environment.

- Add a “default.css” stylesheet (which imports “classic.css”) for compatibility.

- #1788: graphviz extension raises exception when caption option is present.

- #1789: :pyobject: option of literalinclude directive includes following lines after class definitions

- #1790: literalinclude strips empty lines at the head and tail

- #1802: load plugin themes automatically when theme.conf use it as ‘inherit’. Thanks to Takayuki Hirai.

- #1794: custom theme extended from alabaster or sphinx_rtd_theme can’t find base theme.

- #1834: compatibility for docutils-0.13: handle_io_errors keyword argument for docutils.io.FileInput cause TypeError.

- #1823: ‘.’ as <module_path> for sphinx-apidoc cause an unfriendly error. Now ‘.’ is converted to absolute path automatically.

- Fix a crash when setting up extensions which do not support metadata.

- #1784: Provide non-minified JS code in sphinx/search/non-minified-js/*.js

- #1822, #1892: Fix regression for #1061. autosummary can’t generate doc for imported members since sphinx-1.3b3. Thanks to Eric Larson.

- #1793, #1819: “see also” misses a linebreak in text output. Thanks to Takayuki Hirai.

- #1780, #1866: “make text” shows “class” keyword twice. Thanks to Takayuki Hirai.

- #1871: Fix for LaTeX output of tables with one column and multirows.

- Work around the lack of the HTMLParserError exception in Python 3.5.

- #1949: Use safe_getattr in the coverage builder to avoid aborting with descriptors that have custom behavior.

- #1915: Do not generate smart quotes in doc field type annotations.

- #1796: On py3, automated .mo building caused UnicodeDecodeError.

- #1923: Use babel features only if the babel latex element is nonempty.

- #1942: Fix a KeyError in websupport.

- #1903: Fix strange id generation for glossary terms.

- make text will crush if a definition list item has more than 1 classifiers as: term : classifier1 : classifier2.

- #1855: make gettext generates broken po file for definition lists with classifier.

- #1869: Fix problems when dealing with files containing non-ASCII characters. Thanks to Marvin Schmidt.

- #1798: Fix building LaTeX with references in titles.

- #1725: On py2 environment, doctest with using non-ASCII characters causes 'ascii' codec can't decode byte exception.

- #1540: Fix RuntimeError with circular referenced toctree

- #1983: i18n translation feature breaks references which uses section name.

- #1990: Use caption of toctree to title of tableofcontents in LaTeX

- #1987: Fix ampersand is ignored in :menuselection: and :guilabel: on LaTeX builder

- #1994: More supporting non-standard parser (like recommonmark parser) for Translation and WebSupport feature. Now node.rawsource is fall backed to node.astext() during docutils transforming.

- #1989: “make blahblah” on Windows indicate help messages for sphinx-build every time. It was caused by wrong make.bat that generated by Sphinx-1.3.0/1.3.1.

- On Py2 environment, conf.py that is generated by sphinx-quickstart should have u prefixed config value for ‘version’ and ‘release’.

- #2102: On Windows + Py3, using |today| and non-ASCII date format will raise UnicodeEncodeError.

- #1974: UnboundLocalError: local variable ‘domain’ referenced before assignment when using any role and sphinx.ext.intersphinx in same time.

- #2121: multiple words search doesn’t find pages when words across on the page title and the page content.

- #1884, #1885: plug-in html themes cannot inherit another plug-in theme. Thanks to Suzumizaki.

- #1818: sphinx.ext.todo directive generates broken html class attribute as ‘admonition-‘ when language is specified with non-ASCII linguistic area like ‘ru’ or ‘ja’. To fix this, now todo directive can use :class: option.

- #2140: Fix footnotes in table has broken in LaTeX

- #2127: MecabBinder for html searching feature doesn’t work with Python 3. Thanks to Tomoko Uchida.

Release 1.3.1 (released Mar 17, 2015)

Bugs fixed

- #1769: allows generating quickstart files/dirs for destination dir that doesn’t overwrite existent files/dirs. Thanks to WAKAYAMA shirou.

- #1773: sphinx-quickstart doesn’t accept non-ASCII character as a option argument.

- #1766: the message “least Python 2.6 to run” is at best misleading.

- #1772: cross reference in docstrings like :param .write: breaks building.

- #1770, #1774: literalinclude with empty file occurs exception. Thanks to Takayuki Hirai.

- #1777: Sphinx 1.3 can’t load extra theme. Thanks to tell-k.

- #1776: source_suffix = ['.rst'] cause unfriendly error on prior version.

- #1771: automated .mo building doesn’t work properly.

- #1783: Autodoc: Python2 Allow unicode string in __all__. Thanks to Jens Hedegaard Nielsen.

- #1781: Setting html_domain_indices to a list raises a type check warnings.

Release 1.3 (released Mar 10, 2015)

Incompatible changes

- Roles ref, term and menusel now don’t generate emphasis [http://docutils.sourceforge.net/docs/ref/rst/roles.html#emphasis] nodes anymore. If you want to keep italic style, adapt your stylesheet.

- Role numref uses %s as special character to indicate position of figure numbers instead # symbol.

Features added

- Add convenience directives and roles to the C++ domain: directive cpp:var as alias for cpp:member, role :cpp:var as alias for :cpp:member, and role any for cross-reference to any C++ declaraction. #1577, #1744

- The source_suffix config value can now be a list of multiple suffixes.

- Add the ability to specify source parsers by source suffix with the source_parsers config value.

- #1675: A new builder, AppleHelpBuilder, has been added that builds Apple Help Books.

Bugs fixed

- 1.3b3 change breaks a previous gettext output that contains duplicated msgid such as “foo bar” and “version changes in 1.3: foo bar”.

- #1745: latex builder cause maximum recursion depth exceeded when a footnote has a footnote mark itself.

- #1748: SyntaxError in sphinx/ext/ifconfig.py with Python 2.6.

- #1658, #1750: No link created (and warning given) if option does not begin with -, / or +. Thanks to Takayuki Hirai.

- #1753: C++, added missing support for more complex declarations.

- #1700: Add :caption: option for toctree.

- #1742: :name: option is provided for toctree, code-block and literalinclude dirctives.

- #1756: Incorrect section titles in search that was introduced from 1.3b3.

- #1746: C++, fixed name lookup procedure, and added missing lookups in declarations.

- #1765: C++, fix old id generation to use fully qualified names.

Documentation

- #1651: Add vartype field descritpion for python domain.

Release 1.3b3 (released Feb 24, 2015)

Incompatible changes

- Dependency requirement updates: docutils 0.11, Pygments 2.0

- The gettext_enables config value has been renamed to gettext_additional_targets.

- #1735: Use https://docs.python.org/ instead of http protocol. It was used for sphinx.ext.intersphinx and some documentation.

Features added

- #1346: Add new default theme;

- Add ‘alabaster’ theme.

- Add ‘sphinx_rtd_theme’ theme.

- The ‘default’ html theme has been renamed to ‘classic’. ‘default’ is still available, however it will emit notice a recommendation that using new ‘alabaster’ theme.

- Added highlight_options configuration value.

- The language config value is now available in the HTML templates.

- The env-updated event can now return a value, which is interpreted as an iterable of additional docnames that need to be rewritten.

- #772: Support for scoped and unscoped enums in C++. Enumerators in unscoped enums are injected into the parent scope in addition to the enum scope.

- Add todo_include_todos config option to quickstart conf file, handled as described in documentation.

- HTML breadcrumb items tag has class “nav-item” and “nav-item-N” (like nav-item-0, 1, 2...).

- New option sphinx-quickstart --use-make-mode for generating Makefile that use sphinx-build make-mode.

- #1235: i18n: several node can be translated if it is set to gettext_additional_targets in conf.py. Supported nodes are:

- ‘literal-block’

- ‘doctest-block’

- ‘raw’

- ‘image’

- #1227: Add html_scaled_image_link config option to conf.py, to control scaled image link.

Bugs fixed

- LaTeX writer now generates correct markup for cells spanning multiple rows.

- #1674: Do not crash if a module’s __all__ is not a list of strings.

- #1629: Use VerbatimBorderColor to add frame to code-block in LaTeX

- On windows, make-mode didn’t work on Win32 platform if sphinx was invoked as python sphinx-build.py.

- #1687: linkcheck now treats 401 Unauthorized responses as “working”.

- #1690: toctrees with glob option now can also contain entries for single documents with explicit title.

- #1591: html search results for C++ elements now has correct interpage links.

- bizstyle theme: nested long title pages make long breadcrumb that breaks page layout.

- bizstyle theme: all breadcrumb items become ‘Top’ on some mobile browser (iPhone5s safari).

- #1722: restore toctree() template function behavior that was changed at 1.3b1.

- #1732: i18n: localized table caption raises exception.

- #1718: :numref: does not work with capital letters in the label

- #1630: resolve CSS conflicts, div.container css target for literal block wrapper now renamed to div.literal-block-wrapper.

- sphinx.util.pycompat has been restored in its backwards-compatibility; slated for removal in Sphinx 1.4.

- #1719: LaTeX writer does not respect numref_format option in captions

Release 1.3b2 (released Dec 5, 2014)

Incompatible changes

- update bundled ez_setup.py for setuptools-7.0 that requires Python 2.6 or later.

Features added

- #1597: Added possibility to return a new template name from html-page-context.

- PR#314, #1150: Configuration values are now checked for their type. A warning is raised if the configured and the default value do not have the same type and do not share a common non-trivial base class.

Bugs fixed

- PR#311: sphinx-quickstart does not work on python 3.4.

- Fix autodoc_docstring_signature not working with signatures in class docstrings.

- Rebuilding cause crash unexpectedly when source files were added.

- #1607: Fix a crash when building latexpdf with “howto” class

- #1251: Fix again. Sections which depth are lower than :tocdepth: should not be shown on localtoc sidebar.

- make-mode didn’t work on Win32 platform if sphinx was installed by wheel package.

Release 1.3b1 (released Oct 10, 2014)

Incompatible changes

- Dropped support for Python 2.5, 3.1 and 3.2.

- Dropped support for docutils versions up to 0.9.

- Removed the sphinx.ext.oldcmarkup extension.

- The deprecated config values exclude_trees, exclude_dirnames and unused_docs have been removed.

- A new node, sphinx.addnodes.literal_strong, has been added, for text that should appear literally (i.e. no smart quotes) in strong font. Custom writers will have to be adapted to handle this node.

- PR#269, #1476: replace <tt> tag by <code>. User customized stylesheets should be updated If the css contain some styles for tt> tag. Thanks to Takeshi Komiya.

- #1543: templates_path is automatically added to exclude_patterns to avoid reading autosummary rst templates in the templates directory.

- Custom domains should implement the new Domain.resolve_any_xref method to make the any role work properly.

- gettext builder: gettext doesn’t emit uuid information to generated pot files by default. Please set True to gettext_uuid to emit uuid information. Additionally, if the python-levenshtein 3rd-party package is installed, it will improve the calculation time.

- gettext builder: disable extracting/apply ‘index’ node by default. Please set ‘index’ to gettext_enables to enable extracting index entries.

- PR#307: Add frame to code-block in LaTeX. Thanks to Takeshi Komiya.

Features added

- Add support for Python 3.4.

- Add support for docutils 0.12

- Added sphinx.ext.napoleon extension for NumPy and Google style docstring support.

- Added support for parallel reading (parsing) of source files with the sphinx-build -j option. Third-party extensions will need to be checked for compatibility and may need to be adapted if they store information in the build environment object. See env-merge-info.

- Added the any role that can be used to find a cross-reference of any type in any domain. Custom domains should implement the new Domain.resolve_any_xref method to make this work properly.

- Exception logs now contain the last 10 messages emitted by Sphinx.

- Added support for extension versions (a string returned by setup(), these can be shown in the traceback log files). Version requirements for extensions can be specified in projects using the new needs_extensions config value.

- Changing the default role within a document with the default-role [http://docutils.sourceforge.net/docs/ref/rst/directives.html#default-role] directive is now supported.

- PR#214: Added stemming support for 14 languages, so that the built-in document search can now handle these. Thanks to Shibukawa Yoshiki.

- PR#296, PR#303, #76: numfig feature: Assign numbers to figures, tables and code-blocks. This feature is configured with numfig, numfig_secnum_depth and numfig_format. Also numref role is available. Thanks to Takeshi Komiya.

- PR#202: Allow ”.” and “~” prefixed references in :param: doc fields for Python.

- PR#184: Add autodoc_mock_imports, allowing to mock imports of external modules that need not be present when autodocumenting.

- #925: Allow list-typed config values to be provided on the command line, like -D key=val1,val2.

- #668: Allow line numbering of code-block and literalinclude directives to start at an arbitrary line number, with a new lineno-start option.

- PR#172, PR#266: The code-block and literalinclude directives now can have a caption option that shows a filename before the code in the output. Thanks to Nasimul Haque, Takeshi Komiya.

- Prompt for the document language in sphinx-quickstart.

- PR#217: Added config values to suppress UUID and location information in generated gettext catalogs.

- PR#236, #1456: apidoc: Add a -M option to put module documentation before submodule documentation. Thanks to Wes Turner and Luc Saffre.

- #1434: Provide non-minified JS files for jquery.js and underscore.js to clarify the source of the minified files.

- PR#252, #1291: Windows color console support. Thanks to meu31.

- PR#255: When generating latex references, also insert latex target/anchor for the ids defined on the node. Thanks to Olivier Heurtier.

- PR#229: Allow registration of other translators. Thanks to Russell Sim.

- Add app.set_translator() API to register or override a Docutils translator class like html_translator_class.

- PR#267, #1134: add ‘diff’ parameter to literalinclude. Thanks to Richard Wall and WAKAYAMA shirou.

- PR#272: Added ‘bizstyle’ theme. Thanks to Shoji KUMAGAI.

- Automatically compile *.mo files from *.po files when gettext_auto_build is True (default) and *.po is newer than *.mo file.

- #623: sphinx.ext.viewcode supports imported function/class aliases.

- PR#275: sphinx.ext.intersphinx supports multiple target for the inventory. Thanks to Brigitta Sipocz.

- PR#261: Added the env-before-read-docs event that can be connected to modify the order of documents before they are read by the environment.

- #1284: Program options documented with option can now start with +.

- PR#291: The caption of code-block is recognised as a title of ref target. Thanks to Takeshi Komiya.

- PR#298: Add new API: add_latex_package(). Thanks to Takeshi Komiya.

- #1344: add gettext_enables to enable extracting ‘index’ to gettext catalog output / applying translation catalog to generated documentation.

- PR#301, #1583: Allow the line numbering of the directive literalinclude to match that of the included file, using a new lineno-match option. Thanks to Jeppe Pihl.

- PR#299: add various options to sphinx-quickstart. Quiet mode option --quiet will skips wizard mode. Thanks to WAKAYAMA shirou.

- #1623: Return types specified with :rtype: are now turned into links if possible.

Bugs fixed

- #1438: Updated jQuery version from 1.8.3 to 1.11.1.

- #1568: Fix a crash when a “centered” directive contains a reference.

- Now sphinx.ext.autodoc works with python-2.5 again.

- #1563: add_search_language() raises AssertionError for correct type of argument. Thanks to rikoman.

- #1174: Fix smart quotes being applied inside roles like program or makevar.

- PR#235: comment db schema of websupport lacked a length of the node_id field. Thanks to solos.

- #1466,PR#241: Fix failure of the cpp domain parser to parse C+11 “variadic templates” declarations. Thanks to Victor Zverovich.

- #1459,PR#244: Fix default mathjax js path point to http:// that cause mixed-content error on HTTPS server. Thanks to sbrandtb and robo9k.

- PR#157: autodoc remove spurious signatures from @property decorated attributes. Thanks to David Ham.

- PR#159: Add coverage targets to quickstart generated Makefile and make.bat. Thanks to Matthias Troffaes.

- #1251: When specifying toctree :numbered: option and :tocdepth: metadata, sub section number that is larger depth than :tocdepth: is shrunk.

- PR#260: Encode underscore in citation labels for latex export. Thanks to Lennart Fricke.

- PR#264: Fix could not resolve xref for figure node with :name: option. Thanks to Takeshi Komiya.

- PR#265: Fix could not capture caption of graphviz node by xref. Thanks to Takeshi Komiya.

- PR#263, #1013, #1103: Rewrite of C++ domain. Thanks to Jakob Lykke Andersen.

- Hyperlinks to all found nested names and template arguments (#1103).

- Support for function types everywhere, e.g., in std::function<bool(int, int)> (#1013).

- Support for virtual functions.

- Changed interpretation of function arguments to following standard prototype declarations, i.e., void f(arg) means that arg is the type of the argument, instead of it being the name.

- Updated tests.

- Updated documentation with elaborate description of what declarations are supported and how the namespace declarations influence declaration and cross-reference lookup.

- Index names may be different now. Elements are indexed by their fully qualified name. It should be rather easy to change this behaviour and potentially index by namespaces/classes as well.

- PR#258, #939: Add dedent option for code-block and literalinclude. Thanks to Zafar Siddiqui.

- PR#268: Fix numbering section does not work at singlehtml mode. It still ad-hoc fix because there is a issue that section IDs are conflicted. Thanks to Takeshi Komiya.

- PR#273, #1536: Fix RuntimeError with numbered circular toctree. Thanks to Takeshi Komiya.

- PR#274: Set its URL as a default title value if URL appears in toctree. Thanks to Takeshi Komiya.

- PR#276, #1381: rfc and pep roles support custom link text. Thanks to Takeshi Komiya.

- PR#277, #1513: highlights for function pointers in argument list of c:function. Thanks to Takeshi Komiya.

- PR#278: Fix section entries were shown twice if toctree has been put under only directive. Thanks to Takeshi Komiya.

- #1547: pgen2 tokenizer doesn’t recognize ... literal (Ellipsis for py3).

- PR#294: On LaTeX builder, wrap float environment on writing literal_block to avoid separation of caption and body. Thanks to Takeshi Komiya.

- PR#295, #1520: make.bat latexpdf mechanism to cd back to the current directory. Thanks to Peter Suter.

- PR#297, #1571: Add imgpath property to all builders. It make easier to develop builder extensions. Thanks to Takeshi Komiya.

- #1584: Point to master doc in HTML “top” link.

- #1585: Autosummary of modules broken in Sphinx-1.2.3.

- #1610: Sphinx cause AttributeError when MeCab search option is enabled and python-mecab is not installed.

- #1674: Do not crash if a module’s __all__ is not a list of strings.

- #1673: Fix crashes with nitpick_ignore and :doc: references.

- #1686: ifconfig directive doesn’t care about default config values.

- #1642: Fix only one search result appearing in Chrome.

Documentation

- Add clarification about the syntax of tags. (doc/markup/misc.rst)

Release 1.2.3 (released Sep 1, 2014)

Features added

- #1518: sphinx-apidoc command now has a --version option to show version information and exit

- New locales: Hebrew, European Portuguese, Vietnamese.

Bugs fixed

- #636: Keep straight single quotes in literal blocks in the LaTeX build.

- #1419: Generated i18n sphinx.js files are missing message catalog entries from ‘.js_t’ and ‘.html’. The issue was introduced from Sphinx-1.1

- #1363: Fix i18n: missing python domain’s cross-references with currentmodule directive or currentclass directive.

- #1444: autosummary does not create the description from attributes docstring.

- #1457: In python3 environment, make linkcheck cause “Can’t convert ‘bytes’ object to str implicitly” error when link target url has a hash part. Thanks to Jorge_C.

- #1467: Exception on Python3 if nonexistent method is specified by automethod

- #1441: autosummary can’t handle nested classes correctly.

- #1499: With non-callable setup in a conf.py, now sphinx-build emits a user-friendly error message.

- #1502: In autodoc, fix display of parameter defaults containing backslashes.

- #1226: autodoc, autosummary: importing setup.py by automodule will invoke setup process and execute sys.exit(). Now sphinx avoids SystemExit exception and emits warnings without unexpected termination.

- #1503: py:function directive generate incorrectly signature when specifying a default parameter with an empty list []. Thanks to Geert Jansen.

- #1508: Non-ASCII filename raise exception on make singlehtml, latex, man, texinfo and changes.

- #1531: On Python3 environment, docutils.conf with ‘source_link=true’ in the general section cause type error.

- PR#270, #1533: Non-ASCII docstring cause UnicodeDecodeError when uses with inheritance-diagram directive. Thanks to WAKAYAMA shirou.

- PR#281, PR#282, #1509: TODO extension not compatible with websupport. Thanks to Takeshi Komiya.

- #1477: gettext does not extract nodes.line in a table or list.

- #1544: make text generates wrong table when it has empty table cells.

- #1522: Footnotes from table get displayed twice in LaTeX. This problem has been appeared from Sphinx-1.2.1 by #949.

- #508: Sphinx every time exit with zero when is invoked from setup.py command. ex. python setup.py build_sphinx -b doctest return zero even if doctest failed.

Release 1.2.2 (released Mar 2, 2014)

Bugs fixed

- PR#211: When checking for existence of the html_logo file, check the full relative path and not the basename.

- PR#212: Fix traceback with autodoc and __init__ methods without docstring.

- PR#213: Fix a missing import in the setup command.

- #1357: Option names documented by option are now again allowed to not start with a dash or slash, and referencing them will work correctly.

- #1358: Fix handling of image paths outside of the source directory when using the “wildcard” style reference.

- #1374: Fix for autosummary generating overly-long summaries if first line doesn’t end with a period.

- #1383: Fix Python 2.5 compatibility of sphinx-apidoc.

- #1391: Actually prevent using “pngmath” and “mathjax” extensions at the same time in sphinx-quickstart.

- #1386: Fix bug preventing more than one theme being added by the entry point mechanism.

- #1370: Ignore “toctree” nodes in text writer, instead of raising.

- #1364: Fix ‘make gettext’ fails when the ‘.. todolist::’ directive is present.

- #1367: Fix a change of PR#96 that break sphinx.util.docfields.Field.make_field interface/behavior for item argument usage.

Documentation

- Extended the documentation about building extensions.

Release 1.2.1 (released Jan 19, 2014)

Bugs fixed

- #1335: Fix autosummary template overloading with exclamation prefix like {% extends "!autosummary/class.rst" %} cause infinite recursive function call. This was caused by PR#181.

- #1337: Fix autodoc with autoclass_content="both" uses useless object.__init__ docstring when class does not have __init__. This was caused by a change for #1138.

- #1340: Can’t search alphabetical words on the HTML quick search generated with language=’ja’.

- #1319: Do not crash if the html_logo file does not exist.

- #603: Do not use the HTML-ized title for building the search index (that resulted in “literal” being found on every page with a literal in the title).

- #751: Allow production lists longer than a page in LaTeX by using longtable.

- #764: Always look for stopwords lowercased in JS search.

- #814: autodoc: Guard against strange type objects that don’t have __bases__.

- #932: autodoc: Do not crash if __doc__ is not a string.

- #933: Do not crash if an option value is malformed (contains spaces but no option name).

- #908: On Python 3, handle error messages from LaTeX correctly in the pngmath extension.

- #943: In autosummary, recognize “first sentences” to pull from the docstring if they contain uppercase letters.

- #923: Take the entire LaTeX document into account when caching pngmath-generated images. This rebuilds them correctly when pngmath_latex_preamble changes.

- #901: Emit a warning when using docutils’ new “math” markup without a Sphinx math extension active.

- #845: In code blocks, when the selected lexer fails, display line numbers nevertheless if configured.

- #929: Support parsed-literal blocks in LaTeX output correctly.

- #949: Update the tabulary.sty packed with Sphinx.

- #1050: Add anonymous labels into objects.inv to be referenced via intersphinx.

- #1095: Fix print-media stylesheet being included always in the “scrolls” theme.

- #1085: Fix current classname not getting set if class description has :noindex: set.

- #1181: Report option errors in autodoc directives more gracefully.

- #1155: Fix autodocumenting C-defined methods as attributes in Python 3.

- #1233: Allow finding both Python classes and exceptions with the “class” and “exc” roles in intersphinx.

- #1198: Allow “image” for the “figwidth” option of the figure [http://docutils.sourceforge.net/docs/ref/rst/directives.html#figure] directive as documented by docutils.

- #1152: Fix pycode parsing errors of Python 3 code by including two grammar versions for Python 2 and 3, and loading the appropriate version for the running Python version.

- #1017: Be helpful and tell the user when the argument to option does not match the required format.

- #1345: Fix two bugs with nitpick_ignore; now you don’t have to remove the store environment for changes to have effect.

- #1072: In the JS search, fix issues searching for upper-cased words by lowercasing words before stemming.

- #1299: Make behavior of the math directive more consistent and avoid producing empty environments in LaTeX output.

- #1308: Strip HTML tags from the content of “raw” nodes before feeding it to the search indexer.

- #1249: Fix duplicate LaTeX page numbering for manual documents.

- #1292: In the linkchecker, retry HEAD requests when denied by HTTP 405. Also make the redirect code apparent and tweak the output a bit to be more obvious.

- #1285: Avoid name clashes between C domain objects and section titles.

- #848: Always take the newest code in incremental rebuilds with the sphinx.ext.viewcode extension.

- #979, #1266: Fix exclude handling in sphinx-apidoc.

- #1302: Fix regression in sphinx.ext.inheritance_diagram when documenting classes that can’t be pickled.

- #1316: Remove hard-coded font-face resources from epub theme.

- #1329: Fix traceback with empty translation msgstr in .po files.

- #1300: Fix references not working in translated documents in some instances.

- #1283: Fix a bug in the detection of changed files that would try to access doctrees of deleted documents.

- #1330: Fix exclude_patterns behavior with subdirectories in the html_static_path.

- #1323: Fix emitting empty <ul> tags in the HTML writer, which is not valid HTML.

- #1147: Don’t emit a sidebar search box in the “singlehtml” builder.

Documentation

- #1325: Added a “Intersphinx” tutorial section. (doc/tutorial.rst)

Release 1.2 (released Dec 10, 2013)

Features added

- Added sphinx.version_info tuple for programmatic checking of the Sphinx version.

Incompatible changes

- Removed the sphinx.ext.refcounting extension – it is very specific to CPython and has no place in the main distribution.

Bugs fixed

- Restore versionmodified CSS class for versionadded/changed and deprecated directives.

- PR#181: Fix html_theme_path = ['.'] is a trigger of rebuild all documents always (This change keeps the current “theme changes cause a rebuild” feature).

- #1296: Fix invalid charset in HTML help generated HTML files for default locale.

- PR#190: Fix gettext does not extract figure caption and rubric title inside other blocks. Thanks to Michael Schlenker.

- PR#176: Make sure setup_command test can always import Sphinx. Thanks to Dmitry Shachnev.

- #1311: Fix test_linkcode.test_html fails with C locale and Python 3.

- #1269: Fix ResourceWarnings with Python 3.2 or later.

- #1138: Fix: When autodoc_docstring_signature = True and autoclass_content = 'init' or 'both', __init__ line should be removed from class documentation.

Release 1.2 beta3 (released Oct 3, 2013)

Features added

- The Sphinx error log files will now include a list of the loaded extensions for help in debugging.

Incompatible changes

- PR#154: Remove “sphinx” prefix from LaTeX class name except ‘sphinxmanual’ and ‘sphinxhowto’. Now you can use your custom document class without ‘sphinx’ prefix. Thanks to Erik B.

Bugs fixed

- #1265: Fix i18n: crash when translating a section name that is pointed to from a named target.

- A wrong condition broke the search feature on first page that is usually index.rst. This issue was introduced in 1.2b1.

- #703: When Sphinx can’t decode filenames with non-ASCII characters, Sphinx now catches UnicodeError and will continue if possible instead of raising the exception.

Release 1.2 beta2 (released Sep 17, 2013)

Features added

- apidoc now ignores “_private” modules by default, and has an option -P to include them.

- apidoc now has an option to not generate headings for packages and modules, for the case that the module docstring already includes a reST heading.

- PR#161: apidoc can now write each module to a standalone page instead of combining all modules in a package on one page.

- Builders: rebuild i18n target document when catalog updated.

- Support docutils.conf ‘writers’ and ‘html4css1 writer’ section in the HTML writer. The latex, manpage and texinfo writers also support their respective ‘writers’ sections.

- The new html_extra_path config value allows to specify directories with files that should be copied directly to the HTML output directory.

- Autodoc directives for module data and attributes now support an annotation option, so that the default display of the data/attribute value can be overridden.

- PR#136: Autodoc directives now support an imported-members option to include members imported from different modules.

- New locales: Macedonian, Sinhala, Indonesian.

- Theme package collection by using setuptools plugin mechanism.

Incompatible changes

- PR#144, #1182: Force timezone offset to LocalTimeZone on POT-Creation-Date that was generated by gettext builder. Thanks to masklinn and Jakub Wilk.

Bugs fixed

- PR#132: Updated jQuery version to 1.8.3.

- PR#141, #982: Avoid crash when writing PNG file using Python 3. Thanks to Marcin Wojdyr.

- PR#145: In parallel builds, sphinx drops second document file to write. Thanks to tychoish.

- PR#151: Some styling updates to tables in LaTeX.

- PR#153: The “extensions” config value can now be overridden.

- PR#155: Added support for some C++11 function qualifiers.

- Fix: ‘make gettext’ caused UnicodeDecodeError when templates contain utf-8 encoded strings.

- #828: use inspect.getfullargspec() to be able to document functions with keyword-only arguments on Python 3.

- #1090: Fix i18n: multiple cross references (term, ref, doc) in the same line return the same link.

- #1157: Combination of ‘globaltoc.html’ and hidden toctree caused exception.

- #1159: fix wrong generation of objects inventory for Python modules, and add a workaround in intersphinx to fix handling of affected inventories.

- #1160: Citation target missing caused an AssertionError.

- #1162, PR#139: singlehtml builder didn’t copy images to _images/.

- #1173: Adjust setup.py dependencies because Jinja2 2.7 discontinued compatibility with Python < 3.3 and Python < 2.6. Thanks to Alexander Dupuy.

- #1185: Don’t crash when a Python module has a wrong or no encoding declared, and non-ASCII characters are included.

- #1188: sphinx-quickstart raises UnicodeEncodeError if “Project version” includes non-ASCII characters.

- #1189: “Title underline is too short” WARNING is given when using fullwidth characters to “Project name” on quickstart.

- #1190: Output TeX/texinfo/man filename has no basename (only extension) when using non-ASCII characters in the “Project name” on quickstart.

- #1192: Fix escaping problem for hyperlinks in the manpage writer.

- #1193: Fix i18n: multiple link references in the same line return the same link.

- #1176: Fix i18n: footnote reference number missing for auto numbered named footnote and auto symbol footnote.

- PR#146,#1172: Fix ZeroDivisionError in parallel builds. Thanks to tychoish.

- #1204: Fix wrong generation of links to local intersphinx targets.

- #1206: Fix i18n: gettext did not translate admonition directive’s title.

- #1232: Sphinx generated broken ePub files on Windows.

- #1259: Guard the debug output call when emitting events; to prevent the repr() implementation of arbitrary objects causing build failures.

- #1142: Fix NFC/NFD normalizing problem of rst filename on Mac OS X.

- #1234: Ignoring the string consists only of white-space characters.

Release 1.2 beta1 (released Mar 31, 2013)

Incompatible changes

- Removed sphinx.util.compat.directive_dwim() and sphinx.roles.xfileref_role() which were deprecated since version 1.0.

- PR#122: the files given in latex_additional_files now override TeX files included by Sphinx, such as sphinx.sty.

- PR#124: the node generated by versionadded, versionchanged and deprecated directives now includes all added markup (such as “New in version X”) as child nodes, and no additional text must be generated by writers.

- PR#99: the seealso directive now generates admonition nodes instead of the custom seealso node.

Features added

- Markup

- The toctree directive and the toctree() template function now have an includehidden option that includes hidden toctree entries (bugs #790 and #1047). A bug in the maxdepth option for the toctree() template function has been fixed (bug #1046).

- PR#99: Strip down seealso directives to normal admonitions. This removes their unusual CSS classes (admonition-see-also), inconsistent LaTeX admonition title (“See Also” instead of “See also”), and spurious indentation in the text builder.

- HTML builder

- #783: Create a link to full size image if it is scaled with width or height.

- #1067: Improve the ordering of the JavaScript search results: matches in titles come before matches in full text, and object results are better categorized. Also implement a pluggable search scorer.

- #1053: The “rightsidebar” and “collapsiblesidebar” HTML theme options now work together.

- Update to jQuery 1.7.1 and Underscore.js 1.3.1.

- Texinfo builder

- An “Index” node is no longer added when there are no entries.

- “deffn” categories are no longer capitalized if they contain capital letters.

- desc_annotation nodes are now rendered.

- strong and emphasis nodes are now formatted like literals. The reason for this is because the standard Texinfo markup (*strong* and _emphasis_) resulted in confusing output due to the common usage of using these constructs for documenting parameter names.

- Field lists formatting has been tweaked to better display “Info field lists”.

- system_message and problematic nodes are now formatted in a similar fashion as done by the text builder.

- “en-dash” and “em-dash” conversion of hyphens is no longer performed in option directive signatures.

- @ref is now used instead of @pxref for cross-references which prevents the word “see” from being added before the link (does not affect the Info output).

- The @finalout command has been added for better TeX output.

- transition nodes are now formatted using underscores (“_”) instead of asterisks (“*”).

- The default value for the paragraphindent has been changed from 2 to 0 meaning that paragraphs are no longer indented by default.

- #1110: A new configuration value texinfo_no_detailmenu has been added for controlling whether a @detailmenu is added in the “Top” node’s menu.

- Detailed menus are no longer created except for the “Top” node.

- Fixed an issue where duplicate domain indices would result in invalid output.

- LaTeX builder:

- PR#115: Add 'transition' item in latex_elements for customizing how transitions are displayed. Thanks to Jeff Klukas.

- PR#114: The LaTeX writer now includes the “cmap” package by default. The 'cmappkg' item in latex_elements can be used to control this. Thanks to Dmitry Shachnev.

- The 'fontpkg' item in latex_elements now defaults to '' when the language uses the Cyrillic script. Suggested by Dmitry Shachnev.

- The latex_documents, texinfo_documents, and man_pages configuration values will be set to default values based on the master_doc if not explicitly set in conf.py. Previously, if these values were not set, no output would be generated by their respective builders.

- Internationalization:

- Add i18n capabilities for custom templates. For example: The Sphinx reference documentation in doc directory provides a sphinx.pot file with message strings from doc/_templates/*.html when using make gettext.

- PR#61,#703: Add support for non-ASCII filename handling.

- Other builders:

- Added the Docutils-native XML and pseudo-XML builders. See XMLBuilder and PseudoXMLBuilder.

- PR#45: The linkcheck builder now checks #anchors for existence.

- PR#123, #1106: Add epub_use_index configuration value. If provided, it will be used instead of html_use_index for epub builder.

- PR#126: Add epub_tocscope configuration value. The setting controls the generation of the epub toc. The user can now also include hidden toc entries.

- PR#112: Add epub_show_urls configuration value.

- Extensions:

- PR#52: special_members flag to autodoc now behaves like members.

- PR#47: Added sphinx.ext.linkcode extension.

- PR#25: In inheritance diagrams, the first line of the class docstring is now the tooltip for the class.

- Command-line interfaces:

- PR#75: Added --follow-links option to sphinx-apidoc.

- #869: sphinx-build now has the option -T for printing the full traceback after an unhandled exception.

- sphinx-build now supports the standard --help and --version options.

- sphinx-build now provides more specific error messages when called with invalid options or arguments.

- sphinx-build now has a verbose option -v which can be repeated for greater effect. A single occurrence provides a slightly more verbose output than normal. Two or more occurrences of this option provides more detailed output which may be useful for debugging.

- Locales:

- PR#74: Fix some Russian translation.

- PR#54: Added Norwegian bokmaal translation.

- PR#35: Added Slovak translation.

- PR#28: Added Hungarian translation.

- #1113: Add Hebrew locale.

- #1097: Add Basque locale.

- #1037: Fix typos in Polish translation. Thanks to Jakub Wilk.

- #1012: Update Estonian translation.

- Optimizations:

- Speed up building the search index by caching the results of the word stemming routines. Saves about 20 seconds when building the Python documentation.

- PR#108: Add experimental support for parallel building with a new sphinx-build -j option.

Documentation

- PR#88: Added the “Sphinx Developer’s Guide” (doc/devguide.rst) which outlines the basic development process of the Sphinx project.

- Added a detailed “Installing Sphinx” document (doc/install.rst).

Bugs fixed

- PR#124: Fix paragraphs in versionmodified are ignored when it has no dangling paragraphs. Fix wrong html output (nested <p> tag). Fix versionmodified is not translatable. Thanks to Nozomu Kaneko.

- PR#111: Respect add_autodoc_attrgetter() even when inherited-members is set. Thanks to A. Jesse Jiryu Davis.

- PR#97: Fix footnote handling in translated documents.

- Fix text writer not handling visit_legend for figure directive contents.

- Fix text builder not respecting wide/fullwidth characters: title underline width, table layout width and text wrap width.

- Fix leading space in LaTeX table header cells.

- #1132: Fix LaTeX table output for multi-row cells in the first column.

- #1128: Fix Unicode errors when trying to format time strings with a non-standard locale.

- #1127: Fix traceback when autodoc tries to tokenize a non-Python file.

- #1126: Fix double-hyphen to en-dash conversion in wrong places such as command-line option names in LaTeX.

- #1123: Allow whitespaces in filenames given to literalinclude.

- #1120: Added improvements about i18n for themes “basic”, “haiku” and “scrolls” that Sphinx built-in. Thanks to Leonardo J. Caballero G.

- #1118: Updated Spanish translation. Thanks to Leonardo J. Caballero G.

- #1117: Handle .pyx files in sphinx-apidoc.

- #1112: Avoid duplicate download files when referenced from documents in different ways (absolute/relative).

- #1111: Fix failure to find uppercase words in search when html_search_language is ‘ja’. Thanks to Tomo Saito.

- #1108: The text writer now correctly numbers enumerated lists with non-default start values (based on patch by Ewan Edwards).

- #1102: Support multi-context “with” statements in autodoc.

- #1090: Fix gettext not extracting glossary terms.

- #1074: Add environment version info to the generated search index to avoid compatibility issues with old builds.

- #1070: Avoid un-pickling issues when running Python 3 and the saved environment was created under Python 2.

- #1069: Fixed error caused when autodoc would try to format signatures of “partial” functions without keyword arguments (patch by Artur Gaspar).

- #1062: sphinx.ext.autodoc use __init__ method signature for class signature.

- #1055: Fix web support with relative path to source directory.

- #1043: Fix sphinx-quickstart asking again for yes/no questions because input() returns values with an extra ‘r’ on Python 3.2.0 + Windows. Thanks to Régis Décamps.

- #1041: Fix failure of the cpp domain parser to parse a const type with a modifier.

- #1038: Fix failure of the cpp domain parser to parse C+11 “static constexpr” declarations. Thanks to Jakub Wilk.

- #1029: Fix intersphinx_mapping values not being stable if the mapping has plural key/value set with Python 3.3.

- #1028: Fix line block output in the text builder.

- #1024: Improve Makefile/make.bat error message if Sphinx is not found. Thanks to Anatoly Techtonik.

- #1018: Fix “container” directive handling in the text builder.

- #1015: Stop overriding jQuery contains() in the JavaScript.

- #1010: Make pngmath images transparent by default; IE7+ should handle it.

- #1008: Fix test failures with Python 3.3.

- #995: Fix table-of-contents and page numbering for the LaTeX “howto” class.

- #976: Fix gettext does not extract index entries.

- PR#72: #975: Fix gettext not extracting definition terms before docutils 0.10.

- #961: Fix LaTeX output for triple quotes in code snippets.

- #958: Do not preserve environment.pickle after a failed build.

- #955: Fix i18n transformation.

- #940: Fix gettext does not extract figure caption.

- #920: Fix PIL packaging issue that allowed to import Image without PIL namespace. Thanks to Marc Schlaich.

- #723: Fix the search function on local files in WebKit based browsers.

- #440: Fix coarse timestamp resolution in some filesystem generating a wrong list of outdated files.

Release 1.1.3 (Mar 10, 2012)

- PR#40: Fix safe_repr function to decode bytestrings with non-ASCII characters correctly.

- PR#37: Allow configuring sphinx-apidoc via SPHINX_APIDOC_OPTIONS.

- PR#34: Restore Python 2.4 compatibility.

- PR#36: Make the “bibliography to TOC” fix in LaTeX output specific to the document class.

- #695: When the highlight language “python” is specified explicitly, do not try to parse the code to recognize non-Python snippets.

- #859: Fix exception under certain circumstances when not finding appropriate objects to link to.

- #860: Do not crash when encountering invalid doctest examples, just emit a warning.

- #864: Fix crash with some settings of modindex_common_prefix.

- #862: Fix handling of -D and -A options on Python 3.

- #851: Recognize and warn about circular toctrees, instead of running into recursion errors.

- #853: Restore compatibility with docutils trunk.

- #852: Fix HtmlHelp index entry links again.

- #854: Fix inheritance_diagram raising attribute errors on builtins.

- #832: Fix crashes when putting comments or lone terms in a glossary.

- #834, #818: Fix HTML help language/encoding mapping for all Sphinx supported languages.

- #844: Fix crashes when dealing with Unicode output in doctest extension.

- #831: Provide --project flag in setup_command as advertised.

- #875: Fix reading config files under Python 3.

- #876: Fix quickstart test under Python 3.

- #870: Fix spurious KeyErrors when removing documents.

- #892: Fix single-HTML builder misbehaving with the master document in a subdirectory.

- #873: Fix assertion errors with empty only directives.

- #816: Fix encoding issues in the Qt help builder.

Release 1.1.2 (Nov 1, 2011) – 1.1.1 is a silly version number anyway!

- #809: Include custom fixers in the source distribution.

Release 1.1.1 (Nov 1, 2011)

- #791: Fix QtHelp, DevHelp and HtmlHelp index entry links.

- #792: Include “sphinx-apidoc” in the source distribution.

- #797: Don’t crash on a misformatted glossary.

- #801: Make intersphinx work properly without SSL support.

- #805: Make the Sphinx.add_index_to_domain method work correctly.

- #780: Fix Python 2.5 compatibility.

Release 1.1 (Oct 9, 2011)

Incompatible changes

- The py:module directive doesn’t output its platform option value anymore. (It was the only thing that the directive did output, and therefore quite inconsistent.)

- Removed support for old dependency versions; requirements are now:

- Pygments >= 1.2

- Docutils >= 0.7

- Jinja2 >= 2.3

Features added

- Added Python 3.x support.

- New builders and subsystems:

- Added a Texinfo builder.

- Added i18n support for content, a gettext builder and related utilities.

- Added the websupport library and builder.

- #98: Added a sphinx-apidoc script that autogenerates a hierarchy of source files containing autodoc directives to document modules and packages.

- #273: Add an API for adding full-text search support for languages other than English. Add support for Japanese.

- Markup:

- #138: Added an index role, to make inline index entries.

- #454: Added more index markup capabilities: marking see/seealso entries, and main entries for a given key.

- #460: Allowed limiting the depth of section numbers for HTML using the toctree‘s numbered option.

- #586: Implemented improved glossary markup which allows multiple terms per definition.

- #478: Added py:decorator directive to describe decorators.

- C++ domain now supports array definitions.

- C++ domain now supports doc fields (:param x: inside directives).

- Section headings in only directives are now correctly handled.

- Added emphasize-lines option to source code directives.

- #678: C++ domain now supports superclasses.

- HTML builder:

- Added pyramid theme.

- #559: html_add_permalinks is now a string giving the text to display in permalinks.

- #259: HTML table rows now have even/odd CSS classes to enable “Zebra styling”.

- #554: Add theme option sidebarwidth to the basic theme.

- Other builders:

- #516: Added new value of the latex_show_urls option to show the URLs in footnotes.

- #209: Added text_newlines and text_sectionchars config values.

- Added man_show_urls config value.

- #472: linkcheck builder: Check links in parallel, use HTTP HEAD requests and allow configuring the timeout. New config values: linkcheck_timeout and linkcheck_workers.

- #521: Added linkcheck_ignore config value.

- #28: Support row/colspans in tables in the LaTeX builder.

- Configuration and extensibility:

- #537: Added nitpick_ignore.

- #306: Added env-get-outdated event.

- Application.add_stylesheet() now accepts full URIs.

- Autodoc:

- #564: Add autodoc_docstring_signature. When enabled (the default), autodoc retrieves the signature from the first line of the docstring, if it is found there.

- #176: Provide private-members option for autodoc directives.

- #520: Provide special-members option for autodoc directives.

- #431: Doc comments for attributes can now be given on the same line as the assignment.

- #437: autodoc now shows values of class data attributes.

- autodoc now supports documenting the signatures of functools.partial objects.

- Other extensions:

- Added the sphinx.ext.mathjax extension.

- #443: Allow referencing external graphviz files.

- Added inline option to graphviz directives, and fixed the default (block-style) in LaTeX output.

- #590: Added caption option to graphviz directives.

- #553: Added testcleanup blocks in the doctest extension.

- #594: trim_doctest_flags now also removes <BLANKLINE> indicators.

- #367: Added automatic exclusion of hidden members in inheritance diagrams, and an option to selectively enable it.

- Added pngmath_add_tooltips.

- The math extension displaymath directives now support name in addition to label for giving the equation label, for compatibility with Docutils.

- New locales:

- #221: Added Swedish locale.

- #526: Added Iranian locale.

- #694: Added Latvian locale.

- Added Nepali locale.

- #714: Added Korean locale.

- #766: Added Estonian locale.

- Bugs fixed:

- #778: Fix “hide search matches” link on pages linked by search.

- Fix the source positions referenced by the “viewcode” extension.

Release 1.0.8 (Sep 23, 2011)

- #627: Fix tracebacks for AttributeErrors in autosummary generation.

- Fix the abbr role when the abbreviation has newlines in it.

- #727: Fix the links to search results with custom object types.

- #648: Fix line numbers reported in warnings about undefined references.

- #696, #666: Fix C++ array definitions and template arguments that are not type names.

- #633: Allow footnotes in section headers in LaTeX output.

- #616: Allow keywords to be linked via intersphinx.

- #613: Allow Unicode characters in production list token names.

- #720: Add dummy visitors for graphviz nodes for text and man.

- #704: Fix image file duplication bug.

- #677: Fix parsing of multiple signatures in C++ domain.

- #637: Ignore Emacs lock files when looking for source files.

- #544: Allow .pyw extension for importable modules in autodoc.

- #700: Use $(MAKE) in quickstart-generated Makefiles.

- #734: Make sidebar search box width consistent in browsers.

- #644: Fix spacing of centered figures in HTML output.

- #767: Safely encode SphinxError messages when printing them to sys.stderr.

- #611: Fix LaTeX output error with a document with no sections but a link target.

- Correctly treat built-in method descriptors as methods in autodoc.

- #706: Stop monkeypatching the Python textwrap module.

- #657: viewcode now works correctly with source files that have non-ASCII encoding.

- #669: Respect the noindex flag option in py:module directives.

- #675: Fix IndexErrors when including nonexisting lines with literalinclude.

- #676: Respect custom function/method parameter separator strings.

- #682: Fix JS incompatibility with jQuery >= 1.5.

- #693: Fix double encoding done when writing HTMLHelp .hhk files.

- #647: Do not apply SmartyPants in parsed-literal blocks.

- C++ domain now supports array definitions.

Release 1.0.7 (Jan 15, 2011)

- #347: Fix wrong generation of directives of static methods in autosummary.

- #599: Import PIL as from PIL import Image.

- #558: Fix longtables with captions in LaTeX output.

- Make token references work as hyperlinks again in LaTeX output.

- #572: Show warnings by default when reference labels cannot be found.

- #536: Include line number when complaining about missing reference targets in nitpicky mode.

- #590: Fix inline display of graphviz diagrams in LaTeX output.

- #589: Build using app.build() in setup command.

- Fix a bug in the inheritance diagram exception that caused base classes to be skipped if one of them is a builtin.

- Fix general index links for C++ domain objects.

- #332: Make admonition boundaries in LaTeX output visible.

- #573: Fix KeyErrors occurring on rebuild after removing a file.

- Fix a traceback when removing files with globbed toctrees.

- If an autodoc object cannot be imported, always re-read the document containing the directive on next build.

- If an autodoc object cannot be imported, show the full traceback of the import error.

- Fix a bug where the removal of download files and images wasn’t noticed.

- #571: Implement ~ cross-reference prefix for the C domain.

- Fix regression of LaTeX output with the fix of #556.

- #568: Fix lookup of class attribute documentation on descriptors so that comment documentation now works.

- Fix traceback with only directives preceded by targets.

- Fix tracebacks occurring for duplicate C++ domain objects.

- Fix JavaScript domain links to objects with $ in their name.

Release 1.0.6 (Jan 04, 2011)

- #581: Fix traceback in Python domain for empty cross-reference targets.

- #283: Fix literal block display issues on Chrome browsers.

- #383, #148: Support sorting a limited range of accented characters in the general index and the glossary.

- #570: Try decoding -D and -A command-line arguments with the locale’s preferred encoding.

- #528: Observe locale_dirs when looking for the JS translations file.

- #574: Add special code for better support of Japanese documents in the LaTeX builder.

- Regression of #77: If there is only one parameter given with :param: markup, the bullet list is now suppressed again.

- #556: Fix missing paragraph breaks in LaTeX output in certain situations.

- #567: Emit the autodoc-process-docstring event even for objects without a docstring so that it can add content.

- #565: In the LaTeX builder, not only literal blocks require different table handling, but also quite a few other list-like block elements.

- #515: Fix tracebacks in the viewcode extension for Python objects that do not have a valid signature.

- Fix strange reports of line numbers for warnings generated from autodoc-included docstrings, due to different behavior depending on docutils version.

- Several fixes to the C++ domain.

Release 1.0.5 (Nov 12, 2010)

- #557: Add CSS styles required by docutils 0.7 for aligned images and figures.

- In the Makefile generated by LaTeX output, do not delete pdf files on clean; they might be required images.

- #535: Fix LaTeX output generated for line blocks.

- #544: Allow .pyw as a source file extension.

Release 1.0.4 (Sep 17, 2010)

- #524: Open intersphinx inventories in binary mode on Windows, since version 2 contains zlib-compressed data.

- #513: Allow giving non-local URIs for JavaScript files, e.g. in the JSMath extension.

- #512: Fix traceback when intersphinx_mapping is empty.

Release 1.0.3 (Aug 23, 2010)

- #495: Fix internal vs. external link distinction for links coming from a docutils table-of-contents.

- #494: Fix the maxdepth option for the toctree() template callable when used with collapse=True.

- #507: Fix crash parsing Python argument lists containing brackets in string literals.

- #501: Fix regression when building LaTeX docs with figures that don’t have captions.

- #510: Fix inheritance diagrams for classes that are not picklable.

- #497: Introduce separate background color for the sidebar collapse button, making it easier to see.

- #502, #503, #496: Fix small layout bugs in several builtin themes.

Release 1.0.2 (Aug 14, 2010)

- #490: Fix cross-references to objects of types added by the add_object_type() API function.

- Fix handling of doc field types for different directive types.

- Allow breaking long signatures, continuing with backlash-escaped newlines.

- Fix unwanted styling of C domain references (because of a namespace clash with Pygments styles).

- Allow references to PEPs and RFCs with explicit anchors.

- #471: Fix LaTeX references to figures.

- #482: When doing a non-exact search, match only the given type of object.

- #481: Apply non-exact search for Python reference targets with .name for modules too.

- #484: Fix crash when duplicating a parameter in an info field list.

- #487: Fix setting the default role to one provided by the oldcmarkup extension.

- #488: Fix crash when json-py is installed, which provides a json module but is incompatible to simplejson.

- #480: Fix handling of target naming in intersphinx.

- #486: Fix removal of ! for all cross-reference roles.

Release 1.0.1 (Jul 27, 2010)

- #470: Fix generated target names for reST domain objects; they are not in the same namespace.

- #266: Add Bengali language.

- #473: Fix a bug in parsing JavaScript object names.

- #474: Fix building with SingleHTMLBuilder when there is no toctree.

- Fix display names for objects linked to by intersphinx with explicit targets.

- Fix building with the JSON builder.

- Fix hyperrefs in object descriptions for LaTeX.

Release 1.0 (Jul 23, 2010)

Incompatible changes

- Support for domains has been added. A domain is a collection of directives and roles that all describe objects belonging together, e.g. elements of a programming language. A few builtin domains are provided:

- Python

- C

- C++

- JavaScript

- reStructuredText

- The old markup for defining and linking to C directives is now deprecated. It will not work anymore in future versions without activating the oldcmarkup extension; in Sphinx 1.0, it is activated by default.

- Removed support for old dependency versions; requirements are now:

- docutils >= 0.5

- Jinja2 >= 2.2

- Removed deprecated elements:

- exclude_dirs config value

- sphinx.builder module

Features added

- General:

- Added a “nitpicky” mode that emits warnings for all missing references. It is activated by the sphinx-build -n command-line switch or the nitpicky config value.

- Added latexpdf target in quickstart Makefile.

- Markup:

- The menuselection and guilabel roles now support ampersand accelerators.

- New more compact doc field syntax is now recognized: :param type name: description.

- Added tab-width option to literalinclude directive.

- Added titlesonly option to toctree directive.

- Added the prepend and append options to the literalinclude directive.

- #284: All docinfo metadata is now put into the document metadata, not just the author.

- The ref role can now also reference tables by caption.

- The include [http://docutils.sourceforge.net/docs/ref/rst/directives.html#include] directive now supports absolute paths, which are interpreted as relative to the source directory.

- In the Python domain, references like :func:`.name` now look for matching names with any prefix if no direct match is found.

- Configuration:

- Added rst_prolog config value.

- Added html_secnumber_suffix config value to control section numbering format.

- Added html_compact_lists config value to control docutils’ compact lists feature.

- The html_sidebars config value can now contain patterns as keys, and the values can be lists that explicitly select which sidebar templates should be rendered. That means that the builtin sidebar contents can be included only selectively.

- html_static_path can now contain single file entries.

- The new universal config value exclude_patterns makes the old unused_docs, exclude_trees and exclude_dirnames obsolete.

- Added html_output_encoding config value.

- Added the latex_docclass config value and made the “twoside” documentclass option overridable by “oneside”.

- Added the trim_doctest_flags config value, which is true by default.

- Added html_show_copyright config value.

- Added latex_show_pagerefs and latex_show_urls config values.

- The behavior of html_file_suffix changed slightly: the empty string now means “no suffix” instead of “default suffix”, use None for “default suffix”.

- New builders:

- Added a builder for the Epub format.

- Added a builder for manual pages.

- Added a single-file HTML builder.

- HTML output:

- Inline roles now get a CSS class with their name, allowing styles to customize their appearance. Domain-specific roles get two classes, domain and domain-rolename.

- References now get the class internal if they are internal to the whole project, as opposed to internal to the current page.

- External references can be styled differently with the new externalrefs theme option for the default theme.

- In the default theme, the sidebar can experimentally now be made collapsible using the new collapsiblesidebar theme option.

- #129: Toctrees are now wrapped in a div tag with class toctree-wrapper in HTML output.

- The toctree callable in templates now has a maxdepth keyword argument to control the depth of the generated tree.

- The toctree callable in templates now accepts a titles_only keyword argument.

- Added htmltitle block in layout template.

- In the JavaScript search, allow searching for object names including the module name, like sys.argv.

- Added new theme haiku, inspired by the Haiku OS user guide.

- Added new theme nature.

- Added new theme agogo, created by Andi Albrecht.

- Added new theme scrolls, created by Armin Ronacher.

- #193: Added a visitedlinkcolor theme option to the default theme.

- #322: Improved responsiveness of the search page by loading the search index asynchronously.

- Extension API:

- Added html-collect-pages.

- Added needs_sphinx config value and require_sphinx() application API method.

- #200: Added add_stylesheet() application API method.

- Extensions:

- Added the viewcode extension.

- Added the extlinks extension.

- Added support for source ordering of members in autodoc, with autodoc_member_order = 'bysource'.

- Added autodoc_default_flags config value, which can be used to select default flags for all autodoc directives.

- Added a way for intersphinx to refer to named labels in other projects, and to specify the project you want to link to.

- #280: Autodoc can now document instance attributes assigned in __init__ methods.

- Many improvements and fixes to the autosummary extension, thanks to Pauli Virtanen.

- #309: The graphviz extension can now output SVG instead of PNG images, controlled by the graphviz_output_format config value.

- Added alt option to graphviz extension directives.

- Added exclude argument to autodoc.between().

- Translations:

- Added Croatian translation, thanks to Bojan Mihelač.

- Added Turkish translation, thanks to Firat Ozgul.

- Added Catalan translation, thanks to Pau Fernández.

- Added simplified Chinese translation.

- Added Danish translation, thanks to Hjorth Larsen.

- Added Lithuanian translation, thanks to Dalius Dobravolskas.

- Bugs fixed:

- #445: Fix links to result pages when using the search function of HTML built with the dirhtml builder.

- #444: In templates, properly re-escape values treated with the “striptags” Jinja filter.

Previous versions

The changelog for versions before 1.0 can be found in the file CHANGES.old in the source distribution or at Github [https://github.com/sphinx-doc/sphinx/raw/master/CHANGES.old].

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- next |

- previous |

- Sphinx 1.4.1 documentation »

Projects using Sphinx

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 [https://groups.google.com/forum/#!forum/sphinx-users].

I’ve grouped the list into sections to make it easier to find interesting examples.

Documentation using the alabaster theme

- PyLangAcq: http://pylangacq.org/

Documentation using the classic theme

- APSW: http://apidoc.apsw.googlecode.com/hg/index.html

- ASE: https://wiki.fysik.dtu.dk/ase/

- Calibre: http://manual.calibre-ebook.com/

- CodePy: https://documen.tician.de/codepy/

- Cython: http://docs.cython.org/

- Cormoran: http://cormoran.nhopkg.org/docs/

- Director: http://pythonhosted.org/director/

- Dirigible: http://www.projectdirigible.com/

- F2py: http://f2py.sourceforge.net/docs/

- GeoDjango: https://docs.djangoproject.com/en/dev/ref/contrib/gis/

- Genomedata: http://noble.gs.washington.edu/proj/genomedata/doc/1.2.2/genomedata.html

- gevent: http://www.gevent.org/

- Google Wave API: http://wave-robot-python-client.googlecode.com/svn/trunk/pydocs/index.html

- GSL Shell: http://www.nongnu.org/gsl-shell/

- Heapkeeper: http://heapkeeper.org/

- Hands-on Python Tutorial: http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/

- Hedge: https://documen.tician.de/hedge/

- Leo: http://leoeditor.com/

- Lino: http://www.lino-framework.org/

- MeshPy: https://documen.tician.de/meshpy/

- mpmath: http://mpmath.googlecode.com/svn/trunk/doc/build/index.html

- OpenEXR: http://excamera.com/articles/26/doc/index.html

- OpenGDA: http://www.opengda.org/gdadoc/html/

- openWNS: http://docs.openwns.org/

- Paste: http://pythonpaste.org/script/

- Paver: http://paver.github.io/paver/

- Pioneers and Prominent Men of Utah: http://pioneers.rstebbing.com/

- PyCantonese: http://pycantonese.org/

- Pyccuracy: https://github.com/heynemann/pyccuracy/wiki/

- PyCuda: https://documen.tician.de/pycuda/

- Pyevolve: http://pyevolve.sourceforge.net/

- Pylo: https://documen.tician.de/pylo/

- PyMQI: http://pythonhosted.org/pymqi/

- PyPubSub: http://pubsub.sourceforge.net/

- pySPACE: http://pyspace.github.io/pyspace/

- Python: https://docs.python.org/3/

- python-apt: http://apt.alioth.debian.org/python-apt-doc/

- PyUblas: https://documen.tician.de/pyublas/

- Quex: http://quex.sourceforge.net/doc/html/main.html

- Ring programming language: http://ring-lang.sourceforge.net/doc/index.html

- Scapy: http://www.secdev.org/projects/scapy/doc/

- Segway: http://noble.gs.washington.edu/proj/segway/doc/1.1.0/segway.html

- SimPy: http://simpy.readthedocs.org/en/latest/

- SymPy: http://docs.sympy.org/

- WTForms: http://wtforms.simplecodes.com/docs/

- z3c: http://www.ibiblio.org/paulcarduner/z3ctutorial/

Documentation using a customized version of the classic theme

- Advanced Generic Widgets: http://xoomer.virgilio.it/infinity77/AGW_Docs/index.html

- Arb: http://fredrikj.net/arb/

- Bazaar: http://doc.bazaar.canonical.com/en/

- CakePHP: http://book.cakephp.org/2.0/en/index.html

- Chaco: http://docs.enthought.com/chaco/

- Chef: https://docs.chef.io/index.html

- Djagios: http://djagios.org/

- EZ-Draw: http://pageperso.lif.univ-mrs.fr/~edouard.thiel/ez-draw/doc/en/html/ez-manual.html

- GetFEM++: http://home.gna.org/getfem/

- Google or-tools: https://or-tools.googlecode.com/svn/trunk/documentation/user_manual/index.html

- GPAW: https://wiki.fysik.dtu.dk/gpaw/

- Grok: http://grok.zope.org/doc/current/

- Kaa: http://api.freevo.org/kaa-base/

- LEPL: http://www.acooke.org/lepl/

- Mayavi: http://docs.enthought.com/mayavi/mayavi/

- NICOS: http://trac.frm2.tum.de/nicos/doc/nicos-master/index.html

- NOC: http://redmine.nocproject.org/projects/noc

- NumPy: http://docs.scipy.org/doc/numpy/reference/

- OpenCV: http://docs.opencv.org/

- Peach^3: http://peach3.nl/doc/latest/userdoc/

- Sage: http://www.sagemath.org/doc/

- SciPy: http://docs.scipy.org/doc/scipy/reference/

- simuPOP: http://simupop.sourceforge.net/manual_release/build/userGuide.html

- Sprox: http://sprox.org/

- TurboGears: http://turbogears.readthedocs.org/en/latest/

- Varnish: https://www.varnish-cache.org/docs/

- Zentyal: http://doc.zentyal.org/

- Zope: http://docs.zope.org/zope2/index.html

- zc.async: http://pythonhosted.org/zc.async/1.5.0/

Documentation using the sphinxdoc theme

- Fityk: http://fityk.nieto.pl/

- MapServer: http://mapserver.org/

- Matplotlib: http://matplotlib.org/

- Music21: http://web.mit.edu/music21/doc/index.html

- NetworkX: http://networkx.github.io/

- Pweave: http://mpastell.com/pweave/

- Pyre: http://docs.danse.us/pyre/sphinx/

- Pysparse: http://pysparse.sourceforge.net/

- PyTango: http://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/pytango/latest/index.html

- Python Wild Magic: http://vmlaker.github.io/pythonwildmagic/

- Reteisi: http://www.reteisi.org/contents.html

- Sqlkit: http://sqlkit.argolinux.org/

- Turbulenz: http://docs.turbulenz.com/

- WebFaction: https://docs.webfaction.com/

Documentation using another builtin theme

- C/C++ Development with Eclipse: http://eclipsebook.in/ (agogo)

- ESWP3 (http://eswp3.org) (sphinx_rtd_theme)

- Jinja: http://jinja.pocoo.org/ (scrolls)

- jsFiddle: http://doc.jsfiddle.net/ (nature)

- libLAS: http://www.liblas.org/ (nature)

- Linguistica: http://linguistica-uchicago.github.io/lxa5/ (sphinx_rtd_theme)

- MPipe: http://vmlaker.github.io/mpipe/ (sphinx13)

- pip: https://pip.pypa.io/en/latest/ (sphinx_rtd_theme)

- Pyramid web framework: http://docs.pylonsproject.org/projects/pyramid/en/latest/ (pyramid)

- Programmieren mit PyGTK und Glade (German): http://www.florian-diesch.de/doc/python-und-glade/online/ (agogo)

- Satchmo: http://docs.satchmoproject.com/en/latest/ (sphinx_rtd_theme)

- Setuptools: http://pythonhosted.org/setuptools/ (nature)

- Spring Python: http://docs.spring.io/spring-python/1.2.x/sphinx/html/ (nature)

- sqlparse: http://python-sqlparse.googlecode.com/svn/docs/api/index.html (agogo)

- Sylli: http://sylli.sourceforge.net/ (nature)

- Tuleap Open ALM: https://tuleap.net/doc/en/ (nature)

- Valence: http://docs.valence.desire2learn.com/ (haiku)

Documentation using a custom theme/integrated in a site

- Blender: https://www.blender.org/api/250PythonDoc/

- Blinker: http://discorporate.us/projects/Blinker/docs/

- Ceph: http://docs.ceph.com/docs/master/

- Classy: http://www.pocoo.org/projects/classy/

- DEAP: http://deap.gel.ulaval.ca/doc/0.8/index.html

- Django: https://docs.djangoproject.com/

- Elemental: http://libelemental.org/documentation/dev/index.html

- Enterprise Toolkit for Acrobat products: http://www.adobe.com/devnet-docs/acrobatetk/

- e-cidadania: http://e-cidadania.readthedocs.org/en/latest/

- Flask: http://flask.pocoo.org/docs/

- Flask-OpenID: http://pythonhosted.org/Flask-OpenID/

- Gameduino: http://excamera.com/sphinx/gameduino/

- GeoServer: http://docs.geoserver.org/

- GHC - Glasgow Haskell Compiler: http://downloads.haskell.org/~ghc/master/users-guide/

- Glashammer: http://glashammer.org/

- Istihza (Turkish Python documentation project): http://belgeler.istihza.com/py2/

- Lasso: http://lassoguide.com/

- Manage documentation such as source code (fr): http://redaction-technique.org/

- MathJax: http://docs.mathjax.org/en/latest/

- MirrorBrain: http://mirrorbrain.org/docs/

- MyHDL: http://docs.myhdl.org/en/latest/

- nose: http://nose.readthedocs.org/en/latest/

- NoTex: https://www.notex.ch/overview/

- ObjectListView: http://objectlistview.sourceforge.net/python/

- Open ERP: https://doc.odoo.com/

- OpenCV: http://docs.opencv.org/

- Open Dylan: http://opendylan.org/documentation/

- OpenLayers: http://docs.openlayers.org/

- PyEphem: http://rhodesmill.org/pyephem/

- German Plone user manual: http://www.hasecke.com/plone-benutzerhandbuch/

- PSI4: http://www.psicode.org/psi4manual/master/index.html

- Pylons: http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/

- PyMOTW: https://pymotw.com/2/

- python-aspectlib: http://python-aspectlib.readthedocs.org/en/latest/ (sphinx-py3doc-enhanced-theme [https://pypi.python.org/pypi/sphinx_py3doc_enhanced_theme])

- QGIS: http://qgis.org/en/docs/index.html

- qooxdoo: http://manual.qooxdoo.org/current/

- Roundup: http://www.roundup-tracker.org/

- Selenium: http://docs.seleniumhq.org/docs/

- Self: http://www.selflanguage.org/

- Substance D: http://docs.pylonsproject.org/projects/substanced/en/latest/

- Tablib: http://tablib.org/

- SQLAlchemy: http://www.sqlalchemy.org/docs/

- tinyTiM: http://tinytim.sourceforge.net/docs/2.0/

- Ubuntu packaging guide: http://packaging.ubuntu.com/html/

- Werkzeug: http://werkzeug.pocoo.org/docs/

- WFront: http://discorporate.us/projects/WFront/

Homepages and other non-documentation sites

- A personal page: http://www.dehlia.in/

- Benoit Boissinot: http://bboissin.appspot.com/

- lunarsite: http://lunaryorn.de/

- The Wine Cellar Book: http://www.thewinecellarbook.com/doc/en/

- UC Berkeley Advanced Control Systems course: http://msc.berkeley.edu/tomizuka/me233spring13/

- VOR: http://www.vor-cycling.be/

Books produced using Sphinx

- “The repoze.bfg Web Application Framework”: http://www.amazon.com/repoze-bfg-Web-Application-Framework-Version/dp/0615345379

- A Theoretical Physics Reference book: http://www.theoretical-physics.net/

- “Simple and Steady Way of Learning for Software Engineering” (in Japanese): http://www.amazon.co.jp/dp/477414259X/

- “Expert Python Programming”: https://www.packtpub.com/application-development/expert-python-programming

- “Expert Python Programming” (Japanese translation): http://www.amazon.co.jp/dp/4048686291/

- “Pomodoro Technique Illustrated” (Japanese translation): http://www.amazon.co.jp/dp/4048689525/

- “Python Professional Programming” (in Japanese): http://www.amazon.co.jp/dp/4798032948/

- “Die Wahrheit des Sehens. Der DEKALOG von Krzysztof Kieślowski”: http://www.hasecke.eu/Dekalog/

- The “Varnish Book”: http://book.varnish-software.com/4.0/

- “Learning Sphinx” (in Japanese): http://www.oreilly.co.jp/books/9784873116488/

- “LassoGuide”: http://www.lassosoft.com/Lasso-Documentation

- “Software-Dokumentation mit Sphinx”: http://www.amazon.de/dp/1497448689/

Thesis using Sphinx

- “A Web-Based System for Comparative Analysis of OpenStreetMap Data by the Use of CouchDB”: https://www.yumpu.com/et/document/view/11722645/masterthesis-markusmayr-0542042

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- previous |

- Sphinx 1.4.1 documentation »

Sphinx authors

Sphinx is written and maintained by Georg Brandl <georg@python.org>.

Substantial parts of the templates were written by Armin Ronacher <armin.ronacher@active-4.com>.

Other co-maintainers:

- Takayuki Shimizukawa <shimizukawa@gmail.com>

- Daniel Neuhäuser <@DasIch>

- Jon Waltman <@jonwaltman>

- Rob Ruana <@RobRuana>

- Robert Lehmann <@lehmannro>

- Roland Meister <@rolmei>

Other contributors, listed alphabetically, are:

- Alastair Houghton – Apple Help builder

- Andi Albrecht – agogo theme

- Jakob Lykke Andersen – Rewritten C++ domain

- Henrique Bastos – SVG support for graphviz extension

- Daniel Bültmann – todo extension

- Etienne Desautels – apidoc module

- Michael Droettboom – inheritance_diagram extension

- Charles Duffy – original graphviz extension

- Kevin Dunn – MathJax extension

- Josip Dzolonga – coverage builder

- Buck Evan – dummy builder

- Hernan Grecco – search improvements

- Horst Gutmann – internationalization support

- Martin Hans – autodoc improvements

- Doug Hellmann – graphviz improvements

- Timotheus Kampik - JS enhancements, stop words language fix

- Takeshi Komiya – numref feature

- Dave Kuhlman – original LaTeX writer

- Blaise Laflamme – pyramid theme

- Thomas Lamb – linkcheck builder

- Łukasz Langa – partial support for autodoc

- Ian Lee – quickstart improvements

- Robert Lehmann – gettext builder (GSOC project)

- Dan MacKinlay – metadata fixes

- Martin Mahner – nature theme

- Will Maier – directory HTML builder

- Jacob Mason – websupport library (GSOC project)

- Roland Meister – epub builder

- Ezio Melotti – collapsible sidebar JavaScript

- Daniel Neuhäuser – JavaScript domain, Python 3 support (GSOC)

- Christopher Perkins – autosummary integration

- Benjamin Peterson – unittests

20. Powers – HTML output improvements

- Jeppe Pihl – literalinclude improvements

- Rob Ruana – napoleon extension

- Stefan Seefeld – toctree improvements

- Shibukawa Yoshiki – pluggable search API and Japanese search

- Taku Shimizu – epub3 builder

- Antonio Valentino – qthelp builder

- Filip Vavera – napoleon todo directive

- Pauli Virtanen – autodoc improvements, autosummary extension

- Stefan van der Walt – autosummary extension

- Thomas Waldmann – apidoc module fixes

- John Waltman – Texinfo builder

- Barry Warsaw – setup command improvements

- Sebastian Wiesner – image handling, distutils support

- Michael Wilson – Intersphinx HTTP basic auth support

- Joel Wurtz – cellspanning support in LaTeX

- Hong Xu – svg support in imgmath extension and various bug fixes

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

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

Installing Sphinx

Since Sphinx is written in the Python language, you need to install Python (the required version is at least 2.6) and Sphinx.

Sphinx packages are available on the Python Package Index [https://pypi.python.org/pypi/Sphinx].

You can also download a snapshot from the Git repository:

- as a .tar.gz [https://github.com/sphinx-doc/sphinx/archive/master.tar.gz] file or

- as a .zip [https://github.com/sphinx-doc/sphinx/archive/master.zip] file

There are introductions for several environments:

- Debian/Ubuntu: Install Sphinx using packaging system

- Other Linux distributions

- Mac OS X: Install Sphinx using MacPorts

- Windows: Install Python and Sphinx

- Installing Sphinx with pip

Debian/Ubuntu: Install Sphinx using packaging system

You may install using this command if you use Debian/Ubuntu.

$ apt-get install python-sphinx

Other Linux distributions

Most Linux distributions have Sphinx in their package repositories. Usually the package is called “python-sphinx”, “python-Sphinx” or “sphinx”. Be aware that there are two other packages with “sphinx” in their name: a speech recognition toolkit (CMU Sphinx) and a full-text search database (Sphinx search).

Mac OS X: Install Sphinx using MacPorts

If you use Mac OS X MacPorts [http://www.macports.org/], use this command to install all necessary software.

$ sudo port install py27-sphinx

To set up the executable paths, use the port select command:

$ sudo port select --set python python27
$ sudo port select --set sphinx py27-sphinx

Type which sphinx-quickstart to check if the installation was successful.

Windows: Install Python and Sphinx

Install Python

Most Windows users do not have Python, so we begin with the installation of Python itself. If you have already installed Python, please skip this section.

Go to https://www.python.org/, the main download site for Python. Look at the left sidebar and under “Quick Links”, click “Windows Installer” to download.

Note

Currently, Python offers two major versions, 2.x and 3.x. Sphinx 1.3 can run under Python 2.6, 2.7, 3.3, 3.4, with the recommended version being 2.7. This chapter assumes you have installed Python 2.7.

Follow the Windows installer for Python.

After installation, you better add the Python executable directories to the environment variable PATH in order to run Python and package commands such as sphinx-build easily from the Command Prompt.

- Right-click the “My Computer” icon and choose “Properties”

- Click the “Environment Variables” button under the “Advanced” tab

- If “Path” (or “PATH”) is already an entry in the “System variables” list, edit it. If it is not present, add a new variable called “PATH”.

- Add these paths, separating entries by ”;”:

- C:\Python27 – this folder contains the main Python executable

- C:\Python27\Scripts – this folder will contain executables added by Python packages installed with pip (see below)

This is for Python 2.7. If you use another version of Python or installed to a non-default location, change the digits “27” accordingly.

- Now run the Command Prompt. After command prompt window appear, type python and Enter. If the Python installation was successful, the installed Python version is printed, and you are greeted by the prompt >>>. Type Ctrl+Z and Enter to quit.

Install the pip command

Python has a very useful pip command which can download and install 3rd-party libraries with a single command. This is provided by the Python Packaging Authority(PyPA): https://groups.google.com/forum/#!forum/pypa-dev

To install pip, download https://bootstrap.pypa.io/get-pip.py and save it somewhere. After download, invoke the command prompt, go to the directory with get-pip.py and run this command:

C:\> python get-pip.py

Now pip command is installed. From there we can go to the Sphinx install.

Note

pip has been contained in the Python official installation after version

of Python-3.4.0 or Python-2.7.9.

Installing Sphinx with pip

If you finished the installation of pip, type this line in the command prompt:

C:\> pip install sphinx

After installation, type sphinx-build -h on the command prompt. If everything worked fine, you will get a Sphinx version number and a list of options for this command.

That it. Installation is over. Head to First Steps with Sphinx to make a Sphinx project.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

Sphinx development

Sphinx is a maintained by a group of volunteers. We value every contribution!

- The code can be found in a Git repository, at https://github.com/sphinx-doc/sphinx/.

- Issues and feature requests should be raised in the tracker [https://github.com/sphinx-doc/sphinx/issues].

- The mailing list for development is at Google Groups [https://groups.google.com/forum/#!forum/sphinx-dev].

- There is also the #sphinx-doc IRC channel on freenode [http://freenode.net/].

For more about our development process and methods, see the Sphinx Developer’s Guide.

Extensions

To learn how to write your own extension, see Developing extensions for Sphinx.

The sphinx-contrib [https://bitbucket.org/birkenfeld/sphinx-contrib/] repository contains many contributed extensions. Some of them have their own releases on PyPI, others you can install from a checkout.

This is the current list of contributed extensions in that repository:

- aafig: render embedded ASCII art as nice images using aafigure [https://launchpad.net/aafigure].

- actdiag: embed activity diagrams by using actdiag [http://blockdiag.com/en/]

- adadomain: an extension for Ada support (Sphinx 1.0 needed)

- ansi: parse ANSI color sequences inside documents

- autorun: Execute code in a runblock directive.

- blockdiag: embed block diagrams by using blockdiag [http://blockdiag.com/en/]

- cheeseshop: easily link to PyPI packages

- clearquest: create tables from ClearQuest [http://www-03.ibm.com/software/products/en/clearquest] queries.

- cmakedomain [https://bitbucket.org/klorenz/sphinxcontrib-cmakedomain]: a domain for CMake [https://cmake.org]

- coffeedomain: a domain for (auto)documenting CoffeeScript source code.

- context: a builder for ConTeXt.

- doxylink: Link to external Doxygen-generated HTML documentation

- domaintools [https://bitbucket.org/klorenz/sphinxcontrib-domaintools]: A tool for easy domain creation.

- email: obfuscate email addresses

- erlangdomain: an extension for Erlang support (Sphinx 1.0 needed)

- exceltable: embed Excel spreadsheets into documents using exceltable [http://pythonhosted.org/sphinxcontrib-exceltable/]

- feed: an extension for creating syndication feeds and time-based overviews from your site content

- findanything [https://bitbucket.org/klorenz/sphinxcontrib-findanything]: an extension to add Sublime Text 2-like findanything panels to your documentation to find pages, sections and index entries while typing

- gnuplot: produces images using gnuplot [http://www.gnuplot.info/] language.

- googleanalytics: track web visitor statistics by using Google Analytics [http://www.google.com/analytics/]

- googlechart: embed charts by using Google Chart [https://developers.google.com/chart/]

- googlemaps: embed maps by using Google Maps [https://www.google.com/maps]

- httpdomain: a domain for documenting RESTful HTTP APIs.

- hyphenator: client-side hyphenation of HTML using hyphenator [https://github.com/mnater/hyphenator]

- inlinesyntaxhighlight [http://sphinxcontrib-inlinesyntaxhighlight.readthedocs.org]: inline syntax highlighting

- lassodomain: a domain for documenting Lasso [http://www.lassosoft.com/] source code

- libreoffice: an extension to include any drawing supported by LibreOffice (e.g. odg, vsd...).

- lilypond: an extension inserting music scripts from Lilypond [http://lilypond.org/] in PNG format.

- makedomain [https://bitbucket.org/klorenz/sphinxcontrib-makedomain]: a domain for GNU Make [http://www.gnu.org/software/make/]

- matlabdomain: document MATLAB [http://www.mathworks.com/products/matlab/] code.

- mockautodoc: mock imports.

- mscgen: embed mscgen-formatted MSC (Message Sequence Chart)s.

- napoleon: supports Google style [http://google-styleguide.googlecode.com/svn/trunk/pyguide.html] and NumPy style [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt] docstrings.

- nicoviceo: embed videos from nicovideo

- nwdiag: embed network diagrams by using nwdiag [http://blockdiag.com/en/]

- omegat: support tools to collaborate with OmegaT [http://www.omegat.org/] (Sphinx 1.1 needed)

- osaka: convert standard Japanese doc to Osaka dialect (it is joke extension)

- paverutils: an alternate integration of Sphinx with Paver [http://paver.github.io/paver/].

- phpdomain: an extension for PHP support

- plantuml: embed UML diagram by using PlantUML [http://plantuml.com/]

- py_directive: Execute python code in a py directive and return a math node.

- rawfiles: copy raw files, like a CNAME.

- requirements: declare requirements wherever you need (e.g. in test docstrings), mark statuses and collect them in a single list

- restbuilder: a builder for reST (reStructuredText) files.

- rubydomain: an extension for Ruby support (Sphinx 1.0 needed)

- sadisplay: display SqlAlchemy model sadisplay [https://bitbucket.org/estin/sadisplay/wiki/Home]

- sdedit: an extension inserting sequence diagram by using Quick Sequence Diagram Editor (sdedit [http://sdedit.sourceforge.net/])

- seqdiag: embed sequence diagrams by using seqdiag [http://blockdiag.com/en/]

- slide: embed presentation slides on slideshare [http://www.slideshare.net/] and other sites.

- swf [https://bitbucket.org/klorenz/sphinxcontrib-swf]: embed flash files

- sword: an extension inserting Bible verses from Sword [http://www.crosswire.org/sword/].

- tikz: draw pictures with the TikZ/PGF LaTeX package [https://sourceforge.net/projects/pgf/].

- traclinks: create TracLinks [http://trac.edgewall.org/wiki/TracLinks] to a Trac [http://trac.edgewall.org] instance from within Sphinx

- whooshindex: whoosh indexer extension

- youtube: embed videos from YouTube [http://www.youtube.com/]

- zopeext: provide an autointerface directive for using Zope interfaces [http://docs.zope.org/zope.interface/README.html].

See the extension tutorial on getting started with writing your own extensions.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

Python Module Index

a | b | c | d | e | p

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for docutils.parsers.rst

# $Id: __init__.py 7598 2013-01-30 12:39:24Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.

"""
This is ``docutils.parsers.rst`` package. It exports a single class, `Parser`,
the reStructuredText parser.

Usage
=====

1. Create a parser::

parser = docutils.parsers.rst.Parser()

Several optional arguments may be passed to modify the parser's behavior.
Please see `Customizing the Parser`_ below for details.

2. Gather input (a multi-line string), by reading a file or the standard
input::

input = sys.stdin.read()

3. Create a new empty `docutils.nodes.document` tree::

document = docutils.utils.new_document(source, settings)

See `docutils.utils.new_document()` for parameter details.

4. Run the parser, populating the document tree::

parser.parse(input, document)

Parser Overview
===============

The reStructuredText parser is implemented as a state machine, examining its
input one line at a time. To understand how the parser works, please first
become familiar with the `docutils.statemachine` module, then see the
`states` module.

Customizing the Parser
----------------------

Anything that isn't already customizable is that way simply because that type
of customizability hasn't been implemented yet.  Patches welcome!

When instantiating an object of the `Parser` class, two parameters may be
passed: ``rfc2822`` and ``inliner``.  Pass ``rfc2822=True`` to enable an
initial RFC-2822 style header block, parsed as a "field_list" element (with
"class" attribute set to "rfc2822").  Currently this is the only body-level
element which is customizable without subclassing.  (Tip: subclass `Parser`
and change its "state_classes" and "initial_state" attributes to refer to new
classes. Contact the author if you need more details.)

The ``inliner`` parameter takes an instance of `states.Inliner` or a subclass.
It handles inline markup recognition.  A common extension is the addition of
further implicit hyperlinks, like "RFC 2822".  This can be done by subclassing
`states.Inliner`, adding a new method for the implicit markup, and adding a
``(pattern, method)`` pair to the "implicit_dispatch" attribute of the
subclass.  See `states.Inliner.implicit_inline()` for details.  Explicit
inline markup can be customized in a `states.Inliner` subclass via the
``patterns.initial`` and ``dispatch`` attributes (and new methods as
appropriate).
"""

__docformat__ = 'reStructuredText'

import docutils.parsers
import docutils.statemachine
from docutils.parsers.rst import states
from docutils import frontend, nodes, Component
from docutils.transforms import universal

class Parser(docutils.parsers.Parser):

"""The reStructuredText parser."""

supported = ('restructuredtext', 'rst', 'rest', 'restx', 'rtxt', 'rstx')
"""Aliases this parser supports."""

settings_spec = (
'reStructuredText Parser Options',
None,
(('Recognize and link to standalone PEP references (like "PEP 258").',
['--pep-references'],
{'action': 'store_true', 'validator': frontend.validate_boolean}),
('Base URL for PEP references '
'(default "http://www.python.org/dev/peps/").',
['--pep-base-url'],
{'metavar': '<URL>', 'default': 'http://www.python.org/dev/peps/',
'validator': frontend.validate_url_trailing_slash}),
('Template for PEP file part of URL. (default "pep-%04d")',
['--pep-file-url-template'],
{'metavar': '<URL>', 'default': 'pep-%04d'}),
('Recognize and link to standalone RFC references (like "RFC 822").',
['--rfc-references'],
{'action': 'store_true', 'validator': frontend.validate_boolean}),
('Base URL for RFC references (default "http://www.faqs.org/rfcs/").',
['--rfc-base-url'],
{'metavar': '<URL>', 'default': 'http://www.faqs.org/rfcs/',
'validator': frontend.validate_url_trailing_slash}),
('Set number of spaces for tab expansion (default 8).',
['--tab-width'],
{'metavar': '<width>', 'type': 'int', 'default': 8,
'validator': frontend.validate_nonnegative_int}),
('Remove spaces before footnote references.',
['--trim-footnote-reference-space'],
{'action': 'store_true', 'validator': frontend.validate_boolean}),
('Leave spaces before footnote references.',
['--leave-footnote-reference-space'],
{'action': 'store_false', 'dest': 'trim_footnote_reference_space'}),
('Disable directives that insert the contents of external file '
'("include" & "raw"); replaced with a "warning" system message.',
['--no-file-insertion'],
{'action': 'store_false', 'default': 1,
'dest': 'file_insertion_enabled',
'validator': frontend.validate_boolean}),
('Enable directives that insert the contents of external file '
'("include" & "raw").  Enabled by default.',
['--file-insertion-enabled'],
{'action': 'store_true'}),
('Disable the "raw" directives; replaced with a "warning" '
'system message.',
['--no-raw'],
{'action': 'store_false', 'default': 1, 'dest': 'raw_enabled',
'validator': frontend.validate_boolean}),
('Enable the "raw" directive.  Enabled by default.',
['--raw-enabled'],
{'action': 'store_true'}),
('Token name set for parsing code with Pygments: one of '
'"long", "short", or "none (no parsing)". Default is "long".',
['--syntax-highlight'],
{'choices': ['long', 'short', 'none'],
'default': 'long', 'metavar': '<format>'}),
('Change straight quotation marks to typographic form: '
'one of "yes", "no", "alt[ernative]" (default "no").',
['--smart-quotes'],
{'default': False, 'validator': frontend.validate_ternary}),
))

config_section = 'restructuredtext parser'
config_section_dependencies = ('parsers',)

def __init__(self, rfc2822=False, inliner=None):
if rfc2822:
self.initial_state = 'RFC2822Body'
else:
self.initial_state = 'Body'
self.state_classes = states.state_classes
self.inliner = inliner

def get_transforms(self):
return Component.get_transforms(self) + [
universal.SmartQuotes]

def parse(self, inputstring, document):
"""Parse `inputstring` and populate `document`, a document tree."""
self.setup_parse(inputstring, document)
self.statemachine = states.RSTStateMachine(
state_classes=self.state_classes,
initial_state=self.initial_state,
debug=document.reporter.debug_flag)
inputlines = docutils.statemachine.string2lines(
inputstring, tab_width=document.settings.tab_width,
convert_whitespace=True)
self.statemachine.run(inputlines, document, inliner=self.inliner)
self.finish_parse()

class DirectiveError(Exception):

"""
Store a message and a system message level.

To be thrown from inside directive code.

Do not instantiate directly -- use `Directive.directive_error()`
instead!
"""

def __init__(self, level, message):
"""Set error `message` and `level`"""
Exception.__init__(self)
self.level = level
self.msg = message

[docs]class Directive(object):

"""
Base class for reStructuredText directives.

The following attributes may be set by subclasses.  They are
interpreted by the directive parser (which runs the directive
class):

- `required_arguments`: The number of required arguments (default:
0).

- `optional_arguments`: The number of optional arguments (default:
0).

- `final_argument_whitespace`: A boolean, indicating if the final
argument may contain whitespace (default: False).

- `option_spec`: A dictionary, mapping known option names to
conversion functions such as `int` or `float` (default: {}, no
options).  Several conversion functions are defined in the
directives/__init__.py module.

Option conversion functions take a single parameter, the option
argument (a string or ``None``), validate it and/or convert it
to the appropriate form.  Conversion functions may raise
`ValueError` and `TypeError` exceptions.

- `has_content`: A boolean; True if content is allowed.  Client
code must handle the case where content is required but not
supplied (an empty content list will be supplied).

Arguments are normally single whitespace-separated words.  The
final argument may contain whitespace and/or newlines if
`final_argument_whitespace` is True.

If the form of the arguments is more complex, specify only one
argument (either required or optional) and set
`final_argument_whitespace` to True; the client code must do any
context-sensitive parsing.

When a directive implementation is being run, the directive class
is instantiated, and the `run()` method is executed.  During
instantiation, the following instance variables are set:

- ``name`` is the directive type or name (string).

- ``arguments`` is the list of positional arguments (strings).

- ``options`` is a dictionary mapping option names (strings) to
values (type depends on option conversion functions; see
`option_spec` above).

- ``content`` is a list of strings, the directive content line by line.

- ``lineno`` is the absolute line number of the first line
of the directive.

- ``src`` is the name (or path) of the rst source of the directive.

- ``srcline`` is the line number of the first line of the directive
in its source. It may differ from ``lineno``, if the main source
includes other sources with the ``.. include::`` directive.

- ``content_offset`` is the line offset of the first line of the content from
the beginning of the current input.  Used when initiating a nested parse.

- ``block_text`` is a string containing the entire directive.

- ``state`` is the state which called the directive function.

- ``state_machine`` is the state machine which controls the state which called
the directive function.

Directive functions return a list of nodes which will be inserted
into the document tree at the point where the directive was
encountered.  This can be an empty list if there is nothing to
insert.

For ordinary directives, the list must contain body elements or
structural elements.  Some directives are intended specifically
for substitution definitions, and must return a list of `Text`
nodes and/or inline elements (suitable for inline insertion, in
place of the substitution reference).  Such directives must verify
substitution definition context, typically using code like this::

if not isinstance(state, states.SubstitutionDef):
error = state_machine.reporter.error(
'Invalid context: the "%s" directive can only be used '
'within a substitution definition.' % (name),
nodes.literal_block(block_text, block_text), line=lineno)
return [error]
"""

# There is a "Creating reStructuredText Directives" how-to at
# <http://docutils.sf.net/docs/howto/rst-directives.html>.  If you
# update this docstring, please update the how-to as well.

required_arguments = 0
"""Number of required directive arguments."""

optional_arguments = 0
"""Number of optional arguments after the required arguments."""

final_argument_whitespace = False
"""May the final argument contain whitespace?"""

option_spec = None
"""Mapping of option names to validator functions."""

has_content = False
"""May the directive have content?"""

def __init__(self, name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
self.name = name
self.arguments = arguments
self.options = options
self.content = content
self.lineno = lineno
self.content_offset = content_offset
self.block_text = block_text
self.state = state
self.state_machine = state_machine

[docs]    def run(self):
raise NotImplementedError('Must override run() is subclass.')

# Directive errors:

def directive_error(self, level, message):
"""
Return a DirectiveError suitable for being thrown as an exception.

Call "raise self.directive_error(level, message)" from within
a directive implementation to return one single system message
at level `level`, which automatically gets the directive block
and the line number added.

Preferably use the `debug`, `info`, `warning`, `error`, or `severe`
wrapper methods, e.g. ``self.error(message)`` to generate an
ERROR-level directive error.
"""
return DirectiveError(level, message)

def debug(self, message):
return self.directive_error(0, message)

def info(self, message):
return self.directive_error(1, message)

def warning(self, message):
return self.directive_error(2, message)

def error(self, message):
return self.directive_error(3, message)

def severe(self, message):
return self.directive_error(4, message)

# Convenience methods:

def assert_has_content(self):
"""
Throw an ERROR-level DirectiveError if the directive doesn't
have contents.
"""
if not self.content:
raise self.error('Content block expected for the "%s" directive; '
'none found.' % self.name)

def add_name(self, node):
"""Append self.options['name'] to node['names'] if it exists.

Also normalize the name string and register it as explicit target.
"""
if 'name' in self.options:
name = nodes.fully_normalize_name(self.options.pop('name'))
if 'name' in node:
del(node['name'])
node['names'].append(name)
self.state.document.note_explicit_target(node, node)

def convert_directive_function(directive_fn):
"""
Define & return a directive class generated from `directive_fn`.

`directive_fn` uses the old-style, functional interface.
"""

class FunctionalDirective(Directive):

option_spec = getattr(directive_fn, 'options', None)
has_content = getattr(directive_fn, 'content', False)
_argument_spec = getattr(directive_fn, 'arguments', (0, 0, False))
required_arguments, optional_arguments, final_argument_whitespace \
= _argument_spec

def run(self):
return directive_fn(
self.name, self.arguments, self.options, self.content,
self.lineno, self.content_offset, self.block_text,
self.state, self.state_machine)

# Return new-style directive.
return FunctionalDirective

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

All modules for which code is available

- docutils.parsers.rst

- sphinx.addnodes

- sphinx.application

- sphinx.builders

- sphinx.builders.applehelp

- sphinx.builders.changes

- sphinx.builders.devhelp

- sphinx.builders.dummy

- sphinx.builders.epub

- sphinx.builders.epub3

- sphinx.builders.gettext

- sphinx.builders.html

- sphinx.builders.htmlhelp

- sphinx.builders.latex

- sphinx.builders.linkcheck

- sphinx.builders.manpage

- sphinx.builders.qthelp

- sphinx.builders.texinfo

- sphinx.builders.text

- sphinx.builders.xml

- sphinx.config

- sphinx.domains

- sphinx.environment

- sphinx.errors

- sphinx.ext.autodoc

- sphinx.ext.coverage

- sphinx.parsers

- sphinx.websupport

- sphinx.websupport.search

- sphinx.websupport.storage

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.addnodes

# -*- coding: utf-8 -*-
"""
sphinx.addnodes
~~~~~~~~~~~~~~~

Additional docutils nodes.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import warnings

from docutils import nodes

[docs]class toctree(nodes.General, nodes.Element):
"""Node for inserting a "TOC tree"."""

# domain-specific object descriptions (class, function etc.)

[docs]class desc(nodes.Admonition, nodes.Element):
"""Node for object descriptions.

This node is similar to a "definition list" with one definition.  It
contains one or more ``desc_signature`` and a ``desc_content``.
"""

[docs]class desc_signature(nodes.Part, nodes.Inline, nodes.TextElement):
"""Node for object signatures.

The "term" part of the custom Sphinx definition list.
"""

# nodes to use within a desc_signature

[docs]class desc_addname(nodes.Part, nodes.Inline, nodes.TextElement):
"""Node for additional name parts (module name, class name)."""

# compatibility alias
desc_classname = desc_addname

[docs]class desc_type(nodes.Part, nodes.Inline, nodes.TextElement):
"""Node for return types or object type names."""

[docs]class desc_returns(desc_type):
"""Node for a "returns" annotation (a la -> in Python)."""
def astext(self):
return ' -> ' + nodes.TextElement.astext(self)

[docs]class desc_name(nodes.Part, nodes.Inline, nodes.TextElement):
"""Node for the main object name."""

[docs]class desc_parameterlist(nodes.Part, nodes.Inline, nodes.TextElement):
"""Node for a general parameter list."""
child_text_separator = ', '

[docs]class desc_parameter(nodes.Part, nodes.Inline, nodes.TextElement):
"""Node for a single parameter."""

[docs]class desc_optional(nodes.Part, nodes.Inline, nodes.TextElement):
"""Node for marking optional parts of the parameter list."""
child_text_separator = ', '

def astext(self):
return '[' + nodes.TextElement.astext(self) + ']'

[docs]class desc_annotation(nodes.Part, nodes.Inline, nodes.TextElement):
"""Node for signature annotations (not Python 3-style annotations)."""

[docs]class desc_content(nodes.General, nodes.Element):
"""Node for object description content.

This is the "definition" part of the custom Sphinx definition list.
"""

# new admonition-like constructs

[docs]class versionmodified(nodes.Admonition, nodes.TextElement):
"""Node for version change entries.

Currently used for "versionadded", "versionchanged" and "deprecated"
directives.
"""

[docs]class seealso(nodes.Admonition, nodes.Element):
"""Custom "see also" admonition."""

[docs]class productionlist(nodes.Admonition, nodes.Element):
"""Node for grammar production lists.

Contains ``production`` nodes.
"""

[docs]class production(nodes.Part, nodes.Inline, nodes.TextElement):
"""Node for a single grammar production rule."""

# other directive-level nodes

[docs]class index(nodes.Invisible, nodes.Inline, nodes.TextElement):
"""Node for index entries.

This node is created by the ``index`` directive and has one attribute,
``entries``.  Its value is a list of 4-tuples of ``(entrytype, entryname,
target, ignored)``.

*entrytype* is one of "single", "pair", "double", "triple".
"""

class centered(nodes.Part, nodes.TextElement):
"""Deprecated."""

class acks(nodes.Element):
"""Special node for "acks" lists."""

class hlist(nodes.Element):
"""Node for "horizontal lists", i.e. lists that should be compressed to
take up less vertical space.
"""

class hlistcol(nodes.Element):
"""Node for one column in a horizontal list."""

[docs]class compact_paragraph(nodes.paragraph):
"""Node for a compact paragraph (which never makes a <p> node)."""

[docs]class glossary(nodes.Element):
"""Node to insert a glossary."""

[docs]class only(nodes.Element):
"""Node for "only" directives (conditional inclusion based on tags)."""

# meta-information nodes

[docs]class start_of_file(nodes.Element):
"""Node to mark start of a new file, used in the LaTeX builder only."""

[docs]class highlightlang(nodes.Element):
"""Inserted to set the highlight language and line number options for
subsequent code blocks.
"""

class tabular_col_spec(nodes.Element):
"""Node for specifying tabular columns, used for LaTeX output."""

[docs]class meta(nodes.Special, nodes.PreBibliographic, nodes.Element):
"""Node for meta directive -- same as docutils' standard meta node,
but pickleable.
"""

# inline nodes

[docs]class pending_xref(nodes.Inline, nodes.Element):
"""Node for cross-references that cannot be resolved without complete
information about all documents.

These nodes are resolved before writing output, in
BuildEnvironment.resolve_references.
"""

class number_reference(nodes.reference):
"""Node for number references, similar to pending_xref."""

[docs]class download_reference(nodes.reference):
"""Node for download references, similar to pending_xref."""

[docs]class literal_emphasis(nodes.emphasis):
"""Node that behaves like `emphasis`, but further text processors are not
applied (e.g. smartypants for HTML output).
"""

class literal_strong(nodes.strong):
"""Node that behaves like `strong`, but further text processors are not
applied (e.g. smartypants for HTML output).
"""

[docs]class abbreviation(nodes.Inline, nodes.TextElement):
"""Node for abbreviations with explanations."""

[docs]class termsep(nodes.Structural, nodes.Element):
"""Separates two terms within a <term> node.

.. versionchanged:: 1.4
sphinx.addnodes.termsep is deprecated. It will be removed at Sphinx-1.5.
"""

def __init__(self, *args, **kw):
warnings.warn('sphinx.addnodes.termsep will be removed at Sphinx-1.5',
DeprecationWarning, stacklevel=2)
super(termsep, self).__init__(*args, **kw)

class manpage(nodes.Inline, nodes.TextElement):
"""Node for references to manpages."""

# make the new nodes known to docutils; needed because the HTML writer will
# choke at some point if these are not added
nodes._add_node_class_names(k for k in globals().keys()
if k != 'nodes' and k[0] != '_')

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.application

# -*- coding: utf-8 -*-
"""
sphinx.application
~~~~~~~~~~~~~~~~~~

Sphinx application object.

Gracefully adapted from the TextPress system by Armin.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function

import os
import sys
import types
import posixpath
import traceback
from os import path
from collections import deque

from six import iteritems, itervalues, text_type
from six.moves import cStringIO
from docutils import nodes
from docutils.parsers.rst import convert_directive_function, \
directives, roles

import sphinx
from sphinx import package_dir, locale
from sphinx.roles import XRefRole
from sphinx.config import Config
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \
VersionRequirementError, ConfigError
from sphinx.domains import ObjType, BUILTIN_DOMAINS
from sphinx.domains.std import GenericObject, Target, StandardDomain
from sphinx.builders import BUILTIN_BUILDERS
from sphinx.environment import BuildEnvironment
from sphinx.io import SphinxStandaloneReader
from sphinx.util import pycompat  # noqa: imported for side-effects
from sphinx.util import import_object
from sphinx.util.tags import Tags
from sphinx.util.osutil import ENOENT
from sphinx.util.logging import is_suppressed_warning
from sphinx.util.console import bold, lightgray, darkgray, darkgreen, \
term_width_line
from sphinx.util.i18n import find_catalog_source_files

if hasattr(sys, 'intern'):
intern = sys.intern

# List of all known core events. Maps name to arguments description.
events = {
'builder-inited': '',
'env-get-outdated': 'env, added, changed, removed',
'env-purge-doc': 'env, docname',
'env-before-read-docs': 'env, docnames',
'source-read': 'docname, source text',
'doctree-read': 'the doctree before being pickled',
'env-merge-info': 'env, read docnames, other env instance',
'missing-reference': 'env, node, contnode',
'doctree-resolved': 'doctree, docname',
'env-updated': 'env',
'html-collect-pages': 'builder',
'html-page-context': 'pagename, context, doctree or None',
'build-finished': 'exception',
}

CONFIG_FILENAME = 'conf.py'
ENV_PICKLE_FILENAME = 'environment.pickle'

[docs]class Sphinx(object):

def __init__(self, srcdir, confdir, outdir, doctreedir, buildername,
confoverrides=None, status=sys.stdout, warning=sys.stderr,
freshenv=False, warningiserror=False, tags=None, verbosity=0,
parallel=0):
self.verbosity = verbosity
self.next_listener_id = 0
self._extensions = {}
self._extension_metadata = {}
self._additional_source_parsers = {}
self._listeners = {}
self._setting_up_extension = ['?']
self.domains = BUILTIN_DOMAINS.copy()
self.buildername = buildername
self.builderclasses = BUILTIN_BUILDERS.copy()
self.builder = None
self.env = None
self.enumerable_nodes = {}

self.srcdir = srcdir
self.confdir = confdir
self.outdir = outdir
self.doctreedir = doctreedir

self.parallel = parallel

if status is None:
self._status = cStringIO()
self.quiet = True
else:
self._status = status
self.quiet = False

if warning is None:
self._warning = cStringIO()
else:
self._warning = warning
self._warncount = 0
self.warningiserror = warningiserror

self._events = events.copy()
self._translators = {}

# keep last few messages for traceback
self.messagelog = deque(maxlen=10)

# say hello to the world
self.info(bold('Running Sphinx v%s' % sphinx.__display_version__))

# status code for command-line application
self.statuscode = 0

if not path.isdir(outdir):
self.info('making output directory...')
os.makedirs(outdir)

# read config
self.tags = Tags(tags)
self.config = Config(confdir, CONFIG_FILENAME,
confoverrides or {}, self.tags)
self.config.check_unicode(self.warn)
# defer checking types until i18n has been initialized

# initialize some limited config variables before loading extensions
self.config.pre_init_values(self.warn)

# check the Sphinx version if requested
if self.config.needs_sphinx and self.config.needs_sphinx > sphinx.__display_version__:
raise VersionRequirementError(
'This project needs at least Sphinx v%s and therefore cannot '
'be built with this version.' % self.config.needs_sphinx)

# set confdir to srcdir if -C given (!= no confdir); a few pieces
# of code expect a confdir to be set
if self.confdir is None:
self.confdir = self.srcdir

# extension loading support for alabaster theme
# self.config.html_theme is not set from conf.py at here
# for now, sphinx always load a 'alabaster' extension.
if 'alabaster' not in self.config.extensions:
self.config.extensions.append('alabaster')

# load all user-given extension modules
for extension in self.config.extensions:
self.setup_extension(extension)
# the config file itself can be an extension
if self.config.setup:
self._setting_up_extension = ['conf.py']
# py31 doesn't have 'callable' function for below check
if hasattr(self.config.setup, '__call__'):
self.config.setup(self)
else:
raise ConfigError(
"'setup' that is specified in the conf.py has not been " +
"callable. Please provide a callable `setup` function " +
"in order to behave as a sphinx extension conf.py itself."
)

# now that we know all config values, collect them from conf.py
self.config.init_values(self.warn)

# check extension versions if requested
if self.config.needs_extensions:
for extname, needs_ver in self.config.needs_extensions.items():
if extname not in self._extensions:
self.warn('needs_extensions config value specifies a '
'version requirement for extension %s, but it is '
'not loaded' % extname)
continue
has_ver = self._extension_metadata[extname]['version']
if has_ver == 'unknown version' or needs_ver > has_ver:
raise VersionRequirementError(
'This project needs the extension %s at least in '
'version %s and therefore cannot be built with the '
'loaded version (%s).' % (extname, needs_ver, has_ver))

# set up translation infrastructure
self._init_i18n()
# check all configuration values for permissible types
self.config.check_types(self.warn)
# set up source_parsers
self._init_source_parsers()
# set up the build environment
self._init_env(freshenv)
# set up the builder
self._init_builder(self.buildername)
# set up the enumerable nodes
self._init_enumerable_nodes()

def _init_i18n(self):
"""Load translated strings from the configured localedirs if enabled in
the configuration.
"""
if self.config.language is not None:
self.info(bold('loading translations [%s]... ' %
self.config.language), nonl=True)
user_locale_dirs = [
path.join(self.srcdir, x) for x in self.config.locale_dirs]
# compile mo files if sphinx.po file in user locale directories are updated
for catinfo in find_catalog_source_files(
user_locale_dirs, self.config.language, domains=['sphinx'],
charset=self.config.source_encoding):
catinfo.write_mo(self.config.language)
locale_dirs = [None, path.join(package_dir, 'locale')] + user_locale_dirs
else:
locale_dirs = []
self.translator, has_translation = locale.init(locale_dirs, self.config.language)
if self.config.language is not None:
if has_translation or self.config.language == 'en':
# "en" never needs to be translated
self.info('done')
else:
self.info('not available for built-in messages')

def _init_source_parsers(self):
for suffix, parser in iteritems(self._additional_source_parsers):
if suffix not in self.config.source_suffix:
self.config.source_suffix.append(suffix)
if suffix not in self.config.source_parsers:
self.config.source_parsers[suffix] = parser

def _init_env(self, freshenv):
if freshenv:
self.env = BuildEnvironment(self.srcdir, self.doctreedir,
self.config)
self.env.find_files(self.config)
for domain in self.domains.keys():
self.env.domains[domain] = self.domains[domain](self.env)
else:
try:
self.info(bold('loading pickled environment... '), nonl=True)
self.env = BuildEnvironment.frompickle(
self.srcdir, self.config, path.join(self.doctreedir, ENV_PICKLE_FILENAME))
self.env.domains = {}
for domain in self.domains.keys():
# this can raise if the data version doesn't fit
self.env.domains[domain] = self.domains[domain](self.env)
self.info('done')
except Exception as err:
if isinstance(err, IOError) and err.errno == ENOENT:
self.info('not yet created')
else:
self.info('failed: %s' % err)
return self._init_env(freshenv=True)

self.env.set_warnfunc(self.warn)

def _init_builder(self, buildername):
if buildername is None:
print('No builder selected, using default: html', file=self._status)
buildername = 'html'
if buildername not in self.builderclasses:
raise SphinxError('Builder name %s not registered' % 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)
self.emit('builder-inited')

def _init_enumerable_nodes(self):
for node, settings in iteritems(self.enumerable_nodes):
self.env.domains['std'].enumerable_nodes[node] = settings

# ---- main "build" method -------------------------------------------------

def build(self, force_all=False, filenames=None):
try:
if force_all:
self.builder.compile_all_catalogs()
self.builder.build_all()
elif filenames:
self.builder.compile_specific_catalogs(filenames)
self.builder.build_specific(filenames)
else:
self.builder.compile_update_catalogs()
self.builder.build_update()

status = (self.statuscode == 0 and
'succeeded' or 'finished with problems')
if self._warncount:
self.info(bold('build %s, %s warning%s.' %
(status, self._warncount,
self._warncount != 1 and 's' or '')))
else:
self.info(bold('build %s.' % status))
except Exception as err:
# delete the saved env to force a fresh build next time
envfile = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
if path.isfile(envfile):
os.unlink(envfile)
self.emit('build-finished', err)
raise
else:
self.emit('build-finished', None)
self.builder.cleanup()

# ---- logging handling ----------------------------------------------------

def _log(self, message, wfile, nonl=False):
try:
wfile.write(message)
except UnicodeEncodeError:
encoding = getattr(wfile, 'encoding', 'ascii') or 'ascii'
wfile.write(message.encode(encoding, 'replace'))
if not nonl:
wfile.write('\n')
if hasattr(wfile, 'flush'):
wfile.flush()
self.messagelog.append(message)

[docs]    def warn(self, message, location=None, prefix='WARNING: ', type=None, subtype=None):
"""Emit a warning.

If *location* is given, it should either be a tuple of (docname, lineno)
or a string describing the location of the warning as well as possible.

*prefix* usually should not be changed.

*type* and *subtype* are used to suppress warnings with :confval:`suppress_warnings`.

.. note::

For warnings emitted during parsing, you should use
:meth:`.BuildEnvironment.warn` since that will collect all
warnings during parsing for later output.
"""
if is_suppressed_warning(type, subtype, self.config.suppress_warnings):
return

if isinstance(location, tuple):
docname, lineno = location
if docname:
location = '%s:%s' % (self.env.doc2path(docname), lineno or '')
else:
location = None
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._log(warntext, self._warning, True)

[docs]    def info(self, message='', nonl=False):
"""Emit an informational message.

If *nonl* is true, don't emit a newline at the end (which implies that
more info output will follow soon.)
"""
self._log(message, self._status, nonl)

[docs]    def verbose(self, message, *args, **kwargs):
"""Emit a verbose informational message.

The message will only be emitted for verbosity levels >= 1 (i.e. at
least one ``-v`` option was given).

The message can contain %-style interpolation placeholders, which is
formatted with either the ``*args`` or ``**kwargs`` when output.
"""
if self.verbosity < 1:
return
if args or kwargs:
message = message % (args or kwargs)
self._log(message, self._status)

[docs]    def debug(self, message, *args, **kwargs):
"""Emit a debug-level informational message.

The message will only be emitted for verbosity levels >= 2 (i.e. at
least two ``-v`` options were given).

The message can contain %-style interpolation placeholders, which is
formatted with either the ``*args`` or ``**kwargs`` when output.
"""
if self.verbosity < 2:
return
if args or kwargs:
message = message % (args or kwargs)
self._log(darkgray(message), self._status)

[docs]    def debug2(self, message, *args, **kwargs):
"""Emit a lowlevel debug-level informational message.

The message will only be emitted for verbosity level 3 (i.e. three
``-v`` options were given).

The message can contain %-style interpolation placeholders, which is
formatted with either the ``*args`` or ``**kwargs`` when output.
"""
if self.verbosity < 3:
return
if args or kwargs:
message = message % (args or kwargs)
self._log(lightgray(message), self._status)

def _display_chunk(chunk):
if isinstance(chunk, (list, tuple)):
if len(chunk) == 1:
return text_type(chunk[0])
return '%s .. %s' % (chunk[0], chunk[-1])
return text_type(chunk)

def old_status_iterator(self, iterable, summary, colorfunc=darkgreen,
stringify_func=_display_chunk):
l = 0
for item in iterable:
if l == 0:
self.info(bold(summary), nonl=1)
l = 1
self.info(colorfunc(stringify_func(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,
stringify_func=_display_chunk):
if length == 0:
for item in self.old_status_iterator(iterable, summary, colorfunc,
stringify_func):
yield item
return
l = 0
summary = bold(summary)
for item in iterable:
l += 1
s = '%s[%3d%%] %s' % (summary, 100*l/length,
colorfunc(stringify_func(item)))
if self.verbosity:
s += '\n'
else:
s = term_width_line(s)
self.info(s, nonl=1)
yield item
if l > 0:
self.info()

# ---- general extensibility interface -------------------------------------

[docs]    def setup_extension(self, extension):
"""Import and setup a Sphinx extension module. No-op if called twice."""
self.debug('[app] setting up extension: %r', extension)
if extension in self._extensions:
return
self._setting_up_extension.append(extension)
try:
mod = __import__(extension, None, None, ['setup'])
except ImportError as err:
self.verbose('Original exception:\n' + traceback.format_exc())
raise ExtensionError('Could not import extension %s' % extension,
err)
if not hasattr(mod, 'setup'):
self.warn('extension %r has no setup() function; is it really '
'a Sphinx extension module?' % extension)
ext_meta = None
else:
try:
ext_meta = mod.setup(self)
except VersionRequirementError as err:
# add the extension name to the version required
raise VersionRequirementError(
'The %s extension used by this project needs at least '
'Sphinx v%s; it therefore cannot be built with this '
'version.' % (extension, err))
if ext_meta is None:
ext_meta = {}
# special-case for compatibility
if extension == 'rst2pdf.pdfbuilder':
ext_meta = {'parallel_read_safe': True}
try:
if not ext_meta.get('version'):
ext_meta['version'] = 'unknown version'
except Exception:
self.warn('extension %r returned an unsupported object from '
'its setup() function; it should return None or a '
'metadata dictionary' % extension)
ext_meta = {'version': 'unknown version'}
self._extensions[extension] = mod
self._extension_metadata[extension] = ext_meta
self._setting_up_extension.pop()

[docs]    def require_sphinx(self, version):
# check the Sphinx version if requested
if version > sphinx.__display_version__[:3]:
raise VersionRequirementError(version)

def import_object(self, objname, source=None):
"""Import an object from a 'module.name' string."""
return import_object(objname, source=None)

# event interface

def _validate_event(self, event):
event = intern(event)
if event not in self._events:
raise ExtensionError('Unknown event name: %s' % event)

[docs]    def connect(self, event, callback):
self._validate_event(event)
listener_id = self.next_listener_id
if event not in self._listeners:
self._listeners[event] = {listener_id: callback}
else:
self._listeners[event][listener_id] = callback
self.next_listener_id += 1
self.debug('[app] connecting event %r: %r [id=%s]',
event, callback, listener_id)
return listener_id

[docs]    def disconnect(self, listener_id):
self.debug('[app] disconnecting event: [id=%s]', listener_id)
for event in itervalues(self._listeners):
event.pop(listener_id, None)

[docs]    def emit(self, event, *args):
try:
self.debug2('[app] emitting event: %r%s', event, repr(args)[:100])
except Exception:
# not every object likes to be repr()'d (think
# random stuff coming via autodoc)
pass
results = []
if event in self._listeners:
for _, callback in iteritems(self._listeners[event]):
results.append(callback(self, *args))
return results

[docs]    def emit_firstresult(self, event, *args):
for result in self.emit(event, *args):
if result is not None:
return result
return None

# registering addon parts

[docs]    def add_builder(self, builder):
self.debug('[app] adding builder: %r', builder)
if not hasattr(builder, 'name'):
raise ExtensionError('Builder class %s has no "name" attribute'
% builder)
if builder.name in self.builderclasses:
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

[docs]    def add_config_value(self, name, default, rebuild, types=()):
self.debug('[app] adding config value: %r',
(name, default, rebuild) + ((types,) if types else ()))
if name in self.config.values:
raise ExtensionError('Config value %r already present' % name)
if rebuild in (False, True):
rebuild = rebuild and 'env' or ''
self.config.values[name] = (default, rebuild, types)

[docs]    def add_event(self, name):
self.debug('[app] adding event: %r', name)
if name in self._events:
raise ExtensionError('Event %r already present' % name)
self._events[name] = ''

[docs]    def set_translator(self, name, translator_class):
self.info(bold('A Translator for the %s builder is changed.' % name))
self._translators[name] = translator_class

[docs]    def add_node(self, node, **kwds):
self.debug('[app] adding node: %r', (node, kwds))
if not kwds.pop('override', False) and \
hasattr(nodes.GenericNodeVisitor, 'visit_' + node.__name__):
self.warn('while setting up extension %s: node class %r is '
'already registered, its visitors will be overridden' %
(self._setting_up_extension, node.__name__),
type='app', subtype='add_node')
nodes._add_node_class_names([node.__name__])
for key, val in iteritems(kwds):
try:
visit, depart = val
except ValueError:
raise ExtensionError('Value for key %r must be a '
'(visit, depart) function tuple' % key)
translator = self._translators.get(key)
if translator is not None:
pass
elif key == 'html':
from sphinx.writers.html import HTMLTranslator as translator
elif key == 'latex':
from sphinx.writers.latex import LaTeXTranslator as translator
elif key == 'text':
from sphinx.writers.text import TextTranslator as translator
elif key == 'man':
from sphinx.writers.manpage import ManualPageTranslator \
as translator
elif key == 'texinfo':
from sphinx.writers.texinfo import TexinfoTranslator \
as translator
else:
# ignore invalid keys for compatibility
continue
setattr(translator, 'visit_'+node.__name__, visit)
if depart:
setattr(translator, 'depart_'+node.__name__, depart)

[docs]    def add_enumerable_node(self, node, figtype, title_getter=None, **kwds):
self.enumerable_nodes[node] = (figtype, title_getter)
self.add_node(node, **kwds)

def _directive_helper(self, obj, content=None, arguments=None, **options):
if isinstance(obj, (types.FunctionType, types.MethodType)):
obj.content = content
obj.arguments = arguments or (0, 0, False)
obj.options = options
return convert_directive_function(obj)
else:
if content or arguments or options:
raise ExtensionError('when adding directive classes, no '
'additional arguments may be given')
return obj

[docs]    def add_directive(self, name, obj, content=None, arguments=None, **options):
self.debug('[app] adding directive: %r',
(name, obj, content, arguments, options))
if name in directives._directives:
self.warn('while setting up extension %s: directive %r is '
'already registered, it will be overridden' %
(self._setting_up_extension[-1], name),
type='app', subtype='add_directive')
directives.register_directive(
name, self._directive_helper(obj, content, arguments, **options))

[docs]    def add_role(self, name, role):
self.debug('[app] adding role: %r', (name, role))
if name in roles._roles:
self.warn('while setting up extension %s: role %r is '
'already registered, it will be overridden' %
(self._setting_up_extension[-1], name),
type='app', subtype='add_role')
roles.register_local_role(name, role)

[docs]    def add_generic_role(self, name, nodeclass):
# don't use roles.register_generic_role because it uses
# register_canonical_role
self.debug('[app] adding generic role: %r', (name, nodeclass))
if name in roles._roles:
self.warn('while setting up extension %s: role %r is '
'already registered, it will be overridden' %
(self._setting_up_extension[-1], name),
type='app', subtype='add_generic_role')
role = roles.GenericRole(name, nodeclass)
roles.register_local_role(name, role)

[docs]    def add_domain(self, domain):
self.debug('[app] adding domain: %r', domain)
if domain.name in self.domains:
raise ExtensionError('domain %s already registered' % domain.name)
self.domains[domain.name] = domain

[docs]    def override_domain(self, domain):
self.debug('[app] overriding domain: %r', domain)
if domain.name not in self.domains:
raise ExtensionError('domain %s not yet registered' % domain.name)
if not issubclass(domain, self.domains[domain.name]):
raise ExtensionError('new domain not a subclass of registered %s '
'domain' % domain.name)
self.domains[domain.name] = domain

[docs]    def add_directive_to_domain(self, domain, name, obj,
content=None, arguments=None, **options):
self.debug('[app] adding directive to domain: %r',
(domain, name, obj, content, arguments, options))
if domain not in self.domains:
raise ExtensionError('domain %s not yet registered' % domain)
self.domains[domain].directives[name] = \
self._directive_helper(obj, content, arguments, **options)

[docs]    def add_role_to_domain(self, domain, name, role):
self.debug('[app] adding role to domain: %r', (domain, name, role))
if domain not in self.domains:
raise ExtensionError('domain %s not yet registered' % domain)
self.domains[domain].roles[name] = role

[docs]    def add_index_to_domain(self, domain, index):
self.debug('[app] adding index to domain: %r', (domain, index))
if domain not in self.domains:
raise ExtensionError('domain %s not yet registered' % domain)
self.domains[domain].indices.append(index)

[docs]    def add_object_type(self, directivename, rolename, indextemplate='',
parse_node=None, ref_nodeclass=None, objname='',
doc_field_types=[]):
self.debug('[app] adding object type: %r',
(directivename, rolename, indextemplate, parse_node,
ref_nodeclass, objname, doc_field_types))
StandardDomain.object_types[directivename] = \
ObjType(objname or directivename, rolename)
# create a subclass of GenericObject as the new directive
new_directive = type(directivename, (GenericObject, object),
{'indextemplate': indextemplate,
'parse_node': staticmethod(parse_node),
'doc_field_types': doc_field_types})
StandardDomain.directives[directivename] = new_directive
# XXX support more options?
StandardDomain.roles[rolename] = XRefRole(innernodeclass=ref_nodeclass)

# backwards compatible alias
add_description_unit = add_object_type

[docs]    def add_crossref_type(self, directivename, rolename, indextemplate='',
ref_nodeclass=None, objname=''):
self.debug('[app] adding crossref type: %r',
(directivename, rolename, indextemplate, ref_nodeclass,
objname))
StandardDomain.object_types[directivename] = \
ObjType(objname or directivename, rolename)
# create a subclass of Target as the new directive
new_directive = type(directivename, (Target, object),
{'indextemplate': indextemplate})
StandardDomain.directives[directivename] = new_directive
# XXX support more options?
StandardDomain.roles[rolename] = XRefRole(innernodeclass=ref_nodeclass)

[docs]    def add_transform(self, transform):
self.debug('[app] adding transform: %r', transform)
SphinxStandaloneReader.transforms.append(transform)

[docs]    def add_javascript(self, filename):
self.debug('[app] adding javascript: %r', filename)
from sphinx.builders.html import StandaloneHTMLBuilder
if '://' in filename:
StandaloneHTMLBuilder.script_files.append(filename)
else:
StandaloneHTMLBuilder.script_files.append(
posixpath.join('_static', filename))

[docs]    def add_stylesheet(self, filename):
self.debug('[app] adding stylesheet: %r', filename)
from sphinx.builders.html import StandaloneHTMLBuilder
if '://' in filename:
StandaloneHTMLBuilder.css_files.append(filename)
else:
StandaloneHTMLBuilder.css_files.append(
posixpath.join('_static', filename))

[docs]    def add_latex_package(self, packagename, options=None):
self.debug('[app] adding latex package: %r', packagename)
from sphinx.builders.latex import LaTeXBuilder
LaTeXBuilder.usepackages.append((packagename, options))

[docs]    def add_lexer(self, alias, lexer):
self.debug('[app] adding lexer: %r', (alias, lexer))
from sphinx.highlighting import lexers
if lexers is None:
return
lexers[alias] = lexer

[docs]    def add_autodocumenter(self, cls):
self.debug('[app] adding autodocumenter: %r', cls)
from sphinx.ext import autodoc
autodoc.add_documenter(cls)
self.add_directive('auto' + cls.objtype, autodoc.AutoDirective)

[docs]    def add_autodoc_attrgetter(self, type, getter):
self.debug('[app] adding autodoc attrgetter: %r', (type, getter))
from sphinx.ext import autodoc
autodoc.AutoDirective._special_attrgetters[type] = getter

[docs]    def add_search_language(self, cls):
self.debug('[app] adding search language: %r', cls)
from sphinx.search import languages, SearchLanguage
assert issubclass(cls, SearchLanguage)
languages[cls.lang] = cls

[docs]    def add_source_parser(self, suffix, parser):
self.debug('[app] adding search source_parser: %r, %r', (suffix, parser))
if suffix in self._additional_source_parsers:
self.warn('while setting up extension %s: source_parser for %r is '
'already registered, it will be overridden' %
(self._setting_up_extension[-1], suffix),
type='app', subtype='add_source_parser')
self._additional_source_parsers[suffix] = parser

[docs]class TemplateBridge(object):
"""
This class defines the interface for a "template bridge", that is, a class
that renders templates given a template name and a context.
"""

[docs]    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``.

*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')

[docs]    def newest_template_mtime(self):
"""Called by the builder to determine if output files are outdated
because of template changes.  Return the mtime of the newest template
file that was changed.  The default implementation returns ``0``.
"""
return 0

[docs]    def render(self, template, context):
"""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')

[docs]    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')

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.builders

# -*- coding: utf-8 -*-
"""
sphinx.builders
~~~~~~~~~~~~~~~

Builder superclass for all builders.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import os
from os import path

try:
import multiprocessing
except ImportError:
multiprocessing = None

from docutils import nodes

from sphinx.util import i18n, path_stabilize
from sphinx.util.osutil import SEP, relative_uri
from sphinx.util.i18n import find_catalog
from sphinx.util.console import bold, darkgreen
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, \
parallel_available

# side effect: registers roles and directives
from sphinx import roles       # noqa
from sphinx import directives  # noqa

[docs]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 = ''
# doctree versioning method
versioning_method = 'none'
versioning_compare = False
# allow parallel write_doc() calls
allow_parallel = False

def __init__(self, app):
self.env = app.env
self.env.set_versioning_method(self.versioning_method,
self.versioning_compare)
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.tags = app.tags
self.tags.add(self.format)
self.tags.add(self.name)
self.tags.add("format_%s" % self.format)
self.tags.add("builder_%s" % self.name)
# compatibility aliases
self.status_iterator = app.status_iterator
self.old_status_iterator = app.old_status_iterator

# images that need to be copied over (source -> dest)
self.images = {}
# basename of images directory
self.imagedir = ""
# relative path to image directory from current docname (used at writing docs)
self.imgpath = ""

# these get set later
self.parallel_ok = False
self.finish_tasks = None

# load default translator class
self.translator_class = app._translators.get(self.name)

self.init()

# helper methods

[docs]    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()

[docs]    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

[docs]    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))

[docs]    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

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]

# compile po methods

def compile_catalogs(self, catalogs, message):
if not self.config.gettext_auto_build:
return

def cat2relpath(cat):
return path.relpath(cat.mo_path, self.env.srcdir).replace(path.sep, SEP)

self.info(bold('building [mo]: ') + message)
for catalog in self.app.status_iterator(
catalogs, 'writing output... ', darkgreen, len(catalogs),
cat2relpath):
catalog.write_mo(self.config.language)

def compile_all_catalogs(self):
catalogs = i18n.find_catalog_source_files(
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
self.config.language,
charset=self.config.source_encoding,
gettext_compact=self.config.gettext_compact,
force_all=True)
message = 'all of %d po files' % len(catalogs)
self.compile_catalogs(catalogs, message)

def compile_specific_catalogs(self, specified_files):
def to_domain(fpath):
docname, _ = path.splitext(path_stabilize(fpath))
dom = find_catalog(docname, self.config.gettext_compact)
return dom

specified_domains = set(map(to_domain, specified_files))
catalogs = i18n.find_catalog_source_files(
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
self.config.language,
domains=list(specified_domains),
charset=self.config.source_encoding,
gettext_compact=self.config.gettext_compact)
message = 'targets for %d po files that are specified' % len(catalogs)
self.compile_catalogs(catalogs, message)

def compile_update_catalogs(self):
catalogs = i18n.find_catalog_source_files(
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
self.config.language,
charset=self.config.source_encoding,
gettext_compact=self.config.gettext_compact)
message = 'targets for %d po files that are out of date' % len(catalogs)
self.compile_catalogs(catalogs, message)

# build methods

[docs]    def build_all(self):
"""Build all source files."""
self.build(None, summary='all source files', method='all')

[docs]    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 = []
suffixes = tuple(self.config.source_suffix)
for filename in filenames:
filename = path.normpath(path.abspath(filename))
if not filename.startswith(self.srcdir):
self.warn('file %r given on command line is not under the '
'source directory, ignoring' % filename)
continue
if not (path.isfile(filename) or
any(path.isfile(filename + suffix) for suffix in suffixes)):
self.warn('file %r given on command line does not exist, '
'ignoring' % filename)
continue
filename = filename[dirlen:]
for suffix in suffixes:
if filename.endswith(suffix):
filename = filename[:-len(suffix)]
break
filename = filename.replace(path.sep, SEP)
to_write.append(filename)
self.build(to_write, method='specific',
summary='%d source files given on command '
'line' % len(to_write))

[docs]    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))

[docs]    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) + ': ' + summary)

# while reading, collect all warnings from docutils
warnings = []
self.env.set_warnfunc(lambda *args, **kwargs: warnings.append((args, kwargs)))
updated_docnames = set(self.env.update(self.config, self.srcdir,
self.doctreedir, self.app))
self.env.set_warnfunc(self.warn)
for warning, kwargs in warnings:
self.warn(*warning, **kwargs)

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
from sphinx.application import ENV_PICKLE_FILENAME
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

# filter "docnames" (list of outdated files) by the updated
# found_docs of the environment; this will remove docs that
# have since been removed
if docnames and docnames != ['__all__']:
docnames = set(docnames) & self.env.found_docs

# determine if we can write in parallel
self.parallel_ok = False
if parallel_available and self.app.parallel > 1 and self.allow_parallel:
self.parallel_ok = True
for extname, md in self.app._extension_metadata.items():
par_ok = md.get('parallel_write_safe', True)
if not par_ok:
self.app.warn('the %s extension is not safe for parallel '
'writing, doing serial write' % extname)
self.parallel_ok = False
break

#  create a task executor to use for misc. "finish-up" tasks
# if self.parallel_ok:
#     self.finish_tasks = ParallelTasks(self.app.parallel)
# else:
# for now, just execute them serially
self.finish_tasks = SerialTasks()

# write all "normal" documents (or everything for some builders)
self.write(docnames, list(updated_docnames), method)

# finish (write static files etc.)
self.finish()

# wait for all tasks
self.finish_tasks.join()

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)
self.app.debug('docnames to write: %s', ', '.join(sorted(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, []):
if tocdocname in self.env.found_docs:
docnames.add(tocdocname)
docnames.add(self.config.master_doc)

self.info(bold('preparing documents... '), nonl=True)
self.prepare_writing(docnames)
self.info('done')

warnings = []
self.env.set_warnfunc(lambda *args, **kwargs: warnings.append((args, kwargs)))
if self.parallel_ok:
# number of subprocesses is parallel-1 because the main process
# is busy loading doctrees and doing write_doc_serialized()
self._write_parallel(sorted(docnames), warnings,
nproc=self.app.parallel - 1)
else:
self._write_serial(sorted(docnames), warnings)
self.env.set_warnfunc(self.warn)

def _write_serial(self, docnames, warnings):
for docname in self.app.status_iterator(
docnames, 'writing output... ', darkgreen, len(docnames)):
doctree = self.env.get_and_resolve_doctree(docname, self)
self.write_doc_serialized(docname, doctree)
self.write_doc(docname, doctree)
for warning, kwargs in warnings:
self.warn(*warning, **kwargs)

def _write_parallel(self, docnames, warnings, nproc):
def write_process(docs):
local_warnings = []

def warnfunc(*args, **kwargs):
local_warnings.append((args, kwargs))
self.env.set_warnfunc(warnfunc)
for docname, doctree in docs:
self.write_doc(docname, doctree)
return local_warnings

def add_warnings(docs, wlist):
warnings.extend(wlist)

# warm up caches/compile templates using the first document
firstname, docnames = docnames[0], docnames[1:]
doctree = self.env.get_and_resolve_doctree(firstname, self)
self.write_doc_serialized(firstname, doctree)
self.write_doc(firstname, doctree)

tasks = ParallelTasks(nproc)
chunks = make_chunks(docnames, nproc)

for chunk in self.app.status_iterator(
chunks, 'writing output... ', darkgreen, len(chunks)):
arg = []
for i, docname in enumerate(chunk):
doctree = self.env.get_and_resolve_doctree(docname, self)
self.write_doc_serialized(docname, doctree)
arg.append((docname, doctree))
tasks.add_task(write_process, arg, add_warnings)

# make sure all threads have finished
self.info(bold('waiting for workers...'))
tasks.join()

for warning, kwargs in warnings:
self.warn(*warning, **kwargs)

[docs]    def prepare_writing(self, docnames):
"""A place where you can add logic before :meth:`write_doc` is run"""
raise NotImplementedError

[docs]    def write_doc(self, docname, doctree):
"""Where you actually write something to the filesystem."""
raise NotImplementedError

def write_doc_serialized(self, docname, doctree):
"""Handle parts of write_doc that must be called in the main process
if parallel build is active.
"""
pass

[docs]    def finish(self):
"""Finish the building process.

The default implementation does nothing.
"""
pass

def cleanup(self):
"""Cleanup any resources.

The default implementation does nothing.
"""
pass

def get_builder_config(self, option, default):
"""Return a builder specific option.

This method allows customization of common builder settings by
inserting the name of the current builder in the option key.
If the key does not exist, use default as builder name.
"""
# At the moment, only XXX_use_index is looked up this way.
# Every new builder variant must be registered in Config.config_values.
try:
optname = '%s_%s' % (self.name, option)
return getattr(self.config, optname)
except AttributeError:
optname = '%s_%s' % (default, option)
return getattr(self.config, optname)

BUILTIN_BUILDERS = {
'dummy':      ('dummy', 'DummyBuilder'),
'html':       ('html', 'StandaloneHTMLBuilder'),
'dirhtml':    ('html', 'DirectoryHTMLBuilder'),
'singlehtml': ('html', 'SingleFileHTMLBuilder'),
'pickle':     ('html', 'PickleHTMLBuilder'),
'json':       ('html', 'JSONHTMLBuilder'),
'web':        ('html', 'PickleHTMLBuilder'),
'htmlhelp':   ('htmlhelp', 'HTMLHelpBuilder'),
'devhelp':    ('devhelp', 'DevhelpBuilder'),
'qthelp':     ('qthelp', 'QtHelpBuilder'),
'applehelp':  ('applehelp', 'AppleHelpBuilder'),
'epub':       ('epub', 'EpubBuilder'),
'epub3':      ('epub3', 'Epub3Builder'),
'latex':      ('latex', 'LaTeXBuilder'),
'text':       ('text', 'TextBuilder'),
'man':        ('manpage', 'ManualPageBuilder'),
'texinfo':    ('texinfo', 'TexinfoBuilder'),
'changes':    ('changes', 'ChangesBuilder'),
'linkcheck':  ('linkcheck', 'CheckExternalLinksBuilder'),
'websupport': ('websupport', 'WebSupportBuilder'),
'gettext':    ('gettext', 'MessageCatalogBuilder'),
'xml':        ('xml', 'XMLBuilder'),
'pseudoxml':  ('xml', 'PseudoXMLBuilder'),
}

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.applehelp

# -*- coding: utf-8 -*-
"""
sphinx.builders.applehelp
~~~~~~~~~~~~~~~~~~~~~~~~~

Build Apple help books.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function

import codecs
import pipes

from os import path

from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util import copy_static_entry
from sphinx.util.osutil import copyfile, ensuredir
from sphinx.util.console import bold
from sphinx.util.pycompat import htmlescape
from sphinx.util.matching import compile_matchers
from sphinx.errors import SphinxError

import plistlib
import subprocess

# Use plistlib.dump in 3.4 and above
try:
write_plist = plistlib.dump
except AttributeError:
write_plist = plistlib.writePlist

# False access page (used because helpd expects strict XHTML)
access_page_template = '''\
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>%(title)s</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="robots" content="noindex" />
<meta http-equiv="refresh" content="0;url=%(toc)s" />
</head>
<body>
</body>
</html>
'''

class AppleHelpIndexerFailed(SphinxError):
category = 'Help indexer failed'

class AppleHelpCodeSigningFailed(SphinxError):
category = 'Code signing failed'

[docs]class AppleHelpBuilder(StandaloneHTMLBuilder):
"""
Builder that outputs an Apple help book.  Requires Mac OS X as it relies
on the ``hiutil`` command line tool.
"""
name = 'applehelp'

# don't copy the reST source
copysource = False
supported_image_types = ['image/png', 'image/gif', 'image/jpeg',
'image/tiff', 'image/jp2', 'image/svg+xml']

# don't add links
add_permalinks = False

# this is an embedded HTML format
embedded = True

# don't generate the search index or include the search page
search = False

def init(self):
super(AppleHelpBuilder, self).init()
# the output files for HTML help must be .html only
self.out_suffix = '.html'

if self.config.applehelp_bundle_id is None:
raise SphinxError('You must set applehelp_bundle_id before '
'building Apple Help output')

self.bundle_path = path.join(self.outdir,
self.config.applehelp_bundle_name +
'.help')
self.outdir = path.join(self.bundle_path,
'Contents',
'Resources',
self.config.applehelp_locale + '.lproj')

def handle_finish(self):
super(AppleHelpBuilder, self).handle_finish()

self.finish_tasks.add_task(self.copy_localized_files)
self.finish_tasks.add_task(self.build_helpbook)

def copy_localized_files(self):
source_dir = path.join(self.confdir,
self.config.applehelp_locale + '.lproj')
target_dir = self.outdir

if path.isdir(source_dir):
self.info(bold('copying localized files... '), nonl=True)

ctx = self.globalcontext.copy()
matchers = compile_matchers(self.config.exclude_patterns)
copy_static_entry(source_dir, target_dir, self, ctx,
exclude_matchers=matchers)

self.info('done')

def build_helpbook(self):
contents_dir = path.join(self.bundle_path, 'Contents')
resources_dir = path.join(contents_dir, 'Resources')
language_dir = path.join(resources_dir,
self.config.applehelp_locale + '.lproj')

for d in [contents_dir, resources_dir, language_dir]:
ensuredir(d)

# Construct the Info.plist file
toc = self.config.master_doc + self.out_suffix

info_plist = {
'CFBundleDevelopmentRegion': self.config.applehelp_dev_region,
'CFBundleIdentifier': self.config.applehelp_bundle_id,
'CFBundleInfoDictionaryVersion': '6.0',
'CFBundlePackageType': 'BNDL',
'CFBundleShortVersionString': self.config.release,
'CFBundleSignature': 'hbwr',
'CFBundleVersion': self.config.applehelp_bundle_version,
'HPDBookAccessPath': '_access.html',
'HPDBookIndexPath': 'search.helpindex',
'HPDBookTitle': self.config.applehelp_title,
'HPDBookType': '3',
'HPDBookUsesExternalViewer': False,
}

if self.config.applehelp_icon is not None:
info_plist['HPDBookIconPath'] \
= path.basename(self.config.applehelp_icon)

if self.config.applehelp_kb_url is not None:
info_plist['HPDBookKBProduct'] = self.config.applehelp_kb_product
info_plist['HPDBookKBURL'] = self.config.applehelp_kb_url

if self.config.applehelp_remote_url is not None:
info_plist['HPDBookRemoteURL'] = self.config.applehelp_remote_url

self.info(bold('writing Info.plist... '), nonl=True)
with open(path.join(contents_dir, 'Info.plist'), 'wb') as f:
write_plist(info_plist, f)
self.info('done')

# Copy the icon, if one is supplied
if self.config.applehelp_icon:
self.info(bold('copying icon... '), nonl=True)

try:
copyfile(path.join(self.srcdir, self.config.applehelp_icon),
path.join(resources_dir, info_plist['HPDBookIconPath']))

self.info('done')
except Exception as err:
self.warn('cannot copy icon file %r: %s' %
(path.join(self.srcdir, self.config.applehelp_icon),
err))
del info_plist['HPDBookIconPath']

# Build the access page
self.info(bold('building access page...'), nonl=True)
f = codecs.open(path.join(language_dir, '_access.html'), 'w')
try:
f.write(access_page_template % {
'toc': htmlescape(toc, quote=True),
'title': htmlescape(self.config.applehelp_title)
})
finally:
f.close()
self.info('done')

# Generate the help index
self.info(bold('generating help index... '), nonl=True)

args = [
self.config.applehelp_indexer_path,
'-Cf',
path.join(language_dir, 'search.helpindex'),
language_dir
]

if self.config.applehelp_index_anchors is not None:
args.append('-a')

if self.config.applehelp_min_term_length is not None:
args += ['-m', '%s' % self.config.applehelp_min_term_length]

if self.config.applehelp_stopwords is not None:
args += ['-s', self.config.applehelp_stopwords]

if self.config.applehelp_locale is not None:
args += ['-l', self.config.applehelp_locale]

if self.config.applehelp_disable_external_tools:
self.info('skipping')

self.warn('you will need to index this help book with:\n  %s'
% (' '.join([pipes.quote(arg) for arg in args])))
else:
p = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)

output = p.communicate()[0]

if p.returncode != 0:
raise AppleHelpIndexerFailed(output)
else:
self.info('done')

# If we've been asked to, sign the bundle
if self.config.applehelp_codesign_identity:
self.info(bold('signing help book... '), nonl=True)

args = [
self.config.applehelp_codesign_path,
'-s', self.config.applehelp_codesign_identity,
'-f'
]

args += self.config.applehelp_codesign_flags

args.append(self.bundle_path)

if self.config.applehelp_disable_external_tools:
self.info('skipping')

self.warn('you will need to sign this help book with:\n  %s'
% (' '.join([pipes.quote(arg) for arg in args])))
else:
p = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)

output = p.communicate()[0]

if p.returncode != 0:
raise AppleHelpCodeSigningFailed(output)
else:
self.info('done')

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.changes

# -*- coding: utf-8 -*-
"""
sphinx.builders.changes
~~~~~~~~~~~~~~~~~~~~~~~

Changelog builder.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import codecs
from os import path

from six import iteritems

from sphinx import package_dir
from sphinx.util import copy_static_entry
from sphinx.locale import _
from sphinx.theming import Theme
from sphinx.builders import Builder
from sphinx.util.osutil import ensuredir, os_path
from sphinx.util.console import bold
from sphinx.util.pycompat import htmlescape

[docs]class ChangesBuilder(Builder):
"""
Write a summary with all versionadded/changed directives.
"""
name = 'changes'

def init(self):
self.create_template_bridge()
Theme.init_themes(self.confdir, self.config.html_theme_path,
warn=self.warn)
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(iteritems(libchanges)),
'apichanges': sorted(apichanges),
'otherchanges': sorted(iteritems(otherchanges)),
'show_copyright': self.config.html_show_copyright,
'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 + htmlescape(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',
self.env.config.source_encoding)
try:
lines = f.readlines()
except UnicodeDecodeError:
self.warn('could not read %r for changelog creation' % docname)
continue
finally:
f.close()
targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html'
ensuredir(path.dirname(targetfn))
f = codecs.open(targetfn, 'w', 'utf-8')
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
iteritems(self.theme.get_options({})))
copy_static_entry(path.join(package_dir, 'themes', 'default',
'static', 'default.css_t'),
self.outdir, self, themectx)
copy_static_entry(path.join(package_dir, 'themes', 'basic',
'static', 'basic.css'),
self.outdir, self)

def hl(self, text, version):
text = htmlescape(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

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.devhelp

# -*- coding: utf-8 -*-
"""
sphinx.builders.devhelp
~~~~~~~~~~~~~~~~~~~~~~~

Build HTML documentation and Devhelp_ support files.

.. _Devhelp: http://live.gnome.org/devhelp

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import absolute_import

import re
from os import path

from docutils import nodes

from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder

try:
import xml.etree.ElementTree as etree
except ImportError:
try:
import lxml.etree as etree
except ImportError:
try:
import elementtree.ElementTree as etree
except ImportError:
import cElementTree as etree

try:
import gzip

def comp_open(filename, mode='rb'):
return gzip.open(filename + '.gz', mode)
except ImportError:
def comp_open(filename, mode='rb'):
return open(filename, mode)

[docs]class DevhelpBuilder(StandaloneHTMLBuilder):
"""
Builder that also outputs GNOME Devhelp file.
"""
name = 'devhelp'

# 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)
self.out_suffix = '.html'

def handle_finish(self):
self.build_devhelp(self.outdir, self.config.devhelp_basename)

def build_devhelp(self, outdir, outname):
self.info('dumping devhelp index...')

# Basic info
root = etree.Element('book',
title=self.config.html_title,
name=self.config.project,
link="index.html",
version=self.config.version)
tree = etree.ElementTree(root)

# TOC
chapters = etree.SubElement(root, 'chapters')

tocdoc = self.env.get_and_resolve_doctree(
self.config.master_doc, self, prune_toctrees=False)

def write_toc(node, parent):
if isinstance(node, addnodes.compact_paragraph) or \
isinstance(node, nodes.bullet_list):
for subnode in node:
write_toc(subnode, parent)
elif isinstance(node, nodes.list_item):
item = etree.SubElement(parent, 'sub')
for subnode in node:
write_toc(subnode, item)
elif isinstance(node, nodes.reference):
parent.attrib['link'] = node['refuri']
parent.attrib['name'] = node.astext()

def istoctree(node):
return isinstance(node, addnodes.compact_paragraph) and \
'toctree' in node

for node in tocdoc.traverse(istoctree):
write_toc(node, chapters)

# Index
functions = etree.SubElement(root, 'functions')
index = self.env.create_index(self)

def write_index(title, refs, subitems):
if len(refs) == 0:
pass
elif len(refs) == 1:
etree.SubElement(functions, 'function',
name=title, link=refs[0][1])
else:
for i, ref in enumerate(refs):
etree.SubElement(functions, 'function',
name="[%d] %s" % (i, title),
link=ref[1])

if subitems:
parent_title = re.sub(r'\s*\(.*\)\s*$', '', title)
for subitem in subitems:
write_index("%s %s" % (parent_title, subitem[0]),
subitem[1], [])

for (key, group) in index:
for title, (refs, subitems) in group:
write_index(title, refs, subitems)

# Dump the XML file
f = comp_open(path.join(outdir, outname + '.devhelp'), 'w')
try:
tree.write(f, 'utf-8')
finally:
f.close()

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.dummy

# -*- coding: utf-8 -*-
"""
sphinx.builders.dummy
~~~~~~~~~~~~~~~~~~~~~

Do syntax checks, but no writing.

:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

from sphinx.builders import Builder

[docs]class DummyBuilder(Builder):
name = 'dummy'
allow_parallel = True

def init(self):
pass

def get_outdated_docs(self):
return self.env.found_docs

def get_target_uri(self, docname, typ=None):
return ''

def prepare_writing(self, docnames):
pass

def write_doc(self, docname, doctree):
pass

def finish(self):
pass

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.epub

# -*- coding: utf-8 -*-
"""
sphinx.builders.epub
~~~~~~~~~~~~~~~~~~~~

Build epub files.
Originally derived from qthelp.py.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import os
import re
import codecs
import zipfile
from os import path

try:
from PIL import Image
except ImportError:
try:
import Image
except ImportError:
Image = None

from docutils import nodes

from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util.i18n import format_date
from sphinx.util.osutil import ensuredir, copyfile, EEXIST
from sphinx.util.smartypants import sphinx_smarty_pants as ssp
from sphinx.util.console import brown

# (Fragment) templates from which the metainfo files content.opf, toc.ncx,
# mimetype, and META-INF/container.xml are created.
# This template section also defines strings that are embedded in the html
# output but that may be customized by (re-)setting module attributes,
# e.g. from conf.py.

MIMETYPE_TEMPLATE = 'application/epub+zip'  # no EOL!

CONTAINER_TEMPLATE = u'''\
<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0"
xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="content.opf"
media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
'''

TOC_TEMPLATE = u'''\
<?xml version="1.0"?>
<ncx version="2005-1" xmlns="http://www.daisy.org/z3986/2005/ncx/">
<head>
<meta name="dtb:uid" content="%(uid)s"/>
<meta name="dtb:depth" content="%(level)d"/>
<meta name="dtb:totalPageCount" content="0"/>
<meta name="dtb:maxPageNumber" content="0"/>
</head>
<docTitle>
<text>%(title)s</text>
</docTitle>
<navMap>
%(navpoints)s
</navMap>
</ncx>
'''

NAVPOINT_TEMPLATE = u'''\
%(indent)s  <navPoint id="%(navpoint)s" playOrder="%(playorder)d">
%(indent)s    <navLabel>
%(indent)s      <text>%(text)s</text>
%(indent)s    </navLabel>
%(indent)s    <content src="%(refuri)s" />
%(indent)s  </navPoint>'''

NAVPOINT_INDENT = '  '
NODE_NAVPOINT_TEMPLATE = 'navPoint%d'

CONTENT_TEMPLATE = u'''\
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="2.0"
unique-identifier="%(uid)s">
<metadata xmlns:opf="http://www.idpf.org/2007/opf"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:language>%(lang)s</dc:language>
<dc:title>%(title)s</dc:title>
<dc:creator opf:role="aut">%(author)s</dc:creator>
<dc:publisher>%(publisher)s</dc:publisher>
<dc:rights>%(copyright)s</dc:rights>
<dc:identifier id="%(uid)s" opf:scheme="%(scheme)s">%(id)s</dc:identifier>
<dc:date>%(date)s</dc:date>
</metadata>
<manifest>
<item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />
%(files)s
</manifest>
<spine toc="ncx">
%(spine)s
</spine>
<guide>
%(guide)s
</guide>
</package>
'''

COVER_TEMPLATE = u'''\
<meta name="cover" content="%(cover)s"/>
'''

COVERPAGE_NAME = u'epub-cover.html'

FILE_TEMPLATE = u'''\
<item id="%(id)s"
href="%(href)s"
media-type="%(media_type)s" />'''

SPINE_TEMPLATE = u'''\
<itemref idref="%(idref)s" />'''

GUIDE_TEMPLATE = u'''\
<reference type="%(type)s" title="%(title)s" href="%(uri)s" />'''

TOCTREE_TEMPLATE = u'toctree-l%d'

LINK_TARGET_TEMPLATE = u' [%(uri)s]'

FOOTNOTE_LABEL_TEMPLATE = u'#%d'

FOOTNOTES_RUBRIC_NAME = u'Footnotes'

CSS_LINK_TARGET_CLASS = u'link-target'

# XXX These strings should be localized according to epub_language
GUIDE_TITLES = {
'toc': u'Table of Contents',
'cover': u'Cover'
}

MEDIA_TYPES = {
'.html': 'application/xhtml+xml',
'.css': 'text/css',
'.png': 'image/png',
'.gif': 'image/gif',
'.svg': 'image/svg+xml',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.otf': 'application/x-font-otf',
'.ttf': 'application/x-font-ttf',
}

VECTOR_GRAPHICS_EXTENSIONS = ('.svg',)

# Regular expression to match colons only in local fragment identifiers.
# If the URI contains a colon before the #,
# it is an external link that should not change.
REFURI_RE = re.compile("([^#:]*#)(.*)")

# The epub publisher

[docs]class EpubBuilder(StandaloneHTMLBuilder):
"""
Builder that outputs epub files.

It creates the metainfo files container.opf, toc.ncx, mimetype, and
META-INF/container.xml.  Afterwards, all necessary files are zipped to an
epub file.
"""
name = 'epub'

# 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

mimetype_template = MIMETYPE_TEMPLATE
container_template = CONTAINER_TEMPLATE
toc_template = TOC_TEMPLATE
navpoint_template = NAVPOINT_TEMPLATE
navpoint_indent = NAVPOINT_INDENT
node_navpoint_template = NODE_NAVPOINT_TEMPLATE
content_template = CONTENT_TEMPLATE
cover_template = COVER_TEMPLATE
coverpage_name = COVERPAGE_NAME
file_template = FILE_TEMPLATE
spine_template = SPINE_TEMPLATE
guide_template = GUIDE_TEMPLATE
toctree_template = TOCTREE_TEMPLATE
link_target_template = LINK_TARGET_TEMPLATE
css_link_target_class = CSS_LINK_TARGET_CLASS
guide_titles = GUIDE_TITLES
media_types = MEDIA_TYPES
refuri_re = REFURI_RE

def init(self):
StandaloneHTMLBuilder.init(self)
# the output files for epub must be .html only
self.out_suffix = '.html'
self.playorder = 0
self.tocid = 0

def get_theme_config(self):
return self.config.epub_theme, self.config.epub_theme_options

# generic support functions
def make_id(self, name, id_cache={}):
# id_cache is intentionally mutable
"""Return a unique id for name."""
id = id_cache.get(name)
if not id:
id = 'epub-%d' % self.env.new_serialno('epub')
id_cache[name] = id
return id

def esc(self, name):
"""Replace all characters not allowed in text an attribute values."""
# Like cgi.escape, but also replace apostrophe
name = name.replace('&', '&amp;')
name = name.replace('<', '&lt;')
name = name.replace('>', '&gt;')
name = name.replace('"', '&quot;')
name = name.replace('\'', '&#39;')
return name

def get_refnodes(self, doctree, result):
"""Collect section titles, their depth in the toc and the refuri."""
# XXX: is there a better way than checking the attribute
# toctree-l[1-8] on the parent node?
if isinstance(doctree, nodes.reference) and 'refuri' in doctree:
refuri = doctree['refuri']
if refuri.startswith('http://') or refuri.startswith('https://') \
or refuri.startswith('irc:') or refuri.startswith('mailto:'):
return result
classes = doctree.parent.attributes['classes']
for level in range(8, 0, -1):  # or range(1, 8)?
if (self.toctree_template % level) in classes:
result.append({
'level': level,
'refuri': self.esc(refuri),
'text': ssp(self.esc(doctree.astext()))
})
break
else:
for elem in doctree.children:
result = self.get_refnodes(elem, result)
return result

def get_toc(self):
"""Get the total table of contents, containing the master_doc
and pre and post files not managed by sphinx.
"""
doctree = self.env.get_and_resolve_doctree(self.config.master_doc,
self, prune_toctrees=False,
includehidden=True)
self.refnodes = self.get_refnodes(doctree, [])
master_dir = path.dirname(self.config.master_doc)
if master_dir:
master_dir += '/'  # XXX or os.sep?
for item in self.refnodes:
item['refuri'] = master_dir + item['refuri']
self.toc_add_files(self.refnodes)

def toc_add_files(self, refnodes):
"""Add the master_doc, pre and post files to a list of refnodes.
"""
refnodes.insert(0, {
'level': 1,
'refuri': self.esc(self.config.master_doc + '.html'),
'text': ssp(self.esc(
self.env.titles[self.config.master_doc].astext()))
})
for file, text in reversed(self.config.epub_pre_files):
refnodes.insert(0, {
'level': 1,
'refuri': self.esc(file),
'text': ssp(self.esc(text))
})
for file, text in self.config.epub_post_files:
refnodes.append({
'level': 1,
'refuri': self.esc(file),
'text': ssp(self.esc(text))
})

def fix_fragment(self, prefix, fragment):
"""Return a href/id attribute with colons replaced by hyphens."""
return prefix + fragment.replace(':', '-')

def fix_ids(self, tree):
"""Replace colons with hyphens in href and id attributes.

Some readers crash because they interpret the part as a
transport protocol specification.
"""
for node in tree.traverse(nodes.reference):
if 'refuri' in node:
m = self.refuri_re.match(node['refuri'])
if m:
node['refuri'] = self.fix_fragment(m.group(1), m.group(2))
if 'refid' in node:
node['refid'] = self.fix_fragment('', node['refid'])
for node in tree.traverse(addnodes.desc_signature):
ids = node.attributes['ids']
newids = []
for id in ids:
newids.append(self.fix_fragment('', id))
node.attributes['ids'] = newids

def add_visible_links(self, tree, show_urls='inline'):
"""Add visible link targets for external links"""

def make_footnote_ref(doc, label):
"""Create a footnote_reference node with children"""
footnote_ref = nodes.footnote_reference('[#]_')
footnote_ref.append(nodes.Text(label))
doc.note_autofootnote_ref(footnote_ref)
return footnote_ref

def make_footnote(doc, label, uri):
"""Create a footnote node with children"""
footnote = nodes.footnote(uri)
para = nodes.paragraph()
para.append(nodes.Text(uri))
footnote.append(para)
footnote.insert(0, nodes.label('', label))
doc.note_autofootnote(footnote)
return footnote

def footnote_spot(tree):
"""Find or create a spot to place footnotes.

The function returns the tuple (parent, index)."""
# The code uses the following heuristic:
# a) place them after the last existing footnote
# b) place them after an (empty) Footnotes rubric
# c) create an empty Footnotes rubric at the end of the document
fns = tree.traverse(nodes.footnote)
if fns:
fn = fns[-1]
return fn.parent, fn.parent.index(fn) + 1
for node in tree.traverse(nodes.rubric):
if len(node.children) == 1 and \
node.children[0].astext() == FOOTNOTES_RUBRIC_NAME:
return node.parent, node.parent.index(node) + 1
doc = tree.traverse(nodes.document)[0]
rub = nodes.rubric()
rub.append(nodes.Text(FOOTNOTES_RUBRIC_NAME))
doc.append(rub)
return doc, doc.index(rub) + 1

if show_urls == 'no':
return
if show_urls == 'footnote':
doc = tree.traverse(nodes.document)[0]
fn_spot, fn_idx = footnote_spot(tree)
nr = 1
for node in tree.traverse(nodes.reference):
uri = node.get('refuri', '')
if (uri.startswith('http:') or uri.startswith('https:') or
uri.startswith('ftp:')) and uri not in node.astext():
idx = node.parent.index(node) + 1
if show_urls == 'inline':
uri = self.link_target_template % {'uri': uri}
link = nodes.inline(uri, uri)
link['classes'].append(self.css_link_target_class)
node.parent.insert(idx, link)
elif show_urls == 'footnote':
label = FOOTNOTE_LABEL_TEMPLATE % nr
nr += 1
footnote_ref = make_footnote_ref(doc, label)
node.parent.insert(idx, footnote_ref)
footnote = make_footnote(doc, label, uri)
fn_spot.insert(fn_idx, footnote)
footnote_ref['refid'] = footnote['ids'][0]
footnote.add_backref(footnote_ref['ids'][0])
fn_idx += 1

def write_doc(self, docname, doctree):
"""Write one document file.

This method is overwritten in order to fix fragment identifiers
and to add visible external links.
"""
self.fix_ids(doctree)
self.add_visible_links(doctree, self.config.epub_show_urls)
return StandaloneHTMLBuilder.write_doc(self, docname, doctree)

def fix_genindex(self, tree):
"""Fix href attributes for genindex pages."""
# XXX: modifies tree inline
# Logic modeled from themes/basic/genindex.html
for key, columns in tree:
for entryname, (links, subitems, key_) in columns:
for (i, (ismain, link)) in enumerate(links):
m = self.refuri_re.match(link)
if m:
links[i] = (ismain,
self.fix_fragment(m.group(1), m.group(2)))
for subentryname, subentrylinks in subitems:
for (i, (ismain, link)) in enumerate(subentrylinks):
m = self.refuri_re.match(link)
if m:
subentrylinks[i] = (ismain,
self.fix_fragment(m.group(1), m.group(2)))

def is_vector_graphics(self, filename):
"""Does the filename extension indicate a vector graphic format?"""
ext = path.splitext(filename)[-1]
return ext in VECTOR_GRAPHICS_EXTENSIONS

def copy_image_files_pil(self):
"""Copy images using the PIL.
The method tries to read and write the files with the PIL,
converting the format and resizing the image if necessary/possible.
"""
ensuredir(path.join(self.outdir, self.imagedir))
for src in self.app.status_iterator(self.images, 'copying images... ',
brown, len(self.images)):
dest = self.images[src]
try:
img = Image.open(path.join(self.srcdir, src))
except IOError:
if not self.is_vector_graphics(src):
self.warn('cannot read image file %r: copying it instead' %
(path.join(self.srcdir, src), ))
try:
copyfile(path.join(self.srcdir, src),
path.join(self.outdir, self.imagedir, dest))
except (IOError, OSError) as err:
self.warn('cannot copy image file %r: %s' %
(path.join(self.srcdir, src), err))
continue
if self.config.epub_fix_images:
if img.mode in ('P',):
# See PIL documentation for Image.convert()
img = img.convert()
if self.config.epub_max_image_width > 0:
(width, height) = img.size
nw = self.config.epub_max_image_width
if width > nw:
nh = (height * nw) / width
img = img.resize((nw, nh), Image.BICUBIC)
try:
img.save(path.join(self.outdir, self.imagedir, dest))
except (IOError, OSError) as err:
self.warn('cannot write image file %r: %s' %
(path.join(self.srcdir, src), err))

def copy_image_files(self):
"""Copy image files to destination directory.
This overwritten method can use the PIL to convert image files.
"""
if self.images:
if self.config.epub_fix_images or self.config.epub_max_image_width:
if not Image:
self.warn('PIL not found - copying image files')
super(EpubBuilder, self).copy_image_files()
else:
self.copy_image_files_pil()
else:
super(EpubBuilder, self).copy_image_files()

def handle_page(self, pagename, addctx, templatename='page.html',
outfilename=None, event_arg=None):
"""Create a rendered page.

This method is overwritten for genindex pages in order to fix href link
attributes.
"""
if pagename.startswith('genindex'):
self.fix_genindex(addctx['genindexentries'])
StandaloneHTMLBuilder.handle_page(self, pagename, addctx, templatename,
outfilename, event_arg)

# Finish by building the epub file
def handle_finish(self):
"""Create the metainfo files and finally the epub."""
self.get_toc()
self.build_mimetype(self.outdir, 'mimetype')
self.build_container(self.outdir, 'META-INF/container.xml')
self.build_content(self.outdir, 'content.opf')
self.build_toc(self.outdir, 'toc.ncx')
self.build_epub(self.outdir, self.config.epub_basename + '.epub')

def build_mimetype(self, outdir, outname):
"""Write the metainfo file mimetype."""
self.info('writing %s file...' % outname)
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
try:
f.write(self.mimetype_template)
finally:
f.close()

def build_container(self, outdir, outname):
"""Write the metainfo file META-INF/cointainer.xml."""
self.info('writing %s file...' % outname)
fn = path.join(outdir, outname)
try:
os.mkdir(path.dirname(fn))
except OSError as err:
if err.errno != EEXIST:
raise
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
try:
f.write(self.container_template)
finally:
f.close()

def content_metadata(self, files, spine, guide):
"""Create a dictionary with all metadata for the content.opf
file properly escaped.
"""
metadata = {}
metadata['title'] = self.esc(self.config.epub_title)
metadata['author'] = self.esc(self.config.epub_author)
metadata['uid'] = self.esc(self.config.epub_uid)
metadata['lang'] = self.esc(self.config.epub_language)
metadata['publisher'] = self.esc(self.config.epub_publisher)
metadata['copyright'] = self.esc(self.config.epub_copyright)
metadata['scheme'] = self.esc(self.config.epub_scheme)
metadata['id'] = self.esc(self.config.epub_identifier)
metadata['date'] = self.esc(format_date('%Y-%m-%d', language=self.config.language,
warn=self.warn))
metadata['files'] = files
metadata['spine'] = spine
metadata['guide'] = guide
return metadata

def build_content(self, outdir, outname):
"""Write the metainfo file content.opf It contains bibliographic data,
a file list and the spine (the reading order).
"""
self.info('writing %s file...' % outname)

# files
if not outdir.endswith(os.sep):
outdir += os.sep
olen = len(outdir)
projectfiles = []
self.files = []
self.ignored_files = ['.buildinfo', 'mimetype', 'content.opf',
'toc.ncx', 'META-INF/container.xml',
self.config.epub_basename + '.epub'] + \
self.config.epub_exclude_files
for root, dirs, files in os.walk(outdir):
for fn in files:
filename = path.join(root, fn)[olen:]
if filename in self.ignored_files:
continue
ext = path.splitext(filename)[-1]
if ext not in self.media_types:
# we always have JS and potentially OpenSearch files, don't
# always warn about them
if ext not in ('.js', '.xml'):
self.warn('unknown mimetype for %s, ignoring' % filename)
continue
filename = filename.replace(os.sep, '/')
projectfiles.append(self.file_template % {
'href': self.esc(filename),
'id': self.esc(self.make_id(filename)),
'media_type': self.esc(self.media_types[ext])
})
self.files.append(filename)

# spine
spine = []
for item in self.refnodes:
if '#' in item['refuri']:
continue
if item['refuri'] in self.ignored_files:
continue
spine.append(self.spine_template % {
'idref': self.esc(self.make_id(item['refuri']))
})
for info in self.domain_indices:
spine.append(self.spine_template % {
'idref': self.esc(self.make_id(info[0] + self.out_suffix))
})
if self.get_builder_config('use_index', 'epub'):
spine.append(self.spine_template % {
'idref': self.esc(self.make_id('genindex' + self.out_suffix))
})

# add the optional cover
content_tmpl = self.content_template
html_tmpl = None
if self.config.epub_cover:
image, html_tmpl = self.config.epub_cover
image = image.replace(os.sep, '/')
mpos = content_tmpl.rfind('</metadata>')
cpos = content_tmpl.rfind('\n', 0, mpos) + 1
content_tmpl = content_tmpl[:cpos] + \
COVER_TEMPLATE % {'cover': self.esc(self.make_id(image))} + \
content_tmpl[cpos:]
if html_tmpl:
spine.insert(0, self.spine_template % {
'idref': self.esc(self.make_id(self.coverpage_name))})
if self.coverpage_name not in self.files:
ext = path.splitext(self.coverpage_name)[-1]
self.files.append(self.coverpage_name)
projectfiles.append(self.file_template % {
'href': self.esc(self.coverpage_name),
'id': self.esc(self.make_id(self.coverpage_name)),
'media_type': self.esc(self.media_types[ext])
})
ctx = {'image': self.esc(image), 'title': self.config.project}
self.handle_page(
path.splitext(self.coverpage_name)[0], ctx, html_tmpl)

guide = []
auto_add_cover = True
auto_add_toc = True
if self.config.epub_guide:
for type, uri, title in self.config.epub_guide:
file = uri.split('#')[0]
if file not in self.files:
self.files.append(file)
if type == 'cover':
auto_add_cover = False
if type == 'toc':
auto_add_toc = False
guide.append(self.guide_template % {
'type': self.esc(type),
'title': self.esc(title),
'uri': self.esc(uri)
})
if auto_add_cover and html_tmpl:
guide.append(self.guide_template % {
'type': 'cover',
'title': self.guide_titles['cover'],
'uri': self.esc(self.coverpage_name)
})
if auto_add_toc and self.refnodes:
guide.append(self.guide_template % {
'type': 'toc',
'title': self.guide_titles['toc'],
'uri': self.esc(self.refnodes[0]['refuri'])
})
projectfiles = '\n'.join(projectfiles)
spine = '\n'.join(spine)
guide = '\n'.join(guide)

# write the project file
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
try:
f.write(content_tmpl %
self.content_metadata(projectfiles, spine, guide))
finally:
f.close()

def new_navpoint(self, node, level, incr=True):
"""Create a new entry in the toc from the node at given level."""
# XXX Modifies the node
if incr:
self.playorder += 1
self.tocid += 1
node['indent'] = self.navpoint_indent * level
node['navpoint'] = self.esc(self.node_navpoint_template % self.tocid)
node['playorder'] = self.playorder
return self.navpoint_template % node

def insert_subnav(self, node, subnav):
"""Insert nested navpoints for given node.

The node and subnav are already rendered to text.
"""
nlist = node.rsplit('\n', 1)
nlist.insert(-1, subnav)
return '\n'.join(nlist)

def build_navpoints(self, nodes):
"""Create the toc navigation structure.

Subelements of a node are nested inside the navpoint.  For nested nodes
the parent node is reinserted in the subnav.
"""
navstack = []
navlist = []
level = 1
lastnode = None
for node in nodes:
if not node['text']:
continue
file = node['refuri'].split('#')[0]
if file in self.ignored_files:
continue
if node['level'] > self.config.epub_tocdepth:
continue
if node['level'] == level:
navlist.append(self.new_navpoint(node, level))
elif node['level'] == level + 1:
navstack.append(navlist)
navlist = []
level += 1
if lastnode and self.config.epub_tocdup:
# Insert starting point in subtoc with same playOrder
navlist.append(self.new_navpoint(lastnode, level, False))
navlist.append(self.new_navpoint(node, level))
else:
while node['level'] < level:
subnav = '\n'.join(navlist)
navlist = navstack.pop()
navlist[-1] = self.insert_subnav(navlist[-1], subnav)
level -= 1
navlist.append(self.new_navpoint(node, level))
lastnode = node
while level != 1:
subnav = '\n'.join(navlist)
navlist = navstack.pop()
navlist[-1] = self.insert_subnav(navlist[-1], subnav)
level -= 1
return '\n'.join(navlist)

def toc_metadata(self, level, navpoints):
"""Create a dictionary with all metadata for the toc.ncx file
properly escaped.
"""
metadata = {}
metadata['uid'] = self.config.epub_uid
metadata['title'] = self.config.epub_title
metadata['level'] = level
metadata['navpoints'] = navpoints
return metadata

def build_toc(self, outdir, outname):
"""Write the metainfo file toc.ncx."""
self.info('writing %s file...' % outname)

if self.config.epub_tocscope == 'default':
doctree = self.env.get_and_resolve_doctree(self.config.master_doc,
self, prune_toctrees=False,
includehidden=False)
refnodes = self.get_refnodes(doctree, [])
self.toc_add_files(refnodes)
else:
# 'includehidden'
refnodes = self.refnodes
navpoints = self.build_navpoints(refnodes)
level = max(item['level'] for item in self.refnodes)
level = min(level, self.config.epub_tocdepth)
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
try:
f.write(self.toc_template % self.toc_metadata(level, navpoints))
finally:
f.close()

def build_epub(self, outdir, outname):
"""Write the epub file.

It is a zip file with the mimetype file stored uncompressed as the first
entry.
"""
self.info('writing %s file...' % outname)
projectfiles = ['META-INF/container.xml', 'content.opf', 'toc.ncx'] \
+ self.files
epub = zipfile.ZipFile(path.join(outdir, outname), 'w',
zipfile.ZIP_DEFLATED)
epub.write(path.join(outdir, 'mimetype'), 'mimetype',
zipfile.ZIP_STORED)
for file in projectfiles:
fp = path.join(outdir, file)
epub.write(fp, file, zipfile.ZIP_DEFLATED)
epub.close()

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.epub3

# -*- coding: utf-8 -*-
"""
sphinx.builders.epub3
~~~~~~~~~~~~~~~~~~~~~

Build epub3 files.
Originally derived from epub.py.

:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import codecs
from os import path

from sphinx.builders.epub import EpubBuilder

# (Fragment) templates from which the metainfo files content.opf, toc.ncx,
# mimetype, and META-INF/container.xml are created.
# This template section also defines strings that are embedded in the html
# output but that may be customized by (re-)setting module attributes,
# e.g. from conf.py.

NAVIGATION_DOC_TEMPLATE = u'''\
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"\
xmlns:epub="http://www.idpf.org/2007/ops" lang="%(lang)s" xml:lang="%(lang)s">
<head>
<title>%(toc_locale)s</title>
</head>
<body>
<nav epub:type="toc">
<h1>%(toc_locale)s</h1>
<ol>
%(navlist)s
</ol>
</nav>
</body>
</html>
'''

NAVLIST_TEMPLATE = u'''\
%(indent)s  <li>
%(indent)s    <a href="%(refuri)s">%(text)s</a>
%(indent)s  </li>
'''
NAVLIST_INDENT = '      '

PACKAGE_DOC_TEMPLATE = u'''\
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="%(lang)s"
unique-identifier="%(uid)s">
<metadata xmlns:opf="http://www.idpf.org/2007/opf"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:language>%(lang)s</dc:language>
<dc:title>%(title)s</dc:title>
<dc:description>%(description)s</dc:description>
<dc:creator>%(author)s</dc:creator>
<dc:contributor>%(contributor)s</dc:contributor>
<dc:publisher>%(publisher)s</dc:publisher>
<dc:rights>%(copyright)s</dc:rights>
<dc:identifier id="%(uid)s">%(id)s</dc:identifier>
<dc:date>%(date)s</dc:date>
<meta property="dcterms:modified">%(date)s</meta>
</metadata>
<manifest>
<item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />
<item id="nav" href="nav.xhtml"\
media-type="application/xhtml+xml" properties="nav"/>
%(files)s
</manifest>
<spine toc="ncx" page-progression-direction="%(page_progression_direction)s">
<itemref idref="nav" />
%(spine)s
</spine>
<guide>
%(guide)s
</guide>
</package>
'''

# The epub3 publisher

[docs]class Epub3Builder(EpubBuilder):
"""
Builder that outputs epub3 files.

It creates the metainfo files content.opf, nav.xhtml, toc.ncx, mimetype,
and META-INF/container.xml. Afterwards, all necessary files are zipped to
an epub file.
"""
name = 'epub3'

navigation_doc_template = NAVIGATION_DOC_TEMPLATE
navlist_template = NAVLIST_TEMPLATE
navlist_indent = NAVLIST_INDENT
content_template = PACKAGE_DOC_TEMPLATE

# Finish by building the epub file
def handle_finish(self):
"""Create the metainfo files and finally the epub."""
self.get_toc()
self.build_mimetype(self.outdir, 'mimetype')
self.build_container(self.outdir, 'META-INF/container.xml')
self.build_content(self.outdir, 'content.opf')
self.build_navigation_doc(self.outdir, 'nav.xhtml')
self.build_toc(self.outdir, 'toc.ncx')
self.build_epub(self.outdir, self.config.epub_basename + '.epub')

def content_metadata(self, files, spine, guide):
"""Create a dictionary with all metadata for the content.opf
file properly escaped.
"""
metadata = super(Epub3Builder, self).content_metadata(
files, spine, guide)
metadata['description'] = self.esc(self.config.epub3_description)
metadata['contributor'] = self.esc(self.config.epub3_contributor)
metadata['page_progression_direction'] = self.esc(
self.config.epub3_page_progression_direction) or 'default'
return metadata

def new_navlist(self, node, level):
"""Create a new entry in the toc from the node at given level."""
# XXX Modifies the node
self.tocid += 1
node['indent'] = self.navlist_indent * level
navpoint = self.navlist_template % node
return navpoint

def build_navlist(self, nodes):
"""Create the toc navigation structure.

This method is almost same as build_navpoints method in epub.py.
This is because the logical navigation structure of epub3 is not
different from one of epub2.

The difference from build_navpoints method is templates which are used
when generating navigation documents.
"""
navstack = []
navlist = []
level = 1
lastnode = None
for node in nodes:
if not node['text']:
continue
file = node['refuri'].split('#')[0]
if file in self.ignored_files:
continue
if node['level'] > self.config.epub_tocdepth:
continue
if node['level'] == level:
navlist.append(self.new_navlist(node, level))
elif node['level'] == level + 1:
navstack.append(navlist)
navlist = []
level += 1
if lastnode and self.config.epub_tocdup:
navlist.append(self.new_navlist(node, level))
navlist[-1] = '<ol>\n' + navlist[-1]
else:
while node['level'] < level:
subnav = '\n'.join(navlist)
navlist = navstack.pop()
navlist[-1] = self.insert_subnav(navlist[-1], subnav)
level -= 1
navlist[-1] = navlist[-1] + '</ol>'
navlist.append(self.new_navlist(node, level))
lastnode = node
while level != 1:
subnav = '\n'.join(navlist)
navlist = navstack.pop()
navlist[-1] = self.insert_subnav(navlist[-1], subnav)
level -= 1
navlist[-1] = navlist[-1] + '</ol>'
return '\n'.join(navlist)

def navigation_doc_metadata(self, navlist):
"""Create a dictionary with all metadata for the nav.xhtml file
properly escaped.
"""
metadata = {}
metadata['lang'] = self.esc(self.config.epub_language)
metadata['toc_locale'] = self.esc(self.guide_titles['toc'])
metadata['navlist'] = navlist
return metadata

def build_navigation_doc(self, outdir, outname):
"""Write the metainfo file nav.xhtml."""
self.info('writing %s file...' % outname)

if self.config.epub_tocscope == 'default':
doctree = self.env.get_and_resolve_doctree(
self.config.master_doc, self,
prune_toctrees=False, includehidden=False)
refnodes = self.get_refnodes(doctree, [])
self.toc_add_files(refnodes)
else:
# 'includehidden'
refnodes = self.refnodes
navlist = self.build_navlist(refnodes)
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
try:
f.write(self.navigation_doc_template %
self.navigation_doc_metadata(navlist))
finally:
f.close()
# Add nav.xhtml to epub file
self.files.append(outname)

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.gettext

# -*- coding: utf-8 -*-
"""
sphinx.builders.gettext
~~~~~~~~~~~~~~~~~~~~~~~

The MessageCatalogBuilder class.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

from __future__ import unicode_literals

from os import path, walk, getenv
from codecs import open
from time import time
from datetime import datetime, tzinfo, timedelta
from collections import defaultdict
from uuid import uuid4

from six import iteritems

from sphinx.builders import Builder
from sphinx.util import split_index_msg
from sphinx.util.nodes import extract_messages, traverse_translatable_index
from sphinx.util.osutil import safe_relpath, ensuredir, canon_path
from sphinx.util.i18n import find_catalog
from sphinx.util.console import darkgreen, purple, bold
from sphinx.locale import pairindextypes

POHEADER = r"""
# SOME DESCRIPTIVE TITLE.
# Copyright (C) %(copyright)s
# This file is distributed under the same license as the %(project)s package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: %(project)s %(version)s\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: %(ctime)s\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

"""[1:]

class Catalog(object):
"""Catalog of translatable messages."""

def __init__(self):
self.messages = []  # retain insertion order, a la OrderedDict
self.metadata = {}  # msgid -> file, line, uid

def add(self, msg, origin):
if not hasattr(origin, 'uid'):
# Nodes that are replicated like todo don't have a uid,
# however i18n is also unnecessary.
return
if msg not in self.metadata:  # faster lookup in hash
self.messages.append(msg)
self.metadata[msg] = []
self.metadata[msg].append((origin.source, origin.line, origin.uid))

class MsgOrigin(object):
"""
Origin holder for Catalog message origin.
"""

def __init__(self, source, line):
self.source = source
self.line = line
self.uid = uuid4().hex

class I18nBuilder(Builder):
"""
General i18n builder.
"""
name = 'i18n'
versioning_method = 'text'
versioning_compare = None  # be set by `gettext_uuid`

def __init__(self, app):
self.versioning_compare = app.env.config.gettext_uuid
super(I18nBuilder, self).__init__(app)

def init(self):
Builder.init(self)
self.catalogs = defaultdict(Catalog)

def get_target_uri(self, docname, typ=None):
return ''

def get_outdated_docs(self):
return self.env.found_docs

def prepare_writing(self, docnames):
return

def compile_catalogs(self, catalogs, message):
return

def write_doc(self, docname, doctree):
catalog = self.catalogs[find_catalog(docname,
self.config.gettext_compact)]

for node, msg in extract_messages(doctree):
catalog.add(msg, node)

if 'index' in self.env.config.gettext_additional_targets:
# Extract translatable messages from index entries.
for node, entries in traverse_translatable_index(doctree):
for typ, msg, tid, main, key_ in entries:
for m in split_index_msg(typ, msg):
if typ == 'pair' and m in pairindextypes.values():
# avoid built-in translated message was incorporated
# in 'sphinx.util.nodes.process_index_entry'
continue
catalog.add(m, node)

# determine tzoffset once to remain unaffected by DST change during build
timestamp = time()
tzdelta = datetime.fromtimestamp(timestamp) - \
datetime.utcfromtimestamp(timestamp)
# set timestamp from SOURCE_DATE_EPOCH if set
# see https://reproducible-builds.org/specs/source-date-epoch/
source_date_epoch = getenv('SOURCE_DATE_EPOCH')
if source_date_epoch is not None:
timestamp = float(source_date_epoch)
tzdelta = 0

class LocalTimeZone(tzinfo):

def __init__(self, *args, **kw):
super(LocalTimeZone, self).__init__(*args, **kw)
self.tzdelta = tzdelta

def utcoffset(self, dt):
return self.tzdelta

def dst(self, dt):
return timedelta(0)

ltz = LocalTimeZone()

[docs]class MessageCatalogBuilder(I18nBuilder):
"""
Builds gettext-style message catalogs (.pot files).
"""
name = 'gettext'

def init(self):
I18nBuilder.init(self)
self.create_template_bridge()
self.templates.init(self)

def _collect_templates(self):
template_files = set()
for template_path in self.config.templates_path:
tmpl_abs_path = path.join(self.app.srcdir, template_path)
for dirpath, dirs, files in walk(tmpl_abs_path):
for fn in files:
if fn.endswith('.html'):
filename = canon_path(path.join(dirpath, fn))
template_files.add(filename)
return template_files

def _extract_from_template(self):
files = self._collect_templates()
self.info(bold('building [%s]: ' % self.name), nonl=1)
self.info('targets for %d template files' % len(files))

extract_translations = self.templates.environment.extract_translations

for template in self.app.status_iterator(
files, 'reading templates... ', purple, len(files)):
with open(template, 'r', encoding='utf-8') as f:
context = f.read()
for line, meth, msg in extract_translations(context):
origin = MsgOrigin(template, line)
self.catalogs['sphinx'].add(msg, origin)

def build(self, docnames, summary=None, method='update'):
self._extract_from_template()
I18nBuilder.build(self, docnames, summary, method)

def finish(self):
I18nBuilder.finish(self)
data = dict(
version = self.config.version,
copyright = self.config.copyright,
project = self.config.project,
ctime = datetime.fromtimestamp(
timestamp, ltz).strftime('%Y-%m-%d %H:%M%z'),
)
for textdomain, catalog in self.app.status_iterator(
iteritems(self.catalogs), "writing message catalogs... ",
darkgreen, len(self.catalogs),
lambda textdomain__: textdomain__[0]):
# noop if config.gettext_compact is set
ensuredir(path.join(self.outdir, path.dirname(textdomain)))

pofn = path.join(self.outdir, textdomain + '.pot')
pofile = open(pofn, 'w', encoding='utf-8')
try:
pofile.write(POHEADER % data)

for message in catalog.messages:
positions = catalog.metadata[message]

if self.config.gettext_location:
# generate "#: file1:line1\n#: file2:line2 ..."
pofile.write("#: %s\n" % "\n#: ".join(
"%s:%s" % (canon_path(
safe_relpath(source, self.outdir)), line)
for source, line, _ in positions))
if self.config.gettext_uuid:
# generate "# uuid1\n# uuid2\n ..."
pofile.write("# %s\n" % "\n# ".join(
uid for _, _, uid in positions))

# message contains *one* line of text ready for translation
message = message.replace('\\', r'\\'). \
replace('"', r'\"'). \
replace('\n', '\\n"\n"')
pofile.write('msgid "%s"\nmsgstr ""\n\n' % message)

finally:
pofile.close()

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.html

# -*- coding: utf-8 -*-
"""
sphinx.builders.html
~~~~~~~~~~~~~~~~~~~~

Several HTML builders.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import os
import sys
import zlib
import codecs
import posixpath
from os import path
from hashlib import md5

from six import iteritems, text_type, string_types
from six.moves import cPickle as pickle
from docutils import nodes
from docutils.io import DocTreeInput, StringOutput
from docutils.core import Publisher
from docutils.utils import new_document, relative_path
from docutils.frontend import OptionParser
from docutils.readers.doctree import Reader as DoctreeReader

from sphinx import package_dir, __display_version__
from sphinx.util import jsonimpl, copy_static_entry, copy_extra_entry
from sphinx.util.i18n import format_date
from sphinx.util.osutil import SEP, os_path, relative_uri, ensuredir, \
movefile, copyfile
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.matching import patmatch, compile_matchers
from sphinx.locale import _
from sphinx.search import js_index
from sphinx.theming import Theme
from sphinx.builders import Builder
from sphinx.application import ENV_PICKLE_FILENAME
from sphinx.highlighting import PygmentsBridge
from sphinx.util.console import bold, darkgreen, brown
from sphinx.writers.html import HTMLWriter, HTMLTranslator, \
SmartyPantsHTMLTranslator

#: 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'

def get_stable_hash(obj):
"""
Return a stable hash for a Python data structure.  We can't just use
the md5 of str(obj) since for example dictionary items are enumerated
in unpredictable order due to hash randomization in newer Pythons.
"""
if isinstance(obj, dict):
return get_stable_hash(list(obj.items()))
elif isinstance(obj, (list, tuple)):
obj = sorted(get_stable_hash(o) for o in obj)
return md5(text_type(obj).encode('utf8')).hexdigest()

[docs]class StandaloneHTMLBuilder(Builder):
"""
Builds standalone HTML docs.
"""
name = 'html'
format = 'html'
copysource = True
allow_parallel = True
out_suffix = '.html'
link_suffix = '.html'  # defaults to matching out_suffix
indexer_format = js_index
indexer_dumps_unicode = True
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
search = True  # for things like HTML help and Apple help: suppress search

# This is a class attribute because it is mutated by Sphinx.add_javascript.
script_files = ['_static/jquery.js', '_static/underscore.js',
'_static/doctools.js']
# Dito for this one.
css_files = []

default_sidebars = ['localtoc.html', 'relations.html',
'sourcelink.html', 'searchbox.html']

# cached publisher object for snippets
_publisher = None

def init(self):
# a hash of all config values that, if changed, cause a full rebuild
self.config_hash = ''
self.tags_hash = ''
# basename of images directory
self.imagedir = '_images'
# section numbers for headings in the currently visited document
self.secnumbers = {}
# currently written docname
self.current_docname = None

self.init_templates()
self.init_highlighter()
self.init_translator_class()
if self.config.html_file_suffix is not None:
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:
if self._get_translations_js():
self.script_files.append('_static/translations.js')

def _get_translations_js(self):
candidates = [path.join(package_dir, 'locale', self.config.language,
'LC_MESSAGES', 'sphinx.js'),
path.join(sys.prefix, 'share/sphinx/locale',
self.config.language, 'sphinx.js')] + \
[path.join(dir, self.config.language,
'LC_MESSAGES', 'sphinx.js')
for dir in self.config.locale_dirs]
for jsfile in candidates:
if path.isfile(jsfile):
return jsfile
return None

def get_theme_config(self):
return self.config.html_theme, self.config.html_theme_options

def init_templates(self):
Theme.init_themes(self.confdir, self.config.html_theme_path,
warn=self.warn)
themename, themeoptions = self.get_theme_config()
self.theme = Theme(themename, warn=self.warn)
self.theme_options = themeoptions.copy()
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,
self.config.trim_doctest_flags)

def init_translator_class(self):
if self.translator_class is not None:
pass
elif 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 iteritems(self.config.values)
if desc[1] == 'html')
self.config_hash = get_stable_hash(cfgdict)
self.tags_hash = get_stable_hash(sorted(self.tags))
old_config_hash = old_tags_hash = ''
try:
fp = open(path.join(self.outdir, '.buildinfo'))
try:
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
finally:
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.get_outfilename(docname)
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."""
if node is None:
return {'fragment': ''}
doc = new_document(b'<partial node>')
doc.append(node)

if self._publisher is None:
self._publisher = Publisher(
source_class = DocTreeInput,
destination_class=StringOutput)
self._publisher.set_components('standalone',
'restructuredtext', 'pseudoxml')

pub = self._publisher

pub.reader = DoctreeReader()
pub.writer = HTMLWriter(self)
pub.process_programmatic_settings(
None, {'output_encoding': 'unicode'}, None)
pub.set_source(doc, None)
pub.set_destination(None, None)
pub.publish()
return pub.writer.parts

def prepare_writing(self, docnames):
# create the search indexer
self.indexer = None
if self.search:
from sphinx.search import IndexBuilder, languages
lang = self.config.html_search_language or self.config.language
if not lang or lang not in languages:
lang = 'en'
self.indexer = IndexBuilder(self.env, lang,
self.config.html_search_options,
self.config.html_search_scorer)
self.load_indexer(docnames)

self.docwriter = HTMLWriter(self)
self.docsettings = OptionParser(
defaults=self.env.settings,
components=(self.docwriter,),
read_config_files=True).get_default_values()
self.docsettings.compact_lists = bool(self.config.html_compact_lists)

# determine the additional indices to include
self.domain_indices = []
# html_domain_indices can be False/True or a list of index names
indices_config = self.config.html_domain_indices
if indices_config:
for domain_name in sorted(self.env.domains):
domain = self.env.domains[domain_name]
for indexcls in domain.indices:
indexname = '%s-%s' % (domain.name, indexcls.name)
if isinstance(indices_config, list):
if indexname not in indices_config:
continue
# deprecated config value
if indexname == 'py-modindex' and \
not self.config.html_use_modindex:
continue
content, collapse = indexcls(domain).generate()
if content:
self.domain_indices.append(
(indexname, indexcls, content, collapse))

# 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 = format_date(lufmt or _('%b %d, %Y'),
language=self.config.language,
warn=self.warn)
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, string_types):
self.warn('html_use_opensearch config value must now be a string')

self.relations = self.env.collect_relations()

rellinks = []
if self.get_builder_config('use_index', 'html'):
rellinks.append(('genindex', _('General Index'), 'I', _('index')))
for indexname, indexcls, content, collapse in self.domain_indices:
# if it has a short name
if indexcls.shortname:
rellinks.append((indexname, indexcls.localname,
'', indexcls.shortname))

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_copyright = self.config.html_show_copyright,
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,
language = self.config.language,
css_files = self.css_files,
sphinx_version = __display_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
iteritems(self.theme.get_options(self.theme_options)))
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:
# remove link to the master file; we have a generic
# "back to index" link already
parents.pop()
parents.reverse()

# title rendered as HTML
title = self.env.longtitles.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)

# Suffix for the document
source_suffix = '.' + self.env.doc2path(docname).split('.')[-1]

# local TOC and global TOC tree
self_toc = self.env.get_toc_for(docname, self)
toc = self.render_partial(self_toc)['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),
page_source_suffix = source_suffix,
)

def write_doc(self, docname, doctree):
destination = StringOutput(encoding='utf-8')
doctree.settings = self.docsettings

self.secnumbers = self.env.toc_secnumbers.get(docname, {})
self.fignumbers = self.env.toc_fignumbers.get(docname, {})
self.imgpath = relative_uri(self.get_target_uri(docname), '_images')
self.dlpath = relative_uri(self.get_target_uri(docname), '_downloads')
self.current_docname = docname
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.handle_page(docname, ctx, event_arg=doctree)

def write_doc_serialized(self, docname, doctree):
self.imgpath = relative_uri(self.get_target_uri(docname), self.imagedir)
self.post_process_images(doctree)
title = self.env.longtitles.get(docname)
title = title and self.render_partial(title)['title'] or ''
self.index_page(docname, doctree, title)

def finish(self):
self.finish_tasks.add_task(self.gen_indices)
self.finish_tasks.add_task(self.gen_additional_pages)
self.finish_tasks.add_task(self.copy_image_files)
self.finish_tasks.add_task(self.copy_download_files)
self.finish_tasks.add_task(self.copy_static_files)
self.finish_tasks.add_task(self.copy_extra_files)
self.finish_tasks.add_task(self.write_buildinfo)

# dump the search index
self.handle_finish()

def gen_indices(self):
self.info(bold('generating indices...'), nonl=1)

# the global general index
if self.get_builder_config('use_index', 'html'):
self.write_genindex()

# the global domain-specific indices
self.write_domain_indices()

self.info()

def gen_additional_pages(self):
# pages from extensions
for pagelist in self.app.emit('html-collect-pages'):
for pagename, context, template in pagelist:
self.handle_page(pagename, context, template)

self.info(bold('writing additional pages...'), nonl=1)

# 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)

# the search page
if self.search:
self.info(' search', nonl=1)
self.handle_page('search', {}, 'search.html')

# the opensearch xml file
if self.config.html_use_opensearch and self.search:
self.info(' opensearch', nonl=1)
fn = path.join(self.outdir, '_static', 'opensearch.xml')
self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn)

self.info()

def write_genindex(self):
# 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 _k, 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')

def write_domain_indices(self):
for indexname, indexcls, content, collapse in self.domain_indices:
indexcontext = dict(
indextitle = indexcls.localname,
content = content,
collapse_index = collapse,
)
self.info(' ' + indexname, nonl=1)
self.handle_page(indexname, indexcontext, 'domainindex.html')

def copy_image_files(self):
# copy image files
if self.images:
ensuredir(path.join(self.outdir, self.imagedir))
for src in self.app.status_iterator(self.images, 'copying images... ',
brown, len(self.images)):
dest = self.images[src]
try:
copyfile(path.join(self.srcdir, src),
path.join(self.outdir, self.imagedir, dest))
except Exception as err:
self.warn('cannot copy image file %r: %s' %
(path.join(self.srcdir, src), err))

def copy_download_files(self):
def to_relpath(f):
return relative_path(self.srcdir, f)
# copy downloadable files
if self.env.dlfiles:
ensuredir(path.join(self.outdir, '_downloads'))
for src in self.app.status_iterator(self.env.dlfiles,
'copying downloadable files... ',
brown, len(self.env.dlfiles),
stringify_func=to_relpath):
dest = self.env.dlfiles[src][1]
try:
copyfile(path.join(self.srcdir, src),
path.join(self.outdir, '_downloads', dest))
except Exception as err:
self.warn('cannot copy downloadable file %r: %s' %
(path.join(self.srcdir, src), err))

def copy_static_files(self):
# 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 = self._get_translations_js()
if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static',
'translations.js'))

# copy non-minified stemmer JavaScript file
if self.indexer is not None:
jsfile = self.indexer.get_js_stemmer_rawcode()
if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static', '_stemmer.js'))

ctx = self.globalcontext.copy()

# add context items for search function used in searchtools.js_t
if self.indexer is not None:
ctx.update(self.indexer.context_for_searchtool())

# then, copy over theme-supplied static files
if self.theme:
themeentries = [path.join(themepath, 'static')
for themepath in self.theme.get_dirchain()[::-1]]
for entry in themeentries:
copy_static_entry(entry, path.join(self.outdir, '_static'),
self, ctx)
# then, copy over all user-supplied static files
staticentries = [path.join(self.confdir, spath)
for spath in self.config.html_static_path]
matchers = compile_matchers(self.config.exclude_patterns)
for entry in staticentries:
if not path.exists(entry):
self.warn('html_static_path entry %r does not exist' % entry)
continue
copy_static_entry(entry, path.join(self.outdir, '_static'), self,
ctx, exclude_matchers=matchers)
# copy logo and favicon files if not already in static path
if self.config.html_logo:
logobase = path.basename(self.config.html_logo)
logotarget = path.join(self.outdir, '_static', logobase)
if not path.isfile(path.join(self.confdir, self.config.html_logo)):
self.warn('logo file %r does not exist' % self.config.html_logo)
elif not path.isfile(logotarget):
copyfile(path.join(self.confdir, self.config.html_logo),
logotarget)
if self.config.html_favicon:
iconbase = path.basename(self.config.html_favicon)
icontarget = path.join(self.outdir, '_static', iconbase)
if not path.isfile(path.join(self.confdir, self.config.html_favicon)):
self.warn('favicon file %r does not exist' % self.config.html_favicon)
elif not path.isfile(icontarget):
copyfile(path.join(self.confdir, self.config.html_favicon),
icontarget)
self.info('done')

def copy_extra_files(self):
# copy html_extra_path files
self.info(bold('copying extra files... '), nonl=True)
extraentries = [path.join(self.confdir, epath)
for epath in self.config.html_extra_path]
matchers = compile_matchers(self.config.exclude_patterns)
for entry in extraentries:
if not path.exists(entry):
self.warn('html_extra_path entry %r does not exist' % entry)
continue
copy_extra_entry(entry, self.outdir, matchers)
self.info('done')

def write_buildinfo(self):
# 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()

def cleanup(self):
# clean up theme stuff
if self.theme:
self.theme.cleanup()

def post_process_images(self, doctree):
"""Pick the best candidate for an image and link down-scaled images to
their high res version.
"""
Builder.post_process_images(self, doctree)

if self.config.html_scaled_image_link:
for node in doctree.traverse(nodes.image):
scale_keys = ('scale', 'width', 'height')
if not any((key in node) for key in scale_keys) 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('', '', internal=True)
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:
searchindexfn = path.join(self.outdir, self.searchindex_filename)
if self.indexer_dumps_unicode:
f = codecs.open(searchindexfn, 'r', encoding='utf-8')
else:
f = open(searchindexfn, '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, **kwds):
if 'includehidden' not in kwds:
kwds['includehidden'] = False
return self.render_partial(self.env.get_toctree_for(
docname, self, collapse, **kwds))['fragment']

def get_outfilename(self, pagename):
return path.join(self.outdir, os_path(pagename) + self.out_suffix)

def add_sidebars(self, pagename, ctx):
def has_wildcard(pattern):
return any(char in pattern for char in '*?[')
sidebars = None
matched = None
customsidebar = None
for pattern, patsidebars in iteritems(self.config.html_sidebars):
if patmatch(pagename, pattern):
if matched:
if has_wildcard(pattern):
# warn if both patterns contain wildcards
if has_wildcard(matched):
self.warn('page %s matches two patterns in '
'html_sidebars: %r and %r' %
(pagename, matched, pattern))
# else the already matched pattern is more specific
# than the present one, because it contains no wildcard
continue
matched = pattern
sidebars = patsidebars
if sidebars is None:
# keep defaults
pass
elif isinstance(sidebars, string_types):
# 0.x compatible mode: insert custom sidebar before searchbox
customsidebar = sidebars
sidebars = None
ctx['sidebars'] = sidebars
ctx['customsidebar'] = customsidebar

# --------- 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
default_baseuri = self.get_target_uri(pagename)
# in the singlehtml builder, default_baseuri still contains an #anchor
# part, which relative_uri doesn't really like...
default_baseuri = default_baseuri.rsplit('#', 1)[0]

def pathto(otheruri, resource=False, baseuri=default_baseuri):
if resource and '://' in otheruri:
# allow non-local resources given by scheme
return otheruri
elif not resource:
otheruri = self.get_target_uri(otheruri)
uri = relative_uri(baseuri, otheruri) or '#'
return uri
ctx['pathto'] = pathto
ctx['hasdoc'] = lambda name: name in self.env.all_docs
if self.name != 'htmlhelp':
ctx['encoding'] = encoding = self.config.html_output_encoding
else:
ctx['encoding'] = encoding = self.encoding
ctx['toctree'] = lambda **kw: self._get_local_toctree(pagename, **kw)
self.add_sidebars(pagename, ctx)
ctx.update(addctx)

newtmpl = self.app.emit_firstresult('html-page-context', pagename,
templatename, ctx, event_arg)
if newtmpl:
templatename = newtmpl

try:
output = self.templates.render(templatename, ctx)
except UnicodeError:
self.warn("a Unicode error occurred when rendering the page %s. "
"Please make sure all config values that contain "
"non-ASCII content are Unicode strings." % pagename)
return

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', encoding, 'xmlcharrefreplace')
try:
f.write(output)
finally:
f.close()
except (IOError, OSError) as 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))
copyfile(self.env.doc2path(pagename), source_name)

def handle_finish(self):
if self.indexer:
self.finish_tasks.add_task(self.dump_search_index)
self.finish_tasks.add_task(self.dump_inventory)

def dump_inventory(self):
self.info(bold('dumping object inventory... '), nonl=True)
f = open(path.join(self.outdir, INVENTORY_FILENAME), 'wb')
try:
f.write((u'# Sphinx inventory version 2\n'
u'# Project: %s\n'
u'# Version: %s\n'
u'# The remainder of this file is compressed using zlib.\n'
% (self.config.project, self.config.version)).encode('utf-8'))
compressor = zlib.compressobj(9)
for domainname, domain in sorted(self.env.domains.items()):
for name, dispname, type, docname, anchor, prio in \
sorted(domain.get_objects()):
if anchor.endswith(name):
# this can shorten the inventory by as much as 25%
anchor = anchor[:-len(name)] + '$'
uri = self.get_target_uri(docname)
if anchor:
uri += '#' + anchor
if dispname == name:
dispname = u'-'
f.write(compressor.compress(
(u'%s %s:%s %s %s %s\n' % (name, domainname, type,
prio, uri, dispname)).encode('utf-8')))
f.write(compressor.flush())
finally:
f.close()
self.info('done')

def dump_search_index(self):
self.info(
bold('dumping search index in %s ... ' % self.indexer.label()),
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
if self.indexer_dumps_unicode:
f = codecs.open(searchindexfn + '.tmp', 'w', encoding='utf-8')
else:
f = open(searchindexfn + '.tmp', 'wb')
try:
self.indexer.dump(f, self.indexer_format)
finally:
f.close()
movefile(searchindexfn + '.tmp', searchindexfn)
self.info('done')

[docs]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

def prepare_writing(self, docnames):
StandaloneHTMLBuilder.prepare_writing(self, docnames)
self.globalcontext['no_search_suffix'] = True

[docs]class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
"""
A StandaloneHTMLBuilder subclass that puts the whole document tree on one
HTML page.
"""
name = 'singlehtml'
copysource = False

def get_outdated_docs(self):
return 'all documents'

def get_target_uri(self, docname, typ=None):
if docname in self.env.all_docs:
# all references are on the same page...
return self.config.master_doc + self.out_suffix + \
'#document-' + docname
else:
# chances are this is a html_additional_page
return docname + self.out_suffix

def get_relative_uri(self, from_, to, typ=None):
# ignore source
return self.get_target_uri(to, typ)

def fix_refuris(self, tree):
# fix refuris with double anchor
fname = self.config.master_doc + self.out_suffix
for refnode in tree.traverse(nodes.reference):
if 'refuri' not in refnode:
continue
refuri = refnode['refuri']
hashindex = refuri.find('#')
if hashindex < 0:
continue
hashindex = refuri.find('#', hashindex+1)
if hashindex >= 0:
refnode['refuri'] = fname + refuri[hashindex:]

def _get_local_toctree(self, docname, collapse=True, **kwds):
if 'includehidden' not in kwds:
kwds['includehidden'] = False
toctree = self.env.get_toctree_for(docname, self, collapse, **kwds)
self.fix_refuris(toctree)
return self.render_partial(toctree)['fragment']

def assemble_doctree(self):
master = self.config.master_doc
tree = self.env.get_doctree(master)
tree = inline_all_toctrees(self, set(), master, tree, darkgreen, [master])
tree['docname'] = master
self.env.resolve_references(tree, master, self)
self.fix_refuris(tree)
return tree

def assemble_toc_secnumbers(self):
# Assemble toc_secnumbers to resolve section numbers on SingleHTML.
# Merge all secnumbers to single secnumber.
#
# Note: current Sphinx has refid confliction in singlehtml mode.
#       To avoid the problem, it replaces key of secnumbers to
#       tuple of docname and refid.
#
#       There are related codes in inline_all_toctres() and
#       HTMLTranslter#add_secnumber().
new_secnumbers = {}
for docname, secnums in iteritems(self.env.toc_secnumbers):
for id, secnum in iteritems(secnums):
new_secnumbers[(docname, id)] = secnum

return {self.config.master_doc: new_secnumbers}

def get_doc_context(self, docname, body, metatags):
# no relation links...
toc = self.env.get_toctree_for(self.config.master_doc, self, False)
# if there is no toctree, toc is None
if toc:
self.fix_refuris(toc)
toc = self.render_partial(toc)['fragment']
display_toc = True
else:
toc = ''
display_toc = False
return dict(
parents = [],
prev = None,
next = None,
docstitle = None,
title = self.config.html_title,
meta = None,
body = body,
metatags = metatags,
rellinks = [],
sourcename = '',
toc = toc,
display_toc = display_toc,
)

def write(self, *ignored):
docnames = self.env.all_docs

self.info(bold('preparing documents... '), nonl=True)
self.prepare_writing(docnames)
self.info('done')

self.info(bold('assembling single document... '), nonl=True)
doctree = self.assemble_doctree()
self.env.toc_secnumbers = self.assemble_toc_secnumbers()
self.info()
self.info(bold('writing... '), nonl=True)
self.write_doc_serialized(self.config.master_doc, doctree)
self.write_doc(self.config.master_doc, doctree)
self.info('done')

def finish(self):
# no indices or search pages are supported
self.info(bold('writing additional files...'), nonl=1)

# 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:
self.info(' opensearch', nonl=1)
fn = path.join(self.outdir, '_static', 'opensearch.xml')
self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn)

self.info()

self.copy_image_files()
self.copy_download_files()
self.copy_static_files()
self.copy_extra_files()
self.write_buildinfo()
self.dump_inventory()

[docs]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
implementation_dumps_unicode = False
#: additional arguments for dump()
additional_dump_args = ()

#: 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.imagedir = '_images'
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 dump_context(self, context, filename):
if self.implementation_dumps_unicode:
f = codecs.open(filename, 'w', encoding='utf-8')
else:
f = open(filename, 'wb')
try:
self.implementation.dump(context, f, *self.additional_dump_args)
finally:
f.close()

def handle_page(self, pagename, ctx, templatename='page.html',
outfilename=None, event_arg=None):
ctx['current_page_name'] = pagename
self.add_sidebars(pagename, ctx)

if not outfilename:
outfilename = path.join(self.outdir,
os_path(pagename) + self.out_suffix)

# we're not taking the return value here, since no template is
# actually rendered
self.app.emit('html-page-context', pagename, templatename, ctx, event_arg)

ensuredir(path.dirname(outfilename))
self.dump_context(ctx, outfilename)

# 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))
copyfile(self.env.doc2path(pagename), source_name)

def handle_finish(self):
# dump the global context
outfilename = path.join(self.outdir, self.globalcontext_filename)
self.dump_context(self.globalcontext, outfilename)

# 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
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()

[docs]class PickleHTMLBuilder(SerializingHTMLBuilder):
"""
A Builder that dumps the generated HTML into pickle files.
"""
implementation = pickle
implementation_dumps_unicode = False
additional_dump_args = (pickle.HIGHEST_PROTOCOL,)
indexer_format = pickle
indexer_dumps_unicode = False
name = 'pickle'
out_suffix = '.fpickle'
globalcontext_filename = 'globalcontext.pickle'
searchindex_filename = 'searchindex.pickle'

# compatibility alias
WebHTMLBuilder = PickleHTMLBuilder

[docs]class JSONHTMLBuilder(SerializingHTMLBuilder):
"""
A builder that dumps the generated HTML into JSON files.
"""
implementation = jsonimpl
implementation_dumps_unicode = True
indexer_format = jsonimpl
indexer_dumps_unicode = True
name = 'json'
out_suffix = '.fjson'
globalcontext_filename = 'globalcontext.json'
searchindex_filename = 'searchindex.json'

def init(self):
SerializingHTMLBuilder.init(self)

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.htmlhelp

# -*- coding: utf-8 -*-
"""
sphinx.builders.htmlhelp
~~~~~~~~~~~~~~~~~~~~~~~~

Build HTML help support files.
Parts adapted from Python's Doc/tools/prechm.py.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function

import os
import codecs
from os import path

from docutils import nodes

from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util.pycompat import htmlescape

# 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=No
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=%(lcid)#x
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()

# The following list includes only languages supported by Sphinx.
# See http://msdn.microsoft.com/en-us/library/ms930130.aspx for more.
chm_locales = {
# lang:   LCID,  encoding
'ca':    (0x403, 'cp1252'),
'cs':    (0x405, 'cp1250'),
'da':    (0x406, 'cp1252'),
'de':    (0x407, 'cp1252'),
'en':    (0x409, 'cp1252'),
'es':    (0x40a, 'cp1252'),
'et':    (0x425, 'cp1257'),
'fa':    (0x429, 'cp1256'),
'fi':    (0x40b, 'cp1252'),
'fr':    (0x40c, 'cp1252'),
'hr':    (0x41a, 'cp1250'),
'hu':    (0x40e, 'cp1250'),
'it':    (0x410, 'cp1252'),
'ja':    (0x411, 'cp932'),
'ko':    (0x412, 'cp949'),
'lt':    (0x427, 'cp1257'),
'lv':    (0x426, 'cp1257'),
'nl':    (0x413, 'cp1252'),
'no_NB': (0x414, 'cp1252'),
'pl':    (0x415, 'cp1250'),
'pt_BR': (0x416, 'cp1252'),
'ru':    (0x419, 'cp1251'),
'sk':    (0x41b, 'cp1250'),
'sl':    (0x424, 'cp1250'),
'sv':    (0x41d, 'cp1252'),
'tr':    (0x41f, 'cp1254'),
'uk_UA': (0x422, 'cp1251'),
'zh_CN': (0x804, 'cp936'),
'zh_TW': (0x404, 'cp950'),
}

[docs]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

# don't generate search index or include search page
search = False

lcid = 0x409
encoding = 'cp1252'

def init(self):
StandaloneHTMLBuilder.init(self)
# the output files for HTML help must be .html only
self.out_suffix = '.html'
# determine the correct locale setting
locale = chm_locales.get(self.config.language)
if locale is not None:
self.lcid, self.encoding = locale

def open_file(self, outdir, basename, mode='w'):
# open a file with the correct encoding for the selected language
return codecs.open(path.join(outdir, basename), mode,
self.encoding, 'xmlcharrefreplace')

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 = self.open_file(outdir, outname+'.stp')
try:
for word in sorted(stopwords):
print(word, file=f)
finally:
f.close()

self.info('writing project file...')
f = self.open_file(outdir, outname+'.hhp')
try:
f.write(project_template % {'outname': outname,
'title': self.config.html_title,
'version': self.config.version,
'project': self.config.project,
'lcid': self.lcid})
if not outdir.endswith(os.sep):
outdir += os.sep
olen = len(outdir)
for root, dirs, files in os.walk(outdir):
staticdir = root.startswith(path.join(outdir, '_static'))
for fn in files:
if (staticdir and not fn.endswith('.js')) or \
fn.endswith('.html'):
print(path.join(root, fn)[olen:].replace(os.sep, '\\'),
file=f)
finally:
f.close()

self.info('writing TOC file...')
f = self.open_file(outdir, outname+'.hhc')
try:
f.write(contents_header)
# special books
f.write('<LI> ' + object_sitemap % (self.config.html_short_title,
'index.html'))
for indexname, indexcls, content, collapse in self.domain_indices:
f.write('<LI> ' + object_sitemap % (indexcls.localname,
'%s.html' % indexname))
# 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 = htmlescape(node.astext()).replace('"', '&quot;')
f.write(object_sitemap % (title, link))
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 \
'toctree' in node
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 = self.open_file(outdir, outname+'.hhk')
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)
title = htmlescape(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][1])
else:
for i, ref in enumerate(refs):
# XXX: better title?
write_param('Name', '[%d] %s' % (i, ref[1]))
write_param('Local', ref[1])
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, key_) in group:
write_index(title, refs, subitems)
f.write('</UL>\n')
finally:
f.close()

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.latex

# -*- coding: utf-8 -*-
"""
sphinx.builders.latex
~~~~~~~~~~~~~~~~~~~~~

LaTeX builder.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import os
from os import path
import warnings

from six import iteritems
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 texescape
from sphinx.errors import SphinxError
from sphinx.locale import _
from sphinx.builders import Builder
from sphinx.environment import NoUri
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import SEP, copyfile
from sphinx.util.console import bold, darkgreen
from sphinx.writers.latex import LaTeXWriter

[docs]class LaTeXBuilder(Builder):
"""
Builds LaTeX output to create PDF.
"""
name = 'latex'
format = 'latex'
supported_image_types = ['application/pdf', 'image/png', 'image/jpeg']
usepackages = []

def init(self):
self.docnames = []
self.document_data = []
texescape.init()
self.check_options()

def check_options(self):
if self.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'):
self.warn('invalid latex_toplevel_sectioning, ignored: %s' %
self.config.latex_top_sectionlevel)
self.config.latex_top_sectionlevel = None

if self.config.latex_use_parts:
warnings.warn('latex_use_parts will be removed at Sphinx-1.5. '
'Use latex_toplevel_sectioning instead.',
DeprecationWarning)

if self.config.latex_toplevel_sectioning:
self.warn('latex_use_parts conflicts with latex_toplevel_sectioning, ignored.')

def get_outdated_docs(self):
return 'all documents'  # for now

def get_target_uri(self, docname, typ=None):
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 = [list(x) for x in 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,),
read_config_files=True).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)
toctrees = self.env.get_doctree(docname).traverse(addnodes.toctree)
if toctrees:
if toctrees[0].get('maxdepth') > 0:
tocdepth = toctrees[0].get('maxdepth')
else:
tocdepth = None
else:
tocdepth = None
doctree = self.assemble_doctree(
docname, toctree_only,
appendices=((docclass != 'howto') and self.config.latex_appendices or []))
doctree['tocdepth'] = tocdepth
self.post_process_images(doctree)
self.info("writing... ", nonl=1)
doctree.settings = docsettings
doctree.settings.author = author
doctree.settings.title = title
doctree.settings.contentsname = self.get_contentsname(docname)
doctree.settings.docname = docname
doctree.settings.docclass = docclass
docwriter.write(doctree, destination)
self.info("done")

def get_contentsname(self, indexfile):
tree = self.env.get_doctree(indexfile)
contentsname = None
for toctree in tree.traverse(addnodes.toctree):
if 'caption' in toctree:
contentsname = toctree['caption']
break

return contentsname

def assemble_doctree(self, indexfile, toctree_only, appendices):
self.docnames = set([indexfile] + appendices)
self.info(darkgreen(indexfile) + " ", nonl=1)
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 = inline_all_toctrees(self, self.docnames, indexfile, tree,
darkgreen, [indexfile])
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 iteritems(self.images):
self.info(' '+src, nonl=1)
copyfile(path.join(self.srcdir, src),
path.join(self.outdir, dest))
self.info()

# copy TeX support files from texinputs
self.info(bold('copying TeX support files...'))
staticdirname = path.join(package_dir, 'texinputs')
for filename in os.listdir(staticdirname):
if not filename.startswith('.'):
copyfile(path.join(staticdirname, filename),
path.join(self.outdir, filename))

# 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)
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)
logotarget = path.join(self.outdir, logobase)
if not path.isfile(path.join(self.confdir, self.config.latex_logo)):
raise SphinxError('logo file %r does not exist' % self.config.latex_logo)
elif not path.isfile(logotarget):
copyfile(path.join(self.confdir, self.config.latex_logo), logotarget)
self.info('done')

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.linkcheck

# -*- coding: utf-8 -*-
"""
sphinx.builders.linkcheck
~~~~~~~~~~~~~~~~~~~~~~~~~

The CheckExternalLinksBuilder class.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import re
import socket
import codecs
import threading
from os import path

from six.moves import queue
from six.moves.urllib.request import build_opener, Request, HTTPRedirectHandler
from six.moves.urllib.parse import unquote
from six.moves.urllib.error import HTTPError
from six.moves.html_parser import HTMLParser
from docutils import nodes

# 2015-06-25 barry@python.org.  This exception was deprecated in Python 3.3 and
# removed in Python 3.5, however for backward compatibility reasons, we're not
# going to just remove it.  If it doesn't exist, define an exception that will
# never be caught but leaves the code in check_anchor() intact.
try:
from six.moves.html_parser import HTMLParseError
except ImportError:
class HTMLParseError(Exception):
pass

from sphinx.builders import Builder
from sphinx.util import encode_uri
from sphinx.util.console import purple, red, darkgreen, darkgray, \
darkred, turquoise
from sphinx.util.pycompat import TextIOWrapper

class RedirectHandler(HTTPRedirectHandler):
"""A RedirectHandler that records the redirect code we got."""

def redirect_request(self, req, fp, code, msg, headers, newurl):
new_req = HTTPRedirectHandler.redirect_request(self, req, fp, code,
msg, headers, newurl)
req.redirect_code = code
return new_req

# create an opener that will simulate a browser user-agent
opener = build_opener(RedirectHandler)
opener.addheaders = [('User-agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:25.0) '
'Gecko/20100101 Firefox/25.0')]

class HeadRequest(Request):
"""Subclass of urllib2.Request that sends a HEAD request."""
def get_method(self):
return 'HEAD'

class AnchorCheckParser(HTMLParser):
"""Specialized HTML parser that looks for a specific anchor."""

def __init__(self, search_anchor):
HTMLParser.__init__(self)

self.search_anchor = search_anchor
self.found = False

def handle_starttag(self, tag, attrs):
for key, value in attrs:
if key in ('id', 'name') and value == self.search_anchor:
self.found = True

def check_anchor(f, anchor):
"""Reads HTML data from a filelike object 'f' searching for *anchor*.
Returns True if anchor was found, False otherwise.
"""
parser = AnchorCheckParser(anchor)
try:
# Read file in chunks of 8192 bytes. If we find a matching anchor, we
# break the loop early in hopes not to have to download the whole thing.
chunk = f.read(8192)
while chunk and not parser.found:
parser.feed(chunk)
chunk = f.read(8192)
parser.close()
except HTMLParseError:
# HTMLParser is usually pretty good with sloppy HTML, but it tends to
# choke on EOF. But we're done then anyway.
pass
return parser.found

def get_content_charset(f):
content_type = f.headers.get('content-type')
if content_type:
params = (p.strip() for p in content_type.split(';')[1:])
for param in params:
if param.startswith('charset='):
return param[8:]

return None

[docs]class CheckExternalLinksBuilder(Builder):
"""
Checks for broken external links.
"""
name = 'linkcheck'

def init(self):
self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
self.good = set()
self.broken = {}
self.redirected = {}
# set a timeout for non-responding servers
socket.setdefaulttimeout(5.0)
# create output file
open(path.join(self.outdir, 'output.txt'), 'w').close()

# create queues and worker threads
self.wqueue = queue.Queue()
self.rqueue = queue.Queue()
self.workers = []
for i in range(self.app.config.linkcheck_workers):
thread = threading.Thread(target=self.check_thread)
thread.setDaemon(True)
thread.start()
self.workers.append(thread)

def check_thread(self):
kwargs = {}
if self.app.config.linkcheck_timeout:
kwargs['timeout'] = self.app.config.linkcheck_timeout

def check_uri():
# split off anchor
if '#' in uri:
req_url, anchor = uri.split('#', 1)
else:
req_url = uri
anchor = None

# handle non-ASCII URIs
try:
req_url.encode('ascii')
except UnicodeError:
req_url = encode_uri(req_url)

try:
if anchor and self.app.config.linkcheck_anchors and \
not anchor.startswith('!'):
# Read the whole document and see if #anchor exists
# (Anchors starting with ! are ignored since they are
# commonly used for dynamic pages)
req = Request(req_url)
f = opener.open(req, **kwargs)
encoding = 'utf-8'
if hasattr(f.headers, 'get_content_charset'):
encoding = f.headers.get_content_charset() or encoding
else:
encoding = get_content_charset(f) or encoding
found = check_anchor(TextIOWrapper(f, encoding),
unquote(anchor))
f.close()

if not found:
raise Exception("Anchor '%s' not found" % anchor)
else:
try:
# try a HEAD request, which should be easier on
# the server and the network
req = HeadRequest(req_url)
f = opener.open(req, **kwargs)
f.close()
except HTTPError as err:
if err.code != 405:
raise
# retry with GET if that fails, some servers
# don't like HEAD requests and reply with 405
req = Request(req_url)
f = opener.open(req, **kwargs)
f.close()
except HTTPError as err:
if err.code == 401:
# We'll take "Unauthorized" as working.
return 'working', ' - unauthorized', 0
else:
return 'broken', str(err), 0
except Exception as err:
return 'broken', str(err), 0
if f.url.rstrip('/') == req_url.rstrip('/'):
return 'working', '', 0
else:
new_url = f.url
if anchor:
new_url += '#' + anchor
code = getattr(req, 'redirect_code', 0)
return 'redirected', new_url, code

def check():
# check for various conditions without bothering the network
if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'ftp:')):
return 'unchecked', '', 0
elif not uri.startswith(('http:', 'https:')):
return 'local', '', 0
elif uri in self.good:
return 'working', 'old', 0
elif uri in self.broken:
return 'broken', self.broken[uri], 0
elif uri in self.redirected:
return 'redirected', self.redirected[uri][0], self.redirected[uri][1]
for rex in self.to_ignore:
if rex.match(uri):
return 'ignored', '', 0

# need to actually check the URI
for _ in range(self.app.config.linkcheck_retries):
status, info, code = check_uri()
if status != "broken":
break

if status == "working":
self.good.add(uri)
elif status == "broken":
self.broken[uri] = info
elif status == "redirected":
self.redirected[uri] = (info, code)

return (status, info, code)

while True:
uri, docname, lineno = self.wqueue.get()
if uri is None:
break
status, info, code = check()
self.rqueue.put((uri, docname, lineno, status, info, code))

def process_result(self, result):
uri, docname, lineno, status, info, code = result
if status == 'unchecked':
return
if status == 'working' and info == 'old':
return
if lineno:
self.info('(line %4d) ' % lineno, nonl=1)
if status == 'ignored':
self.info(darkgray('-ignored- ') + uri)
elif status == 'local':
self.info(darkgray('-local-   ') + uri)
self.write_entry('local', docname, lineno, uri)
elif status == 'working':
self.info(darkgreen('ok        ')  + uri + info)
elif status == 'broken':
self.write_entry('broken', docname, lineno, uri + ': ' + info)
if self.app.quiet or self.app.warningiserror:
self.warn('broken link: %s' % uri,
'%s:%s' % (self.env.doc2path(docname), lineno))
else:
self.info(red('broken    ') + uri + red(' - ' + info))
elif status == 'redirected':
text, color = {
301: ('permanently', darkred),
302: ('with Found', purple),
303: ('with See Other', purple),
307: ('temporarily', turquoise),
0:   ('with unknown code', purple),
}[code]
self.write_entry('redirected ' + text, docname, lineno,
uri + ' to ' + info)
self.info(color('redirect  ') + uri + color(' - ' + text + ' to '  + info))

def get_target_uri(self, docname, typ=None):
return ''

def get_outdated_docs(self):
return self.env.found_docs

def prepare_writing(self, docnames):
return

def write_doc(self, docname, doctree):
self.info()
n = 0
for node in doctree.traverse(nodes.reference):
if 'refuri' not in node:
continue
uri = node['refuri']
lineno = None
while lineno is None:
node = node.parent
if node is None:
break
lineno = node.line
self.wqueue.put((uri, docname, lineno), False)
n += 1
done = 0
while done < n:
self.process_result(self.rqueue.get())
done += 1

if self.broken:
self.app.statuscode = 1

def write_entry(self, what, docname, line, uri):
output = codecs.open(path.join(self.outdir, 'output.txt'), 'a', 'utf-8')
output.write("%s:%s: [%s] %s\n" % (self.env.doc2path(docname, None),
line, what, uri))
output.close()

def finish(self):
for worker in self.workers:
self.wqueue.put((None, None, None), False)

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.manpage

# -*- coding: utf-8 -*-
"""
sphinx.builders.manpage
~~~~~~~~~~~~~~~~~~~~~~~

Manual pages builder.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

from os import path

from six import string_types
from docutils.io import FileOutput
from docutils.frontend import OptionParser

from sphinx import addnodes
from sphinx.builders import Builder
from sphinx.environment import NoUri
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.console import bold, darkgreen
from sphinx.writers.manpage import ManualPageWriter

[docs]class ManualPageBuilder(Builder):
"""
Builds groff output in manual page format.
"""
name = 'man'
format = 'man'
supported_image_types = []

def init(self):
if not self.config.man_pages:
self.warn('no "man_pages" config value found; no manual pages '
'will be written')

def get_outdated_docs(self):
return 'all manpages'  # for now

def get_target_uri(self, docname, typ=None):
if typ == 'token':
return ''
raise NoUri

def write(self, *ignored):
docwriter = ManualPageWriter(self)
docsettings = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()

self.info(bold('writing... '), nonl=True)

for info in self.config.man_pages:
docname, name, description, authors, section = info
if isinstance(authors, string_types):
if authors:
authors = [authors]
else:
authors = []

targetname = '%s.%s' % (name, section)
self.info(darkgreen(targetname) + ' { ', nonl=True)
destination = FileOutput(
destination_path=path.join(self.outdir, targetname),
encoding='utf-8')

tree = self.env.get_doctree(docname)
docnames = set()
largetree = inline_all_toctrees(self, docnames, docname, tree,
darkgreen, [docname])
self.info('} ', nonl=True)
self.env.resolve_references(largetree, docname, self)
# remove pending_xref nodes
for pendingnode in largetree.traverse(addnodes.pending_xref):
pendingnode.replace_self(pendingnode.children)

largetree.settings = docsettings
largetree.settings.title = name
largetree.settings.subtitle = description
largetree.settings.authors = authors
largetree.settings.section = section

docwriter.write(largetree, destination)
self.info()

def finish(self):
pass

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.qthelp

# -*- coding: utf-8 -*-
"""
sphinx.builders.qthelp
~~~~~~~~~~~~~~~~~~~~~~

Build input files for the Qt collection generator.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import os
import re
import codecs
import posixpath
from os import path

from six import text_type
from docutils import nodes

from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util import force_decode
from sphinx.util.pycompat import htmlescape

_idpattern = re.compile(
r'(?P<title>.+) (\((class in )?(?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 = u'''\
<?xml version="1.0" encoding="utf-8" ?>
<QHelpCollectionProject version="1.0">
<assistant>
<title>%(title)s</title>
<homePage>%(homepage)s</homePage>
<startPage>%(startpage)s</startPage>
</assistant>
<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 = u'''\
<?xml version="1.0" encoding="utf-8" ?>
<QtHelpProject version="1.0">
<namespace>%(namespace)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>'

[docs]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_qhp(self.outdir, self.config.qthelp_basename)

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)

def istoctree(node):
return isinstance(node, addnodes.compact_paragraph) and \
'toctree' in node
sections = []
for node in tocdoc.traverse(istoctree):
sections.extend(self.write_toc(node))

for indexname, indexcls, content, collapse in self.domain_indices:
item = section_template % {'title': indexcls.localname,
'ref': '%s.html' % indexname}
sections.append(' ' * 4 * 4 + item)
# sections may be unicode strings or byte strings, we have to make sure
# they are all unicode strings before joining them
new_sections = []
for section in sections:
if not isinstance(section, text_type):
new_sections.append(force_decode(section, None))
else:
new_sections.append(section)
sections = u'\n'.join(new_sections)

# keywords
keywords = []
index = self.env.create_index(self, group_entries=False)
for (key, group) in index:
for title, (refs, subitems, key_) in group:
keywords.extend(self.build_keywords(title, refs, subitems))
keywords = u'\n'.join(keywords)

# files
if not outdir.endswith(os.sep):
outdir += os.sep
olen = len(outdir)
projectfiles = []
staticdir = path.join(outdir, '_static')
imagesdir = path.join(outdir, self.imagedir)
for root, dirs, files in os.walk(outdir):
resourcedir = root.startswith(staticdir) or \
root.startswith(imagesdir)
for fn in files:
if (resourcedir and not fn.endswith('.js')) or \
fn.endswith('.html'):
filename = path.join(root, fn)[olen:]
projectfiles.append(file_template %
{'filename': htmlescape(filename)})
projectfiles = '\n'.join(projectfiles)

# it seems that the "namespace" may not contain non-alphanumeric
# characters, and more than one successive dot, or leading/trailing
# dots, are also forbidden
nspace = 'org.sphinx.%s.%s' % (outname, self.config.version)
nspace = re.sub('[^a-zA-Z0-9.]', '', nspace)
nspace = re.sub(r'\.+', '.', nspace).strip('.')
nspace = nspace.lower()

# write the project file
f = codecs.open(path.join(outdir, outname+'.qhp'), 'w', 'utf-8')
try:
f.write(project_template % {
'outname': htmlescape(outname),
'title': htmlescape(self.config.html_title),
'version': htmlescape(self.config.version),
'project': htmlescape(self.config.project),
'namespace': htmlescape(nspace),
'masterdoc': htmlescape(self.config.master_doc),
'sections': sections,
'keywords': keywords,
'files': projectfiles})
finally:
f.close()

homepage = 'qthelp://' + posixpath.join(
nspace, 'doc', self.get_target_uri(self.config.master_doc))
startpage = 'qthelp://' + posixpath.join(nspace, 'doc', 'index.html')

self.info('writing collection project file...')
f = codecs.open(path.join(outdir, outname+'.qhcp'), 'w', 'utf-8')
try:
f.write(collection_template % {
'outname': htmlescape(outname),
'title': htmlescape(self.config.html_short_title),
'homepage': htmlescape(homepage),
'startpage': htmlescape(startpage)})
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):
# XXX this should return a Unicode string, not a bytestring
parts = []
if self.isdocnode(node):
refnode = node.children[0][0]
link = refnode['refuri']
title = htmlescape(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 = htmlescape(node.astext()).replace('"', '&quot;')
item = section_template % {'title': title, 'ref': link}
item = u' ' * 4 * indentlevel + item
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 = None

if id:
item = ' '*12 + '<keyword name="%s" id="%s" ref="%s"/>' % (
name, id, ref[1])
else:
item = ' '*12 + '<keyword name="%s" ref="%s"/>' % (name, ref[1])
item.encode('ascii', 'xmlcharrefreplace')
return item

def build_keywords(self, title, refs, subitems):
keywords = []

title = htmlescape(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

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.texinfo

# -*- coding: utf-8 -*-
"""
sphinx.builders.texinfo
~~~~~~~~~~~~~~~~~~~~~~~

Texinfo builder.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

from os import path

from six import iteritems
from docutils import nodes
from docutils.io import FileOutput
from docutils.utils import new_document
from docutils.frontend import OptionParser

from sphinx import addnodes
from sphinx.locale import _
from sphinx.builders import Builder
from sphinx.environment import NoUri
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import SEP, copyfile
from sphinx.util.console import bold, darkgreen
from sphinx.writers.texinfo import TexinfoWriter

TEXINFO_MAKEFILE = '''\
# Makefile for Sphinx Texinfo output

infodir ?= /usr/share/info

MAKEINFO = makeinfo --no-split
MAKEINFO_html = makeinfo --no-split --html
MAKEINFO_plaintext = makeinfo --no-split --plaintext
TEXI2PDF = texi2pdf --batch --expand
INSTALL_INFO = install-info

ALLDOCS = $(basename $(wildcard *.texi))

all: info
info: $(addsuffix .info,$(ALLDOCS))
plaintext: $(addsuffix .txt,$(ALLDOCS))
html: $(addsuffix .html,$(ALLDOCS))
pdf: $(addsuffix .pdf,$(ALLDOCS))

install-info: info
\tfor f in *.info; do \\
\t  cp -t $(infodir) "$$f" && \\
\t  $(INSTALL_INFO) --info-dir=$(infodir) "$$f" ; \\
\tdone

uninstall-info: info
\tfor f in *.info; do \\
\t  rm -f "$(infodir)/$$f"  ; \\
\t  $(INSTALL_INFO) --delete --info-dir=$(infodir) "$$f" ; \\
\tdone

%.info: %.texi
\t$(MAKEINFO) -o '$@' '$<'

%.txt: %.texi
\t$(MAKEINFO_plaintext) -o '$@' '$<'

%.html: %.texi
\t$(MAKEINFO_html) -o '$@' '$<'

%.pdf: %.texi
\t-$(TEXI2PDF) '$<'
\t-$(TEXI2PDF) '$<'
\t-$(TEXI2PDF) '$<'

clean:
\trm -f *.info *.pdf *.txt *.html
\trm -f *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla *.ky *.pg
\trm -f *.vr *.tp *.fn *.fns *.def *.defs *.cp *.cps *.ge *.ges *.mo

.PHONY: all info plaintext html pdf install-info uninstall-info clean
'''

[docs]class TexinfoBuilder(Builder):
"""
Builds Texinfo output to create Info documentation.
"""
name = 'texinfo'
format = 'texinfo'
supported_image_types = ['image/png', 'image/jpeg',
'image/gif']

def init(self):
self.docnames = []
self.document_data = []

def get_outdated_docs(self):
return 'all documents'  # for now

def get_target_uri(self, docname, typ=None):
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 = [list(x) for x in self.config.texinfo_documents]
if not preliminary_document_data:
self.warn('no "texinfo_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('"texinfo_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):
self.init_document_data()
for entry in self.document_data:
docname, targetname, title, author = entry[:4]
targetname += '.texi'
direntry = description = category = ''
if len(entry) > 6:
direntry, description, category = entry[4:7]
toctree_only = False
if len(entry) > 7:
toctree_only = entry[7]
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=(self.config.texinfo_appendices or []))
self.info("writing... ", nonl=1)
self.post_process_images(doctree)
docwriter = TexinfoWriter(self)
settings = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()
settings.author = author
settings.title = title
settings.texinfo_filename = targetname[:-5] + '.info'
settings.texinfo_elements = self.config.texinfo_elements
settings.texinfo_dir_entry = direntry or ''
settings.texinfo_dir_category = category or ''
settings.texinfo_dir_description = description or ''
settings.docname = docname
doctree.settings = settings
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)
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('<texinfo 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 = inline_all_toctrees(self, self.docnames, indexfile, tree,
darkgreen, [indexfile])
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)
# TODO: add support for external :ref:s
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 iteritems(self.images):
self.info(' '+src, nonl=1)
copyfile(path.join(self.srcdir, src),
path.join(self.outdir, dest))
self.info()

self.info(bold('copying Texinfo support files... '), nonl=True)
# copy Makefile
fn = path.join(self.outdir, 'Makefile')
self.info(fn, nonl=1)
try:
mkfile = open(fn, 'w')
try:
mkfile.write(TEXINFO_MAKEFILE)
finally:
mkfile.close()
except (IOError, OSError) as err:
self.warn("error writing file %s: %s" % (fn, err))
self.info(' done')

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.text

# -*- coding: utf-8 -*-
"""
sphinx.builders.text
~~~~~~~~~~~~~~~~~~~~

Plain-text Sphinx builder.

:copyright: Copyright 2007-2016 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.builders import Builder
from sphinx.util.osutil import ensuredir, os_path
from sphinx.writers.text import TextWriter

[docs]class TextBuilder(Builder):
name = 'text'
format = 'text'
out_suffix = '.txt'
allow_parallel = True

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):
self.current_docname = docname
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) as err:
self.warn("error writing file %s: %s" % (outfilename, err))

def finish(self):
pass

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.builders »

Source code for sphinx.builders.xml

# -*- coding: utf-8 -*-
"""
sphinx.builders.xml
~~~~~~~~~~~~~~~~~~~

Docutils-native XML and pseudo-XML builders.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import codecs
from os import path

from docutils import nodes
from docutils.io import StringOutput

from sphinx.builders import Builder
from sphinx.util.osutil import ensuredir, os_path
from sphinx.writers.xml import XMLWriter, PseudoXMLWriter

[docs]class XMLBuilder(Builder):
"""
Builds Docutils-native XML.
"""
name = 'xml'
format = 'xml'
out_suffix = '.xml'
allow_parallel = True

_writer_class = XMLWriter

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 docname

def prepare_writing(self, docnames):
self.writer = self._writer_class(self)

def write_doc(self, docname, doctree):
# work around multiple string % tuple issues in docutils;
# replace tuples in attribute values with lists
doctree = doctree.deepcopy()
for node in doctree.traverse(nodes.Element):
for att, value in node.attributes.items():
if isinstance(value, tuple):
node.attributes[att] = list(value)
value = node.attributes[att]
if isinstance(value, list):
for i, val in enumerate(value):
if isinstance(val, tuple):
value[i] = list(val)
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) as err:
self.warn("error writing file %s: %s" % (outfilename, err))

def finish(self):
pass

[docs]class PseudoXMLBuilder(XMLBuilder):
"""
Builds pseudo-XML for display purposes.
"""
name = 'pseudoxml'
format = 'pseudoxml'
out_suffix = '.pseudoxml'

_writer_class = PseudoXMLWriter

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.config

# -*- coding: utf-8 -*-
"""
sphinx.config
~~~~~~~~~~~~~

Build configuration file handling.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import re
from os import path, environ, getenv
import shlex

from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types

from sphinx.errors import ConfigError
from sphinx.locale import l_
from sphinx.util.osutil import make_filename, cd
from sphinx.util.pycompat import execfile_, NoneType
from sphinx.util.i18n import format_date

nonascii_re = re.compile(br'[\x80-\xff]')
copyright_year_re = re.compile(r'^((\d{4}-)?)(\d{4})(?=[ ,])')

CONFIG_SYNTAX_ERROR = "There is a syntax error in your configuration file: %s"
if PY3:
CONFIG_SYNTAX_ERROR += "\nDid you change the syntax from 2.x to 3.x?"
CONFIG_EXIT_ERROR = "The configuration file (or one of the modules it imports) " \
"called sys.exit()"
CONFIG_TYPE_WARNING = "The config value `{name}' has type `{current.__name__}', " \
"defaults to `{default.__name__}.'"

string_classes = [text_type]
if PY2:
string_classes.append(binary_type)  # => [str, unicode]

[docs]class Config(object):
"""
Configuration file abstraction.
"""

# 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', 'env'),
copyright = ('', 'html'),
version = ('', 'env'),
release = ('', 'env'),
today = ('', 'env'),
# the real default is locale-dependent
today_fmt = (None, 'env', string_classes),

language = (None, 'env', string_classes),
locale_dirs = ([], 'env'),
figure_language_filename = (u'{root}.{language}{ext}', 'env', [str]),

master_doc = ('contents', 'env'),
source_suffix = (['.rst'], 'env'),
source_encoding = ('utf-8-sig', 'env'),
source_parsers = ({}, 'env'),
exclude_patterns = ([], 'env'),
default_role = (None, 'env', string_classes),
add_function_parentheses = (True, 'env'),
add_module_names = (True, 'env'),
trim_footnote_reference_space = (False, 'env'),
show_authors = (False, 'env'),
pygments_style = (None, 'html', string_classes),
highlight_language = ('default', 'env'),
highlight_options = ({}, 'env'),
templates_path = ([], 'html'),
template_bridge = (None, 'html', string_classes),
keep_warnings = (False, 'env'),
suppress_warnings = ([], 'env'),
modindex_common_prefix = ([], 'html'),
rst_epilog = (None, 'env', string_classes),
rst_prolog = (None, 'env', string_classes),
trim_doctest_flags = (True, 'env'),
primary_domain = ('py', 'env', [NoneType]),
needs_sphinx = (None, None, string_classes),
needs_extensions = ({}, None),
nitpicky = (False, 'env'),
nitpick_ignore = ([], 'html'),
numfig = (False, 'env'),
numfig_secnum_depth = (1, 'env'),
numfig_format = ({'figure': l_('Fig. %s'),
'table': l_('Table %s'),
'code-block': l_('Listing %s')},
'env'),

# HTML options
html_theme = ('alabaster', 'html'),
html_theme_path = ([], 'html'),
html_theme_options = ({}, 'html'),
html_title = (lambda self: l_('%s %s documentation') %
(self.project, self.release),
'html', string_classes),
html_short_title = (lambda self: self.html_title, 'html'),
html_style = (None, 'html', string_classes),
html_logo = (None, 'html', string_classes),
html_favicon = (None, 'html', string_classes),
html_static_path = ([], 'html'),
html_extra_path = ([], 'html'),
# the real default is locale-dependent
html_last_updated_fmt = (None, 'html', string_classes),
html_use_smartypants = (True, 'html'),
html_translator_class = (None, 'html', string_classes),
html_sidebars = ({}, 'html'),
html_additional_pages = ({}, 'html'),
html_use_modindex = (True, 'html'),  # deprecated
html_domain_indices = (True, 'html', [list]),
html_add_permalinks = (u'\u00B6', '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', string_classes),
html_link_suffix = (None, 'html', string_classes),
html_show_copyright = (True, 'html'),
html_show_sphinx = (True, 'html'),
html_context = ({}, 'html'),
html_output_encoding = ('utf-8', 'html'),
html_compact_lists = (True, 'html'),
html_secnumber_suffix = ('. ', 'html'),
html_search_language = (None, 'html', string_classes),
html_search_options = ({}, 'html'),
html_search_scorer = ('', None),
html_scaled_image_link = (True, 'html'),

# HTML help only options
htmlhelp_basename = (lambda self: make_filename(self.project), None),

# Qt help only options
qthelp_basename = (lambda self: make_filename(self.project), None),

# Devhelp only options
devhelp_basename = (lambda self: make_filename(self.project), None),

# Apple help options
applehelp_bundle_name = (lambda self: make_filename(self.project),
'applehelp'),
applehelp_bundle_id = (None, 'applehelp', string_classes),
applehelp_dev_region = ('en-us', 'applehelp'),
applehelp_bundle_version = ('1', 'applehelp'),
applehelp_icon = (None, 'applehelp', string_classes),
applehelp_kb_product = (lambda self: '%s-%s' %
(make_filename(self.project), self.release),
'applehelp'),
applehelp_kb_url = (None, 'applehelp', string_classes),
applehelp_remote_url = (None, 'applehelp', string_classes),
applehelp_index_anchors = (False, 'applehelp', string_classes),
applehelp_min_term_length = (None, 'applehelp', string_classes),
applehelp_stopwords = (lambda self: self.language or 'en', 'applehelp'),
applehelp_locale = (lambda self: self.language or 'en', 'applehelp'),
applehelp_title = (lambda self: self.project + ' Help', 'applehelp'),
applehelp_codesign_identity = (lambda self:
environ.get('CODE_SIGN_IDENTITY', None),
'applehelp'),
applehelp_codesign_flags = (lambda self:
shlex.split(
environ.get('OTHER_CODE_SIGN_FLAGS',
'')),
'applehelp'),
applehelp_indexer_path = ('/usr/bin/hiutil', 'applehelp'),
applehelp_codesign_path = ('/usr/bin/codesign', 'applehelp'),
applehelp_disable_external_tools = (False, None),

# Epub options
epub_basename = (lambda self: make_filename(self.project), None),
epub_theme = ('epub', 'html'),
epub_theme_options = ({}, 'html'),
epub_title = (lambda self: self.html_title, 'html'),
epub3_description = ('', 'epub3', string_classes),
epub_author = ('unknown', 'html'),
epub3_contributor = ('unknown', 'epub3', string_classes),
epub_language = (lambda self: self.language or 'en', 'html'),
epub_publisher = ('unknown', 'html'),
epub_copyright = (lambda self: self.copyright, 'html'),
epub_identifier = ('unknown', 'html'),
epub_scheme = ('unknown', 'html'),
epub_uid = ('unknown', 'env'),
epub_cover = ((), 'env'),
epub_guide = ((), 'env'),
epub_pre_files = ([], 'env'),
epub_post_files = ([], 'env'),
epub_exclude_files = ([], 'env'),
epub_tocdepth = (3, 'env'),
epub_tocdup = (True, 'env'),
epub_tocscope = ('default', 'env'),
epub_fix_images = (False, 'env'),
epub_max_image_width = (0, 'env'),
epub_show_urls = ('inline', 'html'),
epub_use_index = (lambda self: self.html_use_index, 'html'),
epub3_page_progression_direction = ('ltr', 'epub3', string_classes),

# LaTeX options
latex_documents = (lambda self: [(self.master_doc,
make_filename(self.project) + '.tex',
self.project,
'', 'manual')],
None),
latex_logo = (None, None, string_classes),
latex_appendices = ([], None),
# now deprecated - use latex_toplevel_sectioning
latex_use_parts = (False, None),
latex_toplevel_sectioning = (None, None, [str]),
latex_use_modindex = (True, None),  # deprecated
latex_domain_indices = (True, None, [list]),
latex_show_urls = ('no', None),
latex_show_pagerefs = (False, 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', None),
latex_font_size = ('10pt', None),
latex_elements = ({}, None),
latex_additional_files = ([], None),
latex_docclass = ({}, None),
# now deprecated - use latex_elements
latex_preamble = ('', None),

# text options
text_sectionchars = ('*=-~"+`', 'env'),
text_newlines = ('unix', 'env'),

# manpage options
man_pages = (lambda self: [(self.master_doc,
make_filename(self.project).lower(),
'%s %s' % (self.project, self.release),
[], 1)],
None),
man_show_urls = (False, None),

# Texinfo options
texinfo_documents = (lambda self: [(self.master_doc,
make_filename(self.project).lower(),
self.project, '',
make_filename(self.project),
'The %s reference manual.' %
make_filename(self.project),
'Python')],
None),
texinfo_appendices = ([], None),
texinfo_elements = ({}, None),
texinfo_domain_indices = (True, None, [list]),
texinfo_show_urls = ('footnote', None),
texinfo_no_detailmenu = (False, None),

# linkcheck options
linkcheck_ignore = ([], None),
linkcheck_retries = (1, None),
linkcheck_timeout = (None, None, [int]),
linkcheck_workers = (5, None),
linkcheck_anchors = (True, None),

# gettext options
gettext_compact = (True, 'gettext'),
gettext_location = (True, 'gettext'),
gettext_uuid = (False, 'gettext'),
gettext_auto_build = (True, 'env'),
gettext_additional_targets = ([], 'env'),

# XML options
xml_pretty = (True, 'env'),
)

def __init__(self, dirname, filename, overrides, tags):
self.overrides = overrides
self.values = Config.config_values.copy()
config = {}
if 'extensions' in overrides:  # XXX do we need this?
if isinstance(overrides['extensions'], string_types):
config['extensions'] = overrides.pop('extensions').split(',')
else:
config['extensions'] = overrides.pop('extensions')
if dirname is not None:
config_file = path.join(dirname, filename)
config['__file__'] = config_file
config['tags'] = tags
with cd(dirname):
# we promise to have the config dir as current dir while the
# config file is executed
try:
execfile_(filename, config)
except SyntaxError as err:
raise ConfigError(CONFIG_SYNTAX_ERROR % err)
except SystemExit:
raise ConfigError(CONFIG_EXIT_ERROR)

self._raw_config = config
# these two must be preinitialized because extensions can add their
# own config values
self.setup = config.get('setup', None)
self.extensions = config.get('extensions', [])

# correct values of copyright year that are not coherent with
# the SOURCE_DATE_EPOCH environment variable (if set)
# See https://reproducible-builds.org/specs/source-date-epoch/
if getenv('SOURCE_DATE_EPOCH') is not None:
for k in ('copyright', 'epub_copyright'):
if k in config:
config[k] = copyright_year_re.sub('\g<1>%s' % format_date('%Y'),
config[k])

def check_types(self, warn):
# check all values for deviation from the default value's type, since
# that can result in TypeErrors all over the place
# NB. since config values might use l_() we have to wait with calling
# this method until i18n is initialized
for name in self._raw_config:
if name not in self.values:
continue  # we don't know a default value
settings = self.values[name]
default, dummy_rebuild = settings[:2]
permitted = settings[2] if len(settings) == 3 else ()

if hasattr(default, '__call__'):
default = default(self)  # could invoke l_()
if default is None and not permitted:
continue  # neither inferrable nor expliclitly permitted types
current = self[name]
if type(current) is type(default):
continue
if type(current) in permitted:
continue

common_bases = (set(type(current).__bases__ + (type(current),)) &
set(type(default).__bases__))
common_bases.discard(object)
if common_bases:
continue  # at least we share a non-trivial base class

warn(CONFIG_TYPE_WARNING.format(
name=name, current=type(current), default=type(default)))

def check_unicode(self, warn):
# check all string values for non-ASCII characters in bytestrings,
# since that can result in UnicodeErrors all over the place
for name, value in iteritems(self._raw_config):
if isinstance(value, binary_type) and nonascii_re.search(value):
warn('the config value %r is set to a string with non-ASCII '
'characters; this can lead to Unicode errors occurring. '
'Please use Unicode strings, e.g. %r.' % (name, u'Content'))

def convert_overrides(self, name, value):
if not isinstance(value, string_types):
return value
else:
defvalue = self.values[name][0]
if isinstance(defvalue, dict):
raise ValueError('cannot override dictionary config setting %r, '
'ignoring (use %r to set individual elements)' %
(name, name + '.key=value'))
elif isinstance(defvalue, list):
return value.split(',')
elif isinstance(defvalue, integer_types):
try:
return int(value)
except ValueError:
raise ValueError('invalid number %r for config value %r, ignoring' %
(value, name))
elif hasattr(defvalue, '__call__'):
return value
elif defvalue is not None and not isinstance(defvalue, string_types):
raise ValueError('cannot override config setting %r with unsupported '
'type, ignoring' % name)
else:
return value

def pre_init_values(self, warn):
"""Initialize some limited config variables before loading extensions"""
variables = ['needs_sphinx', 'suppress_warnings']
for name in variables:
try:
if name in self.overrides:
self.__dict__[name] = self.convert_overrides(name, self.overrides[name])
elif name in self._raw_config:
self.__dict__[name] = self._raw_config[name]
except ValueError as exc:
warn(exc)

def init_values(self, warn):
config = self._raw_config
for valname, value in iteritems(self.overrides):
try:
if '.' in valname:
realvalname, key = valname.split('.', 1)
config.setdefault(realvalname, {})[key] = value
continue
elif valname not in self.values:
warn('unknown config value %r in override, ignoring' % valname)
continue
if isinstance(value, string_types):
config[valname] = self.convert_overrides(valname, value)
else:
config[valname] = value
except ValueError as exc:
warn(exc)
for name in config:
if name in self.values:
self.__dict__[name] = config[name]
if isinstance(self.source_suffix, string_types):
self.source_suffix = [self.source_suffix]

def __getattr__(self, name):
if name.startswith('_'):
raise AttributeError(name)
if name not in self.values:
raise AttributeError('No such config value: %s' % name)
default = self.values[name][0]
if hasattr(default, '__call__'):
return default(self)
return default

def __getitem__(self, name):
return getattr(self, name)

def __setitem__(self, name, value):
setattr(self, name, value)

def __delitem__(self, name):
delattr(self, name)

def __contains__(self, name):
return name in self.values

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.domains

# -*- coding: utf-8 -*-
"""
sphinx.domains
~~~~~~~~~~~~~~

Support for domains, which are groupings of description directives
and roles describing e.g. constructs of one programming language.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

from six import iteritems

from sphinx.errors import SphinxError
from sphinx.locale import _

[docs]class ObjType(object):
"""
An ObjType is the description for a type of object that a domain can
document.  In the object_types attribute of Domain subclasses, object type
names are mapped to instances of this class.

Constructor arguments:

- *lname*: localized name of the type (do not include domain name)
- *roles*: all the roles that can refer to an object of this type
- *attrs*: object attributes -- currently only "searchprio" is known,
which defines the object's priority in the full-text search index,
see :meth:`Domain.get_objects()`.
"""

known_attrs = {
'searchprio': 1,
}

def __init__(self, lname, *roles, **attrs):
self.lname = lname
self.roles = roles
self.attrs = self.known_attrs.copy()
self.attrs.update(attrs)

[docs]class Index(object):
"""
An Index is the description for a domain-specific index.  To add an index to
a domain, subclass Index, overriding the three name attributes:

* `name` is an identifier used for generating file names.
* `localname` is the section title for the index.
* `shortname` is a short name for the index, for use in the relation bar in
HTML output.  Can be empty to disable entries in the relation bar.

and providing a :meth:`generate()` method.  Then, add the index class to
your domain's `indices` list.  Extensions can add indices to existing
domains using :meth:`~sphinx.application.Sphinx.add_index_to_domain()`.
"""

name = None
localname = None
shortname = None

def __init__(self, domain):
if self.name is None or self.localname is None:
raise SphinxError('Index subclass %s has no valid name or localname'
% self.__class__.__name__)
self.domain = domain

[docs]    def generate(self, docnames=None):
"""Return entries for the index given by *name*.  If *docnames* is
given, restrict to entries referring to these docnames.

The return value is a tuple of ``(content, collapse)``, where *collapse*
is a boolean that determines if sub-entries should start collapsed (for
output formats that support collapsing sub-entries).

*content* is a sequence of ``(letter, entries)`` tuples, where *letter*
is the "heading" for the given *entries*, usually the starting letter.

*entries* is a sequence of single entries, where a single entry is a
sequence ``[name, subtype, docname, anchor, extra, qualifier, descr]``.
The items in this sequence have the following meaning:

- `name` -- the name of the index entry to be displayed
- `subtype` -- sub-entry related type:
0 -- normal entry
1 -- entry with sub-entries
2 -- sub-entry
- `docname` -- docname where the entry is located
- `anchor` -- anchor for the entry within `docname`
- `extra` -- extra info for the entry
- `qualifier` -- qualifier for the description
- `descr` -- description for the entry

Qualifier and description are not rendered e.g. in LaTeX output.
"""
return []

[docs]class Domain(object):
"""
A Domain is meant to be a group of "object" description directives for
objects of a similar nature, and corresponding roles to create references to
them.  Examples would be Python modules, classes, functions etc., elements
of a templating language, Sphinx roles and directives, etc.

Each domain has a separate storage for information about existing objects
and how to reference them in `self.data`, which must be a dictionary.  It
also must implement several functions that expose the object information in
a uniform way to parts of Sphinx that allow the user to reference or search
for objects in a domain-agnostic way.

About `self.data`: since all object and cross-referencing information is
stored on a BuildEnvironment instance, the `domain.data` object is also
stored in the `env.domaindata` dict under the key `domain.name`.  Before the
build process starts, every active domain is instantiated and given the
environment object; the `domaindata` dict must then either be nonexistent or
a dictionary whose 'version' key is equal to the domain class'
:attr:`data_version` attribute.  Otherwise, `IOError` is raised and the
pickled environment is discarded.
"""

#: domain name: should be short, but unique
name = ''
#: domain label: longer, more descriptive (used in messages)
label = ''
#: type (usually directive) name -> ObjType instance
object_types = {}
#: directive name -> directive class
directives = {}
#: role name -> role callable
roles = {}
#: a list of Index subclasses
indices = []
#: role name -> a warning message if reference is missing
dangling_warnings = {}

#: data value for a fresh environment
initial_data = {}
#: data version, bump this when the format of `self.data` changes
data_version = 0

def __init__(self, env):
self.env = env
if self.name not in env.domaindata:
assert isinstance(self.initial_data, dict)
new_data = self.initial_data.copy()
new_data['version'] = self.data_version
self.data = env.domaindata[self.name] = new_data
else:
self.data = env.domaindata[self.name]
if self.data['version'] != self.data_version:
raise IOError('data of %r domain out of date' % self.label)
self._role_cache = {}
self._directive_cache = {}
self._role2type = {}
self._type2role = {}
for name, obj in iteritems(self.object_types):
for rolename in obj.roles:
self._role2type.setdefault(rolename, []).append(name)
self._type2role[name] = obj.roles[0] if obj.roles else ''
self.objtypes_for_role = self._role2type.get
self.role_for_objtype = self._type2role.get

[docs]    def role(self, name):
"""Return a role adapter function that always gives the registered
role its full name ('domain:name') as the first argument.
"""
if name in self._role_cache:
return self._role_cache[name]
if name not in self.roles:
return None
fullname = '%s:%s' % (self.name, name)

def role_adapter(typ, rawtext, text, lineno, inliner,
options={}, content=[]):
return self.roles[name](fullname, rawtext, text, lineno,
inliner, options, content)
self._role_cache[name] = role_adapter
return role_adapter

[docs]    def directive(self, name):
"""Return a directive adapter class that always gives the registered
directive its full name ('domain:name') as ``self.name``.
"""
if name in self._directive_cache:
return self._directive_cache[name]
if name not in self.directives:
return None
fullname = '%s:%s' % (self.name, name)
BaseDirective = self.directives[name]

class DirectiveAdapter(BaseDirective):
def run(self):
self.name = fullname
return BaseDirective.run(self)
self._directive_cache[name] = DirectiveAdapter
return DirectiveAdapter

# methods that should be overwritten

[docs]    def clear_doc(self, docname):
"""Remove traces of a document in the domain-specific inventories."""
pass

[docs]    def merge_domaindata(self, docnames, otherdata):
"""Merge in data regarding *docnames* from a different domaindata
inventory (coming from a subprocess in parallel builds).
"""
raise NotImplementedError('merge_domaindata must be implemented in %s '
'to be able to do parallel builds!' %
self.__class__)

[docs]    def process_doc(self, env, docname, document):
"""Process a document after it is read by the environment."""
pass

[docs]    def resolve_xref(self, env, fromdocname, builder,
typ, target, node, contnode):
"""Resolve the pending_xref *node* with the given *typ* and *target*.

This method should return a new node, to replace the xref node,
containing the *contnode* which is the markup content of the
cross-reference.

If no resolution can be found, None can be returned; the xref node will
then given to the 'missing-reference' event, and if that yields no
resolution, replaced by *contnode*.

The method can also raise :exc:`sphinx.environment.NoUri` to suppress
the 'missing-reference' event being emitted.
"""
pass

[docs]    def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode):
"""Resolve the pending_xref *node* with the given *target*.

The reference comes from an "any" or similar role, which means that we
don't know the type.  Otherwise, the arguments are the same as for
:meth:`resolve_xref`.

The method must return a list (potentially empty) of tuples
``('domain:role', newnode)``, where ``'domain:role'`` is the name of a
role that could have created the same reference, e.g. ``'py:func'``.
``newnode`` is what :meth:`resolve_xref` would return.

.. versionadded:: 1.3
"""
raise NotImplementedError

[docs]    def get_objects(self):
"""Return an iterable of "object descriptions", which are tuples with
five items:

* `name`     -- fully qualified name
* `dispname` -- name to display when searching/linking
* `type`     -- object type, a key in ``self.object_types``
* `docname`  -- the document where it is to be found
* `anchor`   -- the anchor name for the object
* `priority` -- how "important" the object is (determines placement
in search results)

- 1: default priority (placed before full-text matches)
- 0: object is important (placed before default-priority objects)
- 2: object is unimportant (placed after full-text matches)
- -1: object should not show up in search at all
"""
return []

[docs]    def get_type_name(self, type, primary=False):
"""Return full name for given ObjType."""
if primary:
return type.lname
return _('%s %s') % (self.label, type.lname)

from sphinx.domains.c import CDomain                     # noqa
from sphinx.domains.cpp import CPPDomain                 # noqa
from sphinx.domains.std import StandardDomain            # noqa
from sphinx.domains.python import PythonDomain           # noqa
from sphinx.domains.javascript import JavaScriptDomain   # noqa
from sphinx.domains.rst import ReSTDomain                # noqa

BUILTIN_DOMAINS = {
'std': StandardDomain,
'py': PythonDomain,
'c': CDomain,
'cpp': CPPDomain,
'js': JavaScriptDomain,
'rst': ReSTDomain,
}

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.environment

# -*- coding: utf-8 -*-
"""
sphinx.environment
~~~~~~~~~~~~~~~~~~

Global creation environment.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import re
import os
import sys
import time
import types
import bisect
import codecs
import string
import unicodedata
from os import path
from glob import glob
from itertools import groupby

from six import iteritems, itervalues, text_type, class_types, next
from six.moves import cPickle as pickle
from docutils import nodes
from docutils.io import NullOutput
from docutils.core import Publisher
from docutils.utils import Reporter, relative_path, get_source_line
from docutils.parsers.rst import roles, directives
from docutils.parsers.rst.languages import en as english
from docutils.parsers.rst.directives.html import MetaBody
from docutils.frontend import OptionParser

from sphinx import addnodes
from sphinx.io import SphinxStandaloneReader, SphinxDummyWriter, SphinxFileInput
from sphinx.util import url_re, get_matching_docs, docname_join, split_into, \
FilenameUniqDict, split_index_msg
from sphinx.util.nodes import clean_astext, make_refnode, WarningStream, is_translatable
from sphinx.util.osutil import SEP, getcwd, fs_encoding, ensuredir
from sphinx.util.images import guess_mimetype
from sphinx.util.i18n import find_catalog_files, get_image_filename_for_language, \
search_image_for_language
from sphinx.util.console import bold, purple
from sphinx.util.matching import compile_matchers
from sphinx.util.parallel import ParallelTasks, parallel_available, make_chunks
from sphinx.util.websupport import is_commentable
from sphinx.errors import SphinxError, ExtensionError
from sphinx.locale import _
from sphinx.versioning import add_uids, merge_doctrees
from sphinx.transforms import SphinxContentsFilter

orig_role_function = roles.role
orig_directive_function = directives.directive

class ElementLookupError(Exception):
pass

default_settings = {
'embed_stylesheet': False,
'cloak_email_addresses': True,
'pep_base_url': 'https://www.python.org/dev/peps/',
'rfc_base_url': 'https://tools.ietf.org/html/',
'input_encoding': 'utf-8-sig',
'doctitle_xform': False,
'sectsubtitle_xform': False,
'halt_level': 5,
'file_insertion_enabled': True,
}

# This is increased every time an environment attribute is added
# or changed to properly invalidate pickle files.
#
# NOTE: increase base version by 2 to have distinct numbers for Py2 and 3
ENV_VERSION = 48 + (sys.version_info[0] - 2)

dummy_reporter = Reporter('', 4, 4)

versioning_conditions = {
'none': False,
'text': is_translatable,
'commentable': is_commentable,
}

class NoUri(Exception):
"""Raised by get_relative_uri if there is no URI available."""
pass

[docs]class BuildEnvironment:
"""
The environment in which the ReST files are translated.
Stores an inventory of cross-file targets and provides doctree
transformations to resolve links to them.
"""

# --------- ENVIRONMENT PERSISTENCE ----------------------------------------

@staticmethod
def frompickle(srcdir, config, filename):
picklefile = open(filename, 'rb')
try:
env = pickle.load(picklefile)
finally:
picklefile.close()
if env.version != ENV_VERSION:
raise IOError('build environment version not current')
if env.srcdir != srcdir:
raise IOError('source directory has changed')
env.config.values = config.values
return env

def topickle(self, filename):
# remove unpicklable attributes
warnfunc = self._warnfunc
self.set_warnfunc(None)
values = self.config.values
del self.config.values
domains = self.domains
del self.domains
picklefile = open(filename, 'wb')
# remove potentially pickling-problematic values from config
for key, val in list(vars(self.config).items()):
if key.startswith('_') or \
isinstance(val, types.ModuleType) or \
isinstance(val, types.FunctionType) or \
isinstance(val, class_types):
del self.config[key]
try:
pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)
finally:
picklefile.close()
# reset attributes
self.domains = domains
self.config.values = values
self.set_warnfunc(warnfunc)

# --------- ENVIRONMENT INITIALIZATION -------------------------------------

def __init__(self, srcdir, doctreedir, config):
self.doctreedir = doctreedir
self.srcdir = srcdir
self.config = config

# the method of doctree versioning; see set_versioning_method
self.versioning_condition = None
self.versioning_compare = None

# the application object; only set while update() runs
self.app = None

# all the registered domains, set by the application
self.domains = {}

# the docutils settings for building
self.settings = default_settings.copy()
self.settings['env'] = self

# the function to write warning messages with
self._warnfunc = None

# this is to invalidate old pickles
self.version = ENV_VERSION

# All "docnames" here are /-separated and relative and exclude
# the source suffix.

self.found_docs = set()     # contains all existing docnames
self.all_docs = {}          # docname -> mtime at the time of reading
# contains all read docnames
self.dependencies = {}      # docname -> set of dependent file
# names, relative to documentation root
self.reread_always = set()  # docnames to re-read unconditionally on
# next build

# File metadata
self.metadata = {}          # docname -> dict of metadata items

# TOC inventory
self.titles = {}            # docname -> title node
self.longtitles = {}        # docname -> title node; only different if
# set differently with title directive
self.tocs = {}              # docname -> table of contents nodetree
self.toc_num_entries = {}   # docname -> number of real entries
# used to determine when to show the TOC
# in a sidebar (don't show if it's only one item)
self.toc_secnumbers = {}    # docname -> dict of sectionid -> number
self.toc_fignumbers = {}    # docname -> dict of figtype ->
# dict of figureid -> number

self.toctree_includes = {}  # docname -> list of toctree includefiles
self.files_to_rebuild = {}  # docname -> set of files
# (containing its TOCs) to rebuild too
self.glob_toctrees = set()  # docnames that have :glob: toctrees
self.numbered_toctrees = set()  # docnames that have :numbered: toctrees

# domain-specific inventories, here to be pickled
self.domaindata = {}        # domainname -> domain-specific dict

# Other inventories
self.citations = {}         # citation name -> docname, labelid
self.indexentries = {}      # docname -> list of
# (type, string, target, aliasname)
self.versionchanges = {}    # version -> list of (type, docname,
# lineno, module, descname, content)

# these map absolute path -> (docnames, unique filename)
self.images = FilenameUniqDict()
self.dlfiles = FilenameUniqDict()

# temporary data storage while reading a document
self.temp_data = {}
# context for cross-references (e.g. current module or class)
# this is similar to temp_data, but will for example be copied to
# attributes of "any" cross references
self.ref_context = {}

def set_warnfunc(self, func):
self._warnfunc = func
self.settings['warning_stream'] = WarningStream(func)

def set_versioning_method(self, method, compare):
"""This sets the doctree versioning method for this environment.

Versioning methods are a builder property; only builders with the same
versioning method can share the same doctree directory.  Therefore, we
raise an exception if the user tries to use an environment with an
incompatible versioning method.
"""
if method not in versioning_conditions:
raise ValueError('invalid versioning method: %r' % method)
condition = versioning_conditions[method]
if self.versioning_condition not in (None, condition):
raise SphinxError('This environment is incompatible with the '
'selected builder, please choose another '
'doctree directory.')
self.versioning_condition = condition
self.versioning_compare = compare

[docs]    def warn(self, docname, msg, lineno=None, **kwargs):
"""Emit a warning.

This differs from using ``app.warn()`` in that the warning may not
be emitted instantly, but collected for emitting all warnings after
the update of the environment.
"""
# strange argument order is due to backwards compatibility
self._warnfunc(msg, (docname, lineno), **kwargs)

[docs]    def warn_node(self, msg, node, **kwargs):
"""Like :meth:`warn`, but with source information taken from *node*."""
self._warnfunc(msg, '%s:%s' % get_source_line(node), **kwargs)

def clear_doc(self, docname):
"""Remove all traces of a source file in the inventory."""
if docname in self.all_docs:
self.all_docs.pop(docname, None)
self.reread_always.discard(docname)
self.metadata.pop(docname, None)
self.dependencies.pop(docname, None)
self.titles.pop(docname, None)
self.longtitles.pop(docname, None)
self.tocs.pop(docname, None)
self.toc_secnumbers.pop(docname, None)
self.toc_fignumbers.pop(docname, None)
self.toc_num_entries.pop(docname, None)
self.toctree_includes.pop(docname, None)
self.indexentries.pop(docname, None)
self.glob_toctrees.discard(docname)
self.numbered_toctrees.discard(docname)
self.images.purge_doc(docname)
self.dlfiles.purge_doc(docname)

for subfn, fnset in list(self.files_to_rebuild.items()):
fnset.discard(docname)
if not fnset:
del self.files_to_rebuild[subfn]
for key, (fn, _ignore) in list(self.citations.items()):
if fn == docname:
del self.citations[key]
for version, changes in self.versionchanges.items():
new = [change for change in changes if change[1] != docname]
changes[:] = new

for domain in self.domains.values():
domain.clear_doc(docname)

def merge_info_from(self, docnames, other, app):
"""Merge global information gathered about *docnames* while reading them
from the *other* environment.

This possibly comes from a parallel build process.
"""
docnames = set(docnames)
for docname in docnames:
self.all_docs[docname] = other.all_docs[docname]
if docname in other.reread_always:
self.reread_always.add(docname)
self.metadata[docname] = other.metadata[docname]
if docname in other.dependencies:
self.dependencies[docname] = other.dependencies[docname]
self.titles[docname] = other.titles[docname]
self.longtitles[docname] = other.longtitles[docname]
self.tocs[docname] = other.tocs[docname]
self.toc_num_entries[docname] = other.toc_num_entries[docname]
# toc_secnumbers and toc_fignumbers are not assigned during read
if docname in other.toctree_includes:
self.toctree_includes[docname] = other.toctree_includes[docname]
self.indexentries[docname] = other.indexentries[docname]
if docname in other.glob_toctrees:
self.glob_toctrees.add(docname)
if docname in other.numbered_toctrees:
self.numbered_toctrees.add(docname)

self.images.merge_other(docnames, other.images)
self.dlfiles.merge_other(docnames, other.dlfiles)

for subfn, fnset in other.files_to_rebuild.items():
self.files_to_rebuild.setdefault(subfn, set()).update(fnset & docnames)
for key, data in other.citations.items():
# XXX duplicates?
if data[0] in docnames:
self.citations[key] = data
for version, changes in other.versionchanges.items():
self.versionchanges.setdefault(version, []).extend(
change for change in changes if change[1] in docnames)

for domainname, domain in self.domains.items():
domain.merge_domaindata(docnames, other.domaindata[domainname])
app.emit('env-merge-info', self, docnames, other)

[docs]    def doc2path(self, docname, base=True, suffix=None):
"""Return the filename for the document name.

If *base* is True, return absolute path under self.srcdir.
If *base* is None, return relative path to self.srcdir.
If *base* is a path string, return absolute path under that.
If *suffix* is not None, add it instead of config.source_suffix.
"""
docname = docname.replace(SEP, path.sep)
if suffix is None:
for candidate_suffix in self.config.source_suffix:
if path.isfile(path.join(self.srcdir, docname) +
candidate_suffix):
suffix = candidate_suffix
break
else:
# document does not exist
suffix = self.config.source_suffix[0]
if base is True:
return path.join(self.srcdir, docname) + suffix
elif base is None:
return docname + suffix
else:
return path.join(base, docname) + suffix

[docs]    def relfn2path(self, filename, docname=None):
"""Return paths to a file referenced from a document, relative to
documentation root and absolute.

In the input "filename", absolute filenames are taken as relative to the
source dir, while relative filenames are relative to the dir of the
containing document.
"""
if filename.startswith('/') or filename.startswith(os.sep):
rel_fn = filename[1:]
else:
docdir = path.dirname(self.doc2path(docname or self.docname,
base=None))
rel_fn = path.join(docdir, filename)
try:
# the path.abspath() might seem redundant, but otherwise artifacts
# such as ".." will remain in the path
return rel_fn, path.abspath(path.join(self.srcdir, rel_fn))
except UnicodeDecodeError:
# the source directory is a bytestring with non-ASCII characters;
# let's try to encode the rel_fn in the file system encoding
enc_rel_fn = rel_fn.encode(sys.getfilesystemencoding())
return rel_fn, path.abspath(path.join(self.srcdir, enc_rel_fn))

def find_files(self, config):
"""Find all source files in the source dir and put them in
self.found_docs.
"""
matchers = compile_matchers(
config.exclude_patterns[:] +
config.templates_path +
config.html_extra_path +
['**/_sources', '.#*', '**/.#*', '*.lproj/**']
)
self.found_docs = set(get_matching_docs(
self.srcdir, config.source_suffix, exclude_matchers=matchers))

# add catalog mo file dependency
for docname in self.found_docs:
catalog_files = find_catalog_files(
docname,
self.srcdir,
self.config.locale_dirs,
self.config.language,
self.config.gettext_compact)
for filename in catalog_files:
self.dependencies.setdefault(docname, set()).add(filename)

def get_outdated_files(self, config_changed):
"""Return (added, changed, removed) sets."""
# clear all files no longer present
removed = set(self.all_docs) - self.found_docs

added = set()
changed = set()

if config_changed:
# config values affect e.g. substitutions
added = self.found_docs
else:
for docname in self.found_docs:
if docname not in self.all_docs:
added.add(docname)
continue
# if the doctree file is not there, rebuild
if not path.isfile(self.doc2path(docname, self.doctreedir,
'.doctree')):
changed.add(docname)
continue
# check the "reread always" list
if docname in self.reread_always:
changed.add(docname)
continue
# check the mtime of the document
mtime = self.all_docs[docname]
newmtime = path.getmtime(self.doc2path(docname))
if newmtime > mtime:
changed.add(docname)
continue
# finally, check the mtime of dependencies
for dep in self.dependencies.get(docname, ()):
try:
# this will do the right thing when dep is absolute too
deppath = path.join(self.srcdir, dep)
if not path.isfile(deppath):
changed.add(docname)
break
depmtime = path.getmtime(deppath)
if depmtime > mtime:
changed.add(docname)
break
except EnvironmentError:
# give it another chance
changed.add(docname)
break

return added, changed, removed

def update(self, config, srcdir, doctreedir, app):
"""(Re-)read all files new or changed since last update.

Store all environment docnames in the canonical format (ie using SEP as
a separator in place of os.path.sep).
"""
config_changed = False
if self.config is None:
msg = '[new config] '
config_changed = True
else:
# check if a config value was changed that affects how
# doctrees are read
for key, descr in iteritems(config.values):
if descr[1] != 'env':
continue
if self.config[key] != config[key]:
msg = '[config changed] '
config_changed = True
break
else:
msg = ''
# this value is not covered by the above loop because it is handled
# specially by the config class
if self.config.extensions != config.extensions:
msg = '[extensions changed] '
config_changed = True
# the source and doctree directories may have been relocated
self.srcdir = srcdir
self.doctreedir = doctreedir
self.find_files(config)
self.config = config

# this cache also needs to be updated every time
self._nitpick_ignore = set(self.config.nitpick_ignore)

app.info(bold('updating environment: '), nonl=1)

added, changed, removed = self.get_outdated_files(config_changed)

# allow user intervention as well
for docs in app.emit('env-get-outdated', self, added, changed, removed):
changed.update(set(docs) & self.found_docs)

# if files were added or removed, all documents with globbed toctrees
# must be reread
if added or removed:
# ... but not those that already were removed
changed.update(self.glob_toctrees & self.found_docs)

msg += '%s added, %s changed, %s removed' % (len(added), len(changed),
len(removed))
app.info(msg)

self.app = app

# clear all files no longer present
for docname in removed:
app.emit('env-purge-doc', self, docname)
self.clear_doc(docname)

# read all new and changed files
docnames = sorted(added | changed)
# allow changing and reordering the list of docs to read
app.emit('env-before-read-docs', self, docnames)

# check if we should do parallel or serial read
par_ok = False
if parallel_available and len(docnames) > 5 and app.parallel > 1:
par_ok = True
for extname, md in app._extension_metadata.items():
ext_ok = md.get('parallel_read_safe')
if ext_ok:
continue
if ext_ok is None:
app.warn('the %s extension does not declare if it '
'is safe for parallel reading, assuming it '
'isn\'t - please ask the extension author to '
'check and make it explicit' % extname)
app.warn('doing serial read')
else:
app.warn('the %s extension is not safe for parallel '
'reading, doing serial read' % extname)
par_ok = False
break
if par_ok:
self._read_parallel(docnames, app, nproc=app.parallel)
else:
self._read_serial(docnames, app)

if config.master_doc not in self.all_docs:
raise SphinxError('master file %s not found' %
self.doc2path(config.master_doc))

self.app = None

for retval in app.emit('env-updated', self):
if retval is not None:
docnames.extend(retval)

return sorted(docnames)

def _read_serial(self, docnames, app):
for docname in app.status_iterator(docnames, 'reading sources... ',
purple, len(docnames)):
# remove all inventory entries for that file
app.emit('env-purge-doc', self, docname)
self.clear_doc(docname)
self.read_doc(docname, app)

def _read_parallel(self, docnames, app, nproc):
# clear all outdated docs at once
for docname in docnames:
app.emit('env-purge-doc', self, docname)
self.clear_doc(docname)

def read_process(docs):
self.app = app
self.warnings = []
self.set_warnfunc(lambda *args, **kwargs: self.warnings.append((args, kwargs)))
for docname in docs:
self.read_doc(docname, app)
# allow pickling self to send it back
self.set_warnfunc(None)
del self.app
del self.domains
del self.config.values
del self.config
return self

def merge(docs, otherenv):
warnings.extend(otherenv.warnings)
self.merge_info_from(docs, otherenv, app)

tasks = ParallelTasks(nproc)
chunks = make_chunks(docnames, nproc)

warnings = []
for chunk in app.status_iterator(
chunks, 'reading sources... ', purple, len(chunks)):
tasks.add_task(read_process, chunk, merge)

# make sure all threads have finished
app.info(bold('waiting for workers...'))
tasks.join()

for warning, kwargs in warnings:
self._warnfunc(*warning, **kwargs)

def check_dependents(self, already):
to_rewrite = self.assign_section_numbers() + self.assign_figure_numbers()
for docname in set(to_rewrite):
if docname not in already:
yield docname

# --------- SINGLE FILE READING --------------------------------------------

def warn_and_replace(self, error):
"""Custom decoding error handler that warns and replaces."""
linestart = error.object.rfind(b'\n', 0, error.start)
lineend = error.object.find(b'\n', error.start)
if lineend == -1:
lineend = len(error.object)
lineno = error.object.count(b'\n', 0, error.start) + 1
self.warn(self.docname, 'undecodable source characters, '
'replacing with "?": %r' %
(error.object[linestart+1:error.start] + b'>>>' +
error.object[error.start:error.end] + b'<<<' +
error.object[error.end:lineend]), lineno)
return (u'?', error.end)

def lookup_domain_element(self, type, name):
"""Lookup a markup element (directive or role), given its name which can
be a full name (with domain).
"""
name = name.lower()
# explicit domain given?
if ':' in name:
domain_name, name = name.split(':', 1)
if domain_name in self.domains:
domain = self.domains[domain_name]
element = getattr(domain, type)(name)
if element is not None:
return element, []
# else look in the default domain
else:
def_domain = self.temp_data.get('default_domain')
if def_domain is not None:
element = getattr(def_domain, type)(name)
if element is not None:
return element, []
# always look in the std domain
element = getattr(self.domains['std'], type)(name)
if element is not None:
return element, []
raise ElementLookupError

def patch_lookup_functions(self):
"""Monkey-patch directive and role dispatch, so that domain-specific
markup takes precedence.
"""
def directive(name, lang_module, document):
try:
return self.lookup_domain_element('directive', name)
except ElementLookupError:
return orig_directive_function(name, lang_module, document)

def role(name, lang_module, lineno, reporter):
try:
return self.lookup_domain_element('role', name)
except ElementLookupError:
return orig_role_function(name, lang_module, lineno, reporter)

directives.directive = directive
roles.role = role

def read_doc(self, docname, app=None):
"""Parse a file and add/update inventory entries for the doctree."""

self.temp_data['docname'] = docname
# defaults to the global default, but can be re-set in a document
self.temp_data['default_domain'] = \
self.domains.get(self.config.primary_domain)

self.settings['input_encoding'] = self.config.source_encoding
self.settings['trim_footnote_reference_space'] = \
self.config.trim_footnote_reference_space
self.settings['gettext_compact'] = self.config.gettext_compact

self.patch_lookup_functions()

docutilsconf = path.join(self.srcdir, 'docutils.conf')
# read docutils.conf from source dir, not from current dir
OptionParser.standard_config_files[1] = docutilsconf
if path.isfile(docutilsconf):
self.note_dependency(docutilsconf)

if self.config.default_role:
role_fn, messages = roles.role(self.config.default_role, english,
0, dummy_reporter)
if role_fn:
roles._roles[''] = role_fn
else:
self.warn(docname, 'default role %s not found' %
self.config.default_role)

codecs.register_error('sphinx', self.warn_and_replace)

# publish manually
reader = SphinxStandaloneReader(self.app, parsers=self.config.source_parsers)
pub = Publisher(reader=reader,
writer=SphinxDummyWriter(),
destination_class=NullOutput)
pub.set_components(None, 'restructuredtext', None)
pub.process_programmatic_settings(None, self.settings, None)
src_path = self.doc2path(docname)
source = SphinxFileInput(app, self, source=None, source_path=src_path,
encoding=self.config.source_encoding)
pub.source = source
pub.settings._source = src_path
pub.set_destination(None, None)
pub.publish()
doctree = pub.document

# post-processing
self.filter_messages(doctree)
self.process_dependencies(docname, doctree)
self.process_images(docname, doctree)
self.process_downloads(docname, doctree)
self.process_metadata(docname, doctree)
self.process_refonly_bullet_lists(docname, doctree)
self.create_title_from(docname, doctree)
self.note_indexentries_from(docname, doctree)
self.note_citations_from(docname, doctree)
self.build_toc_from(docname, doctree)
for domain in itervalues(self.domains):
domain.process_doc(self, docname, doctree)

# allow extension-specific post-processing
if app:
app.emit('doctree-read', doctree)

# store time of reading, for outdated files detection
# (Some filesystems have coarse timestamp resolution;
# therefore time.time() can be older than filesystem's timestamp.
# For example, FAT32 has 2sec timestamp resolution.)
self.all_docs[docname] = max(
time.time(), path.getmtime(self.doc2path(docname)))

if self.versioning_condition:
old_doctree = None
if self.versioning_compare:
# get old doctree
try:
f = open(self.doc2path(docname,
self.doctreedir, '.doctree'), 'rb')
try:
old_doctree = pickle.load(f)
finally:
f.close()
except EnvironmentError:
pass

# add uids for versioning
if not self.versioning_compare or old_doctree is None:
list(add_uids(doctree, self.versioning_condition))
else:
list(merge_doctrees(
old_doctree, doctree, self.versioning_condition))

# make it picklable
doctree.reporter = None
doctree.transformer = None
doctree.settings.warning_stream = None
doctree.settings.env = None
doctree.settings.record_dependencies = None
for metanode in doctree.traverse(MetaBody.meta):
# docutils' meta nodes aren't picklable because the class is nested
metanode.__class__ = addnodes.meta

# cleanup
self.temp_data.clear()
self.ref_context.clear()
roles._roles.pop('', None)  # if a document has set a local default role

# save the parsed doctree
doctree_filename = self.doc2path(docname, self.doctreedir,
'.doctree')
ensuredir(path.dirname(doctree_filename))
f = open(doctree_filename, 'wb')
try:
pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
finally:
f.close()

# utilities to use while reading a document

@property
def docname(self):
"""Returns the docname of the document currently being parsed."""
return self.temp_data['docname']

@property
def currmodule(self):
"""Backwards compatible alias.  Will be removed."""
self.warn(self.docname, 'env.currmodule is being referenced by an '
'extension; this API will be removed in the future')
return self.ref_context.get('py:module')

@property
def currclass(self):
"""Backwards compatible alias.  Will be removed."""
self.warn(self.docname, 'env.currclass is being referenced by an '
'extension; this API will be removed in the future')
return self.ref_context.get('py:class')

[docs]    def new_serialno(self, category=''):
"""Return a serial number, e.g. for index entry targets.

The number is guaranteed to be unique in the current document.
"""
key = category + 'serialno'
cur = self.temp_data.get(key, 0)
self.temp_data[key] = cur + 1
return cur

[docs]    def note_dependency(self, filename):
"""Add *filename* as a dependency of the current document.

This means that the document will be rebuilt if this file changes.

*filename* should be absolute or relative to the source directory.
"""
self.dependencies.setdefault(self.docname, set()).add(filename)

[docs]    def note_reread(self):
"""Add the current document to the list of documents that will
automatically be re-read at the next build.
"""
self.reread_always.add(self.docname)

def note_versionchange(self, type, version, node, lineno):
self.versionchanges.setdefault(version, []).append(
(type, self.temp_data['docname'], lineno,
self.ref_context.get('py:module'),
self.temp_data.get('object'), node.astext()))

# post-processing of read doctrees

def filter_messages(self, doctree):
"""Filter system messages from a doctree."""
filterlevel = self.config.keep_warnings and 2 or 5
for node in doctree.traverse(nodes.system_message):
if node['level'] < filterlevel:
self.app.debug('%s [filtered system message]', node.astext())
node.parent.remove(node)

def process_dependencies(self, docname, doctree):
"""Process docutils-generated dependency info."""
cwd = getcwd()
frompath = path.join(path.normpath(self.srcdir), 'dummy')
deps = doctree.settings.record_dependencies
if not deps:
return
for dep in deps.list:
# the dependency path is relative to the working dir, so get
# one relative to the srcdir
if isinstance(dep, bytes):
dep = dep.decode(fs_encoding)
relpath = relative_path(frompath,
path.normpath(path.join(cwd, dep)))
self.dependencies.setdefault(docname, set()).add(relpath)

def process_downloads(self, docname, doctree):
"""Process downloadable file paths. """
for node in doctree.traverse(addnodes.download_reference):
targetname = node['reftarget']
rel_filename, filename = self.relfn2path(targetname, docname)
self.dependencies.setdefault(docname, set()).add(rel_filename)
if not os.access(filename, os.R_OK):
self.warn_node('download file not readable: %s' % filename,
node)
continue
uniquename = self.dlfiles.add_file(docname, filename)
node['filename'] = uniquename

def process_images(self, docname, doctree):
"""Process and rewrite image URIs."""
def collect_candidates(imgpath, candidates):
globbed = {}
for filename in glob(imgpath):
new_imgpath = relative_path(path.join(self.srcdir, 'dummy'),
filename)
try:
mimetype = guess_mimetype(filename)
if mimetype not in candidates:
globbed.setdefault(mimetype, []).append(new_imgpath)
except (OSError, IOError) as err:
self.warn_node('image file %s not readable: %s' %
(filename, err), node)
for key, files in iteritems(globbed):
candidates[key] = sorted(files, key=len)[0]  # select by similarity

for node in doctree.traverse(nodes.image):
# Map the mimetype to the corresponding image.  The writer may
# choose the best image from these candidates.  The special key * is
# set if there is only single candidate to be used by a writer.
# The special key ? is set for nonlocal URIs.
node['candidates'] = candidates = {}
imguri = node['uri']
if imguri.startswith('data:'):
self.warn_node('image data URI found. some builders might not support', node,
type='image', subtype='data_uri')
candidates['?'] = imguri
continue
elif imguri.find('://') != -1:
self.warn_node('nonlocal image URI found: %s' % imguri, node,
type='image', subtype='nonlocal_uri')
candidates['?'] = imguri
continue
rel_imgpath, full_imgpath = self.relfn2path(imguri, docname)
if self.config.language:
# substitute figures (ex. foo.png -> foo.en.png)
i18n_full_imgpath = search_image_for_language(full_imgpath, self)
if i18n_full_imgpath != full_imgpath:
full_imgpath = i18n_full_imgpath
rel_imgpath = relative_path(path.join(self.srcdir, 'dummy'),
i18n_full_imgpath)
# set imgpath as default URI
node['uri'] = rel_imgpath
if rel_imgpath.endswith(os.extsep + '*'):
if self.config.language:
# Search language-specific figures at first
i18n_imguri = get_image_filename_for_language(imguri, self)
_, full_i18n_imgpath = self.relfn2path(i18n_imguri, docname)
collect_candidates(full_i18n_imgpath, candidates)

collect_candidates(full_imgpath, candidates)
else:
candidates['*'] = rel_imgpath

# map image paths to unique image names (so that they can be put
# into a single directory)
for imgpath in itervalues(candidates):
self.dependencies.setdefault(docname, set()).add(imgpath)
if not os.access(path.join(self.srcdir, imgpath), os.R_OK):
self.warn_node('image file not readable: %s' % imgpath,
node)
continue
self.images.add_file(docname, imgpath)

def process_metadata(self, docname, doctree):
"""Process the docinfo part of the doctree as metadata.

Keep processing minimal -- just return what docutils says.
"""
self.metadata[docname] = md = {}
try:
docinfo = doctree[0]
except IndexError:
# probably an empty document
return
if docinfo.__class__ is not nodes.docinfo:
# nothing to see here
return
for node in docinfo:
# nodes are multiply inherited...
if isinstance(node, nodes.authors):
md['authors'] = [author.astext() for author in node]
elif isinstance(node, nodes.TextElement):  # e.g. author
md[node.__class__.__name__] = node.astext()
else:
name, body = node
md[name.astext()] = body.astext()
for name, value in md.items():
if name in ('tocdepth',):
try:
value = int(value)
except ValueError:
value = 0
md[name] = value

del doctree[0]

def process_refonly_bullet_lists(self, docname, doctree):
"""Change refonly bullet lists to use compact_paragraphs.

Specifically implemented for 'Indices and Tables' section, which looks
odd when html_compact_lists is false.
"""
if self.config.html_compact_lists:
return

class RefOnlyListChecker(nodes.GenericNodeVisitor):
"""Raise `nodes.NodeFound` if non-simple list item is encountered.

Here 'simple' means a list item containing only a paragraph with a
single reference in it.
"""

def default_visit(self, node):
raise nodes.NodeFound

def visit_bullet_list(self, node):
pass

def visit_list_item(self, node):
children = []
for child in node.children:
if not isinstance(child, nodes.Invisible):
children.append(child)
if len(children) != 1:
raise nodes.NodeFound
if not isinstance(children[0], nodes.paragraph):
raise nodes.NodeFound
para = children[0]
if len(para) != 1:
raise nodes.NodeFound
if not isinstance(para[0], addnodes.pending_xref):
raise nodes.NodeFound
raise nodes.SkipChildren

def invisible_visit(self, node):
"""Invisible nodes should be ignored."""
pass

def check_refonly_list(node):
"""Check for list with only references in it."""
visitor = RefOnlyListChecker(doctree)
try:
node.walk(visitor)
except nodes.NodeFound:
return False
else:
return True

for node in doctree.traverse(nodes.bullet_list):
if check_refonly_list(node):
for item in node.traverse(nodes.list_item):
para = item[0]
ref = para[0]
compact_para = addnodes.compact_paragraph()
compact_para += ref
item.replace(para, compact_para)

def create_title_from(self, docname, document):
"""Add a title node to the document (just copy the first section title),
and store that title in the environment.
"""
titlenode = nodes.title()
longtitlenode = titlenode
# explicit title set with title directive; use this only for
# the <title> tag in HTML output
if 'title' in document:
longtitlenode = nodes.title()
longtitlenode += nodes.Text(document['title'])
# look for first section title and use that as the title
for node in document.traverse(nodes.section):
visitor = SphinxContentsFilter(document)
node[0].walkabout(visitor)
titlenode += visitor.get_entry_text()
break
else:
# document has no title
titlenode += nodes.Text('<no title>')
self.titles[docname] = titlenode
self.longtitles[docname] = longtitlenode

def note_indexentries_from(self, docname, document):
entries = self.indexentries[docname] = []
for node in document.traverse(addnodes.index):
try:
for entry in node['entries']:
split_index_msg(entry[0], entry[1])
except ValueError as exc:
self.warn_node(exc, node)
node.parent.remove(node)
else:
for entry in node['entries']:
if len(entry) == 5:
# Since 1.4: new index structure including index_key (5th column)
entries.append(entry)
else:
entries.append(entry + (None,))

def note_citations_from(self, docname, document):
for node in document.traverse(nodes.citation):
label = node[0].astext()
if label in self.citations:
self.warn_node('duplicate citation %s, ' % label +
'other instance in %s' % self.doc2path(
self.citations[label][0]), node)
self.citations[label] = (docname, node['ids'][0])

def note_toctree(self, docname, toctreenode):
"""Note a TOC tree directive in a document and gather information about
file relations from it.
"""
if toctreenode['glob']:
self.glob_toctrees.add(docname)
if toctreenode.get('numbered'):
self.numbered_toctrees.add(docname)
includefiles = toctreenode['includefiles']
for includefile in includefiles:
# note that if the included file is rebuilt, this one must be
# too (since the TOC of the included file could have changed)
self.files_to_rebuild.setdefault(includefile, set()).add(docname)
self.toctree_includes.setdefault(docname, []).extend(includefiles)

def build_toc_from(self, docname, document):
"""Build a TOC from the doctree and store it in the inventory."""
numentries = [0]  # nonlocal again...

def traverse_in_section(node, cls):
"""Like traverse(), but stay within the same section."""
result = []
if isinstance(node, cls):
result.append(node)
for child in node.children:
if isinstance(child, nodes.section):
continue
result.extend(traverse_in_section(child, cls))
return result

def build_toc(node, depth=1):
entries = []
for sectionnode in node:
# find all toctree nodes in this section and add them
# to the toc (just copying the toctree node which is then
# resolved in self.get_and_resolve_doctree)
if isinstance(sectionnode, addnodes.only):
onlynode = addnodes.only(expr=sectionnode['expr'])
blist = build_toc(sectionnode, depth)
if blist:
onlynode += blist.children
entries.append(onlynode)
continue
if not isinstance(sectionnode, nodes.section):
for toctreenode in traverse_in_section(sectionnode,
addnodes.toctree):
item = toctreenode.copy()
entries.append(item)
# important: do the inventory stuff
self.note_toctree(docname, toctreenode)
continue
title = sectionnode[0]
# copy the contents of the section title, but without references
# and unnecessary stuff
visitor = SphinxContentsFilter(document)
title.walkabout(visitor)
nodetext = visitor.get_entry_text()
if not numentries[0]:
# for the very first toc entry, don't add an anchor
# as it is the file's title anyway
anchorname = ''
else:
anchorname = '#' + sectionnode['ids'][0]
numentries[0] += 1
# make these nodes:
# list_item -> compact_paragraph -> reference
reference = nodes.reference(
'', '', internal=True, refuri=docname,
anchorname=anchorname, *nodetext)
para = addnodes.compact_paragraph('', '', reference)
item = nodes.list_item('', para)
sub_item = build_toc(sectionnode, depth + 1)
item += sub_item
entries.append(item)
if entries:
return nodes.bullet_list('', *entries)
return []
toc = build_toc(document)
if toc:
self.tocs[docname] = toc
else:
self.tocs[docname] = nodes.bullet_list('')
self.toc_num_entries[docname] = numentries[0]

def get_toc_for(self, docname, builder):
"""Return a TOC nodetree -- for use on the same page only!"""
tocdepth = self.metadata[docname].get('tocdepth', 0)
try:
toc = self.tocs[docname].deepcopy()
self._toctree_prune(toc, 2, tocdepth)
except KeyError:
# the document does not exist anymore: return a dummy node that
# renders to nothing
return nodes.paragraph()
self.process_only_nodes(toc, builder, docname)
for node in toc.traverse(nodes.reference):
node['refuri'] = node['anchorname'] or '#'
return toc

def get_toctree_for(self, docname, builder, collapse, **kwds):
"""Return the global TOC nodetree."""
doctree = self.get_doctree(self.config.master_doc)
toctrees = []
if 'includehidden' not in kwds:
kwds['includehidden'] = True
if 'maxdepth' not in kwds:
kwds['maxdepth'] = 0
kwds['collapse'] = collapse
for toctreenode in doctree.traverse(addnodes.toctree):
toctree = self.resolve_toctree(docname, builder, toctreenode,
prune=True, **kwds)
if toctree:
toctrees.append(toctree)
if not toctrees:
return None
result = toctrees[0]
for toctree in toctrees[1:]:
result.extend(toctree.children)
return result

def get_domain(self, domainname):
"""Return the domain instance with the specified name.

Raises an ExtensionError if the domain is not registered.
"""
try:
return self.domains[domainname]
except KeyError:
raise ExtensionError('Domain %r is not registered' % domainname)

# --------- RESOLVING REFERENCES AND TOCTREES ------------------------------

def get_doctree(self, docname):
"""Read the doctree for a file from the pickle and return it."""
doctree_filename = self.doc2path(docname, self.doctreedir, '.doctree')
f = open(doctree_filename, 'rb')
try:
doctree = pickle.load(f)
finally:
f.close()
doctree.settings.env = self
doctree.reporter = Reporter(self.doc2path(docname), 2, 5,
stream=WarningStream(self._warnfunc))
return doctree

def get_and_resolve_doctree(self, docname, builder, doctree=None,
prune_toctrees=True, includehidden=False):
"""Read the doctree from the pickle, resolve cross-references and
toctrees and return it.
"""
if doctree is None:
doctree = self.get_doctree(docname)

# resolve all pending cross-references
self.resolve_references(doctree, docname, builder)

# now, resolve all toctree nodes
for toctreenode in doctree.traverse(addnodes.toctree):
result = self.resolve_toctree(docname, builder, toctreenode,
prune=prune_toctrees,
includehidden=includehidden)
if result is None:
toctreenode.replace_self([])
else:
toctreenode.replace_self(result)

return doctree

def _toctree_prune(self, node, depth, maxdepth, collapse=False):
"""Utility: Cut a TOC at a specified depth."""
for subnode in node.children[:]:
if isinstance(subnode, (addnodes.compact_paragraph,
nodes.list_item)):
# for <p> and <li>, just recurse
self._toctree_prune(subnode, depth, maxdepth, collapse)
elif isinstance(subnode, nodes.bullet_list):
# for <ul>, determine if the depth is too large or if the
# entry is to be collapsed
if maxdepth > 0 and depth > maxdepth:
subnode.parent.replace(subnode, [])
else:
# cull sub-entries whose parents aren't 'current'
if (collapse and depth > 1 and
'iscurrent' not in subnode.parent):
subnode.parent.remove(subnode)
else:
# recurse on visible children
self._toctree_prune(subnode, depth+1, maxdepth,  collapse)

def get_toctree_ancestors(self, docname):
parent = {}
for p, children in iteritems(self.toctree_includes):
for child in children:
parent[child] = p
ancestors = []
d = docname
while d in parent and d not in ancestors:
ancestors.append(d)
d = parent[d]
return ancestors

def resolve_toctree(self, docname, builder, toctree, prune=True, maxdepth=0,
titles_only=False, collapse=False, includehidden=False):
"""Resolve a *toctree* node into individual bullet lists with titles
as items, returning None (if no containing titles are found) or
a new node.

If *prune* is True, the tree is pruned to *maxdepth*, or if that is 0,
to the value of the *maxdepth* option on the *toctree* node.
If *titles_only* is True, only toplevel document titles will be in the
resulting tree.
If *collapse* is True, all branches not containing docname will
be collapsed.
"""
if toctree.get('hidden', False) and not includehidden:
return None

# For reading the following two helper function, it is useful to keep
# in mind the node structure of a toctree (using HTML-like node names
# for brevity):
#
# <ul>
#   <li>
#     <p><a></p>
#     <p><a></p>
#     ...
#     <ul>
#       ...
#     </ul>
#   </li>
# </ul>
#
# The transformation is made in two passes in order to avoid
# interactions between marking and pruning the tree (see bug #1046).

toctree_ancestors = self.get_toctree_ancestors(docname)

def _toctree_add_classes(node, depth):
"""Add 'toctree-l%d' and 'current' classes to the toctree."""
for subnode in node.children:
if isinstance(subnode, (addnodes.compact_paragraph,
nodes.list_item)):
# for <p> and <li>, indicate the depth level and recurse
subnode['classes'].append('toctree-l%d' % (depth-1))
_toctree_add_classes(subnode, depth)
elif isinstance(subnode, nodes.bullet_list):
# for <ul>, just recurse
_toctree_add_classes(subnode, depth+1)
elif isinstance(subnode, nodes.reference):
# for <a>, identify which entries point to the current
# document and therefore may not be collapsed
if subnode['refuri'] == docname:
if not subnode['anchorname']:
# give the whole branch a 'current' class
# (useful for styling it differently)
branchnode = subnode
while branchnode:
branchnode['classes'].append('current')
branchnode = branchnode.parent
# mark the list_item as "on current page"
if subnode.parent.parent.get('iscurrent'):
# but only if it's not already done
return
while subnode:
subnode['iscurrent'] = True
subnode = subnode.parent

def _entries_from_toctree(toctreenode, parents,
separate=False, subtree=False):
"""Return TOC entries for a toctree node."""
refs = [(e[0], e[1]) for e in toctreenode['entries']]
entries = []
for (title, ref) in refs:
try:
refdoc = None
if url_re.match(ref):
if title is None:
title = ref
reference = nodes.reference('', '', internal=False,
refuri=ref, anchorname='',
*[nodes.Text(title)])
para = addnodes.compact_paragraph('', '', reference)
item = nodes.list_item('', para)
toc = nodes.bullet_list('', item)
elif ref == 'self':
# 'self' refers to the document from which this
# toctree originates
ref = toctreenode['parent']
if not title:
title = clean_astext(self.titles[ref])
reference = nodes.reference('', '', internal=True,
refuri=ref,
anchorname='',
*[nodes.Text(title)])
para = addnodes.compact_paragraph('', '', reference)
item = nodes.list_item('', para)
# don't show subitems
toc = nodes.bullet_list('', item)
else:
if ref in parents:
self.warn(ref, 'circular toctree references '
'detected, ignoring: %s <- %s' %
(ref, ' <- '.join(parents)))
continue
refdoc = ref
toc = self.tocs[ref].deepcopy()
maxdepth = self.metadata[ref].get('tocdepth', 0)
if ref not in toctree_ancestors or (prune and maxdepth > 0):
self._toctree_prune(toc, 2, maxdepth, collapse)
self.process_only_nodes(toc, builder, ref)
if title and toc.children and len(toc.children) == 1:
child = toc.children[0]
for refnode in child.traverse(nodes.reference):
if refnode['refuri'] == ref and \
not refnode['anchorname']:
refnode.children = [nodes.Text(title)]
if not toc.children:
# empty toc means: no titles will show up in the toctree
self.warn_node(
'toctree contains reference to document %r that '
'doesn\'t have a title: no link will be generated'
% ref, toctreenode)
except KeyError:
# this is raised if the included file does not exist
self.warn_node(
'toctree contains reference to nonexisting document %r'
% ref, toctreenode)
else:
# if titles_only is given, only keep the main title and
# sub-toctrees
if titles_only:
# delete everything but the toplevel title(s)
# and toctrees
for toplevel in toc:
# nodes with length 1 don't have any children anyway
if len(toplevel) > 1:
subtrees = toplevel.traverse(addnodes.toctree)
toplevel[1][:] = subtrees
# resolve all sub-toctrees
for subtocnode in toc.traverse(addnodes.toctree):
if not (subtocnode.get('hidden', False) and
not includehidden):
i = subtocnode.parent.index(subtocnode) + 1
for item in _entries_from_toctree(
subtocnode, [refdoc] + parents,
subtree=True):
subtocnode.parent.insert(i, item)
i += 1
subtocnode.parent.remove(subtocnode)
if separate:
entries.append(toc)
else:
entries.extend(toc.children)
if not subtree and not separate:
ret = nodes.bullet_list()
ret += entries
return [ret]
return entries

maxdepth = maxdepth or toctree.get('maxdepth', -1)
if not titles_only and toctree.get('titlesonly', False):
titles_only = True
if not includehidden and toctree.get('includehidden', False):
includehidden = True

# NOTE: previously, this was separate=True, but that leads to artificial
# separation when two or more toctree entries form a logical unit, so
# separating mode is no longer used -- it's kept here for history's sake
tocentries = _entries_from_toctree(toctree, [], separate=False)
if not tocentries:
return None

newnode = addnodes.compact_paragraph('', '')
caption = toctree.attributes.get('caption')
if caption:
newnode += nodes.caption(caption, '', *[nodes.Text(caption)])
newnode.extend(tocentries)
newnode['toctree'] = True

# prune the tree to maxdepth, also set toc depth and current classes
_toctree_add_classes(newnode, 1)
self._toctree_prune(newnode, 1, prune and maxdepth or 0, collapse)

# set the target paths in the toctrees (they are not known at TOC
# generation time)
for refnode in newnode.traverse(nodes.reference):
if not url_re.match(refnode['refuri']):
refnode['refuri'] = builder.get_relative_uri(
docname, refnode['refuri']) + refnode['anchorname']
return newnode

def resolve_references(self, doctree, fromdocname, builder):
for node in doctree.traverse(addnodes.pending_xref):
contnode = node[0].deepcopy()
newnode = None

typ = node['reftype']
target = node['reftarget']
refdoc = node.get('refdoc', fromdocname)
domain = None

try:
if 'refdomain' in node and node['refdomain']:
# let the domain try to resolve the reference
try:
domain = self.domains[node['refdomain']]
except KeyError:
raise NoUri
newnode = domain.resolve_xref(self, refdoc, builder,
typ, target, node, contnode)
# really hardwired reference types
elif typ == 'any':
newnode = self._resolve_any_reference(builder, node, contnode)
elif typ == 'doc':
newnode = self._resolve_doc_reference(builder, node, contnode)
elif typ == 'citation':
newnode = self._resolve_citation(builder, refdoc, node, contnode)
# no new node found? try the missing-reference event
if newnode is None:
newnode = builder.app.emit_firstresult(
'missing-reference', self, node, contnode)
# still not found? warn if node wishes to be warned about or
# we are in nit-picky mode
if newnode is None:
self._warn_missing_reference(refdoc, typ, target, node, domain)
except NoUri:
newnode = contnode
node.replace_self(newnode or contnode)

# remove only-nodes that do not belong to our builder
self.process_only_nodes(doctree, builder, fromdocname)

# allow custom references to be resolved
builder.app.emit('doctree-resolved', doctree, fromdocname)

def _warn_missing_reference(self, refdoc, typ, target, node, domain):
warn = node.get('refwarn')
if self.config.nitpicky:
warn = True
if self._nitpick_ignore:
dtype = domain and '%s:%s' % (domain.name, typ) or typ
if (dtype, target) in self._nitpick_ignore:
warn = False
# for "std" types also try without domain name
if (not domain or domain.name == 'std') and \
(typ, target) in self._nitpick_ignore:
warn = False
if not warn:
return
if domain and typ in domain.dangling_warnings:
msg = domain.dangling_warnings[typ]
elif typ == 'doc':
msg = 'unknown document: %(target)s'
elif typ == 'citation':
msg = 'citation not found: %(target)s'
elif node.get('refdomain', 'std') not in ('', 'std'):
msg = '%s:%s reference target not found: %%(target)s' % \
(node['refdomain'], typ)
else:
msg = '%r reference target not found: %%(target)s' % typ
self.warn_node(msg % {'target': target}, node, type='ref', subtype=typ)

def _resolve_doc_reference(self, builder, node, contnode):
# directly reference to document by source name;
# can be absolute or relative
docname = docname_join(node['refdoc'], node['reftarget'])
if docname in self.all_docs:
if node['refexplicit']:
# reference with explicit title
caption = node.astext()
else:
caption = clean_astext(self.titles[docname])
innernode = nodes.inline(caption, caption)
innernode['classes'].append('doc')
newnode = nodes.reference('', '', internal=True)
newnode['refuri'] = builder.get_relative_uri(node['refdoc'], docname)
newnode.append(innernode)
return newnode

def _resolve_citation(self, builder, fromdocname, node, contnode):
docname, labelid = self.citations.get(node['reftarget'], ('', ''))
if docname:
try:
newnode = make_refnode(builder, fromdocname,
docname, labelid, contnode)
return newnode
except NoUri:
# remove the ids we added in the CitationReferences
# transform since they can't be transfered to
# the contnode (if it's a Text node)
if not isinstance(contnode, nodes.Element):
del node['ids'][:]
raise
elif 'ids' in node:
# remove ids attribute that annotated at
# transforms.CitationReference.apply.
del node['ids'][:]

def _resolve_any_reference(self, builder, node, contnode):
"""Resolve reference generated by the "any" role."""
refdoc = node['refdoc']
target = node['reftarget']
results = []
# first, try resolving as :doc:
doc_ref = self._resolve_doc_reference(builder, node, contnode)
if doc_ref:
results.append(('doc', doc_ref))
# next, do the standard domain (makes this a priority)
results.extend(self.domains['std'].resolve_any_xref(
self, refdoc, builder, target, node, contnode))
for domain in self.domains.values():
if domain.name == 'std':
continue  # we did this one already
try:
results.extend(domain.resolve_any_xref(self, refdoc, builder,
target, node, contnode))
except NotImplementedError:
# the domain doesn't yet support the new interface
# we have to manually collect possible references (SLOW)
for role in domain.roles:
res = domain.resolve_xref(self, refdoc, builder, role, target,
node, contnode)
if res and isinstance(res[0], nodes.Element):
results.append(('%s:%s' % (domain.name, role), res))
# now, see how many matches we got...
if not results:
return None
if len(results) > 1:
nice_results = ' or '.join(':%s:' % r[0] for r in results)
self.warn_node('more than one target found for \'any\' cross-'
'reference %r: could be %s' % (target, nice_results),
node)
res_role, newnode = results[0]
# Override "any" class with the actual role type to get the styling
# approximately correct.
res_domain = res_role.split(':')[0]
if newnode and newnode[0].get('classes'):
newnode[0]['classes'].append(res_domain)
newnode[0]['classes'].append(res_role.replace(':', '-'))
return newnode

def process_only_nodes(self, doctree, builder, fromdocname=None):
# A comment on the comment() nodes being inserted: replacing by [] would
# result in a "Losing ids" exception if there is a target node before
# the only node, so we make sure docutils can transfer the id to
# something, even if it's just a comment and will lose the id anyway...
for node in doctree.traverse(addnodes.only):
try:
ret = builder.tags.eval_condition(node['expr'])
except Exception as err:
self.warn_node('exception while evaluating only '
'directive expression: %s' % err, node)
node.replace_self(node.children or nodes.comment())
else:
if ret:
node.replace_self(node.children or nodes.comment())
else:
node.replace_self(nodes.comment())

def assign_section_numbers(self):
"""Assign a section number to each heading under a numbered toctree."""
# a list of all docnames whose section numbers changed
rewrite_needed = []

assigned = set()
old_secnumbers = self.toc_secnumbers
self.toc_secnumbers = {}

def _walk_toc(node, secnums, depth, titlenode=None):
# titlenode is the title of the document, it will get assigned a
# secnumber too, so that it shows up in next/prev/parent rellinks
for subnode in node.children:
if isinstance(subnode, nodes.bullet_list):
numstack.append(0)
_walk_toc(subnode, secnums, depth-1, titlenode)
numstack.pop()
titlenode = None
elif isinstance(subnode, nodes.list_item):
_walk_toc(subnode, secnums, depth, titlenode)
titlenode = None
elif isinstance(subnode, addnodes.only):
# at this stage we don't know yet which sections are going
# to be included; just include all of them, even if it leads
# to gaps in the numbering
_walk_toc(subnode, secnums, depth, titlenode)
titlenode = None
elif isinstance(subnode, addnodes.compact_paragraph):
numstack[-1] += 1
if depth > 0:
number = tuple(numstack)
else:
number = None
secnums[subnode[0]['anchorname']] = \
subnode[0]['secnumber'] = number
if titlenode:
titlenode['secnumber'] = number
titlenode = None
elif isinstance(subnode, addnodes.toctree):
_walk_toctree(subnode, depth)

def _walk_toctree(toctreenode, depth):
if depth == 0:
return
for (title, ref) in toctreenode['entries']:
if url_re.match(ref) or ref == 'self' or ref in assigned:
# don't mess with those
continue
if ref in self.tocs:
secnums = self.toc_secnumbers[ref] = {}
assigned.add(ref)
_walk_toc(self.tocs[ref], secnums, depth,
self.titles.get(ref))
if secnums != old_secnumbers.get(ref):
rewrite_needed.append(ref)

for docname in self.numbered_toctrees:
assigned.add(docname)
doctree = self.get_doctree(docname)
for toctreenode in doctree.traverse(addnodes.toctree):
depth = toctreenode.get('numbered', 0)
if depth:
# every numbered toctree gets new numbering
numstack = [0]
_walk_toctree(toctreenode, depth)

return rewrite_needed

def assign_figure_numbers(self):
"""Assign a figure number to each figure under a numbered toctree."""

rewrite_needed = []

assigned = set()
old_fignumbers = self.toc_fignumbers
self.toc_fignumbers = {}
fignum_counter = {}

def get_section_number(docname, section):
anchorname = '#' + section['ids'][0]
secnumbers = self.toc_secnumbers.get(docname, {})
if anchorname in secnumbers:
secnum = secnumbers.get(anchorname)
else:
secnum = secnumbers.get('')

return secnum or tuple()

def get_next_fignumber(figtype, secnum):
counter = fignum_counter.setdefault(figtype, {})

secnum = secnum[:self.config.numfig_secnum_depth]
counter[secnum] = counter.get(secnum, 0) + 1
return secnum + (counter[secnum],)

def register_fignumber(docname, secnum, figtype, fignode):
self.toc_fignumbers.setdefault(docname, {})
fignumbers = self.toc_fignumbers[docname].setdefault(figtype, {})
figure_id = fignode['ids'][0]

fignumbers[figure_id] = get_next_fignumber(figtype, secnum)

def _walk_doctree(docname, doctree, secnum):
for subnode in doctree.children:
if isinstance(subnode, nodes.section):
next_secnum = get_section_number(docname, subnode)
if next_secnum:
_walk_doctree(docname, subnode, next_secnum)
else:
_walk_doctree(docname, subnode, secnum)
continue
elif isinstance(subnode, addnodes.toctree):
for title, subdocname in subnode['entries']:
if url_re.match(subdocname) or subdocname == 'self':
# don't mess with those
continue

_walk_doc(subdocname, secnum)

continue

figtype = self.domains['std'].get_figtype(subnode)
if figtype and subnode['ids']:
register_fignumber(docname, secnum, figtype, subnode)

_walk_doctree(docname, subnode, secnum)

def _walk_doc(docname, secnum):
if docname not in assigned:
assigned.add(docname)
doctree = self.get_doctree(docname)
_walk_doctree(docname, doctree, secnum)

if self.config.numfig:
_walk_doc(self.config.master_doc, tuple())
for docname, fignums in iteritems(self.toc_fignumbers):
if fignums != old_fignumbers.get(docname):
rewrite_needed.append(docname)

return rewrite_needed

def create_index(self, builder, group_entries=True,
_fixre=re.compile(r'(.*) ([(][^()]*[)])')):
"""Create the real index from the collected index entries."""
new = {}

def add_entry(word, subword, link=True, dic=new, key=None):
# Force the word to be unicode if it's a ASCII bytestring.
# This will solve problems with unicode normalization later.
# For instance the RFC role will add bytestrings at the moment
word = text_type(word)
entry = dic.get(word)
if not entry:
dic[word] = entry = [[], {}, key]
if subword:
add_entry(subword, '', link=link, dic=entry[1], key=key)
elif link:
try:
uri = builder.get_relative_uri('genindex', fn) + '#' + tid
except NoUri:
pass
else:
# maintain links in sorted/deterministic order
bisect.insort(entry[0], (main, uri))

for fn, entries in iteritems(self.indexentries):
# new entry types must be listed in directives/other.py!
for type, value, tid, main, index_key in entries:
try:
if type == 'single':
try:
entry, subentry = split_into(2, 'single', value)
except ValueError:
entry, = split_into(1, 'single', value)
subentry = ''
add_entry(entry, subentry, key=index_key)
elif type == 'pair':
first, second = split_into(2, 'pair', value)
add_entry(first, second, key=index_key)
add_entry(second, first, key=index_key)
elif type == 'triple':
first, second, third = split_into(3, 'triple', value)
add_entry(first, second+' '+third, key=index_key)
add_entry(second, third+', '+first, key=index_key)
add_entry(third, first+' '+second, key=index_key)
elif type == 'see':
first, second = split_into(2, 'see', value)
add_entry(first, _('see %s') % second, link=False,
key=index_key)
elif type == 'seealso':
first, second = split_into(2, 'see', value)
add_entry(first, _('see also %s') % second, link=False,
key=index_key)
else:
self.warn(fn, 'unknown index entry type %r' % type)
except ValueError as err:
self.warn(fn, str(err))

# sort the index entries; put all symbols at the front, even those
# following the letters in ASCII, this is where the chr(127) comes from
def keyfunc(entry, lcletters=string.ascii_lowercase + '_'):
lckey = unicodedata.normalize('NFD', entry[0].lower())
if lckey[0:1] in lcletters:
lckey = chr(127) + lckey
# ensure a determinstic order *within* letters by also sorting on
# the entry itself
return (lckey, entry[0])
newlist = sorted(new.items(), key=keyfunc)

if group_entries:
# fixup entries: transform
#   func() (in module foo)
#   func() (in module bar)
# into
#   func()
#     (in module foo)
#     (in module bar)
oldkey = ''
oldsubitems = None
i = 0
while i < len(newlist):
key, (targets, subitems, _key) = newlist[i]
# cannot move if it has subitems; structure gets too complex
if not subitems:
m = _fixre.match(key)
if m:
if oldkey == m.group(1):
# prefixes match: add entry as subitem of the
# previous entry
oldsubitems.setdefault(m.group(2), [[], {}, _key])[0].\
extend(targets)
del newlist[i]
continue
oldkey = m.group(1)
else:
oldkey = key
oldsubitems = subitems
i += 1

# group the entries by letter
def keyfunc2(item, letters=string.ascii_uppercase + '_'):
# hack: mutating the subitems dicts to a list in the keyfunc
k, v = item
v[1] = sorted((si, se) for (si, (se, void, void)) in iteritems(v[1]))
if v[2] is None:
# now calculate the key
letter = unicodedata.normalize('NFD', k[0])[0].upper()
if letter in letters:
return letter
else:
# get all other symbols under one heading
return _('Symbols')
else:
return v[2]
return [(key_, list(group))
for (key_, group) in groupby(newlist, keyfunc2)]

def collect_relations(self):
traversed = set()

def traverse_toctree(parent, docname):
if parent == docname:
self.warn(docname, 'self referenced toctree found. Ignored.')
return

# traverse toctree by pre-order
yield parent, docname
traversed.add(docname)

for child in (self.toctree_includes.get(docname) or []):
for subparent, subdocname in traverse_toctree(docname, child):
if subdocname not in traversed:
yield subparent, subdocname
traversed.add(subdocname)

relations = {}
docnames = traverse_toctree(None, self.config.master_doc)
prevdoc = None
parent, docname = next(docnames)
for nextparent, nextdoc in docnames:
relations[docname] = [parent, prevdoc, nextdoc]
prevdoc = docname
docname = nextdoc
parent = nextparent

relations[docname] = [parent, prevdoc, None]

return relations

def check_consistency(self):
"""Do consistency checks."""
for docname in sorted(self.all_docs):
if docname not in self.files_to_rebuild:
if docname == self.config.master_doc:
# the master file is not included anywhere ;)
continue
if 'orphan' in self.metadata[docname]:
continue
self.warn(docname, 'document isn\'t included in any toctree')

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.errors

# -*- coding: utf-8 -*-
"""
sphinx.errors
~~~~~~~~~~~~~

Contains SphinxError and a few subclasses (in an extra module to avoid
circular import problems).

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import traceback

[docs]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'

[docs]class ExtensionError(SphinxError):
"""Raised if something's wrong with the configuration."""
category = 'Extension error'

def __init__(self, message, orig_exc=None):
SphinxError.__init__(self, 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 = SphinxError.__str__(self)
if self.orig_exc:
return '%s (exception: %s)' % (parent_str, self.orig_exc)
return parent_str

[docs]class ConfigError(SphinxError):
category = 'Configuration error'

[docs]class ThemeError(SphinxError):
category = 'Theme error'

[docs]class VersionRequirementError(SphinxError):
category = 'Sphinx version error'

class PycodeError(Exception):
def __str__(self):
res = self.args[0]
if len(self.args) > 1:
res += ' (exception was: %r)' % self.args[1]
return res

class SphinxParallelError(Exception):
def __init__(self, orig_exc, traceback):
self.orig_exc = orig_exc
self.traceback = traceback

def __str__(self):
return traceback.format_exception_only(
self.orig_exc.__class__, self.orig_exc)[0].strip()

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.ext.autodoc

# -*- coding: utf-8 -*-
"""
sphinx.ext.autodoc
~~~~~~~~~~~~~~~~~~

Automatically insert docstrings for functions, classes or whole modules into
the doctree, thus avoiding duplication between docstrings and documentation
for those who like elaborate docstrings.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import re
import sys
import inspect
import traceback
from types import FunctionType, BuiltinFunctionType, MethodType

from six import PY2, iterkeys, iteritems, itervalues, text_type, class_types, \
string_types, StringIO
from docutils import nodes
from docutils.utils import assemble_option_dict
from docutils.statemachine import ViewList

import sphinx
from sphinx.util import rpartition, force_decode
from sphinx.locale import _
from sphinx.pycode import ModuleAnalyzer, PycodeError
from sphinx.application import ExtensionError
from sphinx.util.nodes import nested_parse_with_titles
from sphinx.util.compat import Directive
from sphinx.util.inspect import getargspec, isdescriptor, safe_getmembers, \
safe_getattr, object_description, is_builtin_class_method
from sphinx.util.docstrings import prepare_docstring

try:
import typing
except ImportError:
typing = None

#: extended signature RE: with explicit module name separated by ::
py_ext_sig_re = re.compile(
r'''^ ([\w.]+::)?            # explicit module name
([\w.]+\.)?            # module and/or class name(s)
(\w+)  \s*             # thing name
(?: \((.*)\)           # optional: arguments
(?:\s* -> \s* (.*))?  #           return annotation
)? $                   # and nothing more
''', re.VERBOSE)

class DefDict(dict):
"""A dict that returns a default on nonexisting keys."""
def __init__(self, default):
dict.__init__(self)
self.default = default

def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
return self.default

def __bool__(self):
# docutils check "if option_spec"
return True
__nonzero__ = __bool__  # for python2 compatibility

def identity(x):
return x

class Options(dict):
"""A dict/attribute hybrid that returns None on nonexisting keys."""
def __getattr__(self, name):
try:
return self[name.replace('_', '-')]
except KeyError:
return None

class _MockModule(object):
"""Used by autodoc_mock_imports."""
def __init__(self, *args, **kwargs):
pass

def __call__(self, *args, **kwargs):
return _MockModule()

@classmethod
def __getattr__(cls, name):
if name in ('__file__', '__path__'):
return '/dev/null'
elif name[0] == name[0].upper():
# Not very good, we assume Uppercase names are classes...
mocktype = type(name, (), {})
mocktype.__module__ = __name__
return mocktype
else:
return _MockModule()

def mock_import(modname):
if '.' in modname:
pkg, _n, mods = modname.rpartition('.')
mock_import(pkg)
mod = _MockModule()
sys.modules[modname] = mod
return mod

ALL = object()
INSTANCEATTR = object()

def members_option(arg):
"""Used to convert the :members: option to auto directives."""
if arg is None:
return ALL
return [x.strip() for x in arg.split(',')]

def members_set_option(arg):
"""Used to convert the :members: option to auto directives."""
if arg is None:
return ALL
return set(x.strip() for x in arg.split(','))

SUPPRESS = object()

def annotation_option(arg):
if arg is None:
# suppress showing the representation of the object
return SUPPRESS
else:
return arg

def bool_option(arg):
"""Used to convert flag options to auto directives.  (Instead of
directives.flag(), which returns None).
"""
return True

class AutodocReporter(object):
"""
A reporter replacement that assigns the correct source name
and line number to a system message, as recorded in a ViewList.
"""
def __init__(self, viewlist, reporter):
self.viewlist = viewlist
self.reporter = reporter

def __getattr__(self, name):
return getattr(self.reporter, name)

def system_message(self, level, message, *children, **kwargs):
if 'line' in kwargs and 'source' not in kwargs:
try:
source, line = self.viewlist.items[kwargs['line']]
except IndexError:
pass
else:
kwargs['source'] = source
kwargs['line'] = line
return self.reporter.system_message(level, message,
*children, **kwargs)

def debug(self, *args, **kwargs):
if self.reporter.debug_flag:
return self.system_message(0, *args, **kwargs)

def info(self, *args, **kwargs):
return self.system_message(1, *args, **kwargs)

def warning(self, *args, **kwargs):
return self.system_message(2, *args, **kwargs)

def error(self, *args, **kwargs):
return self.system_message(3, *args, **kwargs)

def severe(self, *args, **kwargs):
return self.system_message(4, *args, **kwargs)

# Some useful event listener factories for autodoc-process-docstring.

[docs]def cut_lines(pre, post=0, what=None):
"""Return a listener that removes the first *pre* and last *post*
lines of every docstring.  If *what* is a sequence of strings,
only docstrings of a type in *what* will be processed.

Use like this (e.g. in the ``setup()`` function of :file:`conf.py`)::

from sphinx.ext.autodoc import cut_lines
app.connect('autodoc-process-docstring', cut_lines(4, what=['module']))

This can (and should) be used in place of :confval:`automodule_skip_lines`.
"""
def process(app, what_, name, obj, options, lines):
if what and what_ not in what:
return
del lines[:pre]
if post:
# remove one trailing blank line.
if lines and not lines[-1]:
lines.pop(-1)
del lines[-post:]
# make sure there is a blank line at the end
if lines and lines[-1]:
lines.append('')
return process

[docs]def between(marker, what=None, keepempty=False, exclude=False):
"""Return a listener that either keeps, or if *exclude* is True excludes,
lines between lines that match the *marker* regular expression.  If no line
matches, the resulting docstring would be empty, so no change will be made
unless *keepempty* is true.

If *what* is a sequence of strings, only docstrings of a type in *what* will
be processed.
"""
marker_re = re.compile(marker)

def process(app, what_, name, obj, options, lines):
if what and what_ not in what:
return
deleted = 0
delete = not exclude
orig_lines = lines[:]
for i, line in enumerate(orig_lines):
if delete:
lines.pop(i - deleted)
deleted += 1
if marker_re.match(line):
delete = not delete
if delete:
lines.pop(i - deleted)
deleted += 1
if not lines and not keepempty:
lines[:] = orig_lines
# make sure there is a blank line at the end
if lines and lines[-1]:
lines.append('')
return process

def format_annotation(annotation):
"""Return formatted representation of a type annotation.

Show qualified names for types and additional details for types from
the ``typing`` module.

Displaying complex types from ``typing`` relies on its private API.
"""
qualified_name = (annotation.__module__ + '.' + annotation.__qualname__
if annotation else repr(annotation))

if not isinstance(annotation, type):
return repr(annotation)
elif annotation.__module__ == 'builtins':
return annotation.__qualname__
elif typing:
if isinstance(annotation, typing.TypeVar):
return annotation.__name__
elif hasattr(typing, 'GenericMeta') and \
isinstance(annotation, typing.GenericMeta) and \
hasattr(annotation, '__parameters__'):
params = annotation.__parameters__
if params is not None:
param_str = ', '.join(format_annotation(p) for p in params)
return '%s[%s]' % (qualified_name, param_str)
elif hasattr(typing, 'UnionMeta') and \
isinstance(annotation, typing.UnionMeta) and \
hasattr(annotation, '__union_params__'):
params = annotation.__union_params__
if params is not None:
param_str = ', '.join(format_annotation(p) for p in params)
return '%s[%s]' % (qualified_name, param_str)
elif hasattr(typing, 'CallableMeta') and \
isinstance(annotation, typing.CallableMeta) and \
hasattr(annotation, '__args__') and \
hasattr(annotation, '__result__'):
args = annotation.__args__
if args is Ellipsis:
args_str = '...'
else:
formatted_args = (format_annotation(a) for a in args)
args_str = '[%s]' % ', '.join(formatted_args)
return '%s[%s, %s]' % (qualified_name,
args_str,
format_annotation(annotation.__result__))
elif hasattr(typing, 'TupleMeta') and \
isinstance(annotation, typing.TupleMeta) and \
hasattr(annotation, '__tuple_params__') and \
hasattr(annotation, '__tuple_use_ellipsis__'):
params = annotation.__tuple_params__
if params is not None:
param_strings = [format_annotation(p) for p in params]
if annotation.__tuple_use_ellipsis__:
param_strings.append('...')
return '%s[%s]' % (qualified_name,
', '.join(param_strings))
return qualified_name

def formatargspec(function, args, varargs=None, varkw=None, defaults=None,
kwonlyargs=(), kwonlydefaults={}, annotations={}):
"""Return a string representation of an ``inspect.FullArgSpec`` tuple.

An enhanced version of ``inspect.formatargspec()`` that handles typing
annotations better.
"""

def format_arg_with_annotation(name):
if name in annotations:
return '%s: %s' % (name, format_annotation(get_annotation(name)))
return name

def get_annotation(name):
value = annotations[name]
if isinstance(value, string_types):
return introspected_hints.get(name, value)
else:
return value

introspected_hints = (typing.get_type_hints(function)
if typing and hasattr(function, '__code__') else {})

fd = StringIO()
fd.write('(')

formatted = []
defaults_start = len(args) - len(defaults) if defaults else len(args)

for i, arg in enumerate(args):
arg_fd = StringIO()
arg_fd.write(format_arg_with_annotation(arg))
if defaults and i >= defaults_start:
arg_fd.write(' = ' if arg in annotations else '=')
arg_fd.write(object_description(defaults[i - defaults_start]))
formatted.append(arg_fd.getvalue())

if varargs:
formatted.append('*' + format_arg_with_annotation(varargs))

if kwonlyargs:
formatted.append('*')
for kwarg in kwonlyargs:
arg_fd = StringIO()
arg_fd.write(format_arg_with_annotation(kwarg))
if kwonlydefaults and kwarg in kwonlydefaults:
arg_fd.write(' = ' if kwarg in annotations else '=')
arg_fd.write(object_description(kwonlydefaults[kwarg]))
formatted.append(arg_fd.getvalue())

if varkw:
formatted.append('**' + format_arg_with_annotation(varkw))

fd.write(', '.join(formatted))
fd.write(')')

if 'return' in annotations:
fd.write(' -> ')
fd.write(format_annotation(get_annotation('return')))

return fd.getvalue()

class Documenter(object):
"""
A Documenter knows how to autodocument a single object type.  When
registered with the AutoDirective, it will be used to document objects
of that type when needed by autodoc.

Its *objtype* attribute selects what auto directive it is assigned to
(the directive name is 'auto' + objtype), and what directive it generates
by default, though that can be overridden by an attribute called
*directivetype*.

A Documenter has an *option_spec* that works like a docutils directive's;
in fact, it will be used to parse an auto directive's options that matches
the documenter.
"""
#: name by which the directive is called (auto...) and the default
#: generated directive name
objtype = 'object'
#: indentation by which to indent the directive content
content_indent = u'   '
#: priority if multiple documenters return True from can_document_member
priority = 0
#: order if autodoc_member_order is set to 'groupwise'
member_order = 0
#: true if the generated content may contain titles
titles_allowed = False

option_spec = {'noindex': bool_option}

@staticmethod
def get_attr(obj, name, *defargs):
"""getattr() override for types such as Zope interfaces."""
for typ, func in iteritems(AutoDirective._special_attrgetters):
if isinstance(obj, typ):
return func(obj, name, *defargs)
return safe_getattr(obj, name, *defargs)

@classmethod
def can_document_member(cls, member, membername, isattr, parent):
"""Called to see if a member can be documented by this documenter."""
raise NotImplementedError('must be implemented in subclasses')

def __init__(self, directive, name, indent=u''):
self.directive = directive
self.env = directive.env
self.options = directive.genopt
self.name = name
self.indent = indent
# the module and object path within the module, and the fully
# qualified name (all set after resolve_name succeeds)
self.modname = None
self.module = None
self.objpath = None
self.fullname = None
# extra signature items (arguments and return annotation,
# also set after resolve_name succeeds)
self.args = None
self.retann = None
# the object to document (set after import_object succeeds)
self.object = None
self.object_name = None
# the parent/owner of the object to document
self.parent = None
# the module analyzer to get at attribute docs, or None
self.analyzer = None

def add_line(self, line, source, *lineno):
"""Append one line of generated reST to the output."""
self.directive.result.append(self.indent + line, source, *lineno)

def resolve_name(self, modname, parents, path, base):
"""Resolve the module and name of the object to document given by the
arguments and the current module/class.

Must return a pair of the module name and a chain of attributes; for
example, it would return ``('zipfile', ['ZipFile', 'open'])`` for the
``zipfile.ZipFile.open`` method.
"""
raise NotImplementedError('must be implemented in subclasses')

def parse_name(self):
"""Determine what module to import and what attribute to document.

Returns True and sets *self.modname*, *self.objpath*, *self.fullname*,
*self.args* and *self.retann* if parsing and resolving was successful.
"""
# first, parse the definition -- auto directives for classes and
# functions can contain a signature which is then used instead of
# an autogenerated one
try:
explicit_modname, path, base, args, retann = \
py_ext_sig_re.match(self.name).groups()
except AttributeError:
self.directive.warn('invalid signature for auto%s (%r)' %
(self.objtype, self.name))
return False

# support explicit module and class name separation via ::
if explicit_modname is not None:
modname = explicit_modname[:-2]
parents = path and path.rstrip('.').split('.') or []
else:
modname = None
parents = []

self.modname, self.objpath = \
self.resolve_name(modname, parents, path, base)

if not self.modname:
return False

self.args = args
self.retann = retann
self.fullname = (self.modname or '') + \
(self.objpath and '.' + '.'.join(self.objpath) or '')
return True

def import_object(self):
"""Import the object given by *self.modname* and *self.objpath* and set
it as *self.object*.

Returns True if successful, False if an error occurred.
"""
dbg = self.env.app.debug
if self.objpath:
dbg('[autodoc] from %s import %s',
self.modname, '.'.join(self.objpath))
try:
dbg('[autodoc] import %s', self.modname)
for modname in self.env.config.autodoc_mock_imports:
dbg('[autodoc] adding a mock module %s!', self.modname)
mock_import(modname)
__import__(self.modname)
parent = None
obj = self.module = sys.modules[self.modname]
dbg('[autodoc] => %r', obj)
for part in self.objpath:
parent = obj
dbg('[autodoc] getattr(_, %r)', part)
obj = self.get_attr(obj, part)
dbg('[autodoc] => %r', obj)
self.object_name = part
self.parent = parent
self.object = obj
return True
# this used to only catch SyntaxError, ImportError and AttributeError,
# but importing modules with side effects can raise all kinds of errors
except (Exception, SystemExit) as e:
if self.objpath:
errmsg = 'autodoc: failed to import %s %r from module %r' % \
(self.objtype, '.'.join(self.objpath), self.modname)
else:
errmsg = 'autodoc: failed to import %s %r' % \
(self.objtype, self.fullname)
if isinstance(e, SystemExit):
errmsg += ('; the module executes module level statement ' +
'and it might call sys.exit().')
else:
errmsg += '; the following exception was raised:\n%s' % \
traceback.format_exc()
if PY2:
errmsg = errmsg.decode('utf-8')
dbg(errmsg)
self.directive.warn(errmsg)
self.env.note_reread()
return False

def get_real_modname(self):
"""Get the real module name of an object to document.

It can differ from the name of the module through which the object was
imported.
"""
return self.get_attr(self.object, '__module__', None) or self.modname

def check_module(self):
"""Check if *self.object* is really defined in the module given by
*self.modname*.
"""
if self.options.imported_members:
return True

modname = self.get_attr(self.object, '__module__', None)
if modname and modname != self.modname:
return False
return True

def format_args(self):
"""Format the argument signature of *self.object*.

Should return None if the object does not have a signature.
"""
return None

def format_name(self):
"""Format the name of *self.object*.

This normally should be something that can be parsed by the generated
directive, but doesn't need to be (Sphinx will display it unparsed
then).
"""
# normally the name doesn't contain the module (except for module
# directives of course)
return '.'.join(self.objpath) or self.modname

def format_signature(self):
"""Format the signature (arguments and return annotation) of the object.

Let the user process it via the ``autodoc-process-signature`` event.
"""
if self.args is not None:
# signature given explicitly
args = "(%s)" % self.args
else:
# try to introspect the signature
try:
args = self.format_args()
except Exception as err:
self.directive.warn('error while formatting arguments for '
'%s: %s' % (self.fullname, err))
args = None

retann = self.retann

result = self.env.app.emit_firstresult(
'autodoc-process-signature', self.objtype, self.fullname,
self.object, self.options, args, retann)
if result:
args, retann = result

if args is not None:
return args + (retann and (' -> %s' % retann) or '')
else:
return ''

def add_directive_header(self, sig):
"""Add the directive header and options to the generated content."""
domain = getattr(self, 'domain', 'py')
directive = getattr(self, 'directivetype', self.objtype)
name = self.format_name()
sourcename = self.get_sourcename()
self.add_line(u'.. %s:%s:: %s%s' % (domain, directive, name, sig),
sourcename)
if self.options.noindex:
self.add_line(u'   :noindex:', sourcename)
if self.objpath:
# Be explicit about the module, this is necessary since .. class::
# etc. don't support a prepended module name
self.add_line(u'   :module: %s' % self.modname, sourcename)

def get_doc(self, encoding=None, ignore=1):
"""Decode and return lines of the docstring(s) for the object."""
docstring = self.get_attr(self.object, '__doc__', None)
# make sure we have Unicode docstrings, then sanitize and split
# into lines
if isinstance(docstring, text_type):
return [prepare_docstring(docstring, ignore)]
elif isinstance(docstring, str):  # this will not trigger on Py3
return [prepare_docstring(force_decode(docstring, encoding),
ignore)]
# ... else it is something strange, let's ignore it
return []

def process_doc(self, docstrings):
"""Let the user process the docstrings before adding them."""
for docstringlines in docstrings:
if self.env.app:
# let extensions preprocess docstrings
self.env.app.emit('autodoc-process-docstring',
self.objtype, self.fullname, self.object,
self.options, docstringlines)
for line in docstringlines:
yield line

def get_sourcename(self):
if self.analyzer:
# prevent encoding errors when the file name is non-ASCII
if not isinstance(self.analyzer.srcname, text_type):
filename = text_type(self.analyzer.srcname,
sys.getfilesystemencoding(), 'replace')
else:
filename = self.analyzer.srcname
return u'%s:docstring of %s' % (filename, self.fullname)
return u'docstring of %s' % self.fullname

def add_content(self, more_content, no_docstring=False):
"""Add content from docstrings, attribute documentation and user."""
# set sourcename and add content from attribute documentation
sourcename = self.get_sourcename()
if self.analyzer:
attr_docs = self.analyzer.find_attr_docs()
if self.objpath:
key = ('.'.join(self.objpath[:-1]), self.objpath[-1])
if key in attr_docs:
no_docstring = True
docstrings = [attr_docs[key]]
for i, line in enumerate(self.process_doc(docstrings)):
self.add_line(line, sourcename, i)

# add content from docstrings
if not no_docstring:
encoding = self.analyzer and self.analyzer.encoding
docstrings = self.get_doc(encoding)
if not docstrings:
# append at least a dummy docstring, so that the event
# autodoc-process-docstring is fired and can add some
# content if desired
docstrings.append([])
for i, line in enumerate(self.process_doc(docstrings)):
self.add_line(line, sourcename, i)

# add additional content (e.g. from document), if present
if more_content:
for line, src in zip(more_content.data, more_content.items):
self.add_line(line, src[0], src[1])

def get_object_members(self, want_all):
"""Return `(members_check_module, members)` where `members` is a
list of `(membername, member)` pairs of the members of *self.object*.

If *want_all* is True, return all members.  Else, only return those
members given by *self.options.members* (which may also be none).
"""
analyzed_member_names = set()
if self.analyzer:
attr_docs = self.analyzer.find_attr_docs()
namespace = '.'.join(self.objpath)
for item in iteritems(attr_docs):
if item[0][0] == namespace:
analyzed_member_names.add(item[0][1])
if not want_all:
if not self.options.members:
return False, []
# specific members given
members = []
for mname in self.options.members:
try:
members.append((mname, self.get_attr(self.object, mname)))
except AttributeError:
if mname not in analyzed_member_names:
self.directive.warn('missing attribute %s in object %s'
% (mname, self.fullname))
elif self.options.inherited_members:
# safe_getmembers() uses dir() which pulls in members from all
# base classes
members = safe_getmembers(self.object, attr_getter=self.get_attr)
else:
# __dict__ contains only the members directly defined in
# the class (but get them via getattr anyway, to e.g. get
# unbound method objects instead of function objects);
# using list(iterkeys()) because apparently there are objects for which
# __dict__ changes while getting attributes
try:
obj_dict = self.get_attr(self.object, '__dict__')
except AttributeError:
members = []
else:
members = [(mname, self.get_attr(self.object, mname, None))
for mname in list(iterkeys(obj_dict))]
membernames = set(m[0] for m in members)
# add instance attributes from the analyzer
for aname in analyzed_member_names:
if aname not in membernames and \
(want_all or aname in self.options.members):
members.append((aname, INSTANCEATTR))
return False, sorted(members)

def filter_members(self, members, want_all):
"""Filter the given member list.

Members are skipped if

- they are private (except if given explicitly or the private-members
option is set)
- they are special methods (except if given explicitly or the
special-members option is set)
- they are undocumented (except if the undoc-members option is set)

The user can override the skipping decision by connecting to the
``autodoc-skip-member`` event.
"""
ret = []

# search for members in source code too
namespace = '.'.join(self.objpath)  # will be empty for modules

if self.analyzer:
attr_docs = self.analyzer.find_attr_docs()
else:
attr_docs = {}

# process members and determine which to skip
for (membername, member) in members:
# if isattr is True, the member is documented as an attribute
isattr = False

doc = self.get_attr(member, '__doc__', None)
# if the member __doc__ is the same as self's __doc__, it's just
# inherited and therefore not the member's doc
cls = self.get_attr(member, '__class__', None)
if cls:
cls_doc = self.get_attr(cls, '__doc__', None)
if cls_doc == doc:
doc = None
has_doc = bool(doc)

keep = False
if want_all and membername.startswith('__') and \
membername.endswith('__') and len(membername) > 4:
# special __methods__
if self.options.special_members is ALL and \
membername != '__doc__':
keep = has_doc or self.options.undoc_members
elif self.options.special_members and \
self.options.special_members is not ALL and \
membername in self.options.special_members:
keep = has_doc or self.options.undoc_members
elif want_all and membername.startswith('_'):
# ignore members whose name starts with _ by default
keep = self.options.private_members and \
(has_doc or self.options.undoc_members)
elif (namespace, membername) in attr_docs:
# keep documented attributes
keep = True
isattr = True
else:
# ignore undocumented members if :undoc-members: is not given
keep = has_doc or self.options.undoc_members

# give the user a chance to decide whether this member
# should be skipped
if self.env.app:
# let extensions preprocess docstrings
skip_user = self.env.app.emit_firstresult(
'autodoc-skip-member', self.objtype, membername, member,
not keep, self.options)
if skip_user is not None:
keep = not skip_user

if keep:
ret.append((membername, member, isattr))

return ret

def document_members(self, all_members=False):
"""Generate reST for member documentation.

If *all_members* is True, do all members, else those given by
*self.options.members*.
"""
# set current namespace for finding members
self.env.temp_data['autodoc:module'] = self.modname
if self.objpath:
self.env.temp_data['autodoc:class'] = self.objpath[0]

want_all = all_members or self.options.inherited_members or \
self.options.members is ALL
# find out which members are documentable
members_check_module, members = self.get_object_members(want_all)

# remove members given by exclude-members
if self.options.exclude_members:
members = [(membername, member) for (membername, member) in members
if membername not in self.options.exclude_members]

# document non-skipped members
memberdocumenters = []
for (mname, member, isattr) in self.filter_members(members, want_all):
classes = [cls for cls in itervalues(AutoDirective._registry)
if cls.can_document_member(member, mname, isattr, self)]
if not classes:
# don't know how to document this member
continue
# prefer the documenter with the highest priority
classes.sort(key=lambda cls: cls.priority)
# give explicitly separated module name, so that members
# of inner classes can be documented
full_mname = self.modname + '::' + \
'.'.join(self.objpath + [mname])
documenter = classes[-1](self.directive, full_mname, self.indent)
memberdocumenters.append((documenter, isattr))
member_order = self.options.member_order or \
self.env.config.autodoc_member_order
if member_order == 'groupwise':
# sort by group; relies on stable sort to keep items in the
# same group sorted alphabetically
memberdocumenters.sort(key=lambda e: e[0].member_order)
elif member_order == 'bysource' and self.analyzer:
# sort by source order, by virtue of the module analyzer
tagorder = self.analyzer.tagorder

def keyfunc(entry):
fullname = entry[0].name.split('::')[1]
return tagorder.get(fullname, len(tagorder))
memberdocumenters.sort(key=keyfunc)

for documenter, isattr in memberdocumenters:
documenter.generate(
all_members=True, real_modname=self.real_modname,
check_module=members_check_module and not isattr)

# reset current objects
self.env.temp_data['autodoc:module'] = None
self.env.temp_data['autodoc:class'] = None

def generate(self, more_content=None, real_modname=None,
check_module=False, all_members=False):
"""Generate reST for the object given by *self.name*, and possibly for
its members.

If *more_content* is given, include that content. If *real_modname* is
given, use that module name to find attribute docs. If *check_module* is
True, only generate if the object is defined in the module name it is
imported from. If *all_members* is True, document all members.
"""
if not self.parse_name():
# need a module to import
self.directive.warn(
'don\'t know which module to import for autodocumenting '
'%r (try placing a "module" or "currentmodule" directive '
'in the document, or giving an explicit module name)'
% self.name)
return

# now, import the module and get object to document
if not self.import_object():
return

# If there is no real module defined, figure out which to use.
# The real module is used in the module analyzer to look up the module
# where the attribute documentation would actually be found in.
# This is used for situations where you have a module that collects the
# functions and classes of internal submodules.
self.real_modname = real_modname or self.get_real_modname()

# try to also get a source code analyzer for attribute docs
try:
self.analyzer = ModuleAnalyzer.for_module(self.real_modname)
# parse right now, to get PycodeErrors on parsing (results will
# be cached anyway)
self.analyzer.find_attr_docs()
except PycodeError as err:
self.env.app.debug('[autodoc] module analyzer failed: %s', err)
# no source file -- e.g. for builtin and C modules
self.analyzer = None
# at least add the module.__file__ as a dependency
if hasattr(self.module, '__file__') and self.module.__file__:
self.directive.filename_set.add(self.module.__file__)
else:
self.directive.filename_set.add(self.analyzer.srcname)

# check __module__ of object (for members not given explicitly)
if check_module:
if not self.check_module():
return

sourcename = self.get_sourcename()

# make sure that the result starts with an empty line.  This is
# necessary for some situations where another directive preprocesses
# reST and no starting newline is present
self.add_line(u'', sourcename)

# format the object's signature, if any
sig = self.format_signature()

# generate the directive header and options, if applicable
self.add_directive_header(sig)
self.add_line(u'', sourcename)

# e.g. the module directive doesn't have content
self.indent += self.content_indent

# add all content (from docstrings, attribute docs etc.)
self.add_content(more_content)

# document members, if possible
self.document_members(all_members)

class ModuleDocumenter(Documenter):
"""
Specialized Documenter subclass for modules.
"""
objtype = 'module'
content_indent = u''
titles_allowed = True

option_spec = {
'members': members_option, 'undoc-members': bool_option,
'noindex': bool_option, 'inherited-members': bool_option,
'show-inheritance': bool_option, 'synopsis': identity,
'platform': identity, 'deprecated': bool_option,
'member-order': identity, 'exclude-members': members_set_option,
'private-members': bool_option, 'special-members': members_option,
'imported-members': bool_option,
}

@classmethod
def can_document_member(cls, member, membername, isattr, parent):
# don't document submodules automatically
return False

def resolve_name(self, modname, parents, path, base):
if modname is not None:
self.directive.warn('"::" in automodule name doesn\'t make sense')
return (path or '') + base, []

def parse_name(self):
ret = Documenter.parse_name(self)
if self.args or self.retann:
self.directive.warn('signature arguments or return annotation '
'given for automodule %s' % self.fullname)
return ret

def add_directive_header(self, sig):
Documenter.add_directive_header(self, sig)

sourcename = self.get_sourcename()

# add some module-specific options
if self.options.synopsis:
self.add_line(
u'   :synopsis: ' + self.options.synopsis, sourcename)
if self.options.platform:
self.add_line(
u'   :platform: ' + self.options.platform, sourcename)
if self.options.deprecated:
self.add_line(u'   :deprecated:', sourcename)

def get_object_members(self, want_all):
if want_all:
if not hasattr(self.object, '__all__'):
# for implicit module members, check __module__ to avoid
# documenting imported objects
return True, safe_getmembers(self.object)
else:
memberlist = self.object.__all__
# Sometimes __all__ is broken...
if not isinstance(memberlist, (list, tuple)) or not \
all(isinstance(entry, string_types) for entry in memberlist):
self.directive.warn(
'__all__ should be a list of strings, not %r '
'(in module %s) -- ignoring __all__' %
(memberlist, self.fullname))
# fall back to all members
return True, safe_getmembers(self.object)
else:
memberlist = self.options.members or []
ret = []
for mname in memberlist:
try:
ret.append((mname, safe_getattr(self.object, mname)))
except AttributeError:
self.directive.warn(
'missing attribute mentioned in :members: or __all__: '
'module %s, attribute %s' % (
safe_getattr(self.object, '__name__', '???'), mname))
return False, ret

class ModuleLevelDocumenter(Documenter):
"""
Specialized Documenter subclass for objects on module level (functions,
classes, data/constants).
"""
def resolve_name(self, modname, parents, path, base):
if modname is None:
if path:
modname = path.rstrip('.')
else:
# if documenting a toplevel object without explicit module,
# it can be contained in another auto directive ...
modname = self.env.temp_data.get('autodoc:module')
# ... or in the scope of a module directive
if not modname:
modname = self.env.ref_context.get('py:module')
# ... else, it stays None, which means invalid
return modname, parents + [base]

class ClassLevelDocumenter(Documenter):
"""
Specialized Documenter subclass for objects on class level (methods,
attributes).
"""
def resolve_name(self, modname, parents, path, base):
if modname is None:
if path:
mod_cls = path.rstrip('.')
else:
mod_cls = None
# if documenting a class-level object without path,
# there must be a current class, either from a parent
# auto directive ...
mod_cls = self.env.temp_data.get('autodoc:class')
# ... or from a class directive
if mod_cls is None:
mod_cls = self.env.ref_context.get('py:class')
# ... if still None, there's no way to know
if mod_cls is None:
return None, []
modname, cls = rpartition(mod_cls, '.')
parents = [cls]
# if the module name is still missing, get it like above
if not modname:
modname = self.env.temp_data.get('autodoc:module')
if not modname:
modname = self.env.ref_context.get('py:module')
# ... else, it stays None, which means invalid
return modname, parents + [base]

class DocstringSignatureMixin(object):
"""
Mixin for FunctionDocumenter and MethodDocumenter to provide the
feature of reading the signature from the docstring.
"""

def _find_signature(self, encoding=None):
docstrings = self.get_doc(encoding)
self._new_docstrings = docstrings[:]
result = None
for i, doclines in enumerate(docstrings):
# no lines in docstring, no match
if not doclines:
continue
# match first line of docstring against signature RE
match = py_ext_sig_re.match(doclines[0])
if not match:
continue
exmod, path, base, args, retann = match.groups()
# the base name must match ours
valid_names = [self.objpath[-1]]
if isinstance(self, ClassDocumenter):
valid_names.append('__init__')
if hasattr(self.object, '__mro__'):
valid_names.extend(cls.__name__ for cls in self.object.__mro__)
if base not in valid_names:
continue
# re-prepare docstring to ignore more leading indentation
self._new_docstrings[i] = prepare_docstring('\n'.join(doclines[1:]))
result = args, retann
# don't look any further
break
return result

def get_doc(self, encoding=None, ignore=1):
lines = getattr(self, '_new_docstrings', None)
if lines is not None:
return lines
return Documenter.get_doc(self, encoding, ignore)

def format_signature(self):
if self.args is None and self.env.config.autodoc_docstring_signature:
# only act if a signature is not explicitly given already, and if
# the feature is enabled
result = self._find_signature()
if result is not None:
self.args, self.retann = result
return Documenter.format_signature(self)

class DocstringStripSignatureMixin(DocstringSignatureMixin):
"""
Mixin for AttributeDocumenter to provide the
feature of stripping any function signature from the docstring.
"""
def format_signature(self):
if self.args is None and self.env.config.autodoc_docstring_signature:
# only act if a signature is not explicitly given already, and if
# the feature is enabled
result = self._find_signature()
if result is not None:
# Discarding _args is a only difference with
# DocstringSignatureMixin.format_signature.
# Documenter.format_signature use self.args value to format.
_args, self.retann = result
return Documenter.format_signature(self)

class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter):
"""
Specialized Documenter subclass for functions.
"""
objtype = 'function'
member_order = 30

@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return isinstance(member, (FunctionType, BuiltinFunctionType))

def format_args(self):
if inspect.isbuiltin(self.object) or \
inspect.ismethoddescriptor(self.object):
# cannot introspect arguments of a C function or method
return None
try:
argspec = getargspec(self.object)
except TypeError:
if (is_builtin_class_method(self.object, '__new__') and
is_builtin_class_method(self.object, '__init__')):
raise TypeError('%r is a builtin class' % self.object)

# if a class should be documented as function (yay duck
# typing) we try to use the constructor signature as function
# signature without the first argument.
try:
argspec = getargspec(self.object.__new__)
except TypeError:
argspec = getargspec(self.object.__init__)
if argspec[0]:
del argspec[0][0]
args = formatargspec(self.object, *argspec)
# escape backslashes for reST
args = args.replace('\\', '\\\\')
return args

def document_members(self, all_members=False):
pass

class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter):
"""
Specialized Documenter subclass for classes.
"""
objtype = 'class'
member_order = 20
option_spec = {
'members': members_option, 'undoc-members': bool_option,
'noindex': bool_option, 'inherited-members': bool_option,
'show-inheritance': bool_option, 'member-order': identity,
'exclude-members': members_set_option,
'private-members': bool_option, 'special-members': members_option,
}

@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return isinstance(member, class_types)

def import_object(self):
ret = ModuleLevelDocumenter.import_object(self)
# if the class is documented under another name, document it
# as data/attribute
if ret:
if hasattr(self.object, '__name__'):
self.doc_as_attr = (self.objpath[-1] != self.object.__name__)
else:
self.doc_as_attr = True
return ret

def format_args(self):
# for classes, the relevant signature is the __init__ method's
initmeth = self.get_attr(self.object, '__init__', None)
# classes without __init__ method, default __init__ or
# __init__ written in C?
if initmeth is None or \
is_builtin_class_method(self.object, '__init__') or \
not(inspect.ismethod(initmeth) or inspect.isfunction(initmeth)):
return None
try:
argspec = getargspec(initmeth)
except TypeError:
# still not possible: happens e.g. for old-style classes
# with __init__ in C
return None
if argspec[0] and argspec[0][0] in ('cls', 'self'):
del argspec[0][0]
return formatargspec(initmeth, *argspec)

def format_signature(self):
if self.doc_as_attr:
return ''

return DocstringSignatureMixin.format_signature(self)

def add_directive_header(self, sig):
if self.doc_as_attr:
self.directivetype = 'attribute'
Documenter.add_directive_header(self, sig)

# add inheritance info, if wanted
if not self.doc_as_attr and self.options.show_inheritance:
sourcename = self.get_sourcename()
self.add_line(u'', sourcename)
if hasattr(self.object, '__bases__') and len(self.object.__bases__):
bases = [b.__module__ in ('__builtin__', 'builtins') and
u':class:`%s`' % b.__name__ or
u':class:`%s.%s`' % (b.__module__, b.__name__)
for b in self.object.__bases__]
self.add_line(_(u'   Bases: %s') % ', '.join(bases),
sourcename)

def get_doc(self, encoding=None, ignore=1):
lines = getattr(self, '_new_docstrings', None)
if lines is not None:
return lines

content = self.env.config.autoclass_content

docstrings = []
attrdocstring = self.get_attr(self.object, '__doc__', None)
if attrdocstring:
docstrings.append(attrdocstring)

# for classes, what the "docstring" is can be controlled via a
# config value; the default is only the class docstring
if content in ('both', 'init'):
initdocstring = self.get_attr(
self.get_attr(self.object, '__init__', None), '__doc__')
# for new-style classes, no __init__ means default __init__
if (initdocstring is not None and
(initdocstring == object.__init__.__doc__ or  # for pypy
initdocstring.strip() == object.__init__.__doc__)):  # for !pypy
initdocstring = None
if not initdocstring:
# try __new__
initdocstring = self.get_attr(
self.get_attr(self.object, '__new__', None), '__doc__')
# for new-style classes, no __new__ means default __new__
if (initdocstring is not None and
(initdocstring == object.__new__.__doc__ or  # for pypy
initdocstring.strip() == object.__new__.__doc__)):  # for !pypy
initdocstring = None
if initdocstring:
if content == 'init':
docstrings = [initdocstring]
else:
docstrings.append(initdocstring)
doc = []
for docstring in docstrings:
if isinstance(docstring, text_type):
doc.append(prepare_docstring(docstring, ignore))
elif isinstance(docstring, str):  # this will not trigger on Py3
doc.append(prepare_docstring(force_decode(docstring, encoding),
ignore))
return doc

def add_content(self, more_content, no_docstring=False):
if self.doc_as_attr:
classname = safe_getattr(self.object, '__name__', None)
if classname:
content = ViewList(
[_('alias of :class:`%s`') % classname], source='')
ModuleLevelDocumenter.add_content(self, content,
no_docstring=True)
else:
ModuleLevelDocumenter.add_content(self, more_content)

def document_members(self, all_members=False):
if self.doc_as_attr:
return
ModuleLevelDocumenter.document_members(self, all_members)

class ExceptionDocumenter(ClassDocumenter):
"""
Specialized ClassDocumenter subclass for exceptions.
"""
objtype = 'exception'
member_order = 10

# needs a higher priority than ClassDocumenter
priority = 10

@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return isinstance(member, class_types) and \
issubclass(member, BaseException)

class DataDocumenter(ModuleLevelDocumenter):
"""
Specialized Documenter subclass for data items.
"""
objtype = 'data'
member_order = 40
priority = -10
option_spec = dict(ModuleLevelDocumenter.option_spec)
option_spec["annotation"] = annotation_option

@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return isinstance(parent, ModuleDocumenter) and isattr

def add_directive_header(self, sig):
ModuleLevelDocumenter.add_directive_header(self, sig)
sourcename = self.get_sourcename()
if not self.options.annotation:
try:
objrepr = object_description(self.object)
except ValueError:
pass
else:
self.add_line(u'   :annotation: = ' + objrepr, sourcename)
elif self.options.annotation is SUPPRESS:
pass
else:
self.add_line(u'   :annotation: %s' % self.options.annotation,
sourcename)

def document_members(self, all_members=False):
pass

class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter):
"""
Specialized Documenter subclass for methods (normal, static and class).
"""
objtype = 'method'
member_order = 50
priority = 1  # must be more than FunctionDocumenter

@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return inspect.isroutine(member) and \
not isinstance(parent, ModuleDocumenter)

def import_object(self):
ret = ClassLevelDocumenter.import_object(self)
if not ret:
return ret

# to distinguish classmethod/staticmethod
obj = self.parent.__dict__.get(self.object_name)

if isinstance(obj, classmethod):
self.directivetype = 'classmethod'
# document class and static members before ordinary ones
self.member_order = self.member_order - 1
elif isinstance(obj, staticmethod):
self.directivetype = 'staticmethod'
# document class and static members before ordinary ones
self.member_order = self.member_order - 1
else:
self.directivetype = 'method'
return ret

def format_args(self):
if inspect.isbuiltin(self.object) or \
inspect.ismethoddescriptor(self.object):
# can never get arguments of a C function or method
return None
argspec = getargspec(self.object)
if argspec[0] and argspec[0][0] in ('cls', 'self'):
del argspec[0][0]
args = formatargspec(self.object, *argspec)
# escape backslashes for reST
args = args.replace('\\', '\\\\')
return args

def document_members(self, all_members=False):
pass

class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter):
"""
Specialized Documenter subclass for attributes.
"""
objtype = 'attribute'
member_order = 60
option_spec = dict(ModuleLevelDocumenter.option_spec)
option_spec["annotation"] = annotation_option

# must be higher than the MethodDocumenter, else it will recognize
# some non-data descriptors as methods
priority = 10

method_types = (FunctionType, BuiltinFunctionType, MethodType)

@classmethod
def can_document_member(cls, member, membername, isattr, parent):
isdatadesc = isdescriptor(member) and not \
isinstance(member, cls.method_types) and not \
type(member).__name__ in ("type", "method_descriptor",
"instancemethod")
return isdatadesc or (not isinstance(parent, ModuleDocumenter) and
not inspect.isroutine(member) and
not isinstance(member, class_types))

def document_members(self, all_members=False):
pass

def import_object(self):
ret = ClassLevelDocumenter.import_object(self)
if isdescriptor(self.object) and \
not isinstance(self.object, self.method_types):
self._datadescriptor = True
else:
# if it's not a data descriptor
self._datadescriptor = False
return ret

def get_real_modname(self):
return self.get_attr(self.parent or self.object, '__module__', None) \
or self.modname

def add_directive_header(self, sig):
ClassLevelDocumenter.add_directive_header(self, sig)
sourcename = self.get_sourcename()
if not self.options.annotation:
if not self._datadescriptor:
try:
objrepr = object_description(self.object)
except ValueError:
pass
else:
self.add_line(u'   :annotation: = ' + objrepr, sourcename)
elif self.options.annotation is SUPPRESS:
pass
else:
self.add_line(u'   :annotation: %s' % self.options.annotation,
sourcename)

def add_content(self, more_content, no_docstring=False):
if not self._datadescriptor:
# if it's not a data descriptor, its docstring is very probably the
# wrong thing to display
no_docstring = True
ClassLevelDocumenter.add_content(self, more_content, no_docstring)

class InstanceAttributeDocumenter(AttributeDocumenter):
"""
Specialized Documenter subclass for attributes that cannot be imported
because they are instance attributes (e.g. assigned in __init__).
"""
objtype = 'instanceattribute'
directivetype = 'attribute'
member_order = 60

# must be higher than AttributeDocumenter
priority = 11

@classmethod
def can_document_member(cls, member, membername, isattr, parent):
"""This documents only INSTANCEATTR members."""
return isattr and (member is INSTANCEATTR)

def import_object(self):
"""Never import anything."""
# disguise as an attribute
self.objtype = 'attribute'
self._datadescriptor = False
return True

def add_content(self, more_content, no_docstring=False):
"""Never try to get a docstring from the object."""
AttributeDocumenter.add_content(self, more_content, no_docstring=True)

class AutoDirective(Directive):
"""
The AutoDirective class is used for all autodoc directives.  It dispatches
most of the work to one of the Documenters, which it selects through its
*_registry* dictionary.

The *_special_attrgetters* attribute is used to customize ``getattr()``
calls that the Documenters make; its entries are of the form ``type:
getattr_function``.

Note: When importing an object, all items along the import chain are
accessed using the descendant's *_special_attrgetters*, thus this
dictionary should include all necessary functions for accessing
attributes of the parents.
"""
# a registry of objtype -> documenter class
_registry = {}

# a registry of type -> getattr function
_special_attrgetters = {}

# flags that can be given in autodoc_default_flags
_default_flags = set([
'members', 'undoc-members', 'inherited-members', 'show-inheritance',
'private-members', 'special-members',
])

# standard docutils directive settings
has_content = True
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
# allow any options to be passed; the options are parsed further
# by the selected Documenter
option_spec = DefDict(identity)

def warn(self, msg):
self.warnings.append(self.reporter.warning(msg, line=self.lineno))

def run(self):
self.filename_set = set()  # a set of dependent filenames
self.reporter = self.state.document.reporter
self.env = self.state.document.settings.env
self.warnings = []
self.result = ViewList()

try:
source, lineno = self.reporter.get_source_and_line(self.lineno)
except AttributeError:
source = lineno = None
self.env.app.debug('[autodoc] %s:%s: input:\n%s',
source, lineno, self.block_text)

# find out what documenter to call
objtype = self.name[4:]
doc_class = self._registry[objtype]
# add default flags
for flag in self._default_flags:
if flag not in doc_class.option_spec:
continue
negated = self.options.pop('no-' + flag, 'not given') is None
if flag in self.env.config.autodoc_default_flags and \
not negated:
self.options[flag] = None
# process the options with the selected documenter's option_spec
try:
self.genopt = Options(assemble_option_dict(
self.options.items(), doc_class.option_spec))
except (KeyError, ValueError, TypeError) as err:
# an option is either unknown or has a wrong type
msg = self.reporter.error('An option to %s is either unknown or '
'has an invalid value: %s' % (self.name, err),
line=self.lineno)
return [msg]
# generate the output
documenter = doc_class(self, self.arguments[0])
documenter.generate(more_content=self.content)
if not self.result:
return self.warnings

self.env.app.debug2('[autodoc] output:\n%s', '\n'.join(self.result))

# record all filenames as dependencies -- this will at least
# partially make automatic invalidation possible
for fn in self.filename_set:
self.state.document.settings.record_dependencies.add(fn)

# use a custom reporter that correctly assigns lines to source
# filename/description and lineno
old_reporter = self.state.memo.reporter
self.state.memo.reporter = AutodocReporter(self.result,
self.state.memo.reporter)

if documenter.titles_allowed:
node = nodes.section()
# necessary so that the child nodes get the right source/line set
node.document = self.state.document
nested_parse_with_titles(self.state, self.result, node)
else:
node = nodes.paragraph()
node.document = self.state.document
self.state.nested_parse(self.result, 0, node)
self.state.memo.reporter = old_reporter
return self.warnings + node.children

def add_documenter(cls):
"""Register a new Documenter."""
if not issubclass(cls, Documenter):
raise ExtensionError('autodoc documenter %r must be a subclass '
'of Documenter' % cls)
# actually, it should be possible to override Documenters
# if cls.objtype in AutoDirective._registry:
#    raise ExtensionError('autodoc documenter for %r is already '
#                         'registered' % cls.objtype)
AutoDirective._registry[cls.objtype] = cls

def setup(app):
app.add_autodocumenter(ModuleDocumenter)
app.add_autodocumenter(ClassDocumenter)
app.add_autodocumenter(ExceptionDocumenter)
app.add_autodocumenter(DataDocumenter)
app.add_autodocumenter(FunctionDocumenter)
app.add_autodocumenter(MethodDocumenter)
app.add_autodocumenter(AttributeDocumenter)
app.add_autodocumenter(InstanceAttributeDocumenter)

app.add_config_value('autoclass_content', 'class', True)
app.add_config_value('autodoc_member_order', 'alphabetic', True)
app.add_config_value('autodoc_default_flags', [], True)
app.add_config_value('autodoc_docstring_signature', True, True)
app.add_config_value('autodoc_mock_imports', [], True)
app.add_event('autodoc-process-docstring')
app.add_event('autodoc-process-signature')
app.add_event('autodoc-skip-member')

return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

class testcls:
"""test doc string"""

def __getattr__(self, x):
return x

def __setattr__(self, x, y):
"""Attr setter."""

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.ext.coverage

# -*- coding: utf-8 -*-
"""
sphinx.ext.coverage
~~~~~~~~~~~~~~~~~~~

Check Python modules and C API for coverage.  Mostly written by Josip
Dzolonga for the Google Highly Open Participation contest.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import re
import glob
import inspect
from os import path

from six import iteritems
from six.moves import cPickle as pickle

import sphinx
from sphinx.builders import Builder
from sphinx.util.inspect import safe_getattr

# utility
def write_header(f, text, char='-'):
f.write(text + '\n')
f.write(char * len(text) + '\n')

def compile_regex_list(name, exps, warnfunc):
lst = []
for exp in exps:
try:
lst.append(re.compile(exp))
except Exception:
warnfunc('invalid regex %r in %s' % (exp, name))
return lst

[docs]class CoverageBuilder(Builder):

name = 'coverage'

def init(self):
self.c_sourcefiles = []
for pattern in self.config.coverage_c_path:
pattern = path.join(self.srcdir, pattern)
self.c_sourcefiles.extend(glob.glob(pattern))

self.c_regexes = []
for (name, exp) in self.config.coverage_c_regexes.items():
try:
self.c_regexes.append((name, re.compile(exp)))
except Exception:
self.warn('invalid regex %r in coverage_c_regexes' % exp)

self.c_ignorexps = {}
for (name, exps) in iteritems(self.config.coverage_ignore_c_items):
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'

def write(self, *ignored):
self.py_undoc = {}
self.build_py_coverage()
self.write_py_coverage()

self.c_undoc = {}
self.build_c_coverage()
self.write_c_coverage()

def build_c_coverage(self):
# Fetch all the info from the header files
c_objects = self.env.domaindata['c']['objects']
for filename in self.c_sourcefiles:
undoc = set()
f = open(filename, 'r')
try:
for line in f:
for key, regex in self.c_regexes:
match = regex.match(line)
if match:
name = match.groups()[0]
if name not in c_objects:
for exp in self.c_ignorexps.get(key, ()):
if exp.match(name):
break
else:
undoc.add((key, name))
continue
finally:
f.close()
if undoc:
self.c_undoc[filename] = undoc

def write_c_coverage(self):
output_file = path.join(self.outdir, 'c.txt')
op = open(output_file, 'w')
try:
if self.config.coverage_write_headline:
write_header(op, 'Undocumented C API elements', '=')
op.write('\n')

for filename, undoc in iteritems(self.c_undoc):
write_header(op, filename)
for typ, name in sorted(undoc):
op.write(' * %-50s [%9s]\n' % (name, typ))
op.write('\n')
finally:
op.close()

def build_py_coverage(self):
objects = self.env.domaindata['py']['objects']
modules = self.env.domaindata['py']['modules']

skip_undoc = self.config.coverage_skip_undoc_in_source

for mod_name in modules:
ignore = False
for exp in self.mod_ignorexps:
if exp.match(mod_name):
ignore = True
break
if ignore:
continue

try:
mod = __import__(mod_name, fromlist=['foo'])
except ImportError as err:
self.warn('module %s could not be imported: %s' %
(mod_name, err))
self.py_undoc[mod_name] = {'error': err}
continue

funcs = []
classes = {}

for name, obj in inspect.getmembers(mod):
# diverse module attributes are ignored:
if name[0] == '_':
# begins in an underscore
continue
if not hasattr(obj, '__module__'):
# cannot be attributed to a module
continue
if obj.__module__ != mod_name:
# is not defined in this module
continue

full_name = '%s.%s' % (mod_name, name)

if inspect.isfunction(obj):
if full_name not in objects:
for exp in self.fun_ignorexps:
if exp.match(name):
break
else:
if skip_undoc and not obj.__doc__:
continue
funcs.append(name)
elif inspect.isclass(obj):
for exp in self.cls_ignorexps:
if exp.match(name):
break
else:
if full_name not in objects:
if skip_undoc and not obj.__doc__:
continue
# not documented at all
classes[name] = []
continue

attrs = []

for attr_name in dir(obj):
if attr_name not in obj.__dict__:
continue
try:
attr = safe_getattr(obj, attr_name)
except AttributeError:
continue
if not (inspect.ismethod(attr) or
inspect.isfunction(attr)):
continue
if attr_name[0] == '_':
# starts with an underscore, ignore it
continue
if skip_undoc and not attr.__doc__:
# skip methods without docstring if wished
continue

full_attr_name = '%s.%s' % (full_name, attr_name)
if full_attr_name not in objects:
attrs.append(attr_name)

if attrs:
# some attributes are undocumented
classes[name] = attrs

self.py_undoc[mod_name] = {'funcs': funcs, 'classes': classes}

def write_py_coverage(self):
output_file = path.join(self.outdir, 'python.txt')
op = open(output_file, 'w')
failed = []
try:
if self.config.coverage_write_headline:
write_header(op, 'Undocumented Python objects', '=')
keys = sorted(self.py_undoc.keys())
for name in keys:
undoc = self.py_undoc[name]
if 'error' in undoc:
failed.append((name, undoc['error']))
else:
if not undoc['classes'] and not undoc['funcs']:
continue

write_header(op, name)
if undoc['funcs']:
op.write('Functions:\n')
op.writelines(' * %s\n' % x for x in undoc['funcs'])
op.write('\n')
if undoc['classes']:
op.write('Classes:\n')
for name, methods in sorted(
iteritems(undoc['classes'])):
if not methods:
op.write(' * %s\n' % name)
else:
op.write(' * %s -- missing methods:\n\n' % name)
op.writelines('   - %s\n' % x for x in methods)
op.write('\n')

if failed:
write_header(op, 'Modules that failed to import')
op.writelines(' * %s -- %s\n' % x for x in failed)
finally:
op.close()

def finish(self):
# dump the coverage data to a pickle file too
picklepath = path.join(self.outdir, 'undoc.pickle')
dumpfile = open(picklepath, 'wb')
try:
pickle.dump((self.py_undoc, self.c_undoc), dumpfile)
finally:
dumpfile.close()

def setup(app):
app.add_builder(CoverageBuilder)
app.add_config_value('coverage_ignore_modules', [], False)
app.add_config_value('coverage_ignore_functions', [], False)
app.add_config_value('coverage_ignore_classes', [], False)
app.add_config_value('coverage_c_path', [], False)
app.add_config_value('coverage_c_regexes', {}, False)
app.add_config_value('coverage_ignore_c_items', {}, False)
app.add_config_value('coverage_write_headline', True, False)
app.add_config_value('coverage_skip_undoc_in_source', False, False)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.parsers

# -*- coding: utf-8 -*-
"""
sphinx.parsers
~~~~~~~~~~~~~~

A Base class for additional parsers.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import docutils.parsers

[docs]class Parser(docutils.parsers.Parser):
"""
A base class of source parsers.  The additonal parsers should inherits this class instead
of ``docutils.parsers.Parser``.  Compared with ``docutils.parsers.Parser``, this class
improves accessibility to Sphinx APIs.

The subclasses can access following objects and functions:

self.app
The application object (:class:`sphinx.application.Sphinx`)
self.config
The config object (:class:`sphinx.config.Config`)
self.env
The environment object (:class:`sphinx.environment.BuildEnvironment`)
self.warn()
Emit a warning. (Same as :meth:`sphinx.application.Sphinx.warn()`)
self.info()
Emit a informational message. (Same as :meth:`sphinx.application.Sphinx.info()`)
"""

def set_application(self, app):
"""set_application will be called from Sphinx to set app and other instance variables

:param sphinx.application.Sphinx app: Sphinx application object
"""
self.app = app
self.config = app.config
self.env = app.env
self.warn = app.warn
self.info = app.info

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

Source code for sphinx.websupport

# -*- coding: utf-8 -*-
"""
sphinx.websupport
~~~~~~~~~~~~~~~~~

Base Module for web support functions.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import sys
import posixpath
from os import path

from six.moves import cPickle as pickle
from jinja2 import Environment, FileSystemLoader
from docutils.core import publish_parts

from sphinx.application import Sphinx
from sphinx.locale import _
from sphinx.util.osutil import ensuredir
from sphinx.util.jsonimpl import dumps as dump_json
from sphinx.util.pycompat import htmlescape
from sphinx.websupport import errors
from sphinx.websupport.search import BaseSearch, SEARCH_ADAPTERS
from sphinx.websupport.storage import StorageBackend

[docs]class WebSupport(object):
"""The main API class for the web support package. All interactions
with the web support package should occur through this class.
"""
def __init__(self,
srcdir=None,      # only required for building
builddir='',      # the dir with data/static/doctrees subdirs
datadir=None,     # defaults to builddir/data
staticdir=None,   # defaults to builddir/static
doctreedir=None,  # defaults to builddir/doctrees
search=None,      # defaults to no search
storage=None,     # defaults to SQLite in datadir
status=sys.stdout,
warning=sys.stderr,
moderation_callback=None,
allow_anonymous_comments=True,
docroot='',
staticroot='static',
):
# directories
self.srcdir = srcdir
self.builddir = builddir
self.outdir = path.join(builddir, 'data')
self.datadir = datadir or self.outdir
self.staticdir = staticdir or path.join(self.builddir, 'static')
self.doctreedir = staticdir or path.join(self.builddir, 'doctrees')
# web server virtual paths
self.staticroot = staticroot.strip('/')
self.docroot = docroot.strip('/')

self.status = status
self.warning = warning
self.moderation_callback = moderation_callback
self.allow_anonymous_comments = allow_anonymous_comments

self._init_templating()
self._init_search(search)
self._init_storage(storage)

self._globalcontext = None

self._make_base_comment_options()

def _init_storage(self, storage):
if isinstance(storage, StorageBackend):
self.storage = storage
else:
# If a StorageBackend isn't provided, use the default
# SQLAlchemy backend.
from sphinx.websupport.storage.sqlalchemystorage \
import SQLAlchemyStorage
if not storage:
# no explicit DB path given; create default sqlite database
db_path = path.join(self.datadir, 'db', 'websupport.db')
ensuredir(path.dirname(db_path))
storage = 'sqlite:///' + db_path
self.storage = SQLAlchemyStorage(storage)

def _init_templating(self):
import sphinx
template_path = path.join(sphinx.package_dir,
'themes', 'basic')
loader = FileSystemLoader(template_path)
self.template_env = Environment(loader=loader)

def _init_search(self, search):
if isinstance(search, BaseSearch):
self.search = search
else:
mod, cls = SEARCH_ADAPTERS[search or 'null']
mod = 'sphinx.websupport.search.' + mod
SearchClass = getattr(__import__(mod, None, None, [cls]), cls)
search_path = path.join(self.datadir, 'search')
self.search = SearchClass(search_path)
self.results_template = \
self.template_env.get_template('searchresults.html')

[docs]    def build(self):
"""Build the documentation. Places the data into the `outdir`
directory. Use it like this::

support = WebSupport(srcdir, builddir, search='xapian')
support.build()

This will read reStructured text files from `srcdir`. Then it will
build the pickles and search index, placing them into `builddir`.
It will also save node data to the database.
"""
if not self.srcdir:
raise RuntimeError('No srcdir associated with WebSupport object')
app = Sphinx(self.srcdir, self.srcdir, self.outdir, self.doctreedir,
'websupport', status=self.status, warning=self.warning)
app.builder.set_webinfo(self.staticdir, self.staticroot,
self.search, self.storage)

self.storage.pre_build()
app.build()
self.storage.post_build()

def get_globalcontext(self):
"""Load and return the "global context" pickle."""
if not self._globalcontext:
infilename = path.join(self.datadir, 'globalcontext.pickle')
f = open(infilename, 'rb')
try:
self._globalcontext = pickle.load(f)
finally:
f.close()
return self._globalcontext

[docs]    def get_document(self, docname, username='', moderator=False):
"""Load and return a document from a pickle. The document will
be a dict object which can be used to render a template::

support = WebSupport(datadir=datadir)
support.get_document('index', username, moderator)

In most cases `docname` will be taken from the request path and
passed directly to this function. In Flask, that would be something
like this::

@app.route('/<path:docname>')
def index(docname):
username = g.user.name if g.user else ''
moderator = g.user.moderator if g.user else False
try:
document = support.get_document(docname, username,
moderator)
except DocumentNotFoundError:
abort(404)
render_template('doc.html', document=document)

The document dict that is returned contains the following items
to be used during template rendering.

* **body**: The main body of the document as HTML
* **sidebar**: The sidebar of the document as HTML
* **relbar**: A div containing links to related documents
* **title**: The title of the document
* **css**: Links to css files used by Sphinx
* **script**: Javascript containing comment options

This raises :class:`~sphinx.websupport.errors.DocumentNotFoundError`
if a document matching `docname` is not found.

:param docname: the name of the document to load.
"""
docpath = path.join(self.datadir, 'pickles', docname)
if path.isdir(docpath):
infilename = docpath + '/index.fpickle'
if not docname:
docname = 'index'
else:
docname += '/index'
else:
infilename = docpath + '.fpickle'

try:
f = open(infilename, 'rb')
except IOError:
raise errors.DocumentNotFoundError(
'The document "%s" could not be found' % docname)
try:
document = pickle.load(f)
finally:
f.close()

comment_opts = self._make_comment_options(username, moderator)
comment_meta = self._make_metadata(
self.storage.get_metadata(docname, moderator))

document['script'] = comment_opts + comment_meta + document['script']
return document

[docs]    def get_search_results(self, q):
"""Perform a search for the query `q`, and create a set
of search results. Then render the search results as html and
return a context dict like the one created by
:meth:`get_document`::

document = support.get_search_results(q)

:param q: the search query
"""
results = self.search.query(q)
ctx = {
'q': q,
'search_performed': True,
'search_results': results,
'docroot': '../',  # XXX
'_': _,
}
document = {
'body': self.results_template.render(ctx),
'title': 'Search Results',
'sidebar': '',
'relbar': ''
}
return document

[docs]    def get_data(self, node_id, username=None, moderator=False):
"""Get the comments and source associated with `node_id`. If
`username` is given vote information will be included with the
returned comments. The default CommentBackend returns a dict with
two keys, *source*, and *comments*. *source* is raw source of the
node and is used as the starting point for proposals a user can
add. *comments* is a list of dicts that represent a comment, each
having the following items:

============= ======================================================
Key           Contents
============= ======================================================
text          The comment text.
username      The username that was stored with the comment.
id            The comment's unique identifier.
rating        The comment's current rating.
age           The time in seconds since the comment was added.
time          A dict containing time information. It contains the
following keys: year, month, day, hour, minute, second,
iso, and delta. `iso` is the time formatted in ISO
8601 format. `delta` is a printable form of how old
the comment is (e.g. "3 hours ago").
vote          If `user_id` was given, this will be an integer
representing the vote. 1 for an upvote, -1 for a
downvote, or 0 if unvoted.
node          The id of the node that the comment is attached to.
If the comment's parent is another comment rather than
a node, this will be null.
parent        The id of the comment that this comment is attached
to if it is not attached to a node.
children      A list of all children, in this format.
proposal_diff An HTML representation of the differences between the
the current source and the user's proposed source.
============= ======================================================

:param node_id: the id of the node to get comments for.
:param username: the username of the user viewing the comments.
:param moderator: whether the user is a moderator.
"""
return self.storage.get_data(node_id, username, moderator)

def delete_comment(self, comment_id, username='', moderator=False):
"""Delete a comment.

If `moderator` is True, the comment and all descendants will be deleted
from the database, and the function returns ``True``.

If `moderator` is False, the comment will be marked as deleted (but not
removed from the database so as not to leave any comments orphaned), but
only if the `username` matches the `username` on the comment.  The
username and text files are replaced with "[deleted]" .  In this case,
the function returns ``False``.

This raises :class:`~sphinx.websupport.errors.UserNotAuthorizedError`
if moderator is False and `username` doesn't match username on the
comment.

:param comment_id: the id of the comment to delete.
:param username: the username requesting the deletion.
:param moderator: whether the requestor is a moderator.
"""
return self.storage.delete_comment(comment_id, username, moderator)

[docs]    def add_comment(self, text, node_id='', parent_id='', displayed=True,
username=None, time=None, proposal=None,
moderator=False):
"""Add a comment to a node or another comment. Returns the comment
in the same format as :meth:`get_comments`. If the comment is being
attached to a node, pass in the node's id (as a string) with the
node keyword argument::

comment = support.add_comment(text, node_id=node_id)

If the comment is the child of another comment, provide the parent's
id (as a string) with the parent keyword argument::

comment = support.add_comment(text, parent_id=parent_id)

If you would like to store a username with the comment, pass
in the optional `username` keyword argument::

comment = support.add_comment(text, node=node_id,
username=username)

:param parent_id: the prefixed id of the comment's parent.
:param text: the text of the comment.
:param displayed: for moderation purposes
:param username: the username of the user making the comment.
:param time: the time the comment was created, defaults to now.
"""
if username is None:
if self.allow_anonymous_comments:
username = 'Anonymous'
else:
raise errors.UserNotAuthorizedError()
parsed = self._parse_comment_text(text)
comment = self.storage.add_comment(parsed, displayed, username,
time, proposal, node_id,
parent_id, moderator)
comment['original_text'] = text
if not displayed and self.moderation_callback:
self.moderation_callback(comment)
return comment

[docs]    def process_vote(self, comment_id, username, value):
"""Process a user's vote. The web support package relies
on the API user to perform authentication. The API user will
typically receive a comment_id and value from a form, and then
make sure the user is authenticated. A unique username  must be
passed in, which will also be used to retrieve the user's past
voting data. An example, once again in Flask::

@app.route('/docs/process_vote', methods=['POST'])
def process_vote():
if g.user is None:
abort(401)
comment_id = request.form.get('comment_id')
value = request.form.get('value')
if value is None or comment_id is None:
abort(400)
support.process_vote(comment_id, g.user.name, value)
return "success"

:param comment_id: the comment being voted on
:param username: the unique username of the user voting
:param value: 1 for an upvote, -1 for a downvote, 0 for an unvote.
"""
value = int(value)
if not -1 <= value <= 1:
raise ValueError('vote value %s out of range (-1, 1)' % value)
self.storage.process_vote(comment_id, username, value)

def update_username(self, old_username, new_username):
"""To remain decoupled from a webapp's authentication system, the
web support package stores a user's username with each of their
comments and votes. If the authentication system allows a user to
change their username, this can lead to stagnate data in the web
support system. To avoid this, each time a username is changed, this
method should be called.

:param old_username: The original username.
:param new_username: The new username.
"""
self.storage.update_username(old_username, new_username)

def accept_comment(self, comment_id, moderator=False):
"""Accept a comment that is pending moderation.

This raises :class:`~sphinx.websupport.errors.UserNotAuthorizedError`
if moderator is False.

:param comment_id: The id of the comment that was accepted.
:param moderator: Whether the user making the request is a moderator.
"""
if not moderator:
raise errors.UserNotAuthorizedError()
self.storage.accept_comment(comment_id)

def _make_base_comment_options(self):
"""Helper method to create the part of the COMMENT_OPTIONS javascript
that remains the same throughout the lifetime of the
:class:`~sphinx.websupport.WebSupport` object.
"""
self.base_comment_opts = {}

if self.docroot != '':
comment_urls = [
('addCommentURL', '_add_comment'),
('getCommentsURL', '_get_comments'),
('processVoteURL', '_process_vote'),
('acceptCommentURL', '_accept_comment'),
('deleteCommentURL', '_delete_comment')
]
for key, value in comment_urls:
self.base_comment_opts[key] = \
'/' + posixpath.join(self.docroot, value)
if self.staticroot != 'static':
static_urls = [
('commentImage', 'comment.png'),
('closeCommentImage', 'comment-close.png'),
('loadingImage', 'ajax-loader.gif'),
('commentBrightImage', 'comment-bright.png'),
('upArrow', 'up.png'),
('upArrowPressed', 'up-pressed.png'),
('downArrow', 'down.png'),
('downArrowPressed', 'down-pressed.png')
]
for key, value in static_urls:
self.base_comment_opts[key] = \
'/' + posixpath.join(self.staticroot, '_static', value)

def _make_comment_options(self, username, moderator):
"""Helper method to create the parts of the COMMENT_OPTIONS
javascript that are unique to each request.

:param username: The username of the user making the request.
:param moderator: Whether the user making the request is a moderator.
"""
rv = self.base_comment_opts.copy()
if username:
rv.update({
'voting': True,
'username': username,
'moderator': moderator,
})
return '''\
<script type="text/javascript">
var COMMENT_OPTIONS = %s;
</script>
''' % dump_json(rv)

def _make_metadata(self, data):
return '''\
<script type="text/javascript">
var COMMENT_METADATA = %s;
</script>
''' % dump_json(data)

def _parse_comment_text(self, text):
settings = {'file_insertion_enabled': False,
'raw_enabled': False,
'output_encoding': 'unicode'}
try:
ret = publish_parts(text, writer_name='html',
settings_overrides=settings)['fragment']
except Exception:
ret = htmlescape(text)
return ret

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.websupport »

Source code for sphinx.websupport.search

# -*- coding: utf-8 -*-
"""
sphinx.websupport.search
~~~~~~~~~~~~~~~~~~~~~~~~

Server side search support for the web support package.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import re

from six import text_type

[docs]class BaseSearch(object):
def __init__(self, path):
pass

[docs]    def init_indexing(self, changed=[]):
"""Called by the builder to initialize the search indexer. `changed`
is a list of pagenames that will be reindexed. You may want to remove
these from the search index before indexing begins.

:param changed: a list of pagenames that will be re-indexed
"""
pass

[docs]    def finish_indexing(self):
"""Called by the builder when writing has been completed. Use this
to perform any finalization or cleanup actions after indexing is
complete.
"""
pass

[docs]    def feed(self, pagename, title, doctree):
"""Called by the builder to add a doctree to the index. Converts the
`doctree` to text and passes it to :meth:`add_document`. You probably
won't want to override this unless you need access to the `doctree`.
Override :meth:`add_document` instead.

:param pagename: the name of the page to be indexed
:param title: the title of the page to be indexed
:param doctree: is the docutils doctree representation of the page
"""
self.add_document(pagename, title, doctree.astext())

[docs]    def add_document(self, pagename, title, text):
"""Called by :meth:`feed` to add a document to the search index.
This method should should do everything necessary to add a single
document to the search index.

`pagename` is name of the page being indexed. It is the combination
of the source files relative path and filename,
minus the extension. For example, if the source file is
"ext/builders.rst", the `pagename` would be "ext/builders". This
will need to be returned with search results when processing a
query.

:param pagename: the name of the page being indexed
:param title: the page's title
:param text: the full text of the page
"""
raise NotImplementedError()

[docs]    def query(self, q):
"""Called by the web support api to get search results. This method
compiles the regular expression to be used when :meth:`extracting
context <extract_context>`, then calls :meth:`handle_query`.  You
won't want to override this unless you don't want to use the included
:meth:`extract_context` method.  Override :meth:`handle_query` instead.

:param q: the search query string.
"""
self.context_re = re.compile('|'.join(q.split()), re.I)
return self.handle_query(q)

[docs]    def handle_query(self, q):
"""Called by :meth:`query` to retrieve search results for a search
query `q`. This should return an iterable containing tuples of the
following format::

(<path>, <title>, <context>)

`path` and `title` are the same values that were passed to
:meth:`add_document`, and `context` should be a short text snippet
of the text surrounding the search query in the document.

The :meth:`extract_context` method is provided as a simple way
to create the `context`.

:param q: the search query
"""
raise NotImplementedError()

[docs]    def extract_context(self, text, length=240):
"""Extract the context for the search query from the document's
full `text`.

:param text: the full text of the document to create the context for
:param length: the length of the context snippet to return.
"""
res = self.context_re.search(text)
if res is None:
return ''
context_start = max(res.start() - int(length/2), 0)
context_end = context_start + length
context = ''.join([context_start > 0 and '...' or '',
text[context_start:context_end],
context_end < len(text) and '...' or ''])

try:
return text_type(context, errors='ignore')
except TypeError:
return context

def context_for_searchtool(self):
"""Required by the HTML builder."""
return {}

def get_js_stemmer_rawcode(self):
"""Required by the HTML builder."""
return None

# The built-in search adapters.
SEARCH_ADAPTERS = {
'xapian': ('xapiansearch', 'XapianSearch'),
'whoosh': ('whooshsearch', 'WhooshSearch'),
'null':   ('nullsearch', 'NullSearch'),
}

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

- Module code »

- sphinx.websupport »

Source code for sphinx.websupport.storage

# -*- coding: utf-8 -*-
"""
sphinx.websupport.storage
~~~~~~~~~~~~~~~~~~~~~~~~~

Storage for the websupport package.

:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

[docs]class StorageBackend(object):

[docs]    def pre_build(self):
"""Called immediately before the build process begins. Use this
to prepare the StorageBackend for the addition of nodes.
"""
pass

def has_node(self, id):
"""Check to see if a node exists.

:param id: the id to check for.
"""
raise NotImplementedError()

[docs]    def add_node(self, id, document, source):
"""Add a node to the StorageBackend.

:param id: a unique id for the comment.
:param document: the name of the document the node belongs to.
:param source: the source files name.
"""
raise NotImplementedError()

[docs]    def post_build(self):
"""Called after a build has completed. Use this to finalize the
addition of nodes if needed.
"""
pass

[docs]    def add_comment(self, text, displayed, username, time,
proposal, node_id, parent_id, moderator):
"""Called when a comment is being added.

:param text: the text of the comment
:param displayed: whether the comment should be displayed
:param username: the name of the user adding the comment
:param time: a date object with the time the comment was added
:param proposal: the text of the proposal the user made
:param node_id: the id of the node that the comment is being added to
:param parent_id: the id of the comment's parent comment.
:param moderator: whether the user adding the comment is a moderator
"""
raise NotImplementedError()

[docs]    def delete_comment(self, comment_id, username, moderator):
"""Delete a comment.

Raises :class:`~sphinx.websupport.errors.UserNotAuthorizedError`
if moderator is False and `username` doesn't match the username
on the comment.

:param comment_id: The id of the comment being deleted.
:param username: The username of the user requesting the deletion.
:param moderator: Whether the user is a moderator.
"""
raise NotImplementedError()

def get_metadata(self, docname, moderator):
"""Get metadata for a document. This is currently just a dict
of node_id's with associated comment counts.

:param docname: the name of the document to get metadata for.
:param moderator: whether the requester is a moderator.
"""
raise NotImplementedError()

[docs]    def get_data(self, node_id, username, moderator):
"""Called to retrieve all data for a node. This should return a
dict with two keys, *source* and *comments* as described by
:class:`~sphinx.websupport.WebSupport`'s
:meth:`~sphinx.websupport.WebSupport.get_data` method.

:param node_id: The id of the node to get data for.
:param username: The name of the user requesting the data.
:param moderator: Whether the requestor is a moderator.
"""
raise NotImplementedError()

[docs]    def process_vote(self, comment_id, username, value):
"""Process a vote that is being cast. `value` will be either -1, 0,
or 1.

:param comment_id: The id of the comment being voted on.
:param username: The username of the user casting the vote.
:param value: The value of the vote being cast.
"""
raise NotImplementedError()

[docs]    def update_username(self, old_username, new_username):
"""If a user is allowed to change their username this method should
be called so that there is not stagnate data in the storage system.

:param old_username: The username being changed.
:param new_username: What the username is being changed to.
"""
raise NotImplementedError()

[docs]    def accept_comment(self, comment_id):
"""Called when a moderator accepts a comment. After the method is
called the comment should be displayed to all users.

:param comment_id: The id of the comment being accepted.
"""
raise NotImplementedError()

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

Example Google Style Python Docstrings

See also

Example NumPy Style Python Docstrings

Download: example_google.py

# -*- coding: utf-8 -*-
"""Example Google style docstrings.

This module demonstrates documentation as specified by the `Google Python
Style Guide`_. Docstrings may extend over multiple lines. Sections are created
with a section header and a colon followed by a block of indented text.

Example:
Examples can be given using either the ``Example`` or ``Examples``
sections. Sections support any reStructuredText formatting, including
literal blocks::

$ python example_google.py

Section breaks are created by resuming unindented text. Section breaks
are also implicitly created anytime a new section starts.

Attributes:
module_level_variable1 (int): Module level variables may be documented in
either the ``Attributes`` section of the module docstring, or in an
inline docstring immediately following the variable.

Either form is acceptable, but the two should not be mixed. Choose
one convention to document module level variables and be consistent
with it.

Todo:
* For module TODOs
* You have to also use ``sphinx.ext.todo`` extension

.. _Google Python Style Guide:
http://google.github.io/styleguide/pyguide.html

"""

module_level_variable1 = 12345

module_level_variable2 = 98765
"""int: Module level variable documented inline.

The docstring may span multiple lines. The type may optionally be specified
on the first line, separated by a colon.
"""

def module_level_function(param1, param2=None, *args, **kwargs):
"""This is an example of a module level function.

Function parameters should be documented in the ``Args`` section. The name
of each parameter is required. The type and description of each parameter
is optional, but should be included if not obvious.

Parameter types -- if given -- should be specified according to
`PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.

If \*args or \*\*kwargs are accepted,
they should be listed as ``*args`` and ``**kwargs``.

The format for a parameter is::

name (type): description
The description may span multiple lines. Following
lines should be indented. The "(type)" is optional.

Multiple paragraphs are supported in parameter
descriptions.

Args:
param1 (int): The first parameter.
param2 (Optional[str]): The second parameter. Defaults to None.
Second line of description should be indented.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.

Returns:
bool: True if successful, False otherwise.

The return type is optional and may be specified at the beginning of
the ``Returns`` section followed by a colon.

The ``Returns`` section may span multiple lines and paragraphs.
Following lines should be indented to match the first line.

The ``Returns`` section supports any reStructuredText formatting,
including literal blocks::

{
'param1': param1,
'param2': param2
}

Raises:
AttributeError: The ``Raises`` section is a list of all exceptions
that are relevant to the interface.
ValueError: If `param2` is equal to `param1`.

.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/

"""
if param1 == param2:
raise ValueError('param1 may not be equal to param2')
return True

def example_generator(n):
"""Generators have a ``Yields`` section instead of a ``Returns`` section.

Args:
n (int): The upper limit of the range to generate, from 0 to `n` - 1.

Yields:
int: The next number in the range of 0 to `n` - 1.

Examples:
Examples should be written in doctest format, and should illustrate how
to use the function.

>>> print([i for i in example_generator(4)])
[0, 1, 2, 3]

"""
for i in range(n):
yield i

class ExampleError(Exception):
"""Exceptions are documented in the same way as classes.

The __init__ method may be documented in either the class level
docstring, or as a docstring on the __init__ method itself.

Either form is acceptable, but the two should not be mixed. Choose one
convention to document the __init__ method and be consistent with it.

Note:
Do not include the `self` parameter in the ``Args`` section.

Args:
msg (str): Human readable string describing the exception.
code (Optional[int]): Error code.

Attributes:
msg (str): Human readable string describing the exception.
code (int): Exception error code.

"""

def __init__(self, msg, code):
self.msg = msg
self.code = code

class ExampleClass(object):
"""The summary line for a class docstring should fit on one line.

If the class has public attributes, they may be documented here
in an ``Attributes`` section and follow the same formatting as a
function's ``Args`` section. Alternatively, attributes may be documented
inline with the attribute's declaration (see __init__ method below).

Properties created with the ``@property`` decorator should be documented
in the property's getter method.

Attribute and property types -- if given -- should be specified according
to `PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.

Attributes:
attr1 (str): Description of `attr1`.
attr2 (Optional[int]): Description of `attr2`.

.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/

"""

def __init__(self, param1, param2, param3):
"""Example of docstring on the __init__ method.

The __init__ method may be documented in either the class level
docstring, or as a docstring on the __init__ method itself.

Either form is acceptable, but the two should not be mixed. Choose one
convention to document the __init__ method and be consistent with it.

Note:
Do not include the `self` parameter in the ``Args`` section.

Args:
param1 (str): Description of `param1`.
param2 (Optional[int]): Description of `param2`. Multiple
lines are supported.
param3 (List[str]): Description of `param3`.

"""
self.attr1 = param1
self.attr2 = param2
self.attr3 = param3  #: Doc comment *inline* with attribute

#: List[str]: Doc comment *before* attribute, with type specified
self.attr4 = ['attr4']

self.attr5 = None
"""Optional[str]: Docstring *after* attribute, with type specified."""

@property
def readonly_property(self):
"""str: Properties should be documented in their getter method."""
return 'readonly_property'

@property
def readwrite_property(self):
"""List[str]: Properties with both a getter and setter should only
be documented in their getter method.

If the setter method contains notable behavior, it should be
mentioned here.
"""
return ['readwrite_property']

@readwrite_property.setter
def readwrite_property(self, value):
value

def example_method(self, param1, param2):
"""Class methods are similar to regular functions.

Note:
Do not include the `self` parameter in the ``Args`` section.

Args:
param1: The first parameter.
param2: The second parameter.

Returns:
True if successful, False otherwise.

"""
return True

def __special__(self):
"""By default special members with docstrings are not included.

Special members are any methods or attributes that start with and
end with a double underscore. Any special member with a docstring
will be included in the output, if
``napoleon_include_special_with_doc`` is set to True.

This behavior can be enabled by changing the following setting in
Sphinx's conf.py::

napoleon_include_special_with_doc = True

"""
pass

def __special_without_docstring__(self):
pass

def _private(self):
"""By default private members are not included.

Private members are any methods or attributes that start with an
underscore and are *not* special. By default they are not included
in the output.

This behavior can be changed such that private members *are* included
by changing the following setting in Sphinx's conf.py::

napoleon_include_private_with_doc = True

"""
pass

def _private_without_docstring(self):
pass

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

Example NumPy Style Python Docstrings

See also

Example Google Style Python Docstrings

Download: example_numpy.py

# -*- coding: utf-8 -*-
"""Example NumPy style docstrings.

This module demonstrates documentation as specified by the `NumPy
Documentation HOWTO`_. Docstrings may extend over multiple lines. Sections
are created with a section header followed by an underline of equal length.

Example
-------
Examples can be given using either the ``Example`` or ``Examples``
sections. Sections support any reStructuredText formatting, including
literal blocks::

$ python example_numpy.py

Section breaks are created with two blank lines. Section breaks are also
implicitly created anytime a new section starts. Section bodies *may* be
indented:

Notes
-----
This is an example of an indented section. It's like any other section,
but the body is indented to help it stand out from surrounding text.

If a section is indented, then a section break is created by
resuming unindented text.

Attributes
----------
module_level_variable1 : int
Module level variables may be documented in either the ``Attributes``
section of the module docstring, or in an inline docstring immediately
following the variable.

Either form is acceptable, but the two should not be mixed. Choose
one convention to document module level variables and be consistent
with it.

.. _NumPy Documentation HOWTO:
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt

"""

module_level_variable1 = 12345

module_level_variable2 = 98765
"""int: Module level variable documented inline.

The docstring may span multiple lines. The type may optionally be specified
on the first line, separated by a colon.
"""

def module_level_function(param1, param2=None, *args, **kwargs):
"""This is an example of a module level function.

Function parameters should be documented in the ``Parameters`` section.
The name of each parameter is required. The type and description of each
parameter is optional, but should be included if not obvious.

Parameter types -- if given -- should be specified according to
`PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.

If \*args or \*\*kwargs are accepted,
they should be listed as ``*args`` and ``**kwargs``.

The format for a parameter is::

name : type
description

The description may span multiple lines. Following lines
should be indented to match the first line of the description.
The ": type" is optional.

Multiple paragraphs are supported in parameter
descriptions.

Parameters
----------
param1 : int
The first parameter.
param2 : Optional[str]
The second parameter.
*args
Variable length argument list.
**kwargs
Arbitrary keyword arguments.

Returns
-------
bool
True if successful, False otherwise.

The return type is not optional. The ``Returns`` section may span
multiple lines and paragraphs. Following lines should be indented to
match the first line of the description.

The ``Returns`` section supports any reStructuredText formatting,
including literal blocks::

{
'param1': param1,
'param2': param2
}

Raises
------
AttributeError
The ``Raises`` section is a list of all exceptions
that are relevant to the interface.
ValueError
If `param2` is equal to `param1`.

.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/

"""
if param1 == param2:
raise ValueError('param1 may not be equal to param2')
return True

def example_generator(n):
"""Generators have a ``Yields`` section instead of a ``Returns`` section.

Parameters
----------
n : int
The upper limit of the range to generate, from 0 to `n` - 1.

Yields
------
int
The next number in the range of 0 to `n` - 1.

Examples
--------
Examples should be written in doctest format, and should illustrate how
to use the function.

>>> print([i for i in example_generator(4)])
[0, 1, 2, 3]

"""
for i in range(n):
yield i

class ExampleError(Exception):
"""Exceptions are documented in the same way as classes.

The __init__ method may be documented in either the class level
docstring, or as a docstring on the __init__ method itself.

Either form is acceptable, but the two should not be mixed. Choose one
convention to document the __init__ method and be consistent with it.

Note
----
Do not include the `self` parameter in the ``Parameters`` section.

Parameters
----------
msg : str
Human readable string describing the exception.
code : Optional[int]
Numeric error code.

Attributes
----------
msg : str
Human readable string describing the exception.
code : int
Numeric error code.

"""

def __init__(self, msg, code):
self.msg = msg
self.code = code

class ExampleClass(object):
"""The summary line for a class docstring should fit on one line.

If the class has public attributes, they may be documented here
in an ``Attributes`` section and follow the same formatting as a
function's ``Args`` section. Alternatively, attributes may be documented
inline with the attribute's declaration (see __init__ method below).

Properties created with the ``@property`` decorator should be documented
in the property's getter method.

Attribute and property types -- if given -- should be specified according
to `PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.

Attributes
----------
attr1 : str
Description of `attr1`.
attr2 : Optional[int]
Description of `attr2`.

.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/

"""

def __init__(self, param1, param2, param3):
"""Example of docstring on the __init__ method.

The __init__ method may be documented in either the class level
docstring, or as a docstring on the __init__ method itself.

Either form is acceptable, but the two should not be mixed. Choose one
convention to document the __init__ method and be consistent with it.

Note
----
Do not include the `self` parameter in the ``Parameters`` section.

Parameters
----------
param1 : str
Description of `param1`.
param2 : List[str]
Description of `param2`. Multiple
lines are supported.
param3 : Optional[int]
Description of `param3`.

"""
self.attr1 = param1
self.attr2 = param2
self.attr3 = param3  #: Doc comment *inline* with attribute

#: List[str]: Doc comment *before* attribute, with type specified
self.attr4 = ["attr4"]

self.attr5 = None
"""Optional[str]: Docstring *after* attribute, with type specified."""

@property
def readonly_property(self):
"""str: Properties should be documented in their getter method."""
return "readonly_property"

@property
def readwrite_property(self):
"""List[str]: Properties with both a getter and setter should only
be documented in their getter method.

If the setter method contains notable behavior, it should be
mentioned here.
"""
return ["readwrite_property"]

@readwrite_property.setter
def readwrite_property(self, value):
value

def example_method(self, param1, param2):
"""Class methods are similar to regular functions.

Note
----
Do not include the `self` parameter in the ``Parameters`` section.

Parameters
----------
param1
The first parameter.
param2
The second parameter.

Returns
-------
bool
True if successful, False otherwise.

"""
return True

def __special__(self):
"""By default special members with docstrings are not included.

Special members are any methods or attributes that start with and
end with a double underscore. Any special member with a docstring
will be included in the output, if
``napoleon_include_special_with_doc`` is set to True.

This behavior can be enabled by changing the following setting in
Sphinx's conf.py::

napoleon_include_special_with_doc = True

"""
pass

def __special_without_docstring__(self):
pass

def _private(self):
"""By default private members are not included.

Private members are any methods or attributes that start with an
underscore and are *not* special. By default they are not included
in the output.

This behavior can be changed such that private members *are* included
by changing the following setting in Sphinx's conf.py::

napoleon_include_private_with_doc = True

"""
pass

def _private_without_docstring(self):
pass

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

sphinx-apidoc manual page

Synopsis

sphinx-apidoc [options] -o <outputdir> <sourcedir> [pathnames ...]

Description

sphinx-apidoc is a tool for automatic generation of Sphinx sources that, using the autodoc extension, document a whole package in the style of other automatic API documentation tools.

sourcedir must point to a Python package. Any pathnames given are paths to be excluded from the generation.

Warning

sphinx-apidoc generates source files that use sphinx.ext.autodoc to document all found modules. If any modules have side effects on import, these will be executed by autodoc when sphinx-build is run.

If you document scripts (as opposed to library modules), make sure their main routine is protected by a if __name__ == '__main__' condition.

Options

These options are used with -F:

See also

sphinx-build(1)

Author

Etienne Desautels, <etienne.desautels@gmail.com>, Georg Brandl <georg@python.org> et al.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

sphinx-build manual page

Synopsis

sphinx-build [options] <sourcedir> <outdir> [filenames ...]

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

html

HTML file generation. This is the default builder.

dirhtml

HTML file generation with every HTML file named “index.html” in a separate directory.

singlehtml

HTML file generation with all content in a single HTML file.

htmlhelp

Generates files for CHM (compiled help files) generation.

qthelp

Generates files for Qt help collection generation.

devhelp

Generates files for the GNOME Devhelp help viewer.

latex

Generates LaTeX output that can be compiled to a PDF document.

man

Generates manual pages.

texinfo

Generates Texinfo output that can be processed by makeinfo to generate an Info document.

epub

Generates an ePub e-book version of the HTML output.

text

Generates a plain-text version of the documentation.

gettext

Generates Gettext message catalogs for content translation.

changes

Generates HTML files listing changed/added/deprecated items for the current version of the documented project.

linkcheck

Checks the integrity of all external links in the source.

pickle / json

Generates serialized HTML files for use in web applications.

xml

Generates Docutils-native XML files.

pseudoxml

Generates compact pretty-printed “pseudo-XML” files displaying the internal structure of the intermediate document trees.

Options

See also

sphinx-quickstart(1)

Author

Georg Brandl <georg@python.org>, Armin Ronacher <armin.ronacher@active-4.com> et al.

This manual page was initially written by Mikhail Gusarov <dottedmag@dottedmag.net>, for the Debian project.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.

Navigation

- modules

- Sphinx 1.4.1 documentation »

sphinx-quickstart manual page

Synopsis

sphinx-quickstart

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 sphinx-build(1).

See also

sphinx-build(1)

Author

Georg Brandl <georg@python.org>, Armin Ronacher <armin.ronacher@active-4.com> et al.

This manual page was initially written by Mikhail Gusarov <dottedmag@dottedmag.net>, for the Debian project.

© Copyright 2007-2016, Georg Brandl and the Sphinx team. Created using Sphinx 1.4.1+.