Merge branch 'master' into feature-1970-navigate-with-keys

This commit is contained in:
Timotheus Kampik 2016-01-19 22:38:55 +01:00
commit ab54ece529
328 changed files with 5058 additions and 1394 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
*.pyc *.pyc
*.egg *.egg
*.so *.so
*.swp
.dir-locals.el .dir-locals.el
.ropeproject/ .ropeproject/

View File

@ -5,6 +5,7 @@ python:
- "2.7" - "2.7"
- "3.3" - "3.3"
- "3.4" - "3.4"
- "3.5"
- "pypy" - "pypy"
env: env:
- DOCUTILS=0.11 - DOCUTILS=0.11
@ -13,4 +14,7 @@ install:
- pip install docutils==$DOCUTILS - pip install docutils==$DOCUTILS
- pip install -r test-reqs.txt - pip install -r test-reqs.txt
before_script: flake8 before_script: flake8
script: make test script:
- if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then make test-async; fi
- if [[ $TRAVIS_PYTHON_VERSION != '3.5' ]]; then make test; fi

View File

@ -51,13 +51,16 @@ Other contributors, listed alphabetically, are:
* Stefan Seefeld -- toctree improvements * Stefan Seefeld -- toctree improvements
* Shibukawa Yoshiki -- pluggable search API and Japanese search * Shibukawa Yoshiki -- pluggable search API and Japanese search
* Antonio Valentino -- qthelp builder * Antonio Valentino -- qthelp builder
* Filip Vavera -- napoleon todo directive
* Pauli Virtanen -- autodoc improvements, autosummary extension * Pauli Virtanen -- autodoc improvements, autosummary extension
* Stefan van der Walt -- autosummary extension * Stefan van der Walt -- autosummary extension
* Thomas Waldmann -- apidoc module fixes * Thomas Waldmann -- apidoc module fixes
* John Waltman -- Texinfo builder * John Waltman -- Texinfo builder
* Barry Warsaw -- setup command improvements * Barry Warsaw -- setup command improvements
* Sebastian Wiesner -- image handling, distutils support * Sebastian Wiesner -- image handling, distutils support
* Michael Wilson -- Intersphinx HTTP basic auth support
* Joel Wurtz -- cellspanning support in LaTeX * Joel Wurtz -- cellspanning support in LaTeX
* Hong Xu -- svg support in imgmath extension and various bug fixes
Many thanks for all contributions! Many thanks for all contributions!

199
CHANGES
View File

@ -4,17 +4,162 @@ Release 1.4 (in development)
Incompatible changes 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.
Features added Features added
-------------- --------------
* #2092: add todo directive support in napoleon package.
* #1962: when adding directives, roles or nodes from an extension, warn if such * #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). an element is already present (built-in or added by another extension).
* #1935: Make "numfig_format" overridable in latex_elements.
* #1909: Add "doc" references to Intersphinx inventories. * #1909: Add "doc" references to Intersphinx inventories.
* C++ type alias support (e.g., ``.. type:: T = int``) * C++ type alias support (e.g., ``.. type:: T = int``).
* C++ template support for classes, functions, type aliases, and variables (#1729, #1314). * C++ template support for classes, functions, type aliases, and variables (#1729, #1314).
* C++, added new scope management directives ``namespace-push`` and ``namespace-pop``. * C++, added new scope management directives ``namespace-push`` and ``namespace-pop``.
* #1970: Keyboard shortcuts to navigate Next and Previous topics * #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
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
Documentation
-------------
* #1757: Fix for usage of :confval:`html_last_updated_fmt`. Thanks to Ralf Hemmecke.
Release 1.3.5 (in development)
==============================
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 indecies
* #2026: Fix LaTeX builder rais 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: Show warning if Pygments throws an ErrorToken
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 Bugs fixed
---------- ----------
@ -23,9 +168,8 @@ Bugs fixed
* Add a "default.css" stylesheet (which imports "classic.css") for compatibility. * Add a "default.css" stylesheet (which imports "classic.css") for compatibility.
* #1788: graphviz extension raises exception when caption option is present. * #1788: graphviz extension raises exception when caption option is present.
* #1789: ``:pyobject:`` option of ``literalinclude`` directive includes following * #1789: ``:pyobject:`` option of ``literalinclude`` directive includes following
lines after class definitions. lines after class definitions
* #1790: ``literalinclude`` strips empty lines at the head and tail. * #1790: ``literalinclude`` strips empty lines at the head and tail
* #1913: C++, fix assert bug for enumerators in next-to-global and global scope.
* #1802: load plugin themes automatically when theme.conf use it as 'inherit'. Thanks to * #1802: load plugin themes automatically when theme.conf use it as 'inherit'. Thanks to
Takayuki Hirai. Takayuki Hirai.
* #1794: custom theme extended from alabaster or sphinx_rtd_theme can't find base theme. * #1794: custom theme extended from alabaster or sphinx_rtd_theme can't find base theme.
@ -34,7 +178,7 @@ Bugs fixed
* #1823: '.' as <module_path> for sphinx-apidoc cause an unfriendly error. Now '.' * #1823: '.' as <module_path> for sphinx-apidoc cause an unfriendly error. Now '.'
is converted to absolute path automatically. is converted to absolute path automatically.
* Fix a crash when setting up extensions which do not support metadata. * Fix a crash when setting up extensions which do not support metadata.
* #1784: Provide non-minified JS code in ``sphinx/search/*.py`` * #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 * #1822, #1892: Fix regression for #1061. autosummary can't generate doc for imported
members since sphinx-1.3b3. Thanks to Eric Larson. members since sphinx-1.3b3. Thanks to Eric Larson.
* #1793, #1819: "see also" misses a linebreak in text output. Thanks to Takayuki Hirai. * #1793, #1819: "see also" misses a linebreak in text output. Thanks to Takayuki Hirai.
@ -49,7 +193,6 @@ Bugs fixed
* #1923: Use babel features only if the babel latex element is nonempty. * #1923: Use babel features only if the babel latex element is nonempty.
* #1942: Fix a KeyError in websupport. * #1942: Fix a KeyError in websupport.
* #1903: Fix strange id generation for glossary terms. * #1903: Fix strange id generation for glossary terms.
* #1796, On py3, automated .mo building cause UnicodeDecodeError
* ``make text`` will crush if a definition list item has more than 1 classifiers as: * ``make text`` will crush if a definition list item has more than 1 classifiers as:
``term : classifier1 : classifier2``. ``term : classifier1 : classifier2``.
* #1855: make gettext generates broken po file for definition lists with classifier. * #1855: make gettext generates broken po file for definition lists with classifier.
@ -65,15 +208,24 @@ Bugs fixed
* #1994: More supporting non-standard parser (like recommonmark parser) for Translation and * #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 WebSupport feature. Now node.rawsource is fall backed to node.astext() during docutils
transforming. transforming.
* C++, fix parsing of 'signed char' and 'unsigned char' as types. * #1989: "make blahblah" on Windows indicate help messages for sphinx-build every time.
* C++, add missing support for 'friend' functions. It was caused by wrong make.bat that generated by Sphinx-1.3.0/1.3.1.
* C++, add missing support for virtual base classes (thanks to Rapptz). * On Py2 environment, conf.py that is generated by sphinx-quickstart should have u prefixed
* C++, add support for final classes. config value for 'version' and 'release'.
* C++, fix parsing of types prefixed with 'enum'. * #2102: On Windows + Py3, using ``|today|`` and non-ASCII date format will raise
* #2023: Dutch search support uses Danish stemming info UnicodeEncodeError.
* #1974: UnboundLocalError: local variable 'domain' referenced before assignment when
Documentation 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 :confval:`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) Release 1.3.1 (released Mar 17, 2015)
@ -550,7 +702,7 @@ Bugs fixed
if they contain uppercase letters. if they contain uppercase letters.
* #923: Take the entire LaTeX document into account when caching * #923: Take the entire LaTeX document into account when caching
pngmath-generated images. This rebuilds them correctly when pngmath-generated images. This rebuilds them correctly when
`pngmath_latex_preamble` changes. ``pngmath_latex_preamble`` changes.
* #901: Emit a warning when using docutils' new "math" markup without a Sphinx * #901: Emit a warning when using docutils' new "math" markup without a Sphinx
math extension active. math extension active.
* #845: In code blocks, when the selected lexer fails, display line numbers * #845: In code blocks, when the selected lexer fails, display line numbers
@ -879,13 +1031,12 @@ Features added
* Command-line interfaces: * Command-line interfaces:
- PR#75: Added ``--follow-links`` option to sphinx-apidoc. - PR#75: Added ``--follow-links`` option to sphinx-apidoc.
- #869: sphinx-build now has the option :option:`-T` for printing the full - #869: sphinx-build now has the option ``-T`` for printing the full
traceback after an unhandled exception. traceback after an unhandled exception.
- sphinx-build now supports the standard :option:`--help` and - sphinx-build now supports the standard ``--help`` and ``--version`` options.
:option:`--version` options.
- sphinx-build now provides more specific error messages when called with - sphinx-build now provides more specific error messages when called with
invalid options or arguments. invalid options or arguments.
- sphinx-build now has a verbose option :option:`-v` which can be repeated for - sphinx-build now has a verbose option ``-v`` which can be repeated for
greater effect. A single occurrence provides a slightly more verbose output greater effect. A single occurrence provides a slightly more verbose output
than normal. Two or more occurrences of this option provides more detailed than normal. Two or more occurrences of this option provides more detailed
output which may be useful for debugging. output which may be useful for debugging.
@ -907,7 +1058,7 @@ Features added
stemming routines. Saves about 20 seconds when building the Python stemming routines. Saves about 20 seconds when building the Python
documentation. documentation.
- PR#108: Add experimental support for parallel building with a new - PR#108: Add experimental support for parallel building with a new
:option:`-j` option. :option:`sphinx-build -j` option.
Documentation Documentation
------------- -------------
@ -1169,7 +1320,7 @@ Features added
indicators. indicators.
- #367: Added automatic exclusion of hidden members in inheritance - #367: Added automatic exclusion of hidden members in inheritance
diagrams, and an option to selectively enable it. diagrams, and an option to selectively enable it.
- Added `pngmath_add_tooltips`. - Added ``pngmath_add_tooltips``.
- The math extension displaymath directives now support ``name`` in - The math extension displaymath directives now support ``name`` in
addition to ``label`` for giving the equation label, for compatibility addition to ``label`` for giving the equation label, for compatibility
with Docutils. with Docutils.
@ -1497,7 +1648,7 @@ Features added
* General: * General:
- Added a "nitpicky" mode that emits warnings for all missing - Added a "nitpicky" mode that emits warnings for all missing
references. It is activated by the :option:`-n` command-line switch references. It is activated by the :option:`sphinx-build -n` command-line switch
or the `nitpicky` config value. or the `nitpicky` config value.
- Added ``latexpdf`` target in quickstart Makefile. - Added ``latexpdf`` target in quickstart Makefile.

View File

@ -1,7 +1,7 @@
License for Sphinx License for Sphinx
================== ==================
Copyright (c) 2007-2015 by the Sphinx team (see AUTHORS file). Copyright (c) 2007-2016 by the Sphinx team (see AUTHORS file).
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@ -16,6 +16,7 @@ include sphinx-apidoc.py
recursive-include sphinx/texinputs * recursive-include sphinx/texinputs *
recursive-include sphinx/themes * recursive-include sphinx/themes *
recursive-include sphinx/locale * recursive-include sphinx/locale *
recursive-include sphinx/search/non-minified-js *.js
recursive-include sphinx/ext/autosummary/templates * recursive-include sphinx/ext/autosummary/templates *
recursive-include tests * recursive-include tests *
recursive-include utils * recursive-include utils *

View File

@ -8,6 +8,8 @@ DONT_CHECK = -i build -i dist -i sphinx/style/jquery.js \
-i .ropeproject -i doc/_build -i tests/path.py \ -i .ropeproject -i doc/_build -i tests/path.py \
-i tests/coverage.py -i env -i utils/convert.py \ -i tests/coverage.py -i env -i utils/convert.py \
-i tests/typing_test_data.py \ -i tests/typing_test_data.py \
-i tests/test_autodoc_py35.py \
-i tests/build \
-i sphinx/search/da.py \ -i sphinx/search/da.py \
-i sphinx/search/de.py \ -i sphinx/search/de.py \
-i sphinx/search/en.py \ -i sphinx/search/en.py \
@ -55,6 +57,9 @@ reindent:
@$(PYTHON) utils/reindent.py -r -n . @$(PYTHON) utils/reindent.py -r -n .
test: test:
@cd tests; $(PYTHON) run.py -I py35 -d -m '^[tT]est' $(TEST)
test-async:
@cd tests; $(PYTHON) run.py -d -m '^[tT]est' $(TEST) @cd tests; $(PYTHON) run.py -d -m '^[tT]est' $(TEST)
covertest: covertest:

View File

@ -62,11 +62,11 @@
</table> </table>
<p>{%trans%} <p>{%trans%}
You can also download PDF versions of the Sphinx documentation: You can also download PDF/EPUB versions of the Sphinx documentation:
a <a href="http://sphinx-doc.org/sphinx.pdf">version</a> generated from a <a href="http://readthedocs.org/projects/sphinx/downloads/pdf/stable/">PDF version</a> generated from
the LaTeX Sphinx produces, and the LaTeX Sphinx produces, and
a <a href="http://sphinx-doc.org/sphinx-rst2pdf.pdf">version</a> generated a <a href="http://readthedocs.org/projects/sphinx/downloads/epub/stable/">EPUB version</a>.
by rst2pdf.{%endtrans%} {%endtrans%}
</p> </p>
<h2>{%trans%}Examples{%endtrans%}</h2> <h2>{%trans%}Examples{%endtrans%}</h2>

View File

@ -14,15 +14,7 @@
<p>{%trans%}Current version: <b>{{ version }}</b>{%endtrans%}</p> <p>{%trans%}Current version: <b>{{ version }}</b>{%endtrans%}</p>
<p>{%trans%}Get Sphinx from the <a href="https://pypi.python.org/pypi/Sphinx">Python Package <p>{%trans%}Get Sphinx from the <a href="https://pypi.python.org/pypi/Sphinx">Python Package
Index</a>, or install it with:{%endtrans%}</p> Index</a>, or install it with:{%endtrans%}</p>
{% if version.split('b')|length > 1 %}
<pre>pip install Sphinx=={{ version }}</pre>
<p>{%trans%}<a href="http://sphinx-doc.org/">Stable version docs</a>
are also available.{%endtrans%}</p>
{% else %}
<pre>pip install -U Sphinx</pre> <pre>pip install -U Sphinx</pre>
<p>{%trans%}Latest <a href="http://sphinx-doc.org/latest/">development version docs</a>
are also available.{%endtrans%}</p>
{% endif %}
{% endif %} {% endif %}
<h3>{%trans%}Questions? Suggestions?{%endtrans%}</h3> <h3>{%trans%}Questions? Suggestions?{%endtrans%}</h3>

View File

@ -4,7 +4,7 @@
Sphinx layout template for the sphinxdoc theme. Sphinx layout template for the sphinxdoc theme.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
#} #}
{%- extends "basic/layout.html" %} {%- extends "basic/layout.html" %}

View File

@ -4,7 +4,7 @@
* *
* Sphinx stylesheet -- sphinx13 theme. * Sphinx stylesheet -- sphinx13 theme.
* *
* :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details. * :license: BSD, see LICENSE for details.
* *
*/ */

View File

@ -23,6 +23,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. class:: DirectoryHTMLBuilder .. class:: DirectoryHTMLBuilder
@ -36,6 +38,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. versionadded:: 0.6 .. versionadded:: 0.6
@ -48,6 +52,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. versionadded:: 1.0 .. versionadded:: 1.0
@ -61,6 +67,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. module:: sphinx.builders.qthelp .. module:: sphinx.builders.qthelp
@ -72,6 +80,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. _Qt help: http://qt-project.org/doc/qt-4.8/qthelp-framework.html .. _Qt help: http://qt-project.org/doc/qt-4.8/qthelp-framework.html
@ -96,6 +106,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. versionadded:: 1.3 .. versionadded:: 1.3
@ -109,6 +121,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. module:: sphinx.builders.epub .. module:: sphinx.builders.epub
@ -122,6 +136,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. module:: sphinx.builders.latex .. module:: sphinx.builders.latex
@ -145,6 +161,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
Note that a direct PDF builder using ReportLab is available in `rst2pdf Note that a direct PDF builder using ReportLab is available in `rst2pdf
@ -162,6 +180,8 @@ for details.
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. versionadded:: 0.4 .. versionadded:: 0.4
@ -175,6 +195,8 @@ for details.
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. versionadded:: 1.0 .. versionadded:: 1.0
@ -196,6 +218,8 @@ for details.
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. versionadded:: 1.1 .. versionadded:: 1.1
@ -261,6 +285,8 @@ for details.
The old name ``web`` still works as well. The old name ``web`` still works as well.
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
The file suffix is ``.fpickle``. The global context is called The file suffix is ``.fpickle``. The global context is called
@ -276,6 +302,8 @@ for details.
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
The file suffix is ``.fjson``. The global context is called The file suffix is ``.fjson``. The global context is called
@ -293,6 +321,8 @@ for details.
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. versionadded:: 1.1 .. versionadded:: 1.1
@ -307,6 +337,8 @@ for details.
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. module:: sphinx.builders.linkcheck .. module:: sphinx.builders.linkcheck
@ -318,6 +350,8 @@ for details.
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. module:: sphinx.builders.xml .. module:: sphinx.builders.xml
@ -329,6 +363,8 @@ for details.
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. versionadded:: 1.2 .. versionadded:: 1.2
@ -343,6 +379,8 @@ for details.
.. autoattribute:: name .. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: supported_image_types .. autoattribute:: supported_image_types
.. versionadded:: 1.2 .. versionadded:: 1.2

View File

@ -15,7 +15,7 @@ templates_path = ['_templates']
exclude_patterns = ['_build'] exclude_patterns = ['_build']
project = 'Sphinx' project = 'Sphinx'
copyright = '2007-2015, Georg Brandl and the Sphinx team' copyright = '2007-2016, Georg Brandl and the Sphinx team'
version = sphinx.__released__ version = sphinx.__released__
release = version release = version
show_authors = True show_authors = True

View File

@ -96,8 +96,11 @@ General configuration
If given, a dictionary of parser classes for different source suffices. The 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 keys are the suffix, the values can be either a class or a string giving a
fully-qualified name of a parser class. Files with a suffix that is not in fully-qualified name of a parser class. The parser class can be either
the dictionary will be parsed with the default reStructuredText parser. ``docutils.parsers.Parser`` or :class:`sphinx.parsers.Parser`. Files with a
suffix that is not in the dictionary will be parsed with the default
reStructuredText parser.
For example:: For example::
@ -234,7 +237,7 @@ General configuration
If true, Sphinx will warn about *all* references where the target cannot be If true, Sphinx will warn about *all* references where the target cannot be
found. Default is ``False``. You can activate this mode temporarily using found. Default is ``False``. You can activate this mode temporarily using
the :option:`-n` command-line switch. the :option:`-n <sphinx-build -n>` command-line switch.
.. versionadded:: 1.0 .. versionadded:: 1.0
@ -453,7 +456,7 @@ documentation on :ref:`intl` for details.
this path are searched by the standard :mod:`gettext` module. this path are searched by the standard :mod:`gettext` module.
Internal messages are fetched from a text domain of ``sphinx``; so if you Internal messages are fetched from a text domain of ``sphinx``; so if you
add the directory :file:`./locale` to this settting, the message catalogs add the directory :file:`./locale` to this setting, the message catalogs
(compiled from ``.po`` format using :program:`msgfmt`) must be in (compiled from ``.po`` format using :program:`msgfmt`) must be in
:file:`./locale/{language}/LC_MESSAGES/sphinx.mo`. The text domain of :file:`./locale/{language}/LC_MESSAGES/sphinx.mo`. The text domain of
individual documents depends on :confval:`gettext_compact`. individual documents depends on :confval:`gettext_compact`.
@ -565,8 +568,7 @@ that use Sphinx's HTMLWriter class.
The "title" for HTML documentation generated with Sphinx's own templates. 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 This is appended to the ``<title>`` tag of individual pages, and used in the
navigation bar as the "topmost" element. It defaults to :samp:`'{<project>} navigation bar as the "topmost" element. It defaults to :samp:`'{<project>}
v{<revision>} documentation'` (with the values coming from the config v{<revision>} documentation'`.
values).
.. confval:: html_short_title .. confval:: html_short_title
@ -580,7 +582,7 @@ that use Sphinx's HTMLWriter class.
A dictionary of values to pass into the template engine's context for all 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 pages. Single values can also be put in this dictionary using the
:option:`-A` command-line option of ``sphinx-build``. :option:`-A <sphinx-build -A>` command-line option of ``sphinx-build``.
.. versionadded:: 0.5 .. versionadded:: 0.5
@ -637,9 +639,10 @@ that use Sphinx's HTMLWriter class.
.. confval:: html_last_updated_fmt .. confval:: html_last_updated_fmt
If this is not the empty string, a 'Last updated on:' timestamp is inserted If this is not None, a 'Last updated on:' timestamp is inserted
at every page bottom, using the given :func:`strftime` format. Default is at every page bottom, using the given :func:`strftime` format.
``'%b %d, %Y'`` (or a locale-dependent equivalent). The empty string is equivalent to ``'%b %d, %Y'`` (or a
locale-dependent equivalent).
.. confval:: html_use_smartypants .. confval:: html_use_smartypants
@ -873,6 +876,7 @@ that use Sphinx's HTMLWriter class.
* ``es`` -- Spanish * ``es`` -- Spanish
* ``sv`` -- Swedish * ``sv`` -- Swedish
* ``tr`` -- Turkish * ``tr`` -- Turkish
* ``zh`` -- Chinese
.. admonition:: Accelerating build speed .. admonition:: Accelerating build speed
@ -907,6 +911,12 @@ that use Sphinx's HTMLWriter class.
.. versionadded:: 1.1 .. versionadded:: 1.1
The Chinese support has these options:
* ``dict`` -- the ``jieba`` dictionary path if want to use
custom dictionary.
.. confval:: html_search_scorer .. confval:: html_search_scorer
The name of a JavaScript file (relative to the configuration directory) that The name of a JavaScript file (relative to the configuration directory) that
@ -1431,6 +1441,8 @@ These options influence LaTeX output.
'floated' into the next page but may be preceded by any other text. '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 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. and position figures strictly in the order they appear in the source.
.. versionadded:: 1.3
``'footer'`` ``'footer'``
Additional footer content (before the indices), default empty. Additional footer content (before the indices), default empty.

View File

@ -538,7 +538,7 @@ a visibility statement (``public``, ``private`` or ``protected``).
.. cpp:class:: template<typename T, std::size_t N> std::array .. cpp:class:: template<typename T, std::size_t N> std::array
or with a line beak:: or with a line break::
.. cpp:class:: template<typename T, std::size_t N> \ .. cpp:class:: template<typename T, std::size_t N> \
std::array std::array
@ -594,7 +594,7 @@ a visibility statement (``public``, ``private`` or ``protected``).
.. rst:directive:: .. cpp:member:: (member) variable declaration .. rst:directive:: .. cpp:member:: (member) variable declaration
.. cpp:var:: (member) variable declaration .. cpp:var:: (member) variable declaration
Describe a varible or member variable, e.g.,:: Describe a variable or member variable, e.g.,::
.. cpp:member:: std::string MyClass::myMember .. cpp:member:: std::string MyClass::myMember
@ -671,7 +671,7 @@ a visibility statement (``public``, ``private`` or ``protected``).
Namespacing Namespacing
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
Declarations in the C++ doamin are as default placed in global scope. Declarations in the C++ domain are as default placed in global scope.
The current scope can be changed using three namespace directives. The current scope can be changed using three namespace directives.
They manage a stack declarations where ``cpp:namespace`` resets the stack and They manage a stack declarations where ``cpp:namespace`` resets the stack and
changes a given scope. changes a given scope.
@ -755,6 +755,7 @@ Info field lists
The C++ directives support the following info fields (see also :ref:`info-field-lists`): The C++ directives support the following info fields (see also :ref:`info-field-lists`):
* `param`, `parameter`, `arg`, `argument`: Description of a parameter. * `param`, `parameter`, `arg`, `argument`: Description of a parameter.
* `tparam`: Description of a template parameter.
* `returns`, `return`: Description of a return value. * `returns`, `return`: Description of a return value.
* `throws`, `throw`, `exception`: Description of a possibly thrown exception. * `throws`, `throw`, `exception`: Description of a possibly thrown exception.
@ -764,7 +765,7 @@ The C++ directives support the following info fields (see also :ref:`info-field-
Cross-referencing Cross-referencing
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
These roles link to the given object types: These roles link to the given declaration types:
.. rst:role:: cpp:any .. rst:role:: cpp:any
cpp:class cpp:class
@ -775,19 +776,19 @@ These roles link to the given object types:
cpp:enum cpp:enum
cpp:enumerator cpp:enumerator
Reference a C++ object by name. The name must be properly qualified relative to the Reference a C++ declaration by name (see below for details).
position of the link. The name must be properly qualified relative to the position of the link.
.. note:: .. admonition:: Note on References with Templates Parameters/Arguments
Sphinx's syntax to give references a custom title can interfere with Sphinx's syntax to give references a custom title can interfere with
linking to template classes, if nothing follows the closing angle linking to template classes, if nothing follows the closing angle
bracket, i.e. if the link looks like this: ``:cpp:class:`MyClass<T>```. bracket, i.e. if the link looks like this: ``:cpp:class:`MyClass<int>```.
This is interpreted as a link to ``T`` with a title of ``MyClass``. 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, In this case, please escape the opening angle bracket with a backslash,
like this: ``:cpp:class:`MyClass\<T>```. like this: ``:cpp:class:`MyClass\<int>```.
.. admonition:: Note on References .. admonition:: Note on References to Overloaded Functions
It is currently impossible to link to a specific version of an It is currently impossible to link to a specific version of an
overloaded method. Currently the C++ domain is the first domain overloaded method. Currently the C++ domain is the first domain
@ -796,6 +797,80 @@ These roles link to the given object types:
specific overload. Currently Sphinx will link to the first overloaded specific overload. Currently Sphinx will link to the first overloaded
version of the method / function. 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.
.. cpp:class:: Wrapper
.. cpp:class:: template<typename TOuter> \
Outer
.. cpp:class:: template<typename TInner> \
Inner
In general the reference must include the template paraemter declarations, e.g.,
``template\<typename TOuter> Wrapper::Outer`` (:cpp:class:`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`` (:cpp:class:`Wrapper::Outer`)
- ``Wrapper::Outer::Inner`` (:cpp:class:`Wrapper::Outer::Inner`)
- ``template\<typename TInner> Wrapper::Outer::Inner`` (:cpp:class:`template\<typename TInner> Wrapper::Outer::Inner`)
(Full) Template Specialisations
................................
Assume the following declarations.
.. cpp:class:: template<typename TOuter> \
Outer
.. cpp:class:: template<typename TInner> \
Inner
.. cpp:class:: template<> \
Outer<int>
.. cpp:class:: template<typename TInner> \
Inner
.. cpp:class:: template<> \
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>`` (:cpp:class:`template\<> Outer\<int>`)
and ``template\<> template\<> Outer\<int>::Inner\<bool>`` (:cpp:class:`template\<> template\<> Outer\<int>::Inner\<bool>`).
As a shorthand the empty template parameter list can be omitted, e.g., ``Outer\<int>`` (:cpp:class:`Outer\<int>`)
and ``Outer\<int>::Inner\<bool>`` (:cpp:class:`Outer\<int>::Inner\<bool>`).
Partial Template Specialisations
.................................
Assume the following declaration.
.. cpp:class:: template<typename T> \
Outer<T*>
References to partial specialisations must always include the template parameter lists, e.g.,
``template\<typename T> Outer\<T*>`` (:cpp:class:`template\<typename T> Outer\<T*>`).
Currently the lookup only succeed if the template parameter identifiers are equal strings.
The Standard Domain The Standard Domain
------------------- -------------------

View File

@ -24,6 +24,10 @@ Attributes:
one convention to document module level variables and be consistent one convention to document module level variables and be consistent
with it. with it.
Todo:
* For module TODOs
* You have to also use ``sphinx.ext.todo`` extension
.. _Google Python Style Guide: .. _Google Python Style Guide:
http://google.github.io/styleguide/pyguide.html http://google.github.io/styleguide/pyguide.html
@ -237,16 +241,17 @@ class ExampleClass(object):
return True return True
def __special__(self): def __special__(self):
"""By default special members with docstrings are included. """By default special members with docstrings are not included.
Special members are any methods or attributes that start with and Special members are any methods or attributes that start with and
end with a double underscore. Any special member with a docstring end with a double underscore. Any special member with a docstring
will be included in the output. will be included in the output, if
``napoleon_include_special_with_doc`` is set to True.
This behavior can be disabled by changing the following setting in This behavior can be enabled by changing the following setting in
Sphinx's conf.py:: Sphinx's conf.py::
napoleon_include_special_with_doc = False napoleon_include_special_with_doc = True
""" """
pass pass

View File

@ -286,16 +286,17 @@ class ExampleClass(object):
return True return True
def __special__(self): def __special__(self):
"""By default special members with docstrings are included. """By default special members with docstrings are not included.
Special members are any methods or attributes that start with and Special members are any methods or attributes that start with and
end with a double underscore. Any special member with a docstring end with a double underscore. Any special member with a docstring
will be included in the output. will be included in the output, if
``napoleon_include_special_with_doc`` is set to True.
This behavior can be disabled by changing the following setting in This behavior can be enabled by changing the following setting in
Sphinx's conf.py:: Sphinx's conf.py::
napoleon_include_special_with_doc = False napoleon_include_special_with_doc = True
""" """
pass pass

12
doc/ext/githubpages.rst Normal file
View File

@ -0,0 +1,12 @@
.. highlight:: rest
:mod:`sphinx.ext.githubpages` -- Publish HTML docs in GitHub Pages
==================================================================
.. module:: sphinx.ext.githubpages
:synopsis: Publish HTML docs in GitHub Pages
.. versionadded:: 1.4
This extension creates ``.nojekyll`` file on generated HTML directory to publish
the document on GitHub Pages.

View File

@ -87,6 +87,15 @@ It adds these directives:
caption to the diagram. Naturally, diagrams marked as "inline" cannot have a caption to the diagram. Naturally, diagrams marked as "inline" cannot have a
caption. caption.
.. deprecated:: 1.4
``inline`` option is deprecated.
All three directives generate inline node by default. If ``caption`` is given,
these generate block node instead.
.. versionchanged:: 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: There are also these new config values:
.. confval:: graphviz_dot .. confval:: graphviz_dot
@ -97,8 +106,8 @@ There are also these new config values:
Since this setting is not portable from system to system, it is normally not 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 useful to set it in ``conf.py``; rather, giving it on the
:program:`sphinx-build` command line via the :option:`-D` option should be :program:`sphinx-build` command line via the :option:`-D <sphinx-build -D>`
preferable, like this:: option should be preferable, like this::
sphinx-build -b html -D graphviz_dot=C:\graphviz\bin\dot.exe . _build/html sphinx-build -b html -D graphviz_dot=C:\graphviz\bin\dot.exe . _build/html
@ -111,7 +120,18 @@ There are also these new config values:
.. confval:: graphviz_output_format .. confval:: graphviz_output_format
The output format for Graphviz when building HTML files. This must be either The output format for Graphviz when building HTML files. This must be either
``'png'`` or ``'svg'``; the default is ``'png'``. ``'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;
}
.. versionadded:: 1.0 .. versionadded:: 1.0
Previously, output always was PNG. Previously, output always was PNG.

View File

@ -4,7 +4,7 @@ Math support in Sphinx
====================== ======================
.. module:: sphinx.ext.mathbase .. module:: sphinx.ext.mathbase
:synopsis: Common math support for pngmath and mathjax / jsmath. :synopsis: Common math support for imgmath and mathjax / jsmath.
.. versionadded:: 0.5 .. versionadded:: 0.5
@ -17,7 +17,7 @@ support extensions should, if possible, reuse that support too.
.. note:: .. note::
:mod:`.mathbase` is not meant to be added to the :confval:`extensions` config :mod:`.mathbase` is not meant to be added to the :confval:`extensions` config
value, instead, use either :mod:`sphinx.ext.pngmath` or value, instead, use either :mod:`sphinx.ext.imgmath` or
:mod:`sphinx.ext.mathjax` as described below. :mod:`sphinx.ext.mathjax` as described below.
The input language for mathematics is LaTeX markup. This is the de-facto The input language for mathematics is LaTeX markup. This is the de-facto
@ -96,20 +96,27 @@ or use Python raw strings (``r"raw"``).
beautiful mathematical formulas. beautiful mathematical formulas.
:mod:`sphinx.ext.pngmath` -- Render math as PNG images :mod:`sphinx.ext.imgmath` -- Render math as images
------------------------------------------------------ --------------------------------------------------
.. module:: sphinx.ext.pngmath .. module:: sphinx.ext.imgmath
:synopsis: Render math as PNG images. :synopsis: Render math as PNG or SVG images.
This extension renders math via LaTeX and dvipng_ into PNG images. This of .. versionadded:: 1.4
course means that the computer where the docs are built must have both programs
available. This extension renders math via LaTeX and dvipng_ or dvisvgm_ 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 There are various config values you can set to influence how the images are
built: built:
.. confval:: pngmath_latex .. confval:: imgmath_image_format
The output image format. The default is ``'png'``. It should be either
``'png'`` or ``'svg'``.
.. confval:: imgmath_latex
The command name with which to invoke LaTeX. The default is ``'latex'``; you 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 may need to set this to a full path if ``latex`` is not in the executable
@ -117,45 +124,54 @@ built:
Since this setting is not portable from system to system, it is normally not 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 useful to set it in ``conf.py``; rather, giving it on the
:program:`sphinx-build` command line via the :option:`-D` option should be :program:`sphinx-build` command line via the :option:`-D <sphinx-build -D>`
preferable, like this:: option should be preferable, like this::
sphinx-build -b html -D pngmath_latex=C:\tex\latex.exe . _build/html sphinx-build -b html -D imgmath_latex=C:\tex\latex.exe . _build/html
.. versionchanged:: 0.5.1 This value should only contain the path to the latex executable, not further
This value should only contain the path to the latex executable, not arguments; use :confval:`imgmath_latex_args` for that purpose.
further arguments; use :confval:`pngmath_latex_args` for that purpose.
.. confval:: pngmath_dvipng .. confval:: imgmath_dvipng
The command name with which to invoke ``dvipng``. The default is 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 ``'dvipng'``; you may need to set this to a full path if ``dvipng`` is not in
the executable search path. the executable search path. This option is only used when
``imgmath_image_format`` is set to ``'png'``.
.. confval:: pngmath_latex_args .. confval:: 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'``.
.. confval:: imgmath_latex_args
Additional arguments to give to latex, as a list. The default is an empty Additional arguments to give to latex, as a list. The default is an empty
list. list.
.. versionadded:: 0.5.1 .. confval:: imgmath_latex_preamble
.. confval:: pngmath_latex_preamble
Additional LaTeX code to put into the preamble of the short LaTeX files that 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 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. e.g. to add more packages whose commands you want to use in the math.
.. confval:: pngmath_dvipng_args .. confval:: imgmath_dvipng_args
Additional arguments to give to dvipng, as a list. The default value is Additional arguments to give to dvipng, as a list. The default value is
``['-gamma', '1.5', '-D', '110', '-bg', 'Transparent']`` which makes the ``['-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 image a bit darker and larger then it is by default, and produces PNGs with a
transparent background. transparent background. This option is used only when
``imgmath_image_format`` is ``'png'``.
.. versionchanged:: 1.2 .. confval:: imgmath_dvisvgm_args
Now includes ``-bg Transparent`` by default.
.. confval:: pngmath_use_preview 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'``.
.. confval:: imgmath_use_preview
``dvipng`` has the ability to determine the "depth" of the rendered text: for ``dvipng`` has the ability to determine the "depth" of the rendered text: for
example, when typesetting a fraction inline, the baseline of surrounding text example, when typesetting a fraction inline, the baseline of surrounding text
@ -165,14 +181,20 @@ built:
``vertical-align`` style that correctly aligns the baselines. ``vertical-align`` style that correctly aligns the baselines.
Unfortunately, this only works when the `preview-latex package`_ is Unfortunately, this only works when the `preview-latex package`_ is
installed. Therefore, the default for this option is ``False``. installed. Therefore, the default for this option is ``False``.
.. confval:: pngmath_add_tooltips Currently this option is only used when ``imgmath_image_format`` is
``'png'``.
.. confval:: imgmath_add_tooltips
Default: ``True``. If false, do not add the LaTeX code as an "alt" attribute Default: ``True``. If false, do not add the LaTeX code as an "alt" attribute
for math images. for math images.
.. versionadded:: 1.1 .. confval:: imgmath_font_size
The font size (in ``pt``) of the displayed math. The default value is
``12``. It must be a positive integer.
:mod:`sphinx.ext.mathjax` -- Render math via JavaScript :mod:`sphinx.ext.mathjax` -- Render math via JavaScript
@ -235,6 +257,7 @@ package jsMath_. It provides this config value:
.. _dvipng: http://savannah.nongnu.org/projects/dvipng/ .. _dvipng: http://savannah.nongnu.org/projects/dvipng/
.. _dvisvgm: http://dvisvgm.bplaced.net/
.. _MathJax: http://www.mathjax.org/ .. _MathJax: http://www.mathjax.org/
.. _jsMath: http://www.math.union.edu/~dpvc/jsmath/ .. _jsMath: http://www.math.union.edu/~dpvc/jsmath/
.. _preview-latex package: http://www.gnu.org/software/auctex/preview-latex.html .. _preview-latex package: http://www.gnu.org/software/auctex/preview-latex.html

View File

@ -110,6 +110,7 @@ All of the following section headers are supported:
* ``Raises`` * ``Raises``
* ``References`` * ``References``
* ``See Also`` * ``See Also``
* ``Todo``
* ``Warning`` * ``Warning``
* ``Warnings`` *(alias of Warning)* * ``Warnings`` *(alias of Warning)*
* ``Warns`` * ``Warns``

View File

@ -16,6 +16,10 @@ There are two additional directives when using this extension:
It will only show up in the output if :confval:`todo_include_todos` is It will only show up in the output if :confval:`todo_include_todos` is
``True``. ``True``.
.. versionadded:: 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``.
.. rst:directive:: todolist .. rst:directive:: todolist

View File

@ -15,11 +15,7 @@ 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 descriptions that leads to the source code of the described object. A link back
from the source to the description will also be inserted. from the source to the description will also be inserted.
There are currently no configuration values for this extension; you just need to There is an additional config value:
add ``'sphinx.ext.viewcode'`` to your :confval:`extensions` value for it to
work.
There is also an additional config value:
.. confval:: viewcode_import .. confval:: viewcode_import

View File

@ -155,7 +155,7 @@ package.
add_directive('literalinclude', literalinclude_directive, add_directive('literalinclude', literalinclude_directive,
content = 0, arguments = (1, 0, 0), content = 0, arguments = (1, 0, 0),
linenos = directives.flag, linenos = directives.flag,
language = direcitves.unchanged, language = directives.unchanged,
encoding = directives.encoding) encoding = directives.encoding)
.. versionchanged:: 0.6 .. versionchanged:: 0.6
@ -336,6 +336,12 @@ package.
.. versionadded:: 1.1 .. versionadded:: 1.1
.. method:: Sphinx.add_source_parser(name, suffix, parser)
Register a parser class for specified *suffix*.
.. versionadded:: 1.4
.. method:: Sphinx.require_sphinx(version) .. method:: Sphinx.require_sphinx(version)
Compare *version* (which must be a ``major.minor`` version string, Compare *version* (which must be a ``major.minor`` version string,

View File

@ -17,7 +17,11 @@ Build environment API
.. attribute:: srcdir .. attribute:: srcdir
Source directory (the directory containing ``conf.py``). Source directory.
.. attribute:: confdir
Directory containing ``conf.py``.
.. attribute:: doctreedir .. attribute:: doctreedir

View File

@ -52,4 +52,5 @@ APIs used for writing extensions
builderapi builderapi
markupapi markupapi
domainapi domainapi
parserapi
nodes nodes

8
doc/extdev/parserapi.rst Normal file
View File

@ -0,0 +1,8 @@
.. _parser-api:
Parser API
==========
.. module:: sphinx.parsers
.. autoclass:: Parser

View File

@ -32,6 +32,7 @@ These extensions are built in and can be activated by respective entries in the
ext/viewcode ext/viewcode
ext/linkcode ext/linkcode
ext/napoleon ext/napoleon
ext/githubpages
Third-party extensions Third-party extensions

View File

@ -63,7 +63,7 @@ be translated you need to follow these instructions:
msgfmt "usage.po" -o "locale/es/LC_MESSAGES/usage.mo" msgfmt "usage.po" -o "locale/es/LC_MESSAGES/usage.mo"
* Set :confval:`locale_dirs` to ``["locale/"]``. * Set :confval:`locale_dirs` to ``["locale/"]``.
* Set :confval:`language` to ``es`` (also possible via :option:`-D`). * Set :confval:`language` to ``es`` (also possible via :option:`-D <sphinx-build -D>`).
* Run your desired build. * Run your desired build.

View File

@ -100,9 +100,9 @@ Extension options
Enable `sphinx.ext.coverage` extension. Enable `sphinx.ext.coverage` extension.
.. option:: --ext-pngmath .. option:: --ext-imgmath
Enable `sphinx.ext.pngmath` extension. Enable `sphinx.ext.imgmath` extension.
.. option:: --ext-mathjax .. option:: --ext-mathjax

View File

@ -242,9 +242,8 @@ objects:
.. rst:role:: option .. rst:role:: option
A command-line option to an executable program. The leading hyphen(s) must A command-line option to an executable program. This generates a link to
be included. This generates a link to a :rst:dir:`option` directive, if it a :rst:dir:`option` directive, if it exists.
exists.
The following role creates a cross-reference to a term in a The following role creates a cross-reference to a term in a

View File

@ -223,8 +223,10 @@ as long as the text::
================= =================
Normally, there are no heading levels assigned to certain characters as the Normally, there are no heading levels assigned to certain characters as the
structure is determined from the succession of headings. However, for the structure is determined from the succession of headings. However, this
Python documentation, this convention is used which you may follow: 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 parts
* ``*`` with overline, for chapters * ``*`` with overline, for chapters

View File

@ -81,8 +81,6 @@ that has to return the directory with themes in it::
Builtin themes Builtin themes
-------------- --------------
.. cssclass:: right
+--------------------+--------------------+ +--------------------+--------------------+
| **Theme overview** | | | **Theme overview** | |
+--------------------+--------------------+ +--------------------+--------------------+

View File

@ -122,8 +122,9 @@ this::
$ sphinx-build -b html sourcedir builddir $ sphinx-build -b html sourcedir builddir
where *sourcedir* is the :term:`source directory`, and *builddir* is the where *sourcedir* is the :term:`source directory`, and *builddir* is the
directory in which you want to place the built documentation. The :option:`-b` directory in which you want to place the built documentation.
option selects a builder; in this example Sphinx will build HTML files. The :option:`-b <sphinx-build -b>` option selects a builder; in this example
Sphinx will build HTML files.
|more| See :ref:`invocation` for all options that :program:`sphinx-build` |more| See :ref:`invocation` for all options that :program:`sphinx-build`
supports. supports.

View File

@ -135,7 +135,7 @@ add this data to the ``COMMENT_OPTIONS`` that are used in the template.
.. note:: .. note::
This only works works if your documentation is served from your This only works if your documentation is served from your
document root. If it is served from another directory, you will document root. If it is served from another directory, you will
need to prefix the url route with that directory, and give the `docroot` need to prefix the url route with that directory, and give the `docroot`
keyword argument when creating the web support object:: keyword argument when creating the web support object::

View File

@ -53,12 +53,11 @@ requires = [
'snowballstemmer>=1.1', 'snowballstemmer>=1.1',
'babel>=1.3,!=2.0', 'babel>=1.3,!=2.0',
'alabaster>=0.7,<0.8', 'alabaster>=0.7,<0.8',
'sphinx_rtd_theme>=0.1,<2.0',
] ]
extras_require = { extras_require = {
# Environment Marker works for wheel 0.24 or later # Environment Marker works for wheel 0.24 or later
':sys_platform=="win32"': [ ':sys_platform=="win32"': [
'colorama', 'colorama>=0.3.5',
], ],
'websupport': [ 'websupport': [
'sqlalchemy>=0.9', 'sqlalchemy>=0.9',
@ -73,7 +72,7 @@ extras_require = {
# for sdist installation with pip-1.5.6 # for sdist installation with pip-1.5.6
if sys.platform == 'win32': if sys.platform == 'win32':
requires.append('colorama') requires.append('colorama>=0.3.5')
# Provide a "compile_catalog" command that also creates the translated # Provide a "compile_catalog" command that also creates the translated
# JavaScript files if Babel is available. # JavaScript files if Babel is available.

View File

@ -4,7 +4,7 @@
Sphinx - Python documentation toolchain Sphinx - Python documentation toolchain
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Sphinx - Python documentation toolchain Sphinx - Python documentation toolchain
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Sphinx - Python documentation toolchain Sphinx - Python documentation toolchain
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Sphinx - Python documentation toolchain Sphinx - Python documentation toolchain
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
The Sphinx documentation toolchain. The Sphinx documentation toolchain.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
The Sphinx documentation toolchain. The Sphinx documentation toolchain.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
import sys import sys

View File

@ -5,7 +5,7 @@
Additional docutils nodes. Additional docutils nodes.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -212,6 +212,10 @@ class termsep(nodes.Structural, nodes.Element):
"""Separates two terms within a <term> node.""" """Separates two terms within a <term> node."""
class manpage(nodes.Inline, nodes.TextElement):
"""Node for references to manpages."""
# make the new nodes known to docutils; needed because the HTML writer will # make the new nodes known to docutils; needed because the HTML writer will
# choke at some point if these are not added # choke at some point if these are not added
nodes._add_node_class_names(k for k in globals().keys() nodes._add_node_class_names(k for k in globals().keys()

View File

@ -11,7 +11,7 @@
Copyright 2008 Société des arts technologiques (SAT), Copyright 2008 Société des arts technologiques (SAT),
http://www.sat.qc.ca/ http://www.sat.qc.ca/
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from __future__ import print_function from __future__ import print_function
@ -20,6 +20,7 @@ import os
import sys import sys
import optparse import optparse
from os import path from os import path
from six import binary_type
from sphinx.util.osutil import walk from sphinx.util.osutil import walk
from sphinx import __display_version__ from sphinx import __display_version__
@ -369,6 +370,15 @@ Note: By default this script will not overwrite already created files.""")
mastertoctree = text, mastertoctree = text,
language = 'en', language = 'en',
) )
if isinstance(opts.header, binary_type):
d['project'] = d['project'].decode('utf-8')
if isinstance(opts.author, binary_type):
d['author'] = d['author'].decode('utf-8')
if isinstance(opts.version, binary_type):
d['version'] = d['version'].decode('utf-8')
if isinstance(opts.release, binary_type):
d['release'] = d['release'].decode('utf-8')
if not opts.dryrun: if not opts.dryrun:
qs.generate(d, silent=True, overwrite=opts.force) qs.generate(d, silent=True, overwrite=opts.force)
elif not opts.notoc: elif not opts.notoc:

View File

@ -7,7 +7,7 @@
Gracefully adapted from the TextPress system by Armin. Gracefully adapted from the TextPress system by Armin.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from __future__ import print_function from __future__ import print_function
@ -77,6 +77,7 @@ class Sphinx(object):
self.next_listener_id = 0 self.next_listener_id = 0
self._extensions = {} self._extensions = {}
self._extension_metadata = {} self._extension_metadata = {}
self._additional_source_parsers = {}
self._listeners = {} self._listeners = {}
self._setting_up_extension = ['?'] self._setting_up_extension = ['?']
self.domains = BUILTIN_DOMAINS.copy() self.domains = BUILTIN_DOMAINS.copy()
@ -185,6 +186,8 @@ class Sphinx(object):
self._init_i18n() self._init_i18n()
# check all configuration values for permissible types # check all configuration values for permissible types
self.config.check_types(self.warn) self.config.check_types(self.warn)
# set up source_parsers
self._init_source_parsers()
# set up the build environment # set up the build environment
self._init_env(freshenv) self._init_env(freshenv)
# set up the builder # set up the builder
@ -211,6 +214,13 @@ class Sphinx(object):
else: else:
self.info('not available for built-in messages') 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): def _init_env(self, freshenv):
if freshenv: if freshenv:
self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.env = BuildEnvironment(self.srcdir, self.doctreedir,
@ -535,13 +545,14 @@ class Sphinx(object):
builder.name, self.builderclasses[builder.name].__module__)) builder.name, self.builderclasses[builder.name].__module__))
self.builderclasses[builder.name] = builder self.builderclasses[builder.name] = builder
def add_config_value(self, name, default, rebuild): def add_config_value(self, name, default, rebuild, types=()):
self.debug('[app] adding config value: %r', (name, default, rebuild)) self.debug('[app] adding config value: %r',
(name, default, rebuild) + ((types,) if types else ()))
if name in self.config.values: if name in self.config.values:
raise ExtensionError('Config value %r already present' % name) raise ExtensionError('Config value %r already present' % name)
if rebuild in (False, True): if rebuild in (False, True):
rebuild = rebuild and 'env' or '' rebuild = rebuild and 'env' or ''
self.config.values[name] = (default, rebuild) self.config.values[name] = (default, rebuild, types)
def add_event(self, name): def add_event(self, name):
self.debug('[app] adding event: %r', name) self.debug('[app] adding event: %r', name)
@ -751,6 +762,10 @@ class Sphinx(object):
assert issubclass(cls, SearchLanguage) assert issubclass(cls, SearchLanguage)
languages[cls.lang] = cls languages[cls.lang] = cls
def add_source_parser(self, suffix, parser):
self.debug('[app] adding search source_parser: %r, %r', (suffix, parser))
self._additional_source_parsers[suffix] = parser
class TemplateBridge(object): class TemplateBridge(object):
""" """

View File

@ -5,7 +5,7 @@
Builder superclass for all builders. Builder superclass for all builders.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -14,9 +14,8 @@ from os import path
try: try:
import multiprocessing import multiprocessing
import threading
except ImportError: except ImportError:
multiprocessing = threading = None multiprocessing = None
from docutils import nodes from docutils import nodes

View File

@ -5,7 +5,7 @@
Build Apple help books. Build Apple help books.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from __future__ import print_function from __future__ import print_function

View File

@ -5,7 +5,7 @@
Changelog builder. Changelog builder.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -7,7 +7,7 @@
.. _Devhelp: http://live.gnome.org/devhelp .. _Devhelp: http://live.gnome.org/devhelp
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from __future__ import absolute_import from __future__ import absolute_import
@ -91,7 +91,7 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
write_toc(subnode, item) write_toc(subnode, item)
elif isinstance(node, nodes.reference): elif isinstance(node, nodes.reference):
parent.attrib['link'] = node['refuri'] parent.attrib['link'] = node['refuri']
parent.attrib['name'] = node.astext().encode('utf-8') parent.attrib['name'] = node.astext()
def istoctree(node): def istoctree(node):
return isinstance(node, addnodes.compact_paragraph) and \ return isinstance(node, addnodes.compact_paragraph) and \
@ -129,6 +129,6 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
# Dump the XML file # Dump the XML file
f = comp_open(path.join(outdir, outname + '.devhelp'), 'w') f = comp_open(path.join(outdir, outname + '.devhelp'), 'w')
try: try:
tree.write(f) tree.write(f, 'utf-8')
finally: finally:
f.close() f.close()

View File

@ -6,7 +6,7 @@
Build epub files. Build epub files.
Originally derived from qthelp.py. Originally derived from qthelp.py.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
The MessageCatalogBuilder class. The MessageCatalogBuilder class.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Several HTML builders. Several HTML builders.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -6,7 +6,7 @@
Build HTML help support files. Build HTML help support files.
Parts adapted from Python's Doc/tools/prechm.py. Parts adapted from Python's Doc/tools/prechm.py.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from __future__ import print_function from __future__ import print_function

View File

@ -5,7 +5,7 @@
LaTeX builder. LaTeX builder.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -20,6 +20,7 @@ from docutils.frontend import OptionParser
from sphinx import package_dir, addnodes from sphinx import package_dir, addnodes
from sphinx.util import texescape from sphinx.util import texescape
from sphinx.errors import SphinxError
from sphinx.locale import _ from sphinx.locale import _
from sphinx.builders import Builder from sphinx.builders import Builder
from sphinx.environment import NoUri from sphinx.environment import NoUri
@ -94,9 +95,18 @@ class LaTeXBuilder(Builder):
destination_path=path.join(self.outdir, targetname), destination_path=path.join(self.outdir, targetname),
encoding='utf-8') encoding='utf-8')
self.info("processing " + targetname + "... ", nonl=1) self.info("processing " + targetname + "... ", nonl=1)
toctrees = self.env.get_doctree(docname).traverse(addnodes.toctree)
if toctrees:
if toctrees[0].get('maxdepth'):
tocdepth = int(toctrees[0].get('maxdepth'))
else:
tocdepth = None
else:
tocdepth = None
doctree = self.assemble_doctree( doctree = self.assemble_doctree(
docname, toctree_only, docname, toctree_only,
appendices=((docclass != 'howto') and self.config.latex_appendices or [])) appendices=((docclass != 'howto') and self.config.latex_appendices or []))
doctree['tocdepth'] = tocdepth
self.post_process_images(doctree) self.post_process_images(doctree)
self.info("writing... ", nonl=1) self.info("writing... ", nonl=1)
doctree.settings = docsettings doctree.settings = docsettings
@ -191,6 +201,9 @@ class LaTeXBuilder(Builder):
# the logo is handled differently # the logo is handled differently
if self.config.latex_logo: if self.config.latex_logo:
logobase = path.basename(self.config.latex_logo) logobase = path.basename(self.config.latex_logo)
copyfile(path.join(self.confdir, self.config.latex_logo), logotarget = path.join(self.outdir, logobase)
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') self.info('done')

View File

@ -5,7 +5,7 @@
The CheckExternalLinksBuilder class. The CheckExternalLinksBuilder class.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -17,7 +17,7 @@ from os import path
from six.moves import queue from six.moves import queue
from six.moves.urllib.request import build_opener, Request, HTTPRedirectHandler from six.moves.urllib.request import build_opener, Request, HTTPRedirectHandler
from six.moves.urllib.parse import unquote, urlsplit, quote from six.moves.urllib.parse import unquote
from six.moves.urllib.error import HTTPError from six.moves.urllib.error import HTTPError
from six.moves.html_parser import HTMLParser from six.moves.html_parser import HTMLParser
from docutils import nodes from docutils import nodes
@ -33,6 +33,7 @@ except ImportError:
pass pass
from sphinx.builders import Builder from sphinx.builders import Builder
from sphinx.util import encode_uri
from sphinx.util.console import purple, red, darkgreen, darkgray, \ from sphinx.util.console import purple, red, darkgreen, darkgray, \
darkred, turquoise darkred, turquoise
from sphinx.util.pycompat import TextIOWrapper from sphinx.util.pycompat import TextIOWrapper
@ -94,6 +95,17 @@ def check_anchor(f, hash):
return parser.found 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
class CheckExternalLinksBuilder(Builder): class CheckExternalLinksBuilder(Builder):
""" """
Checks for broken external links. Checks for broken external links.
@ -153,15 +165,7 @@ class CheckExternalLinksBuilder(Builder):
try: try:
req_url.encode('ascii') req_url.encode('ascii')
except UnicodeError: except UnicodeError:
split = urlsplit(req_url) req_url = encode_uri(req_url)
req_url = (split[0].encode() + '://' + # scheme
split[1].encode('idna') + # netloc
quote(split[2].encode('utf-8'))) # path
if split[3]: # query
req_url += '?' + quote(split[3].encode('utf-8'))
# go back to Unicode strings which is required by Python 3
# (but now all parts are pure ascii)
req_url = req_url.decode('ascii')
# need to actually check the URI # need to actually check the URI
try: try:
@ -172,6 +176,8 @@ class CheckExternalLinksBuilder(Builder):
encoding = 'utf-8' encoding = 'utf-8'
if hasattr(f.headers, 'get_content_charset'): if hasattr(f.headers, 'get_content_charset'):
encoding = f.headers.get_content_charset() or encoding encoding = f.headers.get_content_charset() or encoding
else:
encoding = get_content_charset(f) or encoding
found = check_anchor(TextIOWrapper(f, encoding), unquote(hash)) found = check_anchor(TextIOWrapper(f, encoding), unquote(hash))
f.close() f.close()
@ -237,11 +243,12 @@ class CheckExternalLinksBuilder(Builder):
elif status == 'working': elif status == 'working':
self.info(darkgreen('ok ') + uri + info) self.info(darkgreen('ok ') + uri + info)
elif status == 'broken': elif status == 'broken':
self.info(red('broken ') + uri + red(' - ' + info))
self.write_entry('broken', docname, lineno, uri + ': ' + info) self.write_entry('broken', docname, lineno, uri + ': ' + info)
if self.app.quiet: if self.app.quiet or self.app.warningiserror:
self.warn('broken link: %s' % uri, self.warn('broken link: %s' % uri,
'%s:%s' % (self.env.doc2path(docname), lineno)) '%s:%s' % (self.env.doc2path(docname), lineno))
else:
self.info(red('broken ') + uri + red(' - ' + info))
elif status == 'redirected': elif status == 'redirected':
text, color = { text, color = {
301: ('permanently', darkred), 301: ('permanently', darkred),

View File

@ -5,7 +5,7 @@
Manual pages builder. Manual pages builder.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Build input files for the Qt collection generator. Build input files for the Qt collection generator.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Texinfo builder. Texinfo builder.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Plain-text Sphinx builder. Plain-text Sphinx builder.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Builder for the web support package. Builder for the web support package.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Docutils-native XML and pseudo-XML builders. Docutils-native XML and pseudo-XML builders.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
sphinx-build command-line handling. sphinx-build command-line handling.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from __future__ import print_function from __future__ import print_function
@ -120,7 +120,7 @@ def main(argv):
# parse options # parse options
try: try:
opts, args = parser.parse_args(argv[1:]) opts, args = parser.parse_args(list(argv[1:]))
except SystemExit as err: except SystemExit as err:
return err.code return err.code
@ -144,6 +144,10 @@ def main(argv):
file=sys.stderr) file=sys.stderr)
return 1 return 1
outdir = abspath(args[1]) outdir = abspath(args[1])
if srcdir == outdir:
print('Error: source directory and destination directory are same.',
file=sys.stderr)
return 1
except IndexError: except IndexError:
parser.print_help() parser.print_help()
return 1 return 1

View File

@ -5,7 +5,7 @@
Build configuration file handling. Build configuration file handling.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -18,7 +18,7 @@ from six import PY3, iteritems, string_types, binary_type, integer_types
from sphinx.errors import ConfigError from sphinx.errors import ConfigError
from sphinx.locale import l_ from sphinx.locale import l_
from sphinx.util.osutil import make_filename, cd from sphinx.util.osutil import make_filename, cd
from sphinx.util.pycompat import execfile_ from sphinx.util.pycompat import execfile_, NoneType
nonascii_re = re.compile(br'[\x80-\xff]') nonascii_re = re.compile(br'[\x80-\xff]')
@ -27,10 +27,8 @@ if PY3:
CONFIG_SYNTAX_ERROR += "\nDid you change the syntax from 2.x to 3.x?" 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) " \ CONFIG_EXIT_ERROR = "The configuration file (or one of the modules it imports) " \
"called sys.exit()" "called sys.exit()"
CONFIG_TYPE_WARNING = "The config value `{name}' has type `{current.__name__}', " \
IGNORE_CONFIG_TYPE_CHECKS = ( "defaults to `{default.__name__}.'"
'html_domain_indices', 'latex_domain_indices', 'texinfo_domain_indices'
)
class Config(object): class Config(object):
@ -50,9 +48,10 @@ class Config(object):
version = ('', 'env'), version = ('', 'env'),
release = ('', 'env'), release = ('', 'env'),
today = ('', 'env'), today = ('', 'env'),
today_fmt = (None, 'env'), # the real default is locale-dependent # the real default is locale-dependent
today_fmt = (None, 'env', [str]),
language = (None, 'env'), language = (None, 'env', [str]),
locale_dirs = ([], 'env'), locale_dirs = ([], 'env'),
master_doc = ('contents', 'env'), master_doc = ('contents', 'env'),
@ -60,23 +59,23 @@ class Config(object):
source_encoding = ('utf-8-sig', 'env'), source_encoding = ('utf-8-sig', 'env'),
source_parsers = ({}, 'env'), source_parsers = ({}, 'env'),
exclude_patterns = ([], 'env'), exclude_patterns = ([], 'env'),
default_role = (None, 'env'), default_role = (None, 'env', [str]),
add_function_parentheses = (True, 'env'), add_function_parentheses = (True, 'env'),
add_module_names = (True, 'env'), add_module_names = (True, 'env'),
trim_footnote_reference_space = (False, 'env'), trim_footnote_reference_space = (False, 'env'),
show_authors = (False, 'env'), show_authors = (False, 'env'),
pygments_style = (None, 'html'), pygments_style = (None, 'html', [str]),
highlight_language = ('python', 'env'), highlight_language = ('python', 'env'),
highlight_options = ({}, 'env'), highlight_options = ({}, 'env'),
templates_path = ([], 'html'), templates_path = ([], 'html'),
template_bridge = (None, 'html'), template_bridge = (None, 'html', [str]),
keep_warnings = (False, 'env'), keep_warnings = (False, 'env'),
modindex_common_prefix = ([], 'html'), modindex_common_prefix = ([], 'html'),
rst_epilog = (None, 'env'), rst_epilog = (None, 'env', [str]),
rst_prolog = (None, 'env'), rst_prolog = (None, 'env', [str]),
trim_doctest_flags = (True, 'env'), trim_doctest_flags = (True, 'env'),
primary_domain = ('py', 'env'), primary_domain = ('py', 'env', [NoneType]),
needs_sphinx = (None, None), needs_sphinx = (None, None, [str]),
needs_extensions = ({}, None), needs_extensions = ({}, None),
nitpicky = (False, 'env'), nitpicky = (False, 'env'),
nitpick_ignore = ([], 'html'), nitpick_ignore = ([], 'html'),
@ -93,36 +92,36 @@ class Config(object):
html_theme_options = ({}, 'html'), html_theme_options = ({}, 'html'),
html_title = (lambda self: l_('%s %s documentation') % html_title = (lambda self: l_('%s %s documentation') %
(self.project, self.release), (self.project, self.release),
'html'), 'html', [str]),
html_short_title = (lambda self: self.html_title, 'html'), html_short_title = (lambda self: self.html_title, 'html'),
html_style = (None, 'html'), html_style = (None, 'html', [str]),
html_logo = (None, 'html'), html_logo = (None, 'html', [str]),
html_favicon = (None, 'html'), html_favicon = (None, 'html', [str]),
html_static_path = ([], 'html'), html_static_path = ([], 'html'),
html_extra_path = ([], 'html'), html_extra_path = ([], 'html'),
# the real default is locale-dependent # the real default is locale-dependent
html_last_updated_fmt = (None, 'html'), html_last_updated_fmt = (None, 'html', [str]),
html_use_smartypants = (True, 'html'), html_use_smartypants = (True, 'html'),
html_translator_class = (None, 'html'), html_translator_class = (None, 'html', [str]),
html_sidebars = ({}, 'html'), html_sidebars = ({}, 'html'),
html_additional_pages = ({}, 'html'), html_additional_pages = ({}, 'html'),
html_use_modindex = (True, 'html'), # deprecated html_use_modindex = (True, 'html'), # deprecated
html_domain_indices = (True, 'html'), html_domain_indices = (True, 'html', [list]),
html_add_permalinks = (u'\u00B6', 'html'), html_add_permalinks = (u'\u00B6', 'html'),
html_use_index = (True, 'html'), html_use_index = (True, 'html'),
html_split_index = (False, 'html'), html_split_index = (False, 'html'),
html_copy_source = (True, 'html'), html_copy_source = (True, 'html'),
html_show_sourcelink = (True, 'html'), html_show_sourcelink = (True, 'html'),
html_use_opensearch = ('', 'html'), html_use_opensearch = ('', 'html'),
html_file_suffix = (None, 'html'), html_file_suffix = (None, 'html', [str]),
html_link_suffix = (None, 'html'), html_link_suffix = (None, 'html', [str]),
html_show_copyright = (True, 'html'), html_show_copyright = (True, 'html'),
html_show_sphinx = (True, 'html'), html_show_sphinx = (True, 'html'),
html_context = ({}, 'html'), html_context = ({}, 'html'),
html_output_encoding = ('utf-8', 'html'), html_output_encoding = ('utf-8', 'html'),
html_compact_lists = (True, 'html'), html_compact_lists = (True, 'html'),
html_secnumber_suffix = ('. ', 'html'), html_secnumber_suffix = ('. ', 'html'),
html_search_language = (None, 'html'), html_search_language = (None, 'html', [str]),
html_search_options = ({}, 'html'), html_search_options = ({}, 'html'),
html_search_scorer = ('', None), html_search_scorer = ('', None),
html_scaled_image_link = (True, 'html'), html_scaled_image_link = (True, 'html'),
@ -139,17 +138,17 @@ class Config(object):
# Apple help options # Apple help options
applehelp_bundle_name = (lambda self: make_filename(self.project), applehelp_bundle_name = (lambda self: make_filename(self.project),
'applehelp'), 'applehelp'),
applehelp_bundle_id = (None, 'applehelp'), applehelp_bundle_id = (None, 'applehelp', [str]),
applehelp_dev_region = ('en-us', 'applehelp'), applehelp_dev_region = ('en-us', 'applehelp'),
applehelp_bundle_version = ('1', 'applehelp'), applehelp_bundle_version = ('1', 'applehelp'),
applehelp_icon = (None, 'applehelp'), applehelp_icon = (None, 'applehelp', [str]),
applehelp_kb_product = (lambda self: '%s-%s' % applehelp_kb_product = (lambda self: '%s-%s' %
(make_filename(self.project), self.release), (make_filename(self.project), self.release),
'applehelp'), 'applehelp'),
applehelp_kb_url = (None, 'applehelp'), applehelp_kb_url = (None, 'applehelp', [str]),
applehelp_remote_url = (None, 'applehelp'), applehelp_remote_url = (None, 'applehelp', [str]),
applehelp_index_anchors = (False, 'applehelp'), applehelp_index_anchors = (False, 'applehelp', [str]),
applehelp_min_term_length = (None, 'applehelp'), applehelp_min_term_length = (None, 'applehelp', [str]),
applehelp_stopwords = (lambda self: self.language or 'en', 'applehelp'), applehelp_stopwords = (lambda self: self.language or 'en', 'applehelp'),
applehelp_locale = (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_title = (lambda self: self.project + ' Help', 'applehelp'),
@ -196,11 +195,11 @@ class Config(object):
self.project, self.project,
'', 'manual')], '', 'manual')],
None), None),
latex_logo = (None, None), latex_logo = (None, None, [str]),
latex_appendices = ([], None), latex_appendices = ([], None),
latex_use_parts = (False, None), latex_use_parts = (False, None),
latex_use_modindex = (True, None), # deprecated latex_use_modindex = (True, None), # deprecated
latex_domain_indices = (True, None), latex_domain_indices = (True, None, [list]),
latex_show_urls = ('no', None), latex_show_urls = ('no', None),
latex_show_pagerefs = (False, None), latex_show_pagerefs = (False, None),
# paper_size and font_size are still separate values # paper_size and font_size are still separate values
@ -236,13 +235,13 @@ class Config(object):
None), None),
texinfo_appendices = ([], None), texinfo_appendices = ([], None),
texinfo_elements = ({}, None), texinfo_elements = ({}, None),
texinfo_domain_indices = (True, None), texinfo_domain_indices = (True, None, [list]),
texinfo_show_urls = ('footnote', None), texinfo_show_urls = ('footnote', None),
texinfo_no_detailmenu = (False, None), texinfo_no_detailmenu = (False, None),
# linkcheck options # linkcheck options
linkcheck_ignore = ([], None), linkcheck_ignore = ([], None),
linkcheck_timeout = (None, None), linkcheck_timeout = (None, None, [int]),
linkcheck_workers = (5, None), linkcheck_workers = (5, None),
linkcheck_anchors = (True, None), linkcheck_anchors = (True, None),
@ -292,25 +291,30 @@ class Config(object):
# NB. since config values might use l_() we have to wait with calling # NB. since config values might use l_() we have to wait with calling
# this method until i18n is initialized # this method until i18n is initialized
for name in self._raw_config: for name in self._raw_config:
if name in IGNORE_CONFIG_TYPE_CHECKS: if name not in self.values:
continue # for a while, ignore multiple types config value. see #1781
if name not in Config.config_values:
continue # we don't know a default value continue # we don't know a default value
default, dummy_rebuild = Config.config_values[name] settings = self.values[name]
default, dummy_rebuild = settings[:2]
permitted = settings[2] if len(settings) == 3 else ()
if hasattr(default, '__call__'): if hasattr(default, '__call__'):
default = default(self) # could invoke l_() default = default(self) # could invoke l_()
if default is None: if default is None and not permitted:
continue continue # neither inferrable nor expliclitly permitted types
current = self[name] current = self[name]
if type(current) is type(default): if type(current) is type(default):
continue continue
if type(current) in permitted:
continue
common_bases = (set(type(current).__bases__ + (type(current),)) & common_bases = (set(type(current).__bases__ + (type(current),)) &
set(type(default).__bases__)) set(type(default).__bases__))
common_bases.discard(object) common_bases.discard(object)
if common_bases: if common_bases:
continue # at least we share a non-trivial base class continue # at least we share a non-trivial base class
warn("the config value %r has type `%s', defaults to `%s.'" %
(name, type(current).__name__, type(default).__name__)) warn(CONFIG_TYPE_WARNING.format(
name=name, current=type(current), default=type(default)))
def check_unicode(self, warn): def check_unicode(self, warn):
# check all string values for non-ASCII characters in bytestrings, # check all string values for non-ASCII characters in bytestrings,

View File

@ -5,7 +5,7 @@
Handlers for additional ReST directives. Handlers for additional ReST directives.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -3,7 +3,7 @@
sphinx.directives.code sphinx.directives.code
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -93,6 +93,7 @@ class CodeBlock(Directive):
'lineno-start': int, 'lineno-start': int,
'emphasize-lines': directives.unchanged_required, 'emphasize-lines': directives.unchanged_required,
'caption': directives.unchanged_required, 'caption': directives.unchanged_required,
'class': directives.class_option,
'name': directives.unchanged, 'name': directives.unchanged,
} }
@ -119,6 +120,7 @@ class CodeBlock(Directive):
literal['language'] = self.arguments[0] literal['language'] = self.arguments[0]
literal['linenos'] = 'linenos' in self.options or \ literal['linenos'] = 'linenos' in self.options or \
'lineno-start' in self.options 'lineno-start' in self.options
literal['classes'] += self.options.get('class', [])
extra_args = literal['highlight_args'] = {} extra_args = literal['highlight_args'] = {}
if hl_lines is not None: if hl_lines is not None:
extra_args['hl_lines'] = hl_lines extra_args['hl_lines'] = hl_lines
@ -165,6 +167,7 @@ class LiteralInclude(Directive):
'append': directives.unchanged_required, 'append': directives.unchanged_required,
'emphasize-lines': directives.unchanged_required, 'emphasize-lines': directives.unchanged_required,
'caption': directives.unchanged, 'caption': directives.unchanged,
'class': directives.class_option,
'name': directives.unchanged, 'name': directives.unchanged,
'diff': directives.unchanged_required, 'diff': directives.unchanged_required,
} }
@ -322,6 +325,7 @@ class LiteralInclude(Directive):
retnode['linenos'] = 'linenos' in self.options or \ retnode['linenos'] = 'linenos' in self.options or \
'lineno-start' in self.options or \ 'lineno-start' in self.options or \
'lineno-match' in self.options 'lineno-match' in self.options
retnode['classes'] += self.options.get('class', [])
extra_args = retnode['highlight_args'] = {} extra_args = retnode['highlight_args'] = {}
if hl_lines is not None: if hl_lines is not None:
extra_args['hl_lines'] = hl_lines extra_args['hl_lines'] = hl_lines

View File

@ -3,7 +3,7 @@
sphinx.directives.other sphinx.directives.other
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -6,7 +6,7 @@
Support for domains, which are groupings of description directives Support for domains, which are groupings of description directives
and roles describing e.g. constructs of one programming language. and roles describing e.g. constructs of one programming language.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
The C language domain. The C language domain.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
The JavaScript domain. The JavaScript domain.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
The Python domain. The Python domain.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
The reStructuredText domain. The reStructuredText domain.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
The standard domain. The standard domain.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -210,10 +210,6 @@ class Program(Directive):
class OptionXRefRole(XRefRole): class OptionXRefRole(XRefRole):
def process_link(self, env, refnode, has_explicit_title, title, target): def process_link(self, env, refnode, has_explicit_title, title, target):
# validate content
if not re.match(r'(.+ )?[-/+\w]', target):
env.warn_node('Malformed :option: %r, does not contain option '
'marker - or -- or / or +' % target, refnode)
refnode['std:program'] = env.ref_context.get('std:program') refnode['std:program'] = env.ref_context.get('std:program')
return title, target return title, target
@ -457,7 +453,7 @@ class StandardDomain(Domain):
'productionlist': ProductionList, 'productionlist': ProductionList,
} }
roles = { roles = {
'option': OptionXRefRole(), 'option': OptionXRefRole(warn_dangling=True),
'envvar': EnvVarXRefRole(), 'envvar': EnvVarXRefRole(),
# links to tokens in grammar productions # links to tokens in grammar productions
'token': XRefRole(), 'token': XRefRole(),
@ -495,6 +491,7 @@ class StandardDomain(Domain):
'the label must precede a section header)', 'the label must precede a section header)',
'numref': 'undefined label: %(target)s', 'numref': 'undefined label: %(target)s',
'keyword': 'unknown keyword: %(target)s', 'keyword': 'unknown keyword: %(target)s',
'option': 'unknown option: %(target)s',
} }
def clear_doc(self, docname): def clear_doc(self, docname):
@ -633,7 +630,8 @@ class StandardDomain(Domain):
return None return None
if env.config.numfig is False: if env.config.numfig is False:
env.warn(fromdocname, 'numfig is disabled. :numref: is ignored.') env.warn(fromdocname, 'numfig is disabled. :numref: is ignored.',
lineno=node.line)
return contnode return contnode
try: try:
@ -648,7 +646,13 @@ class StandardDomain(Domain):
if target == fully_normalize_name(title): if target == fully_normalize_name(title):
title = env.config.numfig_format.get(figtype, '') title = env.config.numfig_format.get(figtype, '')
newtitle = title % '.'.join(map(str, fignumber)) try:
newtitle = title % '.'.join(map(str, fignumber))
except TypeError:
env.warn(fromdocname, 'invalid numfig_format: %s' % title,
lineno=node.line)
return None
return self.build_reference_node(fromdocname, builder, return self.build_reference_node(fromdocname, builder,
docname, labelid, newtitle, 'numref', docname, labelid, newtitle, 'numref',
nodeclass=addnodes.number_reference, nodeclass=addnodes.number_reference,
@ -661,22 +665,23 @@ class StandardDomain(Domain):
return make_refnode(builder, fromdocname, docname, return make_refnode(builder, fromdocname, docname,
labelid, contnode) labelid, contnode)
elif typ == 'option': elif typ == 'option':
progname = node.get('std:program')
target = target.strip() target = target.strip()
# most obvious thing: we are a flag option without program docname, labelid = self.data['progoptions'].get((progname, target), ('', ''))
if target.startswith(('-', '/', '+')):
progname = node.get('std:program')
elif re.search(r'[-/+]', target):
try:
progname, target = re.split(r' (?=-|--|/|\+)', target, 1)
except ValueError:
return None
progname = ws_re.sub('-', progname.strip())
else:
progname = None
docname, labelid = self.data['progoptions'].get((progname, target),
('', ''))
if not docname: if not docname:
return None commands = []
while ws_re.search(target):
subcommand, target = ws_re.split(target, 1)
commands.append(subcommand)
progname = "-".join(commands)
docname, labelid = self.data['progoptions'].get((progname, target),
('', ''))
if docname:
break
else:
return None
return make_refnode(builder, fromdocname, docname, return make_refnode(builder, fromdocname, docname,
labelid, contnode) labelid, contnode)
else: else:

View File

@ -5,7 +5,7 @@
Global creation environment. Global creation environment.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -23,8 +23,8 @@ from os import path
from glob import glob from glob import glob
from itertools import groupby from itertools import groupby
from six import iteritems, itervalues, text_type, class_types, string_types from six import iteritems, itervalues, text_type, class_types, string_types, next
from six.moves import cPickle as pickle, zip from six.moves import cPickle as pickle
from docutils import nodes from docutils import nodes
from docutils.io import FileInput, NullOutput from docutils.io import FileInput, NullOutput
from docutils.core import Publisher from docutils.core import Publisher
@ -38,7 +38,7 @@ from docutils.frontend import OptionParser
from sphinx import addnodes from sphinx import addnodes
from sphinx.util import url_re, get_matching_docs, docname_join, split_into, \ from sphinx.util import url_re, get_matching_docs, docname_join, split_into, \
FilenameUniqDict, get_figtype, import_object FilenameUniqDict, get_figtype, import_object, split_index_msg
from sphinx.util.nodes import clean_astext, make_refnode, WarningStream, is_translatable from sphinx.util.nodes import clean_astext, make_refnode, WarningStream, is_translatable
from sphinx.util.osutil import SEP, getcwd, fs_encoding from sphinx.util.osutil import SEP, getcwd, fs_encoding
from sphinx.util.i18n import find_catalog_files from sphinx.util.i18n import find_catalog_files
@ -105,13 +105,16 @@ class SphinxStandaloneReader(standalone.Reader):
DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks, DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks,
AutoNumbering, SortIds, RemoveTranslatableInline] AutoNumbering, SortIds, RemoveTranslatableInline]
def __init__(self, parsers={}, *args, **kwargs): def __init__(self, app, parsers={}, *args, **kwargs):
standalone.Reader.__init__(self, *args, **kwargs) standalone.Reader.__init__(self, *args, **kwargs)
self.parser_map = {} self.parser_map = {}
for suffix, parser_class in parsers.items(): for suffix, parser_class in parsers.items():
if isinstance(parser_class, string_types): if isinstance(parser_class, string_types):
parser_class = import_object(parser_class, 'source parser') parser_class = import_object(parser_class, 'source parser')
self.parser_map[suffix] = parser_class() parser = parser_class()
if hasattr(parser, 'set_application'):
parser.set_application(app)
self.parser_map[suffix] = parser
def read(self, source, parser, settings): def read(self, source, parser, settings):
self.source = source self.source = source
@ -618,8 +621,8 @@ class BuildEnvironment:
self._read_serial(docnames, app) self._read_serial(docnames, app)
if config.master_doc not in self.all_docs: if config.master_doc not in self.all_docs:
self.warn(None, 'master file %s not found' % raise SphinxError('master file %s not found' %
self.doc2path(config.master_doc)) self.doc2path(config.master_doc))
self.app = None self.app = None
@ -776,7 +779,7 @@ class BuildEnvironment:
codecs.register_error('sphinx', self.warn_and_replace) codecs.register_error('sphinx', self.warn_and_replace)
# publish manually # publish manually
reader = SphinxStandaloneReader(parsers=self.config.source_parsers) reader = SphinxStandaloneReader(self.app, parsers=self.config.source_parsers)
pub = Publisher(reader=reader, pub = Publisher(reader=reader,
writer=SphinxDummyWriter(), writer=SphinxDummyWriter(),
destination_class=NullOutput) destination_class=NullOutput)
@ -1123,7 +1126,14 @@ class BuildEnvironment:
def note_indexentries_from(self, docname, document): def note_indexentries_from(self, docname, document):
entries = self.indexentries[docname] = [] entries = self.indexentries[docname] = []
for node in document.traverse(addnodes.index): for node in document.traverse(addnodes.index):
entries.extend(node['entries']) try:
for type, value, tid, main in node['entries']:
split_index_msg(type, value)
except ValueError as exc:
self.warn_node(exc, node)
node.parent.remove(node)
else:
entries.extend(node['entries'])
def note_citations_from(self, docname, document): def note_citations_from(self, docname, document):
for node in document.traverse(nodes.citation): for node in document.traverse(nodes.citation):
@ -1656,7 +1666,7 @@ class BuildEnvironment:
for role in domain.roles: for role in domain.roles:
res = domain.resolve_xref(self, refdoc, builder, role, target, res = domain.resolve_xref(self, refdoc, builder, role, target,
node, contnode) node, contnode)
if res: if res and isinstance(res[0], nodes.Element):
results.append(('%s:%s' % (domain.name, role), res)) results.append(('%s:%s' % (domain.name, role), res))
# now, see how many matches we got... # now, see how many matches we got...
if not results: if not results:
@ -1951,54 +1961,31 @@ class BuildEnvironment:
for (key_, group) in groupby(newlist, keyfunc2)] for (key_, group) in groupby(newlist, keyfunc2)]
def collect_relations(self): def collect_relations(self):
relations = {} traversed = set()
getinc = self.toctree_includes.get
def traverse_toctree(parent, docname):
# 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]
def collect(parents, parents_set, docname, previous, next):
# circular relationship?
if docname in parents_set:
# we will warn about this in resolve_toctree()
return
includes = getinc(docname)
# previous
if not previous:
# if no previous sibling, go to parent
previous = parents[0][0]
else:
# else, go to previous sibling, or if it has children, to
# the last of its children, or if that has children, to the
# last of those, and so forth
while 1:
previncs = getinc(previous)
if previncs:
previous = previncs[-1]
else:
break
# next
if includes:
# if it has children, go to first of them
next = includes[0]
elif next:
# else, if next sibling, go to it
pass
else:
# else, go to the next sibling of the parent, if present,
# else the grandparent's sibling, if present, and so forth
for parname, parindex in parents:
parincs = getinc(parname)
if parincs and parindex + 1 < len(parincs):
next = parincs[parindex+1]
break
# else it will stay None
# same for children
if includes:
for subindex, args in enumerate(zip(includes,
[None] + includes,
includes[1:] + [None])):
collect([(docname, subindex)] + parents,
parents_set.union([docname]), *args)
relations[docname] = [parents[0][0], previous, next]
collect([(None, 0)], set(), self.config.master_doc, None, None)
return relations return relations
def check_consistency(self): def check_consistency(self):

View File

@ -6,7 +6,7 @@
Contains SphinxError and a few subclasses (in an extra module to avoid Contains SphinxError and a few subclasses (in an extra module to avoid
circular import problems). circular import problems).
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

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

View File

@ -7,7 +7,7 @@
the doctree, thus avoiding duplication between docstrings and documentation the doctree, thus avoiding duplication between docstrings and documentation
for those who like elaborate docstrings. for those who like elaborate docstrings.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -17,8 +17,8 @@ import inspect
import traceback import traceback
from types import FunctionType, BuiltinFunctionType, MethodType from types import FunctionType, BuiltinFunctionType, MethodType
from six import iteritems, itervalues, text_type, class_types, string_types, \ from six import iterkeys, iteritems, itervalues, text_type, class_types, \
StringIO string_types, StringIO
from docutils import nodes from docutils import nodes
from docutils.utils import assemble_option_dict from docutils.utils import assemble_option_dict
from docutils.statemachine import ViewList from docutils.statemachine import ViewList
@ -720,7 +720,7 @@ class Documenter(object):
# __dict__ contains only the members directly defined in # __dict__ contains only the members directly defined in
# the class (but get them via getattr anyway, to e.g. get # the class (but get them via getattr anyway, to e.g. get
# unbound method objects instead of function objects); # unbound method objects instead of function objects);
# using keys() because apparently there are objects for which # using list(iterkeys()) because apparently there are objects for which
# __dict__ changes while getting attributes # __dict__ changes while getting attributes
try: try:
obj_dict = self.get_attr(self.object, '__dict__') obj_dict = self.get_attr(self.object, '__dict__')
@ -728,7 +728,7 @@ class Documenter(object):
members = [] members = []
else: else:
members = [(mname, self.get_attr(self.object, mname, None)) members = [(mname, self.get_attr(self.object, mname, None))
for mname in obj_dict.keys()] for mname in list(iterkeys(obj_dict))]
membernames = set(m[0] for m in members) membernames = set(m[0] for m in members)
# add instance attributes from the analyzer # add instance attributes from the analyzer
for aname in analyzed_member_names: for aname in analyzed_member_names:
@ -1292,9 +1292,11 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter):
docstrings.append(initdocstring) docstrings.append(initdocstring)
doc = [] doc = []
for docstring in docstrings: for docstring in docstrings:
if not isinstance(docstring, text_type): if isinstance(docstring, text_type):
docstring = force_decode(docstring, encoding) doc.append(prepare_docstring(docstring, ignore))
doc.append(prepare_docstring(docstring)) elif isinstance(docstring, str): # this will not trigger on Py3
doc.append(prepare_docstring(force_decode(docstring, encoding),
ignore))
return doc return doc
def add_content(self, more_content, no_docstring=False): def add_content(self, more_content, no_docstring=False):

View File

@ -49,7 +49,7 @@
resolved to a Python object, and otherwise it becomes simple emphasis. resolved to a Python object, and otherwise it becomes simple emphasis.
This can be used as the default role to make links 'smart'. This can be used as the default role to make links 'smart'.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -583,5 +583,5 @@ def setup(app):
app.add_role('autolink', autolink_role) app.add_role('autolink', autolink_role)
app.connect('doctree-read', process_autosummary_toc) app.connect('doctree-read', process_autosummary_toc)
app.connect('builder-inited', process_generate_options) app.connect('builder-inited', process_generate_options)
app.add_config_value('autosummary_generate', [], True) app.add_config_value('autosummary_generate', [], True, [bool])
return {'version': sphinx.__display_version__, 'parallel_read_safe': True} return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -14,7 +14,7 @@
generate: generate:
sphinx-autogen -o source/generated source/*.rst sphinx-autogen -o source/generated source/*.rst
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from __future__ import print_function from __future__ import print_function

View File

@ -6,7 +6,7 @@
Check Python modules and C API for coverage. Mostly written by Josip Check Python modules and C API for coverage. Mostly written by Josip
Dzolonga for the Google Highly Open Participation contest. Dzolonga for the Google Highly Open Participation contest.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -6,7 +6,7 @@
Mimic doctest by automatically executing code snippets and checking Mimic doctest by automatically executing code snippets and checking
their results. their results.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from __future__ import absolute_import from __future__ import absolute_import
@ -45,14 +45,6 @@ else:
return text return text
class _SpoofOutSphinx(doctest._SpoofOut):
# override: convert console encoding to unicode
if PY2:
def getvalue(self):
result = doctest._SpoofOut.getvalue(self)
return result.decode('string_escape')
# set up the necessary directives # set up the necessary directives
class TestDirective(Directive): class TestDirective(Directive):
@ -184,11 +176,6 @@ class TestCode(object):
class SphinxDocTestRunner(doctest.DocTestRunner): class SphinxDocTestRunner(doctest.DocTestRunner):
def __init__(self, *args, **kw):
doctest.DocTestRunner.__init__(self, *args, **kw)
# Override a fake output target for capturing doctest output.
self._fakeout = _SpoofOutSphinx()
def summarize(self, out, verbose=None): def summarize(self, out, verbose=None):
string_io = StringIO() string_io = StringIO()
old_stdout = sys.stdout old_stdout = sys.stdout
@ -262,9 +249,10 @@ Results of doctest builder run on %s
self.outfile.write(text) self.outfile.write(text)
def _warn_out(self, text): def _warn_out(self, text):
self.info(text, nonl=True) if self.app.quiet or self.app.warningiserror:
if self.app.quiet:
self.warn(text) self.warn(text)
else:
self.info(text, nonl=True)
if isinstance(text, binary_type): if isinstance(text, binary_type):
text = force_decode(text, None) text = force_decode(text, None)
self.outfile.write(text) self.outfile.write(text)

View File

@ -20,7 +20,7 @@
You can also give an explicit caption, e.g. :exmpl:`Foo <foo>`. You can also give an explicit caption, e.g. :exmpl:`Foo <foo>`.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

24
sphinx/ext/githubpages.py Normal file
View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
"""
sphinx.ext.githubpages
~~~~~~~~~~~~~~~~~~~~~~
To publish HTML docs at GitHub Pages, create .nojekyll file.
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import sphinx
def create_nojekyll(app, env):
if app.builder.format == 'html':
path = os.path.join(app.builder.outdir, '.nojekyll')
open(path, 'wt').close()
def setup(app):
app.connect('env-updated', create_nojekyll)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -6,7 +6,7 @@
Allow graphviz-formatted graphs to be included in Sphinx-generated Allow graphviz-formatted graphs to be included in Sphinx-generated
documents inline. documents inline.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -36,7 +36,7 @@ class GraphvizError(SphinxError):
category = 'Graphviz error' category = 'Graphviz error'
class graphviz(nodes.General, nodes.Element): class graphviz(nodes.General, nodes.Inline, nodes.Element):
pass pass
@ -66,6 +66,7 @@ class Graphviz(Directive):
'alt': directives.unchanged, 'alt': directives.unchanged,
'inline': directives.flag, 'inline': directives.flag,
'caption': directives.unchanged, 'caption': directives.unchanged,
'graphviz_dot': directives.unchanged,
} }
def run(self): def run(self):
@ -96,13 +97,16 @@ class Graphviz(Directive):
line=self.lineno)] line=self.lineno)]
node = graphviz() node = graphviz()
node['code'] = dotcode node['code'] = dotcode
node['options'] = [] node['options'] = {}
if 'graphviz_dot' in self.options:
node['options']['graphviz_dot'] = self.options['graphviz_dot']
if 'alt' in self.options: if 'alt' in self.options:
node['alt'] = self.options['alt'] node['alt'] = self.options['alt']
node['inline'] = 'inline' in self.options if 'inline' in self.options:
node['inline'] = True
caption = self.options.get('caption') caption = self.options.get('caption')
if caption and not node['inline']: if caption:
node = figure_wrapper(self, node, caption) node = figure_wrapper(self, node, caption)
return [node] return [node]
@ -120,19 +124,23 @@ class GraphvizSimple(Directive):
'alt': directives.unchanged, 'alt': directives.unchanged,
'inline': directives.flag, 'inline': directives.flag,
'caption': directives.unchanged, 'caption': directives.unchanged,
'graphviz_dot': directives.unchanged,
} }
def run(self): def run(self):
node = graphviz() node = graphviz()
node['code'] = '%s %s {\n%s\n}\n' % \ node['code'] = '%s %s {\n%s\n}\n' % \
(self.name, self.arguments[0], '\n'.join(self.content)) (self.name, self.arguments[0], '\n'.join(self.content))
node['options'] = [] node['options'] = {}
if 'graphviz_dot' in self.options:
node['options']['graphviz_dot'] = self.options['graphviz_dot']
if 'alt' in self.options: if 'alt' in self.options:
node['alt'] = self.options['alt'] node['alt'] = self.options['alt']
node['inline'] = 'inline' in self.options if 'inline' in self.options:
node['inline'] = True
caption = self.options.get('caption') caption = self.options.get('caption')
if caption and not node['inline']: if caption:
node = figure_wrapper(self, node, caption) node = figure_wrapper(self, node, caption)
return [node] return [node]
@ -140,8 +148,8 @@ class GraphvizSimple(Directive):
def render_dot(self, code, options, format, prefix='graphviz'): def render_dot(self, code, options, format, prefix='graphviz'):
"""Render graphviz code into a PNG or PDF output file.""" """Render graphviz code into a PNG or PDF output file."""
hashkey = (code + str(options) + graphviz_dot = options.get('graphviz_dot', self.builder.config.graphviz_dot)
str(self.builder.config.graphviz_dot) + hashkey = (code + str(options) + str(graphviz_dot) +
str(self.builder.config.graphviz_dot_args)).encode('utf-8') str(self.builder.config.graphviz_dot_args)).encode('utf-8')
fname = '%s-%s.%s' % (prefix, sha1(hashkey).hexdigest(), format) fname = '%s-%s.%s' % (prefix, sha1(hashkey).hexdigest(), format)
@ -151,8 +159,8 @@ def render_dot(self, code, options, format, prefix='graphviz'):
if path.isfile(outfn): if path.isfile(outfn):
return relfn, outfn return relfn, outfn
if hasattr(self.builder, '_graphviz_warned_dot') or \ if (hasattr(self.builder, '_graphviz_warned_dot') and
hasattr(self.builder, '_graphviz_warned_ps2pdf'): self.builder._graphviz_warned_dot.get(graphviz_dot)):
return None, None return None, None
ensuredir(path.dirname(outfn)) ensuredir(path.dirname(outfn))
@ -161,9 +169,8 @@ def render_dot(self, code, options, format, prefix='graphviz'):
if isinstance(code, text_type): if isinstance(code, text_type):
code = code.encode('utf-8') code = code.encode('utf-8')
dot_args = [self.builder.config.graphviz_dot] dot_args = [graphviz_dot]
dot_args.extend(self.builder.config.graphviz_dot_args) dot_args.extend(self.builder.config.graphviz_dot_args)
dot_args.extend(options)
dot_args.extend(['-T' + format, '-o' + outfn]) dot_args.extend(['-T' + format, '-o' + outfn])
if format == 'png': if format == 'png':
dot_args.extend(['-Tcmapx', '-o%s.map' % outfn]) dot_args.extend(['-Tcmapx', '-o%s.map' % outfn])
@ -173,9 +180,10 @@ def render_dot(self, code, options, format, prefix='graphviz'):
if err.errno != ENOENT: # No such file or directory if err.errno != ENOENT: # No such file or directory
raise raise
self.builder.warn('dot command %r cannot be run (needed for graphviz ' self.builder.warn('dot command %r cannot be run (needed for graphviz '
'output), check the graphviz_dot setting' % 'output), check the graphviz_dot setting' % graphviz_dot)
self.builder.config.graphviz_dot) if not hasattr(self.builder, '_graphviz_warned_dot'):
self.builder._graphviz_warned_dot = True self.builder._graphviz_warned_dot = {}
self.builder._graphviz_warned_dot[graphviz_dot] = True
return None, None return None, None
try: try:
# Graphviz may close standard input when an error occurs, # Graphviz may close standard input when an error occurs,
@ -197,6 +205,15 @@ def render_dot(self, code, options, format, prefix='graphviz'):
return relfn, outfn return relfn, outfn
def warn_for_deprecated_option(self, node):
if hasattr(self.builder, '_graphviz_warned_inline'):
return
if 'inline' in node:
self.builder.warn(':inline: option for graphviz is deprecated since version 1.4.0.')
self.builder._graphviz_warned_inline = True
def render_dot_html(self, node, code, options, prefix='graphviz', def render_dot_html(self, node, code, options, prefix='graphviz',
imgcls=None, alt=None): imgcls=None, alt=None):
format = self.builder.config.graphviz_output_format format = self.builder.config.graphviz_output_format
@ -209,13 +226,6 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
self.builder.warn('dot code %r: ' % code + str(exc)) self.builder.warn('dot code %r: ' % code + str(exc))
raise nodes.SkipNode raise nodes.SkipNode
inline = node.get('inline', False)
if inline:
wrapper = 'span'
else:
wrapper = 'p'
self.body.append(self.starttag(node, wrapper, CLASS='graphviz'))
if fname is None: if fname is None:
self.body.append(self.encode(code)) self.body.append(self.encode(code))
else: else:
@ -223,7 +233,8 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
alt = node.get('alt', self.encode(code).strip()) alt = node.get('alt', self.encode(code).strip())
imgcss = imgcls and 'class="%s"' % imgcls or '' imgcss = imgcls and 'class="%s"' % imgcls or ''
if format == 'svg': if format == 'svg':
svgtag = '<img src="%s" alt="%s" %s/>\n' % (fname, alt, imgcss) svgtag = '''<object data="%s" type="image/svg+xml">
<p class="warning">%s</p></object>\n''' % (fname, alt)
self.body.append(svgtag) self.body.append(svgtag)
else: else:
mapfile = open(outfn + '.map', 'rb') mapfile = open(outfn + '.map', 'rb')
@ -242,11 +253,11 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
(fname, alt, mapname, imgcss)) (fname, alt, mapname, imgcss))
self.body.extend([item.decode('utf-8') for item in imgmap]) self.body.extend([item.decode('utf-8') for item in imgmap])
self.body.append('</%s>\n' % wrapper)
raise nodes.SkipNode raise nodes.SkipNode
def html_visit_graphviz(self, node): def html_visit_graphviz(self, node):
warn_for_deprecated_option(self, node)
render_dot_html(self, node, node['code'], node['options']) render_dot_html(self, node, node['code'], node['options'])
@ -257,8 +268,8 @@ def render_dot_latex(self, node, code, options, prefix='graphviz'):
self.builder.warn('dot code %r: ' % code + str(exc)) self.builder.warn('dot code %r: ' % code + str(exc))
raise nodes.SkipNode raise nodes.SkipNode
inline = node.get('inline', False) is_inline = self.is_inline(node)
if inline: if is_inline:
para_separator = '' para_separator = ''
else: else:
para_separator = '\n' para_separator = '\n'
@ -270,6 +281,7 @@ def render_dot_latex(self, node, code, options, prefix='graphviz'):
def latex_visit_graphviz(self, node): def latex_visit_graphviz(self, node):
warn_for_deprecated_option(self, node)
render_dot_latex(self, node, node['code'], node['options']) render_dot_latex(self, node, node['code'], node['options'])
@ -285,10 +297,12 @@ def render_dot_texinfo(self, node, code, options, prefix='graphviz'):
def texinfo_visit_graphviz(self, node): def texinfo_visit_graphviz(self, node):
warn_for_deprecated_option(self, node)
render_dot_texinfo(self, node, node['code'], node['options']) render_dot_texinfo(self, node, node['code'], node['options'])
def text_visit_graphviz(self, node): def text_visit_graphviz(self, node):
warn_for_deprecated_option(self, node)
if 'alt' in node.attributes: if 'alt' in node.attributes:
self.add_text(_('[graph: %s]') % node['alt']) self.add_text(_('[graph: %s]') % node['alt'])
else: else:
@ -297,6 +311,7 @@ def text_visit_graphviz(self, node):
def man_visit_graphviz(self, node): def man_visit_graphviz(self, node):
warn_for_deprecated_option(self, node)
if 'alt' in node.attributes: if 'alt' in node.attributes:
self.body.append(_('[graph: %s]') % node['alt']) self.body.append(_('[graph: %s]') % node['alt'])
else: else:

View File

@ -16,7 +16,7 @@
namespace of the project configuration (that is, all variables from namespace of the project configuration (that is, all variables from
``conf.py`` are available.) ``conf.py`` are available.)
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

284
sphinx/ext/imgmath.py Normal file
View File

@ -0,0 +1,284 @@
# -*- coding: utf-8 -*-
"""
sphinx.ext.imgmath
~~~~~~~~~~~~~~~~~~
Render math in HTML via dvipng or dvisvgm.
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
import codecs
import shutil
import tempfile
import posixpath
from os import path
from subprocess import Popen, PIPE
from hashlib import sha1
from six import text_type
from docutils import nodes
import sphinx
from sphinx.errors import SphinxError
from sphinx.util.png import read_png_depth, write_png_depth
from sphinx.util.osutil import ensuredir, ENOENT, cd
from sphinx.util.pycompat import sys_encoding
from sphinx.ext.mathbase import setup_math as mathbase_setup, wrap_displaymath
class MathExtError(SphinxError):
category = 'Math extension error'
def __init__(self, msg, stderr=None, stdout=None):
if stderr:
msg += '\n[stderr]\n' + stderr.decode(sys_encoding, 'replace')
if stdout:
msg += '\n[stdout]\n' + stdout.decode(sys_encoding, 'replace')
SphinxError.__init__(self, msg)
DOC_HEAD = r'''
\documentclass[12pt]{article}
\usepackage[utf8x]{inputenc}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amssymb}
\usepackage{amsfonts}
\usepackage{anyfontsize}
\usepackage{bm}
\pagestyle{empty}
'''
DOC_BODY = r'''
\begin{document}
\fontsize{%d}{%d}\selectfont %s
\end{document}
'''
DOC_BODY_PREVIEW = r'''
\usepackage[active]{preview}
\begin{document}
\begin{preview}
\fontsize{%s}{%s}\selectfont %s
\end{preview}
\end{document}
'''
depth_re = re.compile(br'\[\d+ depth=(-?\d+)\]')
def render_math(self, math):
"""Render the LaTeX math expression *math* using latex and dvipng or
dvisvgm.
Return the filename relative to the built document and the "depth",
that is, the distance of image bottom and baseline in pixels, if the
option to use preview_latex is switched on.
Error handling may seem strange, but follows a pattern: if LaTeX or dvipng
(dvisvgm) aren't available, only a warning is generated (since that enables
people on machines without these programs to at least build the rest of the
docs successfully). If the programs are there, however, they may not fail
since that indicates a problem in the math source.
"""
image_format = self.builder.config.imgmath_image_format
if image_format not in ('png', 'svg'):
raise MathExtError(
'imgmath_image_format must be either "png" or "svg"')
font_size = self.builder.config.imgmath_font_size
use_preview = self.builder.config.imgmath_use_preview
latex = DOC_HEAD + self.builder.config.imgmath_latex_preamble
latex += (use_preview and DOC_BODY_PREVIEW or DOC_BODY) % (
font_size, int(round(font_size * 1.2)), math)
shasum = "%s.%s" % (sha1(latex.encode('utf-8')).hexdigest(), image_format)
relfn = posixpath.join(self.builder.imgpath, 'math', shasum)
outfn = path.join(self.builder.outdir, self.builder.imagedir, 'math', shasum)
if path.isfile(outfn):
depth = read_png_depth(outfn)
return relfn, depth
# if latex or dvipng (dvisvgm) has failed once, don't bother to try again
if hasattr(self.builder, '_imgmath_warned_latex') or \
hasattr(self.builder, '_imgmath_warned_image_translator'):
return None, None
# use only one tempdir per build -- the use of a directory is cleaner
# than using temporary files, since we can clean up everything at once
# just removing the whole directory (see cleanup_tempdir)
if not hasattr(self.builder, '_imgmath_tempdir'):
tempdir = self.builder._imgmath_tempdir = tempfile.mkdtemp()
else:
tempdir = self.builder._imgmath_tempdir
tf = codecs.open(path.join(tempdir, 'math.tex'), 'w', 'utf-8')
tf.write(latex)
tf.close()
# build latex command; old versions of latex don't have the
# --output-directory option, so we have to manually chdir to the
# temp dir to run it.
ltx_args = [self.builder.config.imgmath_latex, '--interaction=nonstopmode']
# add custom args from the config file
ltx_args.extend(self.builder.config.imgmath_latex_args)
ltx_args.append('math.tex')
with cd(tempdir):
try:
p = Popen(ltx_args, stdout=PIPE, stderr=PIPE)
except OSError as err:
if err.errno != ENOENT: # No such file or directory
raise
self.builder.warn('LaTeX command %r cannot be run (needed for math '
'display), check the imgmath_latex setting' %
self.builder.config.imgmath_latex)
self.builder._imgmath_warned_latex = True
return None, None
stdout, stderr = p.communicate()
if p.returncode != 0:
raise MathExtError('latex exited with error', stderr, stdout)
ensuredir(path.dirname(outfn))
if image_format == 'png':
image_translator = 'dvipng'
image_translator_executable = self.builder.config.imgmath_dvipng
# use some standard dvipng arguments
image_translator_args = [self.builder.config.imgmath_dvipng]
image_translator_args += ['-o', outfn, '-T', 'tight', '-z9']
# add custom ones from config value
image_translator_args.extend(self.builder.config.imgmath_dvipng_args)
if use_preview:
image_translator_args.append('--depth')
elif image_format == 'svg':
image_translator = 'dvisvgm'
image_translator_executable = self.builder.config.imgmath_dvisvgm
# use some standard dvisvgm arguments
image_translator_args = [self.builder.config.imgmath_dvisvgm]
image_translator_args += ['-o', outfn]
# add custom ones from config value
image_translator_args.extend(self.builder.config.imgmath_dvisvgm_args)
# last, the input file name
image_translator_args.append(path.join(tempdir, 'math.dvi'))
else:
raise MathExtError(
'imgmath_image_format must be either "png" or "svg"')
# last, the input file name
image_translator_args.append(path.join(tempdir, 'math.dvi'))
try:
p = Popen(image_translator_args, stdout=PIPE, stderr=PIPE)
except OSError as err:
if err.errno != ENOENT: # No such file or directory
raise
self.builder.warn('%s command %r cannot be run (needed for math '
'display), check the imgmath_%s setting' %
image_translator, image_translator_executable,
image_translator)
self.builder._imgmath_warned_image_translator = True
return None, None
stdout, stderr = p.communicate()
if p.returncode != 0:
raise MathExtError('%s exited with error',
image_translator, stderr, stdout)
depth = None
if use_preview and image_format == 'png': # depth is only useful for png
for line in stdout.splitlines():
m = depth_re.match(line)
if m:
depth = int(m.group(1))
write_png_depth(outfn, depth)
break
return relfn, depth
def cleanup_tempdir(app, exc):
if exc:
return
if not hasattr(app.builder, '_imgmath_tempdir'):
return
try:
shutil.rmtree(app.builder._mathpng_tempdir)
except Exception:
pass
def get_tooltip(self, node):
if self.builder.config.imgmath_add_tooltips:
return ' alt="%s"' % self.encode(node['latex']).strip()
return ''
def html_visit_math(self, node):
try:
fname, depth = render_math(self, '$'+node['latex']+'$')
except MathExtError as exc:
msg = text_type(exc)
sm = nodes.system_message(msg, type='WARNING', level=2,
backrefs=[], source=node['latex'])
sm.walkabout(self)
self.builder.warn('display latex %r: ' % node['latex'] + msg)
raise nodes.SkipNode
if fname is None:
# something failed -- use text-only as a bad substitute
self.body.append('<span class="math">%s</span>' %
self.encode(node['latex']).strip())
else:
c = ('<img class="math" src="%s"' % fname) + get_tooltip(self, node)
if depth is not None:
c += ' style="vertical-align: %dpx"' % (-depth)
self.body.append(c + '/>')
raise nodes.SkipNode
def html_visit_displaymath(self, node):
if node['nowrap']:
latex = node['latex']
else:
latex = wrap_displaymath(node['latex'], None)
try:
fname, depth = render_math(self, latex)
except MathExtError as exc:
sm = nodes.system_message(str(exc), type='WARNING', level=2,
backrefs=[], source=node['latex'])
sm.walkabout(self)
self.builder.warn('inline latex %r: ' % node['latex'] + str(exc))
raise nodes.SkipNode
self.body.append(self.starttag(node, 'div', CLASS='math'))
self.body.append('<p>')
if node['number']:
self.body.append('<span class="eqno">(%s)</span>' % node['number'])
if fname is None:
# something failed -- use text-only as a bad substitute
self.body.append('<span class="math">%s</span></p>\n</div>' %
self.encode(node['latex']).strip())
else:
self.body.append(('<img src="%s"' % fname) + get_tooltip(self, node) +
'/></p>\n</div>')
raise nodes.SkipNode
def setup(app):
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
app.add_config_value('imgmath_image_format', 'png', 'html')
app.add_config_value('imgmath_dvipng', 'dvipng', 'html')
app.add_config_value('imgmath_dvisvgm', 'dvisvgm', 'html')
app.add_config_value('imgmath_latex', 'latex', 'html')
app.add_config_value('imgmath_use_preview', False, 'html')
app.add_config_value('imgmath_dvipng_args',
['-gamma', '1.5', '-D', '110', '-bg', 'Transparent'],
'html')
app.add_config_value('imgmath_dvisvgm_args', ['--no-fonts'], 'html')
app.add_config_value('imgmath_latex_args', [], 'html')
app.add_config_value('imgmath_latex_preamble', '', 'html')
app.add_config_value('imgmath_add_tooltips', True, 'html')
app.add_config_value('imgmath_font_size', 12, 'html')
app.connect('build-finished', cleanup_tempdir)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -32,7 +32,7 @@ r"""
The graph is inserted as a PNG+image map into HTML and a PDF in The graph is inserted as a PNG+image map into HTML and a PDF in
LaTeX. LaTeX.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -227,10 +227,10 @@ class InheritanceGraph(object):
} }
def _format_node_attrs(self, attrs): def _format_node_attrs(self, attrs):
return ','.join(['%s=%s' % x for x in attrs.items()]) return ','.join(['%s=%s' % x for x in sorted(attrs.items())])
def _format_graph_attrs(self, attrs): def _format_graph_attrs(self, attrs):
return ''.join(['%s=%s;\n' % x for x in attrs.items()]) return ''.join(['%s=%s;\n' % x for x in sorted(attrs.items())])
def generate_dot(self, name, urls={}, env=None, def generate_dot(self, name, urls={}, env=None,
graph_attrs={}, node_attrs={}, edge_attrs={}): graph_attrs={}, node_attrs={}, edge_attrs={}):
@ -264,6 +264,7 @@ class InheritanceGraph(object):
this_node_attrs = n_attrs.copy() this_node_attrs = n_attrs.copy()
if fullname in urls: if fullname in urls:
this_node_attrs['URL'] = '"%s"' % urls[fullname] this_node_attrs['URL'] = '"%s"' % urls[fullname]
this_node_attrs['target'] = '"_top"'
if tooltip: if tooltip:
this_node_attrs['tooltip'] = tooltip this_node_attrs['tooltip'] = tooltip
res.append(' "%s" [%s];\n' % res.append(' "%s" [%s];\n' %
@ -348,12 +349,20 @@ def html_visit_inheritance_diagram(self, node):
name = 'inheritance%s' % graph_hash name = 'inheritance%s' % graph_hash
# Create a mapping from fully-qualified class names to URLs. # Create a mapping from fully-qualified class names to URLs.
graphviz_output_format = self.builder.env.config.graphviz_output_format.upper()
current_filename = self.builder.current_docname + self.builder.out_suffix
urls = {} urls = {}
for child in node: for child in node:
if child.get('refuri') is not None: if child.get('refuri') is not None:
urls[child['reftitle']] = child.get('refuri') if graphviz_output_format == 'SVG':
urls[child['reftitle']] = "../" + child.get('refuri')
else:
urls[child['reftitle']] = child.get('refuri')
elif child.get('refid') is not None: elif child.get('refid') is not None:
urls[child['reftitle']] = '#' + child.get('refid') if graphviz_output_format == 'SVG':
urls[child['reftitle']] = '../' + current_filename + '#' + child.get('refid')
else:
urls[child['reftitle']] = '#' + child.get('refid')
dotcode = graph.generate_dot(name, urls, env=self.builder.env) dotcode = graph.generate_dot(name, urls, env=self.builder.env)
render_dot_html(self, node, dotcode, [], 'inheritance', 'inheritance', render_dot_html(self, node, dotcode, [], 'inheritance', 'inheritance',

View File

@ -20,7 +20,7 @@
also be specified individually, e.g. if the docs should be buildable also be specified individually, e.g. if the docs should be buildable
without Internet access. without Internet access.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -34,7 +34,7 @@ from os import path
import re import re
from six import iteritems from six import iteritems
from six.moves.urllib import request from six.moves.urllib import parse, request
from docutils import nodes from docutils import nodes
from docutils.utils import relative_path from docutils.utils import relative_path
@ -43,14 +43,14 @@ from sphinx.locale import _
from sphinx.builders.html import INVENTORY_FILENAME from sphinx.builders.html import INVENTORY_FILENAME
handlers = [request.ProxyHandler(), request.HTTPRedirectHandler(), default_handlers = [request.ProxyHandler(), request.HTTPRedirectHandler(),
request.HTTPHandler()] request.HTTPHandler()]
try: try:
handlers.append(request.HTTPSHandler) default_handlers.append(request.HTTPSHandler)
except AttributeError: except AttributeError:
pass pass
request.install_opener(request.build_opener(*handlers)) default_opener = request.build_opener(*default_handlers)
UTF8StreamReader = codecs.lookup('utf-8')[2] UTF8StreamReader = codecs.lookup('utf-8')[2]
@ -124,15 +124,109 @@ def read_inventory_v2(f, uri, join, bufsize=16*1024):
return invdata return invdata
def _strip_basic_auth(url):
"""Returns *url* with basic auth credentials removed. Also returns the
basic auth username and password if they're present in *url*.
E.g.: https://user:pass@example.com => https://example.com
*url* need not include basic auth credentials.
:param url: url which may or may not contain basic auth credentials
:type url: ``str``
:return: 3-``tuple`` of:
* (``str``) -- *url* with any basic auth creds removed
* (``str`` or ``NoneType``) -- basic auth username or ``None`` if basic
auth username not given
* (``str`` or ``NoneType``) -- basic auth password or ``None`` if basic
auth password not given
:rtype: ``tuple``
"""
url_parts = parse.urlsplit(url)
username = url_parts.username
password = url_parts.password
frags = list(url_parts)
# swap out "user[:pass]@hostname" for "hostname"
frags[1] = url_parts.hostname
url = parse.urlunsplit(frags)
return (url, username, password)
def _read_from_url(url):
"""Reads data from *url* with an HTTP *GET*.
This function supports fetching from resources which use basic HTTP auth as
laid out by RFC1738 § 3.1. See § 5 for grammar definitions for URLs.
.. seealso:
https://www.ietf.org/rfc/rfc1738.txt
:param url: URL of an HTTP resource
:type url: ``str``
:return: data read from resource described by *url*
:rtype: ``file``-like object
"""
url, username, password = _strip_basic_auth(url)
if username is not None and password is not None:
# case: url contains basic auth creds
password_mgr = request.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, url, username, password)
handler = request.HTTPBasicAuthHandler(password_mgr)
opener = request.build_opener(default_handlers + [handler])
else:
opener = default_opener
return opener.open(url)
def _get_safe_url(url):
"""Gets version of *url* with basic auth passwords obscured. This function
returns results suitable for printing and logging.
E.g.: https://user:12345@example.com => https://user:********@example.com
.. note::
The number of astrisks is invariant in the length of the basic auth
password, so minimal information is leaked.
:param url: a url
:type url: ``str``
:return: *url* with password obscured
:rtype: ``str``
"""
safe_url = url
url, username, _ = _strip_basic_auth(url)
if username is not None:
# case: url contained basic auth creds; obscure password
url_parts = parse.urlsplit(url)
safe_netloc = '{0}@{1}'.format(username, url_parts.hostname)
# replace original netloc w/ obscured version
frags = list(url_parts)
frags[1] = safe_netloc
safe_url = parse.urlunsplit(frags)
return safe_url
def fetch_inventory(app, uri, inv): def fetch_inventory(app, uri, inv):
"""Fetch, parse and return an intersphinx inventory file.""" """Fetch, parse and return an intersphinx inventory file."""
# both *uri* (base URI of the links to generate) and *inv* (actual # both *uri* (base URI of the links to generate) and *inv* (actual
# location of the inventory file) can be local or remote URIs # location of the inventory file) can be local or remote URIs
localuri = uri.find('://') == -1 localuri = '://' not in uri
if not localuri:
# case: inv URI points to remote resource; strip any existing auth
uri, _, _ = _strip_basic_auth(uri)
join = localuri and path.join or posixpath.join join = localuri and path.join or posixpath.join
try: try:
if inv.find('://') != -1: if '://' in inv:
f = request.urlopen(inv) f = _read_from_url(inv)
else: else:
f = open(path.join(app.srcdir, inv), 'rb') f = open(path.join(app.srcdir, inv), 'rb')
except Exception as err: except Exception as err:
@ -194,7 +288,9 @@ def load_mappings(app):
# files; remote ones only if the cache time is expired # files; remote ones only if the cache time is expired
if '://' not in inv or uri not in cache \ if '://' not in inv or uri not in cache \
or cache[uri][1] < cache_time: or cache[uri][1] < cache_time:
app.info('loading intersphinx inventory from %s...' % inv) safe_inv_url = _get_safe_url(inv)
app.info(
'loading intersphinx inventory from %s...' % safe_inv_url)
invdata = fetch_inventory(app, uri, inv) invdata = fetch_inventory(app, uri, inv)
if invdata: if invdata:
cache[uri] = (name, now, invdata) cache[uri] = (name, now, invdata)
@ -230,6 +326,7 @@ def missing_reference(app, env, node, contnode):
objtypes = ['%s:%s' % (domain.name, objtype) objtypes = ['%s:%s' % (domain.name, objtype)
for domain in env.domains.values() for domain in env.domains.values()
for objtype in domain.object_types] for objtype in domain.object_types]
domain = None
elif node['reftype'] == 'doc': elif node['reftype'] == 'doc':
domain = 'std' # special case domain = 'std' # special case
objtypes = ['std:doc'] objtypes = ['std:doc']

View File

@ -6,7 +6,7 @@
Set up everything for use of JSMath to display math in HTML Set up everything for use of JSMath to display math in HTML
via JavaScript. via JavaScript.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -26,7 +26,7 @@ def html_visit_math(self, node):
def html_visit_displaymath(self, node): def html_visit_displaymath(self, node):
if node['nowrap']: if node['nowrap']:
self.body.append(self.starttag(node, 'div', CLASS='math')) self.body.append(self.starttag(node, 'div', CLASS='math'))
self.body.append(node['latex']) self.body.append(self.encode(node['latex']))
self.body.append('</div>') self.body.append('</div>')
raise nodes.SkipNode raise nodes.SkipNode
for i, part in enumerate(node['latex'].split('\n\n')): for i, part in enumerate(node['latex'].split('\n\n')):

View File

@ -5,7 +5,7 @@
Add external links to module code in Python object descriptions. Add external links to module code in Python object descriptions.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Set up math support in source files and LaTeX/text output. Set up math support in source files and LaTeX/text output.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -56,6 +56,17 @@ def eq_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
return [node], [] return [node], []
def is_in_section_title(node):
"""Determine whether the node is in a section title"""
from sphinx.util.nodes import traverse_parent
for ancestor in traverse_parent(node):
if isinstance(ancestor, nodes.title) and \
isinstance(ancestor.parent, nodes.section):
return True
return False
class MathDirective(Directive): class MathDirective(Directive):
has_content = True has_content = True
@ -91,7 +102,12 @@ class MathDirective(Directive):
def latex_visit_math(self, node): def latex_visit_math(self, node):
self.body.append('\\(' + node['latex'] + '\\)') if is_in_section_title(node):
protect = r'\protect'
else:
protect = ''
equation = protect + r'\(' + node['latex'] + protect + r'\)'
self.body.append(equation)
raise nodes.SkipNode raise nodes.SkipNode
@ -214,3 +230,4 @@ def setup_math(app, htmlinlinevisitors, htmldisplayvisitors):
app.add_role('eq', eq_role) app.add_role('eq', eq_role)
app.add_directive('math', MathDirective) app.add_directive('math', MathDirective)
app.connect('doctree-resolved', number_equations) app.connect('doctree-resolved', number_equations)
app.add_latex_package('amsfonts')

View File

@ -7,7 +7,7 @@
Sphinx's HTML writer -- requires the MathJax JavaScript library on your Sphinx's HTML writer -- requires the MathJax JavaScript library on your
webserver/computer. webserver/computer.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -30,7 +30,7 @@ def html_visit_displaymath(self, node):
self.body.append(self.starttag(node, 'div', CLASS='math')) self.body.append(self.starttag(node, 'div', CLASS='math'))
if node['nowrap']: if node['nowrap']:
self.body.append(self.builder.config.mathjax_display[0] + self.body.append(self.builder.config.mathjax_display[0] +
node['latex'] + self.encode(node['latex']) +
self.builder.config.mathjax_display[1]) self.builder.config.mathjax_display[1])
self.body.append('</div>') self.body.append('</div>')
raise nodes.SkipNode raise nodes.SkipNode

View File

@ -5,7 +5,7 @@
Support for NumPy and Google style docstrings. Support for NumPy and Google style docstrings.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -34,7 +34,7 @@ class Config(object):
napoleon_google_docstring = True napoleon_google_docstring = True
napoleon_numpy_docstring = True napoleon_numpy_docstring = True
napoleon_include_private_with_doc = False napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = True napoleon_include_special_with_doc = False
napoleon_use_admonition_for_examples = False napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False napoleon_use_admonition_for_references = False
@ -43,7 +43,7 @@ class Config(object):
napoleon_use_rtype = True napoleon_use_rtype = True
.. _Google style: .. _Google style:
http://google-styleguide.googlecode.com/svn/trunk/pyguide.html http://google.github.io/styleguide/pyguide.html
.. _NumPy style: .. _NumPy style:
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
@ -71,7 +71,7 @@ class Config(object):
# This will NOT be included in the docs # This will NOT be included in the docs
pass pass
napoleon_include_special_with_doc : bool, defaults to True napoleon_include_special_with_doc : bool, defaults to False
True to include special members (like ``__membername__``) with True to include special members (like ``__membername__``) with
docstrings in the documentation. False to fall back to Sphinx's docstrings in the documentation. False to fall back to Sphinx's
default behavior. default behavior.
@ -209,7 +209,7 @@ class Config(object):
'napoleon_google_docstring': (True, 'env'), 'napoleon_google_docstring': (True, 'env'),
'napoleon_numpy_docstring': (True, 'env'), 'napoleon_numpy_docstring': (True, 'env'),
'napoleon_include_private_with_doc': (False, 'env'), 'napoleon_include_private_with_doc': (False, 'env'),
'napoleon_include_special_with_doc': (True, 'env'), 'napoleon_include_special_with_doc': (False, 'env'),
'napoleon_use_admonition_for_examples': (False, 'env'), 'napoleon_use_admonition_for_examples': (False, 'env'),
'napoleon_use_admonition_for_notes': (False, 'env'), 'napoleon_use_admonition_for_notes': (False, 'env'),
'napoleon_use_admonition_for_references': (False, 'env'), 'napoleon_use_admonition_for_references': (False, 'env'),
@ -239,12 +239,12 @@ def setup(app):
See Also See Also
-------- --------
The Sphinx documentation on `Extensions`_, the `Extension Tutorial`_, and `The Sphinx documentation on Extensions
the `Extension API`_. <http://sphinx-doc.org/extensions.html>`_
.. _Extensions: http://sphinx-doc.org/extensions.html `The Extension Tutorial <http://sphinx-doc.org/extdev/tutorial.html>`_
.. _Extension Tutorial: http://sphinx-doc.org/ext/tutorial.html
.. _Extension API: http://sphinx-doc.org/ext/appapi.html `The Extension API <http://sphinx-doc.org/extdev/appapi.html>`_
""" """
from sphinx.application import Sphinx from sphinx.application import Sphinx

View File

@ -7,7 +7,7 @@
Classes for docstring parsing and formatting. Classes for docstring parsing and formatting.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -15,7 +15,7 @@ import collections
import inspect import inspect
import re import re
from six import string_types from six import string_types, u
from six.moves import range from six.moves import range
from sphinx.ext.napoleon.iterators import modify_iter from sphinx.ext.napoleon.iterators import modify_iter
@ -144,6 +144,7 @@ class GoogleDocstring(UnicodeMixin):
'raises': self._parse_raises_section, 'raises': self._parse_raises_section,
'references': self._parse_references_section, 'references': self._parse_references_section,
'see also': self._parse_see_also_section, 'see also': self._parse_see_also_section,
'todo': self._parse_todo_section,
'warning': self._parse_warning_section, 'warning': self._parse_warning_section,
'warnings': self._parse_warning_section, 'warnings': self._parse_warning_section,
'warns': self._parse_warns_section, 'warns': self._parse_warns_section,
@ -161,7 +162,7 @@ class GoogleDocstring(UnicodeMixin):
Unicode version of the docstring. Unicode version of the docstring.
""" """
return u'\n'.join(self.lines()) return u('\n').join(self.lines())
def lines(self): def lines(self):
"""Return the parsed lines of the docstring in reStructuredText format. """Return the parsed lines of the docstring in reStructuredText format.
@ -211,10 +212,7 @@ class GoogleDocstring(UnicodeMixin):
_name = match.group(1) _name = match.group(1)
_type = match.group(2) _type = match.group(2)
if _name[:2] == '**': _name = self._escape_args_and_kwargs(_name)
_name = r'\*\*'+_name[2:]
elif _name[:1] == '*':
_name = r'\*'+_name[1:]
if prefer_type and not _type: if prefer_type and not _type:
_type, _name = _name, _type _type, _name = _name, _type
@ -296,6 +294,14 @@ class GoogleDocstring(UnicodeMixin):
min_indent = self._get_min_indent(lines) min_indent = self._get_min_indent(lines)
return [line[min_indent:] for line in lines] return [line[min_indent:] for line in lines]
def _escape_args_and_kwargs(self, name):
if name[:2] == '**':
return r'\*\*' + name[2:]
elif name[:1] == '*':
return r'\*' + name[1:]
else:
return name
def _format_admonition(self, admonition, lines): def _format_admonition(self, admonition, lines):
lines = self._strip_empty(lines) lines = self._strip_empty(lines)
if len(lines) == 1: if len(lines) == 1:
@ -606,6 +612,10 @@ class GoogleDocstring(UnicodeMixin):
lines = self._consume_to_next_section() lines = self._consume_to_next_section()
return self._format_admonition('seealso', lines) return self._format_admonition('seealso', lines)
def _parse_todo_section(self, section):
lines = self._consume_to_next_section()
return self._format_admonition('todo', lines)
def _parse_warning_section(self, section): def _parse_warning_section(self, section):
lines = self._consume_to_next_section() lines = self._consume_to_next_section()
return self._format_admonition('warning', lines) return self._format_admonition('warning', lines)
@ -766,6 +776,7 @@ class NumpyDocstring(GoogleDocstring):
else: else:
_name, _type = line, '' _name, _type = line, ''
_name, _type = _name.strip(), _type.strip() _name, _type = _name.strip(), _type.strip()
_name = self._escape_args_and_kwargs(_name)
if prefer_type and not _type: if prefer_type and not _type:
_type, _name = _name, _type _type, _name = _name, _type
indent = self._get_indent(line) indent = self._get_indent(line)

View File

@ -7,7 +7,7 @@
A collection of helpful iterators. A collection of helpful iterators.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -3,9 +3,10 @@
sphinx.ext.pngmath sphinx.ext.pngmath
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
Render math in HTML via dvipng. Render math in HTML via dvipng. This extension has been deprecated; please
use sphinx.ext.imgmath instead.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -236,6 +237,7 @@ def html_visit_displaymath(self, node):
def setup(app): def setup(app):
app.warn('sphinx.ext.pngmath has been deprecated. Please use sphinx.ext.imgmath instead.')
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None)) mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
app.add_config_value('pngmath_dvipng', 'dvipng', 'html') app.add_config_value('pngmath_dvipng', 'dvipng', 'html')
app.add_config_value('pngmath_latex', 'latex', 'html') app.add_config_value('pngmath_latex', 'latex', 'html')

View File

@ -8,17 +8,19 @@
all todos of your project and lists them along with a backlink to the all todos of your project and lists them along with a backlink to the
original location. original location.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from docutils import nodes from docutils import nodes
from docutils.parsers.rst import directives
import sphinx import sphinx
from sphinx.locale import _ from sphinx.locale import _
from sphinx.environment import NoUri from sphinx.environment import NoUri
from sphinx.util.nodes import set_source_info from sphinx.util.nodes import set_source_info
from sphinx.util.compat import Directive, make_admonition from docutils.parsers.rst import Directive
from docutils.parsers.rst.directives.admonitions import BaseAdmonition
class todo_node(nodes.Admonition, nodes.Element): class todo_node(nodes.Admonition, nodes.Element):
@ -29,27 +31,35 @@ class todolist(nodes.General, nodes.Element):
pass pass
class Todo(Directive): class Todo(BaseAdmonition):
""" """
A todo entry, displayed (if configured) in the form of an admonition. A todo entry, displayed (if configured) in the form of an admonition.
""" """
node_class = todo_node
has_content = True has_content = True
required_arguments = 0 required_arguments = 0
optional_arguments = 0 optional_arguments = 0
final_argument_whitespace = False final_argument_whitespace = False
option_spec = {} option_spec = {
'class': directives.class_option,
}
def run(self): def run(self):
if not self.options.get('class'):
self.options['class'] = ['admonition-todo']
(todo,) = super(Todo, self).run()
if isinstance(todo, nodes.system_message):
return [todo]
todo.insert(0, nodes.title(text=_('Todo')))
set_source_info(self, todo)
env = self.state.document.settings.env env = self.state.document.settings.env
targetid = 'index-%s' % env.new_serialno('index') targetid = 'index-%s' % env.new_serialno('index')
targetnode = nodes.target('', '', ids=[targetid]) targetnode = nodes.target('', '', ids=[targetid])
return [targetnode, todo]
ad = make_admonition(todo_node, self.name, [_('Todo')], self.options,
self.content, self.lineno, self.content_offset,
self.block_text, self.state, self.state_machine)
set_source_info(self, ad[0])
return [targetnode] + ad
def process_todos(app, doctree): def process_todos(app, doctree):
@ -165,6 +175,7 @@ def merge_info(app, env, docnames, other):
def visit_todo_node(self, node): def visit_todo_node(self, node):
self.visit_admonition(node) self.visit_admonition(node)
# self.visit_admonition(node, 'todo')
def depart_todo_node(self, node): def depart_todo_node(self, node):

View File

@ -5,7 +5,7 @@
Add links to module code in Python object descriptions. Add links to module code in Python object descriptions.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Highlight code blocks using Pygments. Highlight code blocks using Pygments.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
@ -183,9 +183,13 @@ class PygmentsBridge(object):
formatter = self.get_formatter(**kwargs) formatter = self.get_formatter(**kwargs)
try: try:
hlsource = highlight(source, lexer, formatter) hlsource = highlight(source, lexer, formatter)
except ErrorToken: except ErrorToken as exc:
# this is most probably not the selected language, # this is most probably not the selected language,
# so let it pass unhighlighted # so let it pass unhighlighted
if warn:
warn('Could not parse literal_block as "%s". highlighting skipped.' % lang)
else:
raise exc
hlsource = highlight(source, lexers['none'], formatter) hlsource = highlight(source, lexers['none'], formatter)
if self.dest == 'html': if self.dest == 'html':
return hlsource return hlsource

View File

@ -5,7 +5,7 @@
Glue code for the jinja2 templating engine. Glue code for the jinja2 templating engine.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """

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