Merge branch 'master' into template-body

This commit is contained in:
Takeshi KOMIYA 2018-08-20 00:10:14 +09:00
commit ad8129b695
176 changed files with 9859 additions and 2267 deletions

View File

@ -7,8 +7,8 @@ environment:
matrix:
- PYTHON: 27
TEST_IGNORE: --ignore py35
- PYTHON: 36
- PYTHON: 36-x64
- PYTHON: 37
- PYTHON: 37-x64
install:
- C:\Python%PYTHON%\python.exe -m pip install -U pip setuptools

2
.gitignore vendored
View File

@ -29,3 +29,5 @@ doc/locale/
tests/.coverage
tests/build/
utils/regression_test.js
node_modules/

View File

@ -7,6 +7,7 @@ env:
global:
- PYTHONFAULTHANDLER=x
- SKIP_LATEX_BUILD=1
- IS_PYTHON=true
matrix:
include:
@ -24,20 +25,36 @@ matrix:
env:
- TOXENV=py36
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
- python: 'nightly'
- python: '3.7'
env: TOXENV=py37
dist: xenial
sudo: true
- python: 'nightly'
env: TOXENV=py38
dist: xenial
sudo: true
- python: '3.6'
env: TOXENV=docs
- python: '3.6'
env: TOXENV=mypy
- python: '2.7'
- python: '3.6'
env: TOXENV=flake8
- language: node_js
node_js:
- 10.7
env: IS_PYTHON=false
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
install:
- pip install -U tox codecov
- if [ $IS_PYTHON = true ]; then pip install -U tox codecov; fi
- if [ $IS_PYTHON = false ]; then npm install; fi
script:
- tox -- -v
- if [ $IS_PYTHON = true ]; then tox -- -v; fi
- if [ $IS_PYTHON = false ]; then npm test; fi
after_success:
- if [[ -e .coverage ]]; then codecov -e $TOXENV; fi

View File

@ -14,6 +14,7 @@ Other co-maintainers:
* Takeshi Komiya <@tk0miya>
* Jean-François Burnol <@jfbu>
* Yoshiki Shibukawa <@shibu_jp>
* Timotheus Kampik - <@TimKam>
Other contributors, listed alphabetically, are:
@ -37,12 +38,12 @@ Other contributors, listed alphabetically, are:
* Zac Hatfield-Dodds -- doctest reporting improvements
* Doug Hellmann -- graphviz improvements
* Tim Hoffmann -- theme improvements
* Timotheus Kampik - JS theme & search enhancements
* Dave Kuhlman -- original LaTeX writer
* Blaise Laflamme -- pyramid theme
* Chris Lamb -- reproducibility fixes
* Thomas Lamb -- linkcheck builder
* Łukasz Langa -- partial support for autodoc
* Martin Larralde -- additional napoleon admonitions
* Ian Lee -- quickstart improvements
* Robert Lehmann -- gettext builder (GSOC project)
* Dan MacKinlay -- metadata fixes

139
CHANGES
View File

@ -4,9 +4,17 @@ Release 1.8.0 (in development)
Dependencies
------------
* LaTeX: :confval:`latex_use_xindy`, if ``True`` (default for
``xelatex/lualatex``), instructs ``make latexpdf`` to use :program:`xindy`
for general index. Make sure your LaTeX distribution includes it.
(refs: #5134)
Incompatible changes
--------------------
* #5156: the :py:mod:`sphinx.ext.graphviz: extension runs `dot` in the
directory of the document being built instead of in the root directory of
the documentation.
* #4460: extensions which stores any data to environment should return the
version of its env data structure as metadata. In detail, please see
:ref:`ext-metadata`.
@ -38,15 +46,24 @@ Incompatible changes
* Modifying a template variable ``script_files`` in templates is allowed now.
Please use ``app.add_js_file()`` instead.
* #5072: Save environment object also with only new documents
* #5035: qthelp builder allows dashes in :confval:`qthelp_namespace`
* LaTeX: with lualatex or xelatex use by default :program:`xindy` as
UTF-8 able replacement of :program:`makeindex` (refs: #5134). After
upgrading Sphinx, please clean latex build repertory of existing project
before new build.
* #5163: html: hlist items are now aligned to top
* ``highlightlang`` directive is processed on resolving phase
Deprecated
----------
* :confval:`source_parsers` is deprecated
* quickstart: ``--epub`` option becomes default, so it is deprecated
* Drop function based directive support. For now, Sphinx only supports class
based directives.
* ``sphinx.util.docutils.directive_helper()`` is deprecated
* ``sphinx.cmdline`` is deprecated
* ``sphinx.make_mode`` is deprecated
* ``sphinx.locale.l_()`` is deprecated
* #2157: helper function ``warn()`` for HTML themes is deprecated
* ``app.override_domain()`` is deprecated
@ -71,9 +88,11 @@ Deprecated
* ``env._read_parallel()`` is deprecated
* ``env.write_doctree()`` is deprecated
* ``env._nitpick_ignore`` is deprecated
* ``env.versionchanges`` is deprecated
* ``env.dump()`` is deprecated
* ``env.dumps()`` is deprecated
* ``env.topickle()`` is deprecated
* ``env.note_versionchange()`` is deprecated
* ``sphinx.writers.latex.Table.caption_footnotetexts`` is deprecated
* ``sphinx.writers.latex.Table.header_footnotetexts`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.footnotestack`` is deprecated
@ -84,13 +103,31 @@ Deprecated
* ``sphinx.writers.latex.LaTeXTranslator.unrestrict_footnote()`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.push_hyperlink_ids()`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.pop_hyperlink_ids()`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.check_latex_elements()`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.bibitems`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.hlsettingstack`` is deprecated
* ``sphinx.writers.latex.ExtBabel.get_shorthandoff()`` is deprecated
* ``sphinx.writers.html.HTMLTranslator.highlightlang`` is deprecated
* ``sphinx.writers.html.HTMLTranslator.highlightlang_base`` is deprecated
* ``sphinx.writers.html.HTMLTranslator.highlightlangopts`` is deprecated
* ``sphinx.writers.html.HTMLTranslator.highlightlinenothreshold`` is deprecated
* ``sphinx.writers.html5.HTMLTranslator.highlightlang`` is deprecated
* ``sphinx.writers.html5.HTMLTranslator.highlightlang_base`` is deprecated
* ``sphinx.writers.html5.HTMLTranslator.highlightlangopts`` is deprecated
* ``sphinx.writers.html5.HTMLTranslator.highlightlinenothreshold`` is deprecated
* ``sphinx.ext.mathbase`` extension is deprecated
* ``sphinx.ext.mathbase.math`` node is deprecated
* ``sphinx.ext.mathbase.displaymath`` node is deprecated
* ``sphinx.ext.mathbase.eqref`` node is deprecated
* ``sphinx.ext.mathbase.is_in_section_title()`` is deprecated
* ``sphinx.ext.mathbase.MathDomain`` is deprecated
* ``sphinx.ext.mathbase.setup_math()`` is deprecated
* ``sphinx.directives.other.VersionChanges`` is deprecated
* ``sphinx.highlighting.PygmentsBridge.unhighlight()`` is deprecated
* ``sphinx.ext.mathbase.get_node_equation_number()`` is deprecated
* ``sphinx.ext.mathbase.wrap_displaymath()`` is deprecated
* The ``trim_doctest_flags`` argument of ``sphinx.highlighting.PygmentsBridge``
is deprecated
For more details, see `deprecation APIs list
<http://www.sphinx-doc.org/en/master/extdev/index.html#deprecated-apis>`_
@ -130,10 +167,17 @@ Features added
* #4785: napoleon: Add strings to translation file for localisation
* #4927: Display a warning when invalid values are passed to linenothreshold
option of highlight directive
* C++, add a ``cpp:texpr`` role as a sibling to ``cpp:expr``.
* C++, add support for unions.
* C++, add support for anonymous entities using names staring with ``@``.
Fixes #3593 and #2683.
* C++:
- Add a ``cpp:texpr`` role as a sibling to ``cpp:expr``.
- Add support for unions.
- #3593, #2683: add support for anonymous entities using names staring with ``@``.
- #5147: add support for (most) character literals.
- Cross-referencing entities inside primary templates is supported,
and now properly documented.
- #1552: add new cross-referencing format for ``cpp:any`` and ``cpp:func`` roles,
for referencing specific function overloads.
* #3606: MathJax should be loaded with async attribute
* html: Output ``canonical_url`` metadata if :confval:`html_baseurl` set (refs:
#4193)
@ -141,6 +185,24 @@ Features added
* #3784: mathjax: Add :confval:`mathjax_options` to give options to script tag
for mathjax
* #4362: latex: Don't overwrite .tex file if document not changed
* #1431: latex: Add alphanumeric enumerated list support
* Add :confval:`latex_use_xindy` for UTF-8 savvy indexing, defaults to ``True``
if :confval:`latex_engine` is ``'xelatex'`` or ``'lualatex'``. (refs: #5134,
#5192, #5212)
* #4976: ``SphinxLoggerAdapter.info()`` now supports ``location`` parameter
* #5122: setuptools: support nitpicky option
* #2820: autoclass directive supports nested class
* Add ``app.add_html_math_renderer()`` to register a math renderer for HTML
* Apply :confval:`trim_doctest_flags` to all builders (cf. text, manpages)
* #5140: linkcheck: Add better Accept header to HTTP client
* #4614: sphinx-build: Add ``--keep-going`` option to show all warnings
* Add :rst:role:`math:numref` role to refer equations (Same as :rst:role:`eq`)
* quickstart: epub builder is enabled by default
* #5246: Add :confval:`singlehtml_sidebars` to configure sidebars for singlehtml
builder
* #5273: doctest: Skip doctest conditionally
* #5306: autodoc: emit a warning for invalid typehints
* #5215: autodoc: :confval:`autodoc_default_flags` accepts option values as dict
Bugs fixed
----------
@ -150,6 +212,16 @@ Bugs fixed
* #4945: i18n: fix lang_COUNTRY not fallback correctly for IndexBuilder. Thanks
to Shengjing Zhu.
* #4983: productionlist directive generates invalid IDs for the tokens
* #5132: (lualatex) PDF build fails if indexed word starts with Unicode character
* #5133: latex: index headings "Symbols" and "Numbers" not internationalized
* #5114: sphinx-build: Handle errors on scanning documents
* epub: spine has been broken when "self" is listed on toctree (refs: #4611)
* #344: autosummary does not understand docstring of module level attributes
* #5191: C++, prevent nested declarations in functions to avoid lookup problems.
* #5126: C++, add missing isPack method for certain template parameter types.
* #5187: C++, parse attributes on declerators as well.
* C++, parse delete expressions and basic new expressions as well.
* #5002: graphviz: SVGs do not adapt to the column width
Testing
--------
@ -163,8 +235,9 @@ Documentation
-------------
* #5083: Fix wrong make.bat option for internationalization.
* #5115: napoleon: add admonitions added by #4613 to the docs.
Release 1.7.6 (in development)
Release 1.7.8 (in development)
==============================
Dependencies
@ -182,6 +255,39 @@ Features added
Bugs fixed
----------
Testing
--------
Release 1.7.7 (released Aug 19, 2018)
=====================================
Bugs fixed
----------
* #5198: document not in toctree warning when including files only for parallel
builds
* LaTeX: reduce "Token not allowed in a PDF string" hyperref warnings in latex
console output (refs: #5236)
* LaTeX: suppress "remreset Warning: The remreset package is obsolete" in latex
console output with recent LaTeX (refs: #5237)
* #5234: PDF output: usage of PAPER environment variable is broken since Sphinx
1.5
* LaTeX: fix the :confval:`latex_engine` documentation regarding Latin Modern
font with XeLaTeX/LuaLateX (refs: #5251)
* #5280: autodoc: Fix wrong type annotations for complex typing
* autodoc: Optional types are wrongly rendered
* #5291: autodoc crashed by ForwardRef types
* #5211: autodoc: No docs generated for functools.partial functions
* #5306: autodoc: ``getargspec()`` raises NameError for invalid typehints
* #5298: imgmath: math_number_all causes equations to have two numbers in html
* #5294: sphinx-quickstart blank prompts in PowerShell
Release 1.7.6 (released Jul 17, 2018)
=====================================
Bugs fixed
----------
* #5037: LaTeX ``\sphinxupquote{}`` breaks in Russian
* sphinx.testing uses deprecated pytest API; ``Node.get_marker(name)``
* #5016: crashed when recommonmark.AutoStrictify is enabled
@ -197,9 +303,26 @@ Bugs fixed
* #5036: quickstart: Typing Ctrl-U clears the whole of line
* #5066: html: "relations" sidebar is not shown by default
* #5091: latex: curly braces in index entries are not handled correctly
Testing
--------
* #5070: epub: Wrong internal href fragment links
* #5104: apidoc: Interface of ``sphinx.apidoc:main()`` has changed
* #4272: PDF builds of French projects have issues with XeTeX
* #5076: napoleon raises RuntimeError with python 3.7
* #5125: sphinx-build: Interface of ``sphinx:main()`` has changed
* sphinx-build: ``sphinx.cmd.build.main()`` refers ``sys.argv`` instead of given
argument
* #5146: autosummary: warning is emitted when the first line of docstring ends
with literal notation
* autosummary: warnings of autosummary indicates wrong location (refs: #5146)
* #5143: autodoc: crashed on inspecting dict like object which does not support
sorting
* #5139: autodoc: Enum argument missing if it shares value with another
* #4946: py domain: rtype field could not handle "None" as a type
* #5176: LaTeX: indexing of terms containing ``@``, ``!``, or ``"`` fails
* #5161: html: crashes if copying static files are failed
* #5167: autodoc: Fix formatting type annotations for tuples with more than two
arguments
* #3329: i18n: crashed by auto-symbol footnote references
* #5158: autosummary: module summary has been broken when it starts with heading
Release 1.7.5 (released May 29, 2018)
=====================================

View File

@ -154,6 +154,12 @@ These are the basic steps needed to start developing on Sphinx.
tox -e docs -- -b html,latexpdf
* To run JavaScript tests with `Karma <https://karma-runner.github.io>`_,
execute the following commands (requires `Node.js <https://nodejs.org>`_)::
npm install
npm run test
You can also test by installing dependencies in your local environment. ::
pip install .[test]
@ -302,8 +308,8 @@ Debugging Tips
in `this repository <https://github.com/shibukawa/snowball-stemmer.jsx>`_.
You can get the resulting JavaScript files using the following command::
$ npm install
$ node_modules/.bin/grunt build # -> dest/*.global.js
npm install
node_modules/.bin/grunt build # -> dest/*.global.js
Branch Model
@ -402,3 +408,6 @@ and other ``test_*.py`` files under ``tests`` directory.
.. versionadded:: 1.6
``sphinx.testing`` as a experimental.
.. versionadded:: 1.8
Sphinx also runs JavaScript tests.

1016
EXAMPLES

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
PYTHON ?= python
PYTHON ?= python3
.PHONY: all
all: clean-pyc clean-backupfiles style-check type-check test

View File

@ -1,6 +1,6 @@
# Makefile for Sphinx documentation
#
PYTHON ?= python
PYTHON ?= python3
# You can set these variables from the command line.
SPHINXOPTS =

View File

@ -73,11 +73,8 @@
</table>
<p>{%trans%}
You can also download PDF/EPUB versions of the Sphinx documentation:
a <a href="https://media.readthedocs.org/pdf/sphinx/stable/sphinx.pdf">PDF version</a> generated from
the LaTeX Sphinx producer, and
an <a href="https://media.readthedocs.org/epub/sphinx/stable/sphinx.epub">EPUB version</a>.
{%endtrans%}
You can also download PDF/EPUB versions of the Sphinx documentation
from pop up menu on lower right corner.{%endtrans%}
</p>
<h2>{%trans%}Examples{%endtrans%}</h2>

View File

@ -72,6 +72,7 @@ latex_elements = {
''',
}
latex_show_urls = 'footnote'
latex_use_xindy = True
autodoc_member_order = 'groupwise'
todo_include_todos = True

View File

@ -12,16 +12,16 @@ Sphinx documentation contents
usage/restructuredtext/index
usage/markdown
usage/configuration
usage/builders/index
usage/extensions/index
intro
man/index
builders
intl
theming
setuptools
templating
latex
extensions
extdev/index
websupport

View File

@ -1,25 +0,0 @@
Builtin Sphinx extensions
-------------------------
These extensions are built in and can be activated by respective entries in the
:confval:`extensions` configuration value:
.. toctree::
autodoc
autosectionlabel
autosummary
coverage
doctest
extlinks
githubpages
graphviz
ifconfig
imgconverter
inheritance
intersphinx
linkcode
math
napoleon
todo
viewcode

View File

@ -93,6 +93,8 @@ package.
.. automethod:: Sphinx.add_html_theme(name, theme_path)
.. automethod:: Sphinx.add_html_math_renderer(name, inline_renderers, block_renderers)
.. automethod:: Sphinx.add_message_catalog(catalog, locale_dir)
.. automethod:: Sphinx.is_parallel_allowed(typ)

View File

@ -131,16 +131,52 @@ The following is a list of deprecated interface.
- 4.0
- :meth:`~sphinx.application.Sphinx.add_js_file()`
* - ``sphinx.directives.other.VersionChanges``
- 1.8
- 3.0
- ``sphinx.domains.changeset.VersionChanges``
* - ``sphinx.highlighting.PygmentsBridge.unhighlight()``
- 1.8
- 3.0
- N/A
* - ``trim_doctest_flags`` arguments of
``sphinx.highlighting.PygmentsBridge``
- 1.8
- 3.0
- N/A
* - ``sphinx.ext.mathbase``
- 1.8
- 3.0
- N/A
* - ``sphinx.ext.mathbase.MathDomain``
- 1.8
- 3.0
- ``sphinx.domains.math.MathDomain``
* - ``sphinx.ext.mathbase.setup_math()``
- 1.8
- 3.0
- :meth:`~sphinx.application.Sphinx.add_html_math_renderer()`
* - ``sphinx.ext.mathbase.is_in_section_title()``
- 1.8
- 3.0
- N/A
* - ``sphinx.ext.mathbase.get_node_equation_number()``
- 1.8
- 3.0
- ``sphinx.util.math.get_node_equation_number()``
* - ``sphinx.ext.mathbase.wrap_displaymath()``
- 1.8
- 3.0
- ``sphinx.util.math.wrap_displaymath()``
* - ``sphinx.ext.mathbase.math`` (node)
- 1.8
- 3.0
@ -216,11 +252,61 @@ The following is a list of deprecated interface.
- 3.0
- N/A
* - ``sphinx.writers.latex.LaTeXTranslator.hlsettingstack``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.latex.ExtBabel.get_shorthandoff()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html.HTMLTranslator.highlightlang()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html.HTMLTranslator.highlightlang_base()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html.HTMLTranslator.highlightlangopts()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html.HTMLTranslator.highlightlinenothreshold()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html5.HTMLTranslator.highlightlang()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html5.HTMLTranslator.highlightlang_base()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html5.HTMLTranslator.highlightlangopts()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html5.HTMLTranslator.highlightlinenothreshold()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.latex.LaTeXTranslator.check_latex_elements()``
- 1.8
- 3.0
- Nothing
* - ``sphinx.application.CONFIG_FILENAME``
- 1.8
- 3.0
@ -304,6 +390,11 @@ The following is a list of deprecated interface.
- 3.0
- :confval:`nitpick_ignore`
* - ``BuildEnvironment.versionchanges``
- 1.8
- 3.0
- N/A
* - ``BuildEnvironment.update()``
- 1.8
- 3.0
@ -329,6 +420,11 @@ The following is a list of deprecated interface.
- 3.0
- ``Builder.write_doctree()``
* - ``BuildEnvironment.note_versionchange()``
- 1.8
- 3.0
- ``ChangesDomain.note_changeset()``
* - ``warn()`` (template helper function)
- 1.8
- 3.0
@ -349,6 +445,11 @@ The following is a list of deprecated interface.
- 3.0
- ``sphinx.cmd.build``
* - ``sphinx.make_mode``
- 1.8
- 3.0
- ``sphinx.cmd.make_mode``
* - ``sphinx.locale.l_()``
- 1.8
- 3.0

View File

@ -50,6 +50,10 @@ Logging API
If true, the logger does not fold lines at the end of the log message.
The default is ``False``.
**location**
Where the message emitted. For more detail, see
:meth:`SphinxLoggerAdapter.warning`.
**color**
The color of logs. By default, debug level logs are
colored as ``"darkgray"``, and debug2 level ones are ``"lightgray"``.

View File

@ -12,7 +12,7 @@ __ http://docutils.sourceforge.net/docs/dev/hacking.html#parsing-the-document
In Sphinx, the parser modules works as same as docutils. The parsers are
registered to Sphinx by extensions using Application APIs;
:meth:`Sphinx.add_source_suffix()` and :meth:`Sphinx.add_source_parsers()`.
:meth:`.Sphinx.add_source_suffix()` and :meth:`.Sphinx.add_source_parser()`.
The *source suffix* is a mapping from file suffix to file type. For example,
``.rst`` file is mapped to ``'restructuredtext'`` type. Sphinx uses the

View File

@ -1,16 +0,0 @@
.. _extensions:
Sphinx Extensions
=================
Since many projects will need special features in their documentation, Sphinx
allows adding "extensions" to the build process, each of which can modify almost
any aspect of document processing.
This chapter describes the extensions bundled with Sphinx. For the API
documentation on writing your own extension, see :ref:`dev-extensions`.
.. toctree::
ext/builtins
ext/thirdparty

View File

@ -12,7 +12,8 @@ Glossary
use the builder builders that e.g. check for broken links in the
documentation, or build coverage information.
See :ref:`builders` for an overview over Sphinx's built-in builders.
See :doc:`/usage/builders/index` for an overview over Sphinx's built-in
builders.
configuration directory
The directory containing :file:`conf.py`. By default, this is the same as
@ -66,6 +67,12 @@ Glossary
parsing stage, so that successive runs only need to read and parse new and
changed documents.
extension
A custom :term:`role`, :term:`directive` or other aspect of Sphinx that
allows users to modify any aspect of the build process within Sphinx.
For more information, refer to :doc:`/usage/extensions/index`.
master document
The document that contains the root :rst:dir:`toctree` directive.

View File

@ -86,8 +86,8 @@ Options
Build compact pretty-printed "pseudo-XML" files displaying the
internal structure of the intermediate document trees.
See :ref:`builders` for a list of all builders shipped with Sphinx.
Extensions can add their own builders.
See :doc:`/usage/builders/index` for a list of all builders shipped with
Sphinx. Extensions can add their own builders.
.. _make_mode:
@ -96,7 +96,7 @@ Options
Alternative to :option:`-b`. Uses the Sphinx :program:`make_mode` module,
which provides the same build functionality as a default :ref:`Makefile or
Make.bat <makefile_options>`. In addition to all Sphinx
:ref:`builders <builders>`, the following build pipelines are available:
:doc:`/usage/builders/index`, the following build pipelines are available:
**latexpdf**
Build LaTeX files and run them through :program:`pdflatex`, or as per
@ -229,6 +229,13 @@ Options
Turn warnings into errors. This means that the build stops at the first
warning and ``sphinx-build`` exits with exit status 1.
.. option:: --keep-going
With -W option, keep going processing when getting warnings to the end
of build, and ``sphinx-build`` exits with exit status 1.
.. versionadded:: 1.8
.. option:: -T
Display the full traceback when an unhandled exception occurs. Otherwise,
@ -273,7 +280,16 @@ variables to customize behavior:
.. describe:: PAPER
The value for '"papersize"` key of :confval:`latex_elements`.
This sets the ``'papersize'`` key of :confval:`latex_elements`:
i.e. ``PAPER=a4`` sets it to ``'a4paper'`` and ``PAPER=letter`` to
``'letterpaper'``.
.. note::
Usage of this environment variable got broken at Sphinx 1.5 as
``a4`` or ``letter`` ended up as option to LaTeX document in
place of the needed ``a4paper``, resp. ``letterpaper``. Fixed at
1.7.7.
.. describe:: SPHINXBUILD

View File

@ -181,6 +181,14 @@ Options for setuptools integration
.. versionadded:: 1.3
.. confval:: nitpicky
Run in nit-picky mode. Currently, this generates warnings for all missing
references. See the config value :confval:`nitpick_ignore` for a way to
exclude some references as "known missing".
.. versionadded:: 1.8
.. confval:: pdb
A boolean to configure ``pdb`` on exception. Default is false.

View File

@ -150,7 +150,7 @@ These themes are:
- **collapsiblesidebar** (true or false): Add an *experimental* JavaScript
snippet that makes the sidebar collapsible via a button on its side.
*Doesn't work with "stickysidebar".* Defaults to ``False``.
Defaults to ``False``.
- **externalrefs** (true or false): Display external links differently from
internal links. Defaults to ``False``.

View File

@ -1,13 +1,14 @@
.. _builders:
Available builders
==================
========
Builders
========
.. module:: sphinx.builders
:synopsis: Available built-in builder classes.
These are the built-in Sphinx builders. More builders can be added by
:ref:`extensions <extensions>`.
:doc:`extensions </usage/extensions/index>`.
The builder's "name" must be given to the **-b** command-line option of
:program:`sphinx-build` to select a builder.
@ -75,8 +76,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. class:: QtHelpBuilder
This builder produces the same output as the standalone HTML builder, but
also generates `Qt help`_ collection support files that allow
the Qt collection generator to compile them.
also generates `Qt help`_ collection support files that allow the Qt
collection generator to compile them.
.. autoattribute:: name
@ -144,7 +145,8 @@ The builder's "name" must be given to the **-b** command-line option of
.. versionchanged:: 1.5
Since Sphinx-1.5, the epub3 builder is used for the default builder of epub.
Since Sphinx-1.5, the epub3 builder is used for the default builder of
epub.
.. module:: sphinx.builders.latex
.. class:: LaTeXBuilder
@ -159,12 +161,12 @@ The builder's "name" must be given to the **-b** command-line option of
in a "minimal" TeX distribution installation. For example, on Ubuntu, the
following packages need to be installed for successful PDF builds:
* texlive-latex-recommended
* texlive-fonts-recommended
* texlive-latex-extra
* latexmk (for ``make latexpdf`` on GNU/Linux and MacOS X)
* latex-xcolor (old Ubuntu)
* texlive-luatex, texlive-xetex (see :confval:`latex_engine`)
* ``texlive-latex-recommended``
* ``texlive-fonts-recommended``
* ``texlive-latex-extra``
* ``latexmk`` (for ``make latexpdf`` on GNU/Linux and MacOS X)
* ``latex-xcolor`` (old Ubuntu)
* ``texlive-luatex``, ``texlive-xetex`` (see :confval:`latex_engine`)
The testing of Sphinx LaTeX is done on Ubuntu trusty with the above
mentioned packages, which are from a TeXLive 2013 snapshot dated
@ -178,7 +180,7 @@ The builder's "name" must be given to the **-b** command-line option of
Since 1.6, ``make latexpdf`` uses ``latexmk`` (not on Windows). This
makes sure the needed number of runs is automatically executed to get
the cross-references, bookmarks, indices, and tables of contents right.
One can pass to ``latexmk`` options via the ``LATEXMKOPTS``
Makefile variable. For example:
@ -311,7 +313,6 @@ name is ``rinoh``. Refer to the `rinohtype manual`_ for details.
The filename for the search index Sphinx generates.
See :ref:`serialization-details` for details about the output format.
.. versionadded:: 0.5

View File

@ -65,8 +65,9 @@ General configuration
.. confval:: extensions
A list of strings that are module names of :ref:`extensions`. These can be
extensions coming with Sphinx (named ``sphinx.ext.*``) or custom ones.
A list of strings that are module names of :doc:`extensions
<extensions/index>`. These can be extensions coming with Sphinx (named
``sphinx.ext.*``) or custom ones.
Note that you can extend :data:`sys.path` within the conf file if your
extensions live in another directory -- but make sure you use absolute paths.
@ -142,7 +143,7 @@ General configuration
.. versionadded:: 1.3
.. deprecated:: 1.8
Now Sphinx provides an API :meth:`Sphinx.add_source_parser` to register
Now Sphinx provides an API :meth:`.Sphinx.add_source_parser` to register
a source parser. Please use it instead.
.. confval:: master_doc
@ -772,6 +773,35 @@ documentation on :ref:`intl` for details.
Added ``{path}`` and ``{basename}`` tokens.
.. _math-options:
Options for Math
----------------
These options influence Math notations.
.. confval:: math_number_all
Set this option to ``True`` if you want all displayed math to be numbered.
The default is ``False``.
.. confval:: math_eqref_format
A string that are used for format of label of references to equations.
As a special character, ``{number}`` will be replaced to equaition number.
Example: ``'Eq.{number}'`` is rendered as ``Eq.10``
.. confval:: math_numfig
If ``True``, displayed math equations are numbered across pages when
:confval:`numfig` is enabled. The :confval:`numfig_secnum_depth` setting
is respected. The :rst:role:`eq`, not :rst:role:`numref`, role
must be used to reference equation numbers. Default is ``True``.
.. versionadded:: 1.7
.. _html-options:
Options for HTML output
@ -1289,6 +1319,13 @@ that use Sphinx's HTMLWriter class.
.. versionadded:: 1.3
.. confval:: html_math_renderer
The name of math_renderer extension for HTML output. The default is
``'mathjax'``.
.. versionadded:: 1.8
.. confval:: html_experimental_html5_writer
Output is processed with HTML5 writer. This feature needs docutils 0.13 or
@ -1296,6 +1333,16 @@ that use Sphinx's HTMLWriter class.
.. versionadded:: 1.6
Options for Single HTML output
-------------------------------
.. confval:: singlehtml_sidebars
Custom sidebar templates, must be a dictionary that maps document names to
template names. And it only allows a key named `'index'`. All other keys
are ignored. For more information, refer to :confval:`html_sidebars`. By
default, it is same as :confval:`html_sidebars`.
.. _htmlhelp-options:
@ -1748,15 +1795,33 @@ information.
preamble.
If your project uses such extra Unicode characters, switching the engine to
XeLaTeX or LuaLaTeX often provides a quick fix. They only work with UTF-8
encoded sources and can (in fact, should) use OpenType fonts, either from
the system or the TeX install tree. Recent LaTeX releases will default with
these engines to the Latin Modern OpenType font, which has good coverage of
Latin and Cyrillic scripts (it is provided by standard LaTeX installation),
and Sphinx does not modify this default. Refer to the documentation of the
LaTeX ``polyglossia`` package to see how to instruct LaTeX to use some
other OpenType font if Unicode coverage proves insufficient (or use
directly ``\setmainfont`` et. al. as in :ref:`this example <latex-basic>`.)
XeLaTeX or LuaLaTeX and setting up the document to use an OpenType font
with wide-enough glyph coverage is often easier than sticking with PDFLaTeX
and trying to get it to work with the Unicode characters.
The :confval:`latex_elements` ``'fontpkg'`` key allows to set up the
document fonts, see :ref:`this example <latex-basic>`. Currently, for
XeLaTeX and LuaLaTeX, Sphinx leaves this key empty and LaTeX then defaults
to the `Latin Modern`_ font family (from the TeX distribution fonts). This
font family provides good coverage of Latin scripts (European languages,
Vietnamese) but Cyrillic requires some other OpenType font; for example
Computer Modern Unicode (see `babel-russian`_ documentation on how to load
it in the LaTeX document). In future, it is planned Sphinx will provide
another default choice of OpenType font than `Latin Modern`_, perhaps
`Libertinus`_, which is included in recent TeX distributions and supports
Latin and Cyrillic and also has an accompanying math font.
With XeLaTeX and LuaLaTeX, Sphinx configures the LaTeX document to use
`polyglossia`_. For some languages the `babel`_ support appears
preferable; Sphinx uses currently `babel`_ for French and perhaps will also
for some more languages in future. One can use the
:confval:`latex_elements` ``'babel'`` key to override Sphinx's default.
.. _`Latin Modern`: http://www.gust.org.pl/projects/e-foundry/latin-modern
.. _`polyglossia`: https://ctan.org/pkg/polyglossia
.. _`babel`: https://ctan.org/pkg/babel
.. _`babel-russian`: https://ctan.org/pkg/babel-russian
.. _`Libertinus`: https://ctan.org/pkg/libertinus
.. confval:: latex_documents
@ -1764,32 +1829,39 @@ information.
It must be a list of tuples ``(startdocname, targetname, title, author,
documentclass, toctree_only)``, where the items are:
* *startdocname*: document name that is the "root" of the LaTeX file. All
documents referenced by it in TOC trees will be included in the LaTeX file
too. (If you want only one LaTeX file, use your :confval:`master_doc`
here.)
* *targetname*: file name of the LaTeX file in the output directory.
* *title*: LaTeX document title. Can be empty to use the title of the
*startdoc*. This is inserted as LaTeX markup, so special characters like a
*startdocname*
String that specifies the :term:`document name` of the LaTeX file's master
document. All documents referenced by the *startdoc* document in TOC trees
will be included in the LaTeX file. (If you want to use the default master
document for your LaTeX build, provide your :confval:`master_doc` here.)
*targetname*
File name of the LaTeX file in the output directory.
*title*
LaTeX document title. Can be empty to use the title of the *startdoc*
document. This is inserted as LaTeX markup, so special characters like a
backslash or ampersand must be represented by the proper LaTeX commands if
they are to be inserted literally.
* *author*: Author for the LaTeX document. The same LaTeX markup caveat as
for *title* applies. Use ``\\and`` to separate multiple authors, as in:
``'John \\and Sarah'`` (backslashes must be Python-escaped to reach
LaTeX).
* *documentclass*: Normally, one of ``'manual'`` or ``'howto'`` (provided
by Sphinx and based on ``'report'``, resp. ``'article'``; Japanese
documents use ``'jsbook'``, resp. ``'jreport'``.) "howto" (non-Japanese)
documents will not get appendices. Also they have a simpler title page.
Other document classes can be given. Independently of the document class,
the "sphinx" package is always loaded in order to define Sphinx's custom
LaTeX commands.
* *toctree_only*: Must be ``True`` or ``False``. If true, the *startdoc*
document itself is not included in the output, only the documents
referenced by it via TOC trees. With this option, you can put extra stuff
in the master document that shows up in the HTML, but not the LaTeX
output.
*author*
Author for the LaTeX document. The same LaTeX markup caveat as for *title*
applies. Use ``\\and`` to separate multiple authors, as in:
``'John \\and Sarah'`` (backslashes must be Python-escaped to reach LaTeX).
*documentclass*
Normally, one of ``'manual'`` or ``'howto'`` (provided by Sphinx and based
on ``'report'``, resp. ``'article'``; Japanese documents use ``'jsbook'``,
resp. ``'jreport'``.) "howto" (non-Japanese) documents will not get
appendices. Also they have a simpler title page. Other document classes
can be given. Independently of the document class, the "sphinx" package is
always loaded in order to define Sphinx's custom LaTeX commands.
*toctree_only*
Must be ``True`` or ``False``. If true, the *startdoc* document itself is
not included in the output, only the documents referenced by it via TOC
trees. With this option, you can put extra stuff in the master document
that shows up in the HTML, but not the LaTeX output.
.. versionadded:: 1.2
In the past including your own document class required you to prepend the
@ -1871,6 +1943,37 @@ information.
.. versionadded:: 1.6
.. confval:: latex_use_xindy
If ``True``, the PDF build from the LaTeX files created by Sphinx
will use :program:`xindy` (doc__) rather than :program:`makeindex`
for preparing the index of general terms (from :rst:dir:`index`
usage). This means that words with UTF-8 characters will get
ordered correctly for the :confval:`language`.
__ http://xindy.sourceforge.net/
- This option is ignored if :confval:`latex_engine` is ``'platex'``
(Japanese documents; :program:`mendex` replaces :program:`makeindex`
then).
- The default is ``True`` for ``'xelatex'`` or ``'lualatex'`` as
:program:`makeindex`, if any indexed term starts with a non-ascii
character, creates ``.ind`` files containing invalid bytes for
UTF-8 encoding. With ``'lualatex'`` this then breaks the PDF
build.
- The default is ``False`` for ``'pdflatex'`` but ``True`` is
recommended for non-English documents as soon as some indexed
terms use non-ascii characters from the language script.
Sphinx adds to :program:`xindy` base distribution some dedicated support
for using ``'pdflatex'`` engine with Cyrillic scripts. And whether with
``'pdflatex'`` or Unicode engines, Cyrillic documents handle correctly the
indexing of Latin names, even with diacritics.
.. versionadded:: 1.8
.. confval:: latex_elements
.. versionadded:: 0.5
@ -1925,19 +2028,14 @@ information.
is ``'\\usepackage{polyglossia}\n\\setmainlanguage{<language>}'``.
.. versionchanged:: 1.6
``'lualatex'`` uses same default setting as ``'xelatex'``
.. versionchanged:: 1.7.6
For French, ``xelatex`` and ``lualatex`` default to using
``babel``, not ``polyglossia``.
``'fontpkg'``
Font package inclusion, default ``'\\usepackage{times}'`` (which uses
Times for text, Helvetica for sans serif and Courier for code-blocks).
.. hint::
Courier is much wider than Times, and Sphinx emits LaTeX command
``\small`` in code-blocks to compensate. Since ``1.5`` this is not
hard-coded anymore: ``\fvset{fontsize=auto}`` can be added to
preamble to not change font size in code-blocks. Since ``1.8`` a
separate ``'fvset'`` key is provided for this.
.. versionchanged:: 1.2
Defaults to ``''`` when the :confval:`language` uses the Cyrillic
script.
@ -1945,8 +2043,7 @@ information.
Defaults to ``''`` when :confval:`latex_engine` is ``'xelatex'``.
.. versionchanged:: 1.6
Defaults to ``''`` also with ``'lualatex'``.
.. versionchanged:: 1.8
``'xelatex'`` and ``'lualatex'`` do ``\fvset{fontsize=auto}``.
``'fncychap'``
Inclusion of the "fncychap" package (which makes fancy chapter titles),
default ``'\\usepackage[Bjarne]{fncychap}'`` for English documentation
@ -2114,13 +2211,18 @@ information.
index is full of long entries.
``'fvset'``
Customization of ``fancyvrb`` LaTeX package. Defaults to
``'\\fvset{fontsize=\\small}'``, because default font (Courier) used in
code-blocks is wider and taller than default text font (Times).
Customization of ``fancyvrb`` LaTeX package. Currently, Sphinx uses
this key to set the fontsize in code-blocks according to the
:confval:`latex_engine`.
For ``'xelatex'`` and ``'lualatex'``, defaults to
``'\\fvset{fontsize=auto}'``, because the default fonts are part of
one unified typeface family (Latin Modern OpenType).
- ``'pdflatex'`` uses ``'fvset': '\\fvset{fontsize=\\small}'``,
to mitigate the size difference between the default monospaced font
(Courier) and the default text font (Times). You may need to modify
this if you use custom fonts.
- ``'xelatex'`` and ``'lualatex'`` use ``'\\fvset{fontsize=auto}'``,
as there is no size difference between the regular and the
monospaced fonts used by default by Sphinx with these engines.
.. versionadded:: 1.8
@ -2226,9 +2328,11 @@ These options influence manual page output.
section)``, where the items are:
*startdocname*
Document name that is the "root" of the manual page. All documents
referenced by it in TOC trees will be included in the manual file too.
(If you want one master manual page, use your :confval:`master_doc` here.)
String that specifies the :term:`document name` of the manual page's master
document. All documents referenced by the *startdoc* document in TOC trees
will be included in the manual file. (If you want to use the default
master document for your manual pages build, use your :confval:`master_doc`
here.)
*name*
Name of the manual page. This should be a short string without spaces or
@ -2271,17 +2375,19 @@ These options influence Texinfo output.
are:
*startdocname*
Document name that is the "root" of the Texinfo file. All documents
referenced by it in TOC trees will be included in the Texinfo file too.
(If you want only one Texinfo file, use your :confval:`master_doc` here.)
String that specifies the :term:`document name` of the the Texinfo file's
master document. All documents referenced by the *startdoc* document in
TOC trees will be included in the Texinfo file. (If you want to use the
default master document for your Texinfo build, provide your
:confval:`master_doc` here.)
*targetname*
File name (no extension) of the Texinfo file in the output directory.
*title*
Texinfo document title. Can be empty to use the title of the *startdoc*.
Inserted as Texinfo markup, so special characters like ``@`` and ``{}``
will need to be escaped to be inserted literally.
Texinfo document title. Can be empty to use the title of the *startdoc*
document. Inserted as Texinfo markup, so special characters like ``@`` and
``{}`` will need to be escaped to be inserted literally.
*author*
Author for the Texinfo document. Inserted as Texinfo markup. Use ``@*``
@ -2450,12 +2556,21 @@ Options for the linkcheck builder
.. confval:: linkcheck_anchors_ignore
A list of regular expressions that match URIs that should skip checking
the validity of anchors in links. This allows skipping entire sites, where
anchors are used to control dynamic pages, or just specific anchors within
a page, where JavaScript is used to add anchors dynamically, or use the
fragment as part of to trigger an internal REST request. Default is
``["/#!"]``.
A list of regular expressions that match anchors Sphinx should skip when
checking the validity of anchors in links. This allows skipping anchors that
a website's JavaScript adds to control dynamic pages or when triggering an
internal REST request. Default is ``["^!"]``.
.. note::
If you want to ignore anchors of a specific page or of pages that match a
specific pattern (but still check occurrences of the same page(s) that
don't have anchors), use :confval:`linkcheck_ignore` instead, for example
as follows::
linkcheck_ignore = [
'http://www.sphinx-doc.org/en/1.7/intro.html#'
]
.. versionadded:: 1.5

View File

@ -341,7 +341,8 @@ There are also new config values that you can set:
This value is a list of autodoc directive flags that should be automatically
applied to all autodoc directives. The supported flags are ``'members'``,
``'undoc-members'``, ``'private-members'``, ``'special-members'``,
``'inherited-members'``, ``'show-inheritance'`` and ``'ignore-module-all'``.
``'inherited-members'``, ``'show-inheritance'``, ``'ignore-module-all'``
and ``'exclude-members'``.
If you set one of these flags in this config value, you can use a negated
form, :samp:`'no-{flag}'`, in an autodoc directive, to disable it once.
@ -353,8 +354,26 @@ There are also new config values that you can set:
the directive will be interpreted as if only ``:members:`` was given.
You can also set `autodoc_default_flags` to a dictionary, mapping option
names to the values which can used in .rst files. For example::
autodoc_default_flags = {
'members': 'var1, var2',
'member-order': 'bysource',
'special-members': '__init__',
'undoc-members': None,
'exclude-members': '__weakref__'
}
Setting ``None`` is equivalent to giving the option name in the list format
(i.e. it means "yes/true/on").
.. versionadded:: 1.0
.. versionchanged:: 1.8
Specifying in dictionary format added.
.. confval:: autodoc_docstring_signature
Functions imported from C modules cannot be introspected, and therefore the
@ -405,6 +424,7 @@ There are also new config values that you can set:
.. versionadded:: 1.7
Docstring preprocessing
-----------------------

View File

@ -27,6 +27,7 @@ default. The ``autosectionlabel_prefix_document`` configuration variable can be
used to make headings which appear multiple times but in different documents
unique.
Configuration
-------------

View File

@ -25,7 +25,6 @@ The :mod:`sphinx.ext.autosummary` extension does this in two parts:
These files by default contain only the corresponding
:mod:`sphinx.ext.autodoc` directive, but can be customized with templates.
.. rst:directive:: autosummary
Insert a table that contains links to documented items, and a short summary
@ -59,7 +58,6 @@ The :mod:`sphinx.ext.autosummary` extension does this in two parts:
:event:`autodoc-process-docstring` and :event:`autodoc-process-signature`
hooks as :mod:`~sphinx.ext.autodoc`.
**Options**
* If you want the :rst:dir:`autosummary` table to also serve as a

View File

@ -4,7 +4,6 @@
.. module:: sphinx.ext.coverage
:synopsis: Check Python modules and C API for coverage in the documentation.
This extension features one additional builder, the :class:`CoverageBuilder`.
.. class:: CoverageBuilder
@ -14,7 +13,6 @@ This extension features one additional builder, the :class:`CoverageBuilder`.
.. todo:: Write this section.
Several new configuration values can be used to specify what the builder
should check:

View File

@ -165,7 +165,6 @@ a comma-separated list of group names.
Output text.
The following is an example for the usage of the directives. The test via
:rst:dir:`doctest` and the test via :rst:dir:`testcode` and
:rst:dir:`testoutput` are equivalent. ::
@ -199,6 +198,81 @@ The following is an example for the usage of the directives. The test via
This parrot wouldn't voom if you put 3000 volts through it!
Skipping tests conditionally
----------------------------
``skipif``, a string option, can be used to skip directives conditionally. This
may be useful e.g. when a different set of tests should be run depending on the
environment (hardware, network/VPN, optional dependencies or different versions
of dependencies). The ``skipif`` option is supported by all of the doctest
directives. Below are typical use cases for ``skipif`` when used for different
directives:
- :rst:dir:`testsetup` and :rst:dir:`testcleanup`
- conditionally skip test setup and/or cleanup
- customize setup/cleanup code per environment
- :rst:dir:`doctest`
- conditionally skip both a test and its output verification
- :rst:dir:`testcode`
- conditionally skip a test
- customize test code per environment
- :rst:dir:`testoutput`
- conditionally skip output assertion for a skipped test
- expect different output depending on the environment
The value of the ``skipif`` option is evaluated as a Python expression. If the
result is a true value, the directive is omitted from the test run just as if
it wasn't present in the file at all.
Instead of repeating an expression, the :confval:`doctest_global_setup`
configuration option can be used to assign it to a variable which can then be
used instead.
Here's an example which skips some tests if Pandas is not installed:
.. code-block:: py
:caption: conf.py
extensions = ['sphinx.ext.doctest']
doctest_global_setup = '''
try:
import pandas as pd
except ImportError:
pd = None
'''
.. code-block:: rst
:caption: contents.rst
.. testsetup::
:skipif: pd is None
data = pd.Series([42])
.. doctest::
:skipif: pd is None
>>> data.iloc[0]
42
.. testcode::
:skipif: pd is None
print(data.iloc[-1])
.. testoutput::
:skipif: pd is None
42
Configuration
-------------

View File

@ -7,7 +7,6 @@
.. versionadded:: 1.0
This extension is meant to help with the common pattern of having many external
links that point to URLs on one and the same site, e.g. links to bug trackers,
version control web interfaces, or simply subpages in other websites. It does

View File

@ -1,5 +1,3 @@
.. highlight:: rest
:mod:`sphinx.ext.githubpages` -- Publish HTML docs in GitHub Pages
==================================================================

View File

@ -13,7 +13,6 @@ your documents.
It adds these directives:
.. rst:directive:: graphviz
Directive to embed graphviz code. The input code for ``dot`` is given as the

View File

@ -1,28 +1,30 @@
.. highlight:: rest
.. _sphinx.ext.imgconverter:
:mod:`sphinx.ext.imgconverter` -- A reference implementation for image converter using Imagemagick
==================================================================================================
:mod:`sphinx.ext.imgconverter` -- A reference image converter using Imagemagick
===============================================================================
.. module:: sphinx.ext.imgconverter
:synopsis: Convert images to appropriate format for builders
.. versionadded:: 1.6
This extension converts images in your document to appropriate format for builders.
For example, it allows you to use SVG images with LaTeX builder.
This extension converts images in your document to appropriate format for
builders. For example, it allows you to use SVG images with LaTeX builder.
As a result, you don't mind what image format the builder supports.
Internally, this extension uses Imagemagick_ to convert images.
.. _Imagemagick: https://www.imagemagick.org/script/index.php
.. note:: Imagemagick rasterizes a SVG image on conversion. As a result, the image
becomes not scalable. To avoid that, please use other image converters
like sphinxcontrib-svg2pdfconverter_ (which uses Inkscape or rsvg-convert).
.. note::
Imagemagick rasterizes a SVG image on conversion. As a result, the image
becomes not scalable. To avoid that, please use other image converters like
`sphinxcontrib-svg2pdfconverter`__ (which uses Inkscape or
``rsvg-convert``).
.. __: https://github.com/missinglinkelectronics/sphinxcontrib-svg2pdfconverter
.. _sphinxcontrib-svg2pdfconverter: https://github.com/missinglinkelectronics/sphinxcontrib-svg2pdfconverter
Configuration
-------------

View File

@ -1,9 +1,50 @@
==========
Extensions
==========
Since many projects will need special features in their documentation, Sphinx
allows adding "extensions" to the build process, each of which can modify
almost any aspect of document processing.
This chapter describes the extensions bundled with Sphinx. For the API
documentation on writing your own extension, refer to :ref:`dev-extensions`.
Built-in extensions
-------------------
These extensions are built in and can be activated by respective entries in the
:confval:`extensions` configuration value:
.. toctree::
autodoc
autosectionlabel
autosummary
coverage
doctest
extlinks
githubpages
graphviz
ifconfig
imgconverter
inheritance
intersphinx
linkcode
math
napoleon
todo
viewcode
Third-party extensions
----------------------
.. todo:: This should reference the GitHub organization now
You can find several extensions contributed by users in the `Sphinx Contrib`_
repository. It is open for anyone who wants to maintain an extension
publicly; just send a short message asking for write permissions.
repository. It is open for anyone who wants to maintain an extension publicly;
just send a short message asking for write permissions.
There are also several extensions hosted elsewhere. The `Sphinx extension
survey <https://sphinxext-survey.readthedocs.io/>`__ and `awesome-sphinxdoc
@ -16,15 +57,13 @@ list (`join here <https://groups.google.com/forum/#!forum/sphinx-dev>`_).
.. _Sphinx Contrib: https://bitbucket.org/birkenfeld/sphinx-contrib
Where to put your own extensions?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Extensions local to a project should be put within the project's directory
structure. Set Python's module search path, ``sys.path``, accordingly so that
Sphinx can find them.
E.g., if your extension ``foo.py`` lies in the ``exts`` subdirectory of the
project root, put into :file:`conf.py`::
Sphinx can find them. For example, if your extension ``foo.py`` lies in the
``exts`` subdirectory of the project root, put into :file:`conf.py`::
import sys, os

View File

@ -91,7 +91,9 @@ It adds this directive:
.. versionchanged:: 1.7
Added ``top-classes`` option to limit the scope of inheritance graphs.
New config values are:
Configuration
-------------
.. confval:: inheritance_graph_attrs

View File

@ -38,8 +38,9 @@ Behind the scenes, this works as follows:
specified individually, e.g. if the docs should be buildable without Internet
access.
Configuring Intersphinx
-----------------------
Configuration
-------------
To use Intersphinx linking, add ``'sphinx.ext.intersphinx'`` to your
:confval:`extensions` config value, and use these new config values to activate
@ -136,12 +137,14 @@ linking:
exception is raised if the server has not issued a response for timeout
seconds.
Showing all links of an Intersphinx mapping file
------------------------------------------------
To show all Intersphinx links and their targets of an Intersphinx mapping file, run
``python -msphinx.ext.intersphinx url-or-path``. This is helpful when searching for the root cause of a broken
Intersphinx link in a documentation project. The following example prints the Intersphinx mapping of the Python 3
To show all Intersphinx links and their targets of an Intersphinx mapping file,
run ``python -msphinx.ext.intersphinx url-or-path``. This is helpful when
searching for the root cause of a broken Intersphinx link in a documentation
project. The following example prints the Intersphinx mapping of the Python 3
documentation::
$ python -msphinx.ext.intersphinx https://docs.python.org/3/objects.inv

View File

@ -16,6 +16,10 @@ found somewhere on the Internet.
In your configuration, you need to specify a :confval:`linkcode_resolve`
function that returns an URL based on the object.
Configuration
-------------
.. confval:: linkcode_resolve
This is a function ``linkcode_resolve(domain, info)``,

View File

@ -2,123 +2,20 @@
.. _math-support:
Math support in Sphinx
======================
Math support for HTML outputs in Sphinx
=======================================
.. module:: sphinx.ext.mathbase
:synopsis: Common math support for imgmath and mathjax / jsmath.
.. versionadded:: 0.5
.. versionchanged:: 1.8
Math support for non-HTML builders is integrated to sphinx-core.
So mathbase extension is no longer needed.
Since mathematical notation isn't natively supported by HTML in any way, Sphinx
supports math in documentation with several extensions.
The basic math support is contained in :mod:`sphinx.ext.mathbase`. Other math
support extensions should, if possible, reuse that support too.
.. note::
:mod:`.mathbase` is not meant to be added to the :confval:`extensions` config
value, instead, use either :mod:`sphinx.ext.imgmath` or
:mod:`sphinx.ext.mathjax` as described below.
The input language for mathematics is LaTeX markup. This is the de-facto
standard for plain-text math notation and has the added advantage that no
further translation is necessary when building LaTeX output.
Keep in mind that when you put math markup in **Python docstrings** read by
:mod:`autodoc <sphinx.ext.autodoc>`, you either have to double all backslashes,
or use Python raw strings (``r"raw"``).
:mod:`.mathbase` provides the following config values:
.. confval:: math_number_all
Set this option to ``True`` if you want all displayed math to be numbered.
The default is ``False``.
.. confval:: math_eqref_format
A string that are used for format of label of references to equations.
As a special character, ``{number}`` will be replaced to equaition number.
Example: ``'Eq.{number}'`` is rendered as ``Eq.10``
.. confval:: math_numfig
If ``True``, displayed math equations are numbered across pages when
:confval:`numfig` is enabled. The :confval:`numfig_secnum_depth` setting
is respected. The :rst:role:`eq`, not :rst:role:`numref`, role
must be used to reference equation numbers. Default is ``True``.
.. versionadded:: 1.7
:mod:`.mathbase` defines these new markup elements:
.. rst:role:: math
Role for inline math. Use like this::
Since Pythagoras, we know that :math:`a^2 + b^2 = c^2`.
.. rst:directive:: math
Directive for displayed math (math that takes the whole line for itself).
The directive supports multiple equations, which should be separated by a
blank line::
.. math::
(a + b)^2 = a^2 + 2ab + b^2
(a - b)^2 = a^2 - 2ab + b^2
In addition, each single equation is set within a ``split`` environment,
which means that you can have multiple aligned lines in an equation,
aligned at ``&`` and separated by ``\\``::
.. math::
(a + b)^2 &= (a + b)(a + b) \\
&= a^2 + 2ab + b^2
For more details, look into the documentation of the `AmSMath LaTeX
package`_.
When the math is only one line of text, it can also be given as a directive
argument::
.. math:: (a + b)^2 = a^2 + 2ab + b^2
Normally, equations are not numbered. If you want your equation to get a
number, use the ``label`` option. When given, it selects an internal label
for the equation, by which it can be cross-referenced, and causes an equation
number to be issued. See :rst:role:`eq` for an example. The numbering
style depends on the output format.
There is also an option ``nowrap`` that prevents any wrapping of the given
math in a math environment. When you give this option, you must make sure
yourself that the math is properly set up. For example::
.. math::
:nowrap:
\begin{eqnarray}
y & = & ax^2 + bx + c \\
f(x) & = & x^2 + 2xy + y^2
\end{eqnarray}
.. rst:role:: eq
Role for cross-referencing equations via their label. Example::
.. math:: e^{i\pi} + 1 = 0
:label: euler
Euler's identity, equation :eq:`euler`, was elected one of the most
beautiful mathematical formulas.
gives a math support to HTML document with several extensions.
:mod:`sphinx.ext.imgmath` -- Render math as images
--------------------------------------------------
@ -271,6 +168,23 @@ Sphinx.
The default is empty (``{}``).
.. confval:: mathjax_config
The inline configuration options for mathjax. The value is used as a
parameter of ``MathJax.Hub.Config()``. For more information, please
read `Using in-line configuration options`_.
For example::
mathjax_config = {
'extensions': ['tex2jax.js'],
'jax': ['input/TeX', 'output/HTML-CSS'],
}
The default is empty (not configured).
.. _Using in-line configuration options: http://docs.mathjax.org/en/latest/configuration.html#using-in-line-configuration-options
:mod:`sphinx.ext.jsmath` -- Render math via JavaScript
------------------------------------------------------
@ -299,4 +213,3 @@ package jsMath_. It provides this config value:
.. _MathJax: https://www.mathjax.org/
.. _jsMath: http://www.math.union.edu/~dpvc/jsmath/
.. _preview-latex package: https://www.gnu.org/software/auctex/preview-latex.html
.. _AmSMath LaTeX package: https://www.ams.org/publications/authors/tex/amslatex

View File

@ -1,5 +1,5 @@
:mod:`sphinx.ext.napoleon` -- Support for NumPy and Google style docstrings
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
===========================================================================
.. module:: sphinx.ext.napoleon
:synopsis: Support for NumPy and Google style docstrings
@ -8,8 +8,8 @@
.. versionadded:: 1.3
Napoleon - *Marching toward legible docstrings*
===============================================
Overview
--------
.. highlight:: text
@ -25,7 +25,7 @@ Are you tired of writing docstrings that look like this::
:returns: A buffered writable file descriptor
:rtype: BufferedFileStorage
`ReStructuredText`_ is great, but it creates visually dense, hard to read
`reStructuredText`_ is great, but it creates visually dense, hard to read
`docstrings`_. Compare the jumble above to the same thing rewritten
according to the `Google Python Style Guide`_::
@ -40,8 +40,8 @@ according to the `Google Python Style Guide`_::
Much more legible, no?
Napoleon is a :doc:`../extensions` that enables Sphinx to parse both `NumPy`_
and `Google`_ style docstrings - the style recommended by `Khan Academy`_.
Napoleon is a :term:`extension` that enables Sphinx to parse both `NumPy`_ and
`Google`_ style docstrings - the style recommended by `Khan Academy`_.
Napoleon is a pre-processor that parses `NumPy`_ and `Google`_ style
docstrings and converts them to reStructuredText before Sphinx attempts to
@ -61,7 +61,7 @@ source code files.
https://github.com/Khan/style-guides/blob/master/style/python.md#docstrings
Getting Started
---------------
~~~~~~~~~~~~~~~
1. After :doc:`setting up Sphinx </usage/quickstart>` to build your docs,
enable napoleon in the Sphinx `conf.py` file::
@ -77,7 +77,7 @@ Getting Started
Docstrings
----------
~~~~~~~~~~
Napoleon interprets every docstring that :mod:`autodoc <sphinx.ext.autodoc>`
can find, including docstrings on: ``modules``, ``classes``, ``attributes``,
@ -91,15 +91,21 @@ All standard reStructuredText formatting still works as expected.
.. _Sections:
Docstring Sections
------------------
~~~~~~~~~~~~~~~~~~
All of the following section headers are supported:
* ``Args`` *(alias of Parameters)*
* ``Arguments`` *(alias of Parameters)*
* ``Attention``
* ``Attributes``
* ``Caution``
* ``Danger``
* ``Error``
* ``Example``
* ``Examples``
* ``Hint``
* ``Important``
* ``Keyword Args`` *(alias of Keyword Arguments)*
* ``Keyword Arguments``
* ``Methods``
@ -112,6 +118,7 @@ All of the following section headers are supported:
* ``Raises``
* ``References``
* ``See Also``
* ``Tip``
* ``Todo``
* ``Warning``
* ``Warnings`` *(alias of Warning)*
@ -120,7 +127,7 @@ All of the following section headers are supported:
* ``Yields``
Google vs NumPy
---------------
~~~~~~~~~~~~~~~
Napoleon supports two styles of docstrings: `Google`_ and `NumPy`_. The
main difference between the two styles is that Google uses indention to
@ -188,7 +195,7 @@ not be mixed. Choose one style for your project and be consistent with it.
Type Annotations
----------------
~~~~~~~~~~~~~~~~
`PEP 484`_ introduced a standard way to express types in Python code.
This is an alternative to expressing types directly in docstrings.
@ -242,7 +249,7 @@ Google style with types in docstrings::
Configuration
=============
-------------
Listed below are all the settings used by napoleon and their default
values. These settings can be changed in the Sphinx `conf.py` file. Make
@ -271,8 +278,6 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
.. _NumPy style:
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
.. confval:: napoleon_google_docstring
True to parse `Google style`_ docstrings. False to disable support

View File

@ -27,7 +27,10 @@ There are two additional directives when using this extension:
documentation, if :confval:`todo_include_todos` is ``True``.
There is also an additional config value:
These can be configured as seen below.
Configuration
-------------
.. confval:: todo_include_todos

View File

@ -7,9 +7,8 @@
.. versionadded:: 1.0
This extension looks at your Python object descriptions (``.. class::``,
``.. function::`` etc.) and tries to find the source files where the objects are
This extension looks at your Python object descriptions (``.. class::``, ``..
function::`` etc.) and tries to find the source files where the objects are
contained. When found, a separate HTML page will be output for each module with
a highlighted version of the source code, and a link will be added to all object
descriptions that leads to the source code of the described object. A link back
@ -33,14 +32,15 @@ This extension works only on HTML related builders like ``html``,
``singlehtml``. By default ``epub`` builder doesn't
support this extension (see :confval:`viewcode_enable_epub`).
There is an additional config value:
Configuration
-------------
.. confval:: viewcode_follow_imported_members
If this is ``True``, viewcode extension will follow alias objects that
imported from another module such as functions, classes and attributes.
As side effects, this option
else they produce nothing. The default is ``True``.
imported from another module such as functions, classes and attributes. As
side effects, this option else they produce nothing. The default is
``True``.
.. versionadded:: 1.3

View File

@ -127,7 +127,7 @@ directory in which you want to place the built documentation.
The :option:`-b <sphinx-build -b>` option selects a builder; in this example
Sphinx will build HTML files.
|more| Refer to the :program:`sphinx-build man page <sphinx-build>` for all
|more| Refer to the :doc:`sphinx-build man page </man/sphinx-build>` for all
options that :program:`sphinx-build` supports.
However, :program:`sphinx-quickstart` script creates a :file:`Makefile` and a
@ -318,12 +318,7 @@ features of intersphinx.
More topics to be covered
-------------------------
- :doc:`Other extensions </extensions>`:
* :doc:`/ext/math`,
* :doc:`/ext/viewcode`,
* :doc:`/ext/doctest`,
* ...
- :doc:`Other extensions </usage/extensions/index>`:
- Static files
- :doc:`Selecting a theme </theming>`
- :doc:`/setuptools`
@ -336,7 +331,7 @@ More topics to be covered
.. [#] This is the usual layout. However, :file:`conf.py` can also live in
another directory, the :term:`configuration directory`. Refer to the
:program:`sphinx-build man page <sphinx-build>` for more information.
:doc:`sphinx-build man page </man/sphinx-build>` for more information.
.. |more| image:: /_static/more.png
:align: middle

View File

@ -444,7 +444,7 @@ candidates. For instance, if the file name ``gnu.*`` was given and two files
:file:`gnu.pdf` and :file:`gnu.png` existed in the source tree, the LaTeX
builder would choose the former, while the HTML builder would prefer the
latter. Supported image types and choosing priority are defined at
:ref:`builders`.
:doc:`/usage/builders/index`.
Note that image file names should not contain spaces.

View File

@ -1005,9 +1005,63 @@ this reason, the following directive exists:
Math
----
.. todo:: Move this in here.
The input language for mathematics is LaTeX markup. This is the de-facto
standard for plain-text math notation and has the added advantage that no
further translation is necessary when building LaTeX output.
See :ref:`math-support`.
Keep in mind that when you put math markup in **Python docstrings** read by
:mod:`autodoc <sphinx.ext.autodoc>`, you either have to double all backslashes,
or use Python raw strings (``r"raw"``).
.. rst:directive:: math
Directive for displayed math (math that takes the whole line for itself).
The directive supports multiple equations, which should be separated by a
blank line::
.. math::
(a + b)^2 = a^2 + 2ab + b^2
(a - b)^2 = a^2 - 2ab + b^2
In addition, each single equation is set within a ``split`` environment,
which means that you can have multiple aligned lines in an equation,
aligned at ``&`` and separated by ``\\``::
.. math::
(a + b)^2 &= (a + b)(a + b) \\
&= a^2 + 2ab + b^2
For more details, look into the documentation of the `AmSMath LaTeX
package`_.
When the math is only one line of text, it can also be given as a directive
argument::
.. math:: (a + b)^2 = a^2 + 2ab + b^2
Normally, equations are not numbered. If you want your equation to get a
number, use the ``label`` option. When given, it selects an internal label
for the equation, by which it can be cross-referenced, and causes an equation
number to be issued. See :rst:role:`eq` for an example. The numbering
style depends on the output format.
There is also an option ``nowrap`` that prevents any wrapping of the given
math in a math environment. When you give this option, you must make sure
yourself that the math is properly set up. For example::
.. math::
:nowrap:
\begin{eqnarray}
y & = & ax^2 + bx + c \\
f(x) & = & x^2 + 2xy + y^2
\end{eqnarray}
.. _AmSMath LaTeX package: https://www.ams.org/publications/authors/tex/amslatex
Grammar production displays

View File

@ -1005,20 +1005,46 @@ These roles link to the given declaration types:
When a custom title is not needed it may be useful to use the roles for inline expressions,
:rst:role:`cpp:expr` and :rst:role:`cpp:texpr`, where angle brackets do not need escaping.
.. admonition:: Note on References to Overloaded Functions
It is currently impossible to link to a specific version of an overloaded
function. Currently the C++ domain is the first domain that has basic
support for overloaded functions and until there is more data for comparison
we don't want to select a bad syntax to reference a specific overload.
Currently Sphinx will link to the first overloaded version of the 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``.
Overloaded (member) functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When a (member) function is referenced using just its name, the reference
will point to an arbitrary matching overload.
The :rst:role:`cpp:any` and :rst:role:`cpp:func` roles will an alternative
format, which simply is a complete function declaration.
This will resolve to the exact matching overload.
As example, consider the following class declaration:
.. cpp:namespace-push:: overload_example
.. cpp:class:: C
.. cpp:function:: void f(double d) const
.. cpp:function:: void f(double d)
.. cpp:function:: void f(int i)
.. cpp:function:: void f()
References using the :rst:role:`cpp:func` role:
- Arbitrary overload: ``C::f``, :cpp:func:`C::f`
- Also arbitrary overload: ``C::f()``, :cpp:func:`C::f()`
- Specific overload: ``void C::f()``, :cpp:func:`void C::f()`
- Specific overload: ``void C::f(int)``, :cpp:func:`void C::f(int)`
- Specific overload: ``void C::f(double)``, :cpp:func:`void C::f(double)`
- Specific overload: ``void C::f(double) const``, :cpp:func:`void C::f(double) const`
Note that the :confval:`add_function_parentheses` configuration variable
does not influence specific overload references.
.. cpp:namespace-pop::
Templated declarations
^^^^^^^^^^^^^^^^^^^^^^
@ -1033,19 +1059,25 @@ Assume the following declarations.
Inner
In general the reference must include the template parameter 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.
and template arguments for the prefix of qualified names. For example:
The inner class template cannot 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.
- ``template\<typename TOuter> Wrapper::Outer``
(:cpp:class:`template\<typename TOuter> Wrapper::Outer`)
- ``template\<typename TOuter> template\<typename TInner> Wrapper::Outer<TOuter>::Inner``
(:cpp:class:`template\<typename TOuter> template\<typename TInner> Wrapper::Outer<TOuter>::Inner`)
- ``Wrapper::Outer`` (:cpp:class:`Wrapper::Outer`)
- ``Wrapper::Outer::Inner`` (:cpp:class:`Wrapper::Outer::Inner`)
Currently the lookup only succeed if the template parameter identifiers are equal strings.
That is, ``template\<typename UOuter> Wrapper::Outer`` will not work.
As a shorthand notation, if a template parameter list is omitted,
then the lookup will assume either a primary template or a non-template,
but not a partial template specialisation.
This means the following references work as well:
- ``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`)
@ -1325,6 +1357,25 @@ These roles are provided to refer to the described objects:
.. rst:role:: rst:dir
rst:role
.. _math-domain:
The Math Domain
---------------
The math domain (name **math**) provides the following roles::
.. rst:role:: math:numref
Role for cross-referencing equations defined by :rst:dir:`math` directive
via their label. Example::
.. math:: e^{i\pi} + 1 = 0
:label: euler
Euler's identity, equation :math:numref:`euler`, was elected one of the
most beautiful mathematical formulas.
.. versionadded:: 1.8
More domains
------------

View File

@ -62,7 +62,7 @@ Cross-referencing anything
by :rst:role:`doc`, :rst:role:`ref` or :rst:role:`option`.
Custom objects added to the standard domain by extensions (see
:meth:`Sphinx.add_object_type`) are also searched.
:meth:`.Sphinx.add_object_type`) are also searched.
* Then, it looks for objects (targets) in all loaded domains. It is up to
the domains how specific a match must be. For example, in the Python
@ -277,6 +277,20 @@ The following role creates a cross-reference to a term in a
during build.
Math
----
.. rst:role:: math
Role for inline math. Use like this::
Since Pythagoras, we know that :math:`a^2 + b^2 = c^2`.
.. rst:role:: eq
Same as :rst:role:`math:numref`.
Other semantic markup
---------------------

72
karma.conf.js Normal file
View File

@ -0,0 +1,72 @@
// Karma configuration
// Generated on Sat Jul 21 2018 22:01:48 GMT+0200 (CEST)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'sphinx/themes/basic/static/underscore.js',
'sphinx/themes/basic/static/jquery.js',
'sphinx/themes/basic/static/doctools.js',
'tests/js/*.js'
],
// list of files / patterns to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome', 'Firefox'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}

2886
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

20
package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "sphinx",
"scripts": {
"test": "./node_modules/.bin/karma start --browsers Firefox --single-run"
},
"repository": {
"type": "git",
"url": "git+https://github.com/sphinx-doc/sphinx.git"
},
"bugs": {
"url": "https://github.com/sphinx-doc/sphinx/issues"
},
"devDependencies": {
"jasmine-core": "^3.1.0",
"karma": "^3.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-firefox-launcher": "^1.1.0",
"karma-jasmine": "^1.1.2"
}
}

View File

@ -31,8 +31,8 @@ directory = sphinx/locale/
[flake8]
max-line-length = 95
ignore = E116,E241,E251,E741,I101
exclude = .git,.tox,.venv,tests/*,build/*,doc/_build/*,sphinx/search/*,doc/ext/example*.py
ignore = E116,E241,E251,E741,W504,I101
exclude = .git,.tox,.venv,tests/*,build/*,doc/_build/*,sphinx/search/*,doc/usage/extensions/example*.py
application-import-names = sphinx
import-order-style = smarkets

View File

@ -71,16 +71,16 @@ if __version__.endswith('+'):
pass
def main(*args, **kwargs):
# type: (Any, Any) -> int
def main(argv=sys.argv): # type: ignore
# type: (List[unicode]) -> int
from .cmd import build
warnings.warn(
'`sphinx.main()` has moved to `sphinx.cmd.build.main()`.',
RemovedInSphinx20Warning,
stacklevel=2,
)
args = args[1:] # skip first argument to adjust arguments (refs: #4615)
return build.main(*args, **kwargs)
argv = argv[1:] # skip first argument to adjust arguments (refs: #4615)
return build.main(argv)
def build_main(argv=sys.argv):

View File

@ -9,6 +9,7 @@
:license: BSD, see LICENSE for details.
"""
import sys
import warnings
from sphinx.deprecation import RemovedInSphinx20Warning
@ -16,19 +17,18 @@ from sphinx.ext.apidoc import main as _main
if False:
# For type annotation
from typing import Any # NOQA
from typing import List # NOQA
from sphinx.application import Sphinx # NOQA
def main(*args, **kwargs):
# type: (Any, Any) -> None
def main(argv=sys.argv):
# type: (List[str]) -> None
warnings.warn(
'`sphinx.apidoc.main()` has moved to `sphinx.ext.apidoc.main()`.',
RemovedInSphinx20Warning,
stacklevel=2,
)
args = args[1:] # skip first argument to adjust arguments (refs: #4615)
_main(*args, **kwargs)
_main(argv[1:]) # skip first argument to adjust arguments (refs: #4615)
# So program can be started with "python -m sphinx.apidoc ..."

View File

@ -80,6 +80,7 @@ builtin_extensions = (
'sphinx.builders.xml',
'sphinx.config',
'sphinx.domains.c',
'sphinx.domains.changeset',
'sphinx.domains.cpp',
'sphinx.domains.javascript',
'sphinx.domains.math',
@ -96,6 +97,7 @@ builtin_extensions = (
'sphinx.registry',
'sphinx.roles',
'sphinx.transforms.post_transforms',
'sphinx.transforms.post_transforms.code',
'sphinx.transforms.post_transforms.images',
'sphinx.transforms.post_transforms.compat',
'sphinx.util.compat',
@ -128,8 +130,8 @@ class Sphinx(object):
def __init__(self, srcdir, confdir, outdir, doctreedir, buildername,
confoverrides=None, status=sys.stdout, warning=sys.stderr,
freshenv=False, warningiserror=False, tags=None, verbosity=0,
parallel=0):
# type: (unicode, unicode, unicode, unicode, unicode, Dict, IO, IO, bool, bool, List[unicode], int, int) -> None # NOQA
parallel=0, keep_going=False):
# type: (unicode, unicode, unicode, unicode, unicode, Dict, IO, IO, bool, bool, List[unicode], int, int, bool) -> None # NOQA
self.phase = BuildPhase.INITIALIZATION
self.verbosity = verbosity
self.extensions = {} # type: Dict[unicode, Extension]
@ -172,7 +174,11 @@ class Sphinx(object):
else:
self._warning = warning
self._warncount = 0
self.warningiserror = warningiserror
self.keep_going = warningiserror and keep_going
if self.keep_going:
self.warningiserror = False
else:
self.warningiserror = warningiserror
logging.setup(self, self._status, self._warning)
self.events = EventManager()
@ -334,6 +340,9 @@ class Sphinx(object):
self.builder.compile_update_catalogs()
self.builder.build_update()
if self._warncount and self.keep_going:
self.statuscode = 1
status = (self.statuscode == 0 and
__('succeeded') or __('finished with problems'))
if self._warncount:
@ -642,7 +651,7 @@ class Sphinx(object):
a title.
Other keyword arguments are used for node visitor functions. See the
:meth:`Sphinx.add_node` for details.
:meth:`.Sphinx.add_node` for details.
.. versionadded:: 1.4
"""
@ -850,8 +859,9 @@ class Sphinx(object):
object. It will automatically add index entries if *indextemplate*
is nonempty; if given, it must contain exactly one instance of
``%s``. See the example below for how the template will be
interpreted. * Create a new role (called *rolename*) to
cross-reference to these object descriptions.
interpreted.
- Create a new role (called *rolename*) to cross-reference to these
object descriptions.
- If you provide *parse_node*, it must be a function that takes a
string and a docutils node, and it must populate the node with
children parsed from the string. It must then return the name of the
@ -1219,6 +1229,20 @@ class Sphinx(object):
logger.debug('[app] adding HTML theme: %r, %r', name, theme_path)
self.html_themes[name] = theme_path
def add_html_math_renderer(self, name, inline_renderers=None, block_renderers=None):
# type: (unicode, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
"""Register a math renderer for HTML.
The *name* is a name of the math renderer. Both *inline_renderers* and
*block_renderes* are used as visitor functions for HTML writer.
*inline_renderers* is used for inline math node (``nodes.math`)). The
another is used for block math node (``nodes.math_block``). About
visitor functions, see :meth:`add_node` for more details.
.. versionadded:: 1.8
"""
self.registry.add_html_math_renderer(name, inline_renderers, block_renderers)
def add_message_catalog(self, catalog, locale_dir):
# type: (unicode, unicode) -> None
"""Register a message catalog.

View File

@ -195,7 +195,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
"""Collect section titles, their depth in the toc and the refuri."""
# XXX: is there a better way than checking the attribute
# toctree-l[1-8] on the parent node?
if isinstance(doctree, nodes.reference) and 'refuri' in doctree:
if isinstance(doctree, nodes.reference) and doctree.get('refuri'):
refuri = doctree['refuri']
if refuri.startswith('http://') or refuri.startswith('https://') \
or refuri.startswith('irc:') or refuri.startswith('mailto:'):
@ -272,6 +272,16 @@ class EpubBuilder(StandaloneHTMLBuilder):
node['refuri'] = self.fix_fragment(m.group(1), m.group(2))
if 'refid' in node:
node['refid'] = self.fix_fragment('', node['refid'])
for node in tree.traverse(nodes.target):
for i, node_id in enumerate(node['ids']):
if ':' in node_id:
node['ids'][i] = self.fix_fragment('', node_id)
next_node = node.next_node(siblings=True)
if next_node and isinstance(next_node, nodes.Element):
for i, node_id in enumerate(next_node['ids']):
if ':' in node_id:
next_node['ids'][i] = self.fix_fragment('', node_id)
for node in tree.traverse(addnodes.desc_signature):
ids = node.attributes['ids']
newids = []

View File

@ -11,11 +11,13 @@
import codecs
from os import path
from typing import cast
from six import iteritems
from sphinx import package_dir
from sphinx.builders import Builder
from sphinx.domains.changeset import ChangeSetDomain
from sphinx.locale import _, __
from sphinx.theming import HTMLThemeFactory
from sphinx.util import logging
@ -60,6 +62,7 @@ class ChangesBuilder(Builder):
def write(self, *ignored):
# type: (Any) -> None
version = self.config.version
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
libchanges = {} # type: Dict[unicode, List[Tuple[unicode, unicode, int]]]
apichanges = [] # type: List[Tuple[unicode, unicode, int]]
otherchanges = {} # type: Dict[Tuple[unicode, unicode], List[Tuple[unicode, unicode, int]]] # NOQA
@ -67,21 +70,22 @@ class ChangesBuilder(Builder):
logger.info(bold(__('no changes in version %s.') % version))
return
logger.info(bold('writing summary file...'))
for type, docname, lineno, module, descname, content in \
self.env.versionchanges[version]:
if isinstance(descname, tuple):
descname = descname[0]
ttext = self.typemap[type]
context = content.replace('\n', ' ')
if descname and docname.startswith('c-api'):
for changeset in domain.get_changesets_for(version):
if isinstance(changeset.descname, tuple):
descname = changeset.descname[0]
else:
descname = changeset.descname
ttext = self.typemap[changeset.type]
context = changeset.content.replace('\n', ' ')
if descname and changeset.docname.startswith('c-api'):
if context:
entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext,
context)
else:
entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
apichanges.append((entry, docname, lineno))
elif descname or module:
if not module:
apichanges.append((entry, changeset.docname, changeset.lineno))
elif descname or changeset.module:
if not changeset.module:
module = _('Builtins')
if not descname:
descname = _('Module level')
@ -90,15 +94,15 @@ class ChangesBuilder(Builder):
context)
else:
entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
libchanges.setdefault(module, []).append((entry, docname,
lineno))
libchanges.setdefault(module, []).append((entry, changeset.docname,
changeset.lineno))
else:
if not context:
continue
entry = '<i>%s:</i> %s' % (ttext.capitalize(), context)
title = self.env.titles[docname].astext()
otherchanges.setdefault((docname, title), []).append(
(entry, docname, lineno))
title = self.env.titles[changeset.docname].astext()
otherchanges.setdefault((changeset.docname, title), []).append(
(entry, changeset.docname, changeset.lineno))
ctx = {
'project': self.config.project,

View File

@ -36,7 +36,7 @@ from sphinx.deprecation import RemovedInSphinx20Warning, RemovedInSphinx30Warnin
from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.environment.adapters.toctree import TocTree
from sphinx.errors import ThemeError
from sphinx.errors import ConfigError, ThemeError
from sphinx.highlighting import PygmentsBridge
from sphinx.locale import _, __
from sphinx.search import js_index
@ -386,8 +386,7 @@ class StandaloneHTMLBuilder(Builder):
style = self.theme.get_config('theme', 'pygments_style', 'none')
else:
style = 'sphinx'
self.highlighter = PygmentsBridge('html', style,
self.config.trim_doctest_flags)
self.highlighter = PygmentsBridge('html', style)
def init_css_files(self):
# type: () -> None
@ -421,7 +420,7 @@ class StandaloneHTMLBuilder(Builder):
def add_js_file(self, filename, **kwargs):
# type: (unicode, **unicode) -> None
if '://' not in filename:
if filename and '://' not in filename:
filename = posixpath.join('_static', filename)
self.script_files.append(JavaScript(filename, **kwargs)) # type: ignore
@ -438,6 +437,27 @@ class StandaloneHTMLBuilder(Builder):
else:
return HTMLTranslator
@property
def math_renderer_name(self):
# type: () -> unicode
name = self.get_builder_config('math_renderer', 'html')
if name is not None:
# use given name
return name
else:
# not given: choose a math_renderer from registered ones as possible
renderers = list(self.app.registry.html_inline_math_renderers)
if len(renderers) == 1:
# only default math_renderer (mathjax) is registered
return renderers[0]
elif len(renderers) == 2:
# default and another math_renderer are registered; prior the another
renderers.remove('mathjax')
return renderers[0]
else:
# many math_renderers are registered. can't choose automatically!
return None
def get_outdated_docs(self):
# type: () -> Iterator[unicode]
try:
@ -848,85 +868,94 @@ class StandaloneHTMLBuilder(Builder):
try:
copyfile(path.join(self.srcdir, src),
path.join(self.outdir, '_downloads', dest))
except Exception as err:
except EnvironmentError as err:
logger.warning(__('cannot copy downloadable file %r: %s'),
path.join(self.srcdir, src), err)
def copy_static_files(self):
# type: () -> None
# copy static files
logger.info(bold(__('copying static files... ')), nonl=True)
ensuredir(path.join(self.outdir, '_static'))
# first, create pygments style file
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f:
f.write(self.highlighter.get_stylesheet()) # type: ignore
# then, copy translations JavaScript file
if self.config.language is not None:
jsfile = self._get_translations_js()
if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static',
'translations.js'))
try:
# copy static files
logger.info(bold(__('copying static files... ')), nonl=True)
ensuredir(path.join(self.outdir, '_static'))
# first, create pygments style file
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f:
f.write(self.highlighter.get_stylesheet()) # type: ignore
# then, copy translations JavaScript file
if self.config.language is not None:
jsfile = self._get_translations_js()
if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static',
'translations.js'))
# copy non-minified stemmer JavaScript file
if self.indexer is not None:
jsfile = self.indexer.get_js_stemmer_rawcode()
if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static', '_stemmer.js'))
# copy non-minified stemmer JavaScript file
if self.indexer is not None:
jsfile = self.indexer.get_js_stemmer_rawcode()
if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static', '_stemmer.js'))
ctx = self.globalcontext.copy()
ctx = self.globalcontext.copy()
# add context items for search function used in searchtools.js_t
if self.indexer is not None:
ctx.update(self.indexer.context_for_searchtool())
# add context items for search function used in searchtools.js_t
if self.indexer is not None:
ctx.update(self.indexer.context_for_searchtool())
# then, copy over theme-supplied static files
if self.theme:
for theme_path in self.theme.get_theme_dirs()[::-1]:
entry = path.join(theme_path, 'static')
copy_asset(entry, path.join(self.outdir, '_static'), excluded=DOTFILES,
# then, copy over theme-supplied static files
if self.theme:
for theme_path in self.theme.get_theme_dirs()[::-1]:
entry = path.join(theme_path, 'static')
copy_asset(entry, path.join(self.outdir, '_static'), excluded=DOTFILES,
context=ctx, renderer=self.templates)
# then, copy over all user-supplied static files
excluded = Matcher(self.config.exclude_patterns + ["**/.*"])
for static_path in self.config.html_static_path:
entry = path.join(self.confdir, static_path)
if not path.exists(entry):
logger.warning(__('html_static_path entry %r does not exist'), entry)
continue
copy_asset(entry, path.join(self.outdir, '_static'), excluded,
context=ctx, renderer=self.templates)
# then, copy over all user-supplied static files
excluded = Matcher(self.config.exclude_patterns + ["**/.*"])
for static_path in self.config.html_static_path:
entry = path.join(self.confdir, static_path)
if not path.exists(entry):
logger.warning(__('html_static_path entry %r does not exist'), entry)
continue
copy_asset(entry, path.join(self.outdir, '_static'), excluded,
context=ctx, renderer=self.templates)
# copy logo and favicon files if not already in static path
if self.config.html_logo:
logobase = path.basename(self.config.html_logo)
logotarget = path.join(self.outdir, '_static', logobase)
if not path.isfile(path.join(self.confdir, self.config.html_logo)):
logger.warning(__('logo file %r does not exist'), self.config.html_logo)
elif not path.isfile(logotarget):
copyfile(path.join(self.confdir, self.config.html_logo),
logotarget)
if self.config.html_favicon:
iconbase = path.basename(self.config.html_favicon)
icontarget = path.join(self.outdir, '_static', iconbase)
if not path.isfile(path.join(self.confdir, self.config.html_favicon)):
logger.warning(__('favicon file %r does not exist'), self.config.html_favicon)
elif not path.isfile(icontarget):
copyfile(path.join(self.confdir, self.config.html_favicon),
icontarget)
logger.info('done')
# copy logo and favicon files if not already in static path
if self.config.html_logo:
logobase = path.basename(self.config.html_logo)
logotarget = path.join(self.outdir, '_static', logobase)
if not path.isfile(path.join(self.confdir, self.config.html_logo)):
logger.warning(__('logo file %r does not exist'), self.config.html_logo)
elif not path.isfile(logotarget):
copyfile(path.join(self.confdir, self.config.html_logo),
logotarget)
if self.config.html_favicon:
iconbase = path.basename(self.config.html_favicon)
icontarget = path.join(self.outdir, '_static', iconbase)
if not path.isfile(path.join(self.confdir, self.config.html_favicon)):
logger.warning(__('favicon file %r does not exist'),
self.config.html_favicon)
elif not path.isfile(icontarget):
copyfile(path.join(self.confdir, self.config.html_favicon),
icontarget)
logger.info('done')
except EnvironmentError as err:
# TODO: In py3, EnvironmentError (and IOError) was merged into OSError.
# So it should be replaced by IOError on dropping py2 support
logger.warning(__('cannot copy static file %r'), err)
def copy_extra_files(self):
# type: () -> None
# copy html_extra_path files
logger.info(bold(__('copying extra files... ')), nonl=True)
excluded = Matcher(self.config.exclude_patterns)
try:
# copy html_extra_path files
logger.info(bold(__('copying extra files... ')), nonl=True)
excluded = Matcher(self.config.exclude_patterns)
for extra_path in self.config.html_extra_path:
entry = path.join(self.confdir, extra_path)
if not path.exists(entry):
logger.warning(__('html_extra_path entry %r does not exist'), entry)
continue
for extra_path in self.config.html_extra_path:
entry = path.join(self.confdir, extra_path)
if not path.exists(entry):
logger.warning(__('html_extra_path entry %r does not exist'), entry)
continue
copy_asset(entry, self.outdir, excluded)
logger.info(__('done'))
copy_asset(entry, self.outdir, excluded)
logger.info(__('done'))
except EnvironmentError as err:
logger.warning(__('cannot copy extra file %r'), err)
def write_buildinfo(self):
# type: () -> None
@ -1037,7 +1066,8 @@ class StandaloneHTMLBuilder(Builder):
sidebars = [name.strip() for name in theme_default_sidebars.split(',')]
# user sidebar settings
for pattern, patsidebars in iteritems(self.config.html_sidebars):
html_sidebars = self.get_builder_config('sidebars', 'html')
for pattern, patsidebars in iteritems(html_sidebars):
if patmatch(pagename, pattern):
if matched:
if has_wildcard(pattern):
@ -1601,21 +1631,39 @@ def setup_js_tag_helper(app, pagename, templatexname, context, doctree):
def js_tag(js):
# type: (JavaScript) -> unicode
attrs = []
body = '' # type: unicode
if isinstance(js, JavaScript):
for key in sorted(js.attributes):
value = js.attributes[key]
if value is not None:
attrs.append('%s="%s"' % (key, htmlescape(value, True)))
attrs.append('src="%s"' % pathto(js.filename, resource=True))
if key == 'body':
body = value
else:
attrs.append('%s="%s"' % (key, htmlescape(value, True)))
if js.filename:
attrs.append('src="%s"' % pathto(js.filename, resource=True))
else:
# str value (old styled)
attrs.append('type="text/javascript"')
attrs.append('src="%s"' % pathto(js, resource=True))
return '<script %s></script>' % ' '.join(attrs)
return '<script %s>%s</script>' % (' '.join(attrs), body)
context['js_tag'] = js_tag
def validate_math_renderer(app):
# type: (Sphinx) -> None
if app.builder.format != 'html':
return
name = app.builder.math_renderer_name # type: ignore
if name is None:
raise ConfigError(__('Many math_renderers are registered. '
'But no math_renderer is selected.'))
elif name not in app.registry.html_inline_math_renderers:
raise ConfigError(__('Unknown math_renderer %r is given.') % name)
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# builders
@ -1665,12 +1713,19 @@ def setup(app):
app.add_config_value('html_scaled_image_link', True, 'html')
app.add_config_value('html_experimental_html5_writer', None, 'html')
app.add_config_value('html_baseurl', '', 'html')
app.add_config_value('html_math_renderer', None, 'env')
app.add_config_value('singlehtml_sidebars', lambda self: self.html_sidebars, 'html')
# event handlers
app.connect('config-inited', convert_html_css_files)
app.connect('config-inited', convert_html_js_files)
app.connect('builder-inited', validate_math_renderer)
app.connect('html-page-context', setup_js_tag_helper)
# load default math renderer
app.setup_extension('sphinx.ext.mathjax')
return {
'version': 'builtin',
'parallel_read_safe': True,

View File

@ -34,7 +34,7 @@ from sphinx.util.docutils import SphinxFileOutput, new_document
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import SEP, make_filename
from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
from sphinx.writers.latex import DEFAULT_SETTINGS, LaTeXWriter, LaTeXTranslator
if False:
# For type annotation
@ -44,6 +44,67 @@ if False:
from sphinx.config import Config # NOQA
XINDY_LANG_OPTIONS = {
# language codes from docutils.writers.latex2e.Babel
# ! xindy language names may differ from those in use by LaTeX/babel
# ! xindy does not support all Latin scripts as recognized by LaTeX/babel
# ! not all xindy-supported languages appear in Babel.language_codes
# cd /usr/local/texlive/2018/texmf-dist/xindy/modules/lang
# find . -name '*utf8.xdy'
# LATIN
'sq': '-L albanian -C utf8 ',
'hr': '-L croatian -C utf8 ',
'cs': '-L czech -C utf8 ',
'da': '-L danish -C utf8 ',
'nl': '-L dutch -C ij-as-ij-utf8 ',
'en': '-L english -C utf8 ',
'eo': '-L esperanto -C utf8 ',
'et': '-L estonian -C utf8 ',
'fi': '-L finnish -C utf8 ',
'fr': '-L french -C utf8 ',
'de': '-L german -C din5007-utf8 ',
'is': '-L icelandic -C utf8 ',
'it': '-L italian -C utf8 ',
'la': '-L latin -C utf8 ',
'lv': '-L latvian -C utf8 ',
'lt': '-L lithuanian -C utf8 ',
'dsb': '-L lower-sorbian -C utf8 ',
'ds': '-L lower-sorbian -C utf8 ', # trick, no conflict
'nb': '-L norwegian -C utf8 ',
'no': '-L norwegian -C utf8 ', # and what about nynorsk?
'pl': '-L polish -C utf8 ',
'pt': '-L portuguese -C utf8 ',
'ro': '-L romanian -C utf8 ',
'sk': '-L slovak -C small-utf8 ', # there is also slovak-large
'sl': '-L slovenian -C utf8 ',
'es': '-L spanish -C modern-utf8 ', # there is also spanish-traditional
'sv': '-L swedish -C utf8 ',
'tr': '-L turkish -C utf8 ',
'hsb': '-L upper-sorbian -C utf8 ',
'hs': '-L upper-sorbian -C utf8 ', # trick, no conflict
'vi': '-L vietnamese -C utf8 ',
# CYRILLIC
# for usage with pdflatex, needs also cyrLICRutf8.xdy module
'be': '-L belarusian -C utf8 ',
'bg': '-L bulgarian -C utf8 ',
'mk': '-L macedonian -C utf8 ',
'mn': '-L mongolian -C cyrillic-utf8 ',
'ru': '-L russian -C utf8 ',
'sr': '-L serbian -C utf8 ',
'sh-cyrl': '-L serbian -C utf8 ',
'sh': '-L serbian -C utf8 ', # trick, no conflict
'uk': '-L ukrainian -C utf8 ',
# GREEK
# can work only with xelatex/lualatex, not supported by texindy+pdflatex
'el': '-L greek -C utf8 ',
# FIXME, not compatible with [:2] slice but does Sphinx support Greek ?
'el-polyton': '-L greek -C polytonic-utf8 ',
} # type: Dict[unicode, unicode]
XINDY_CYRILLIC_SCRIPTS = [
'be', 'bg', 'mk', 'mn', 'ru', 'sr', 'sh', 'uk',
] # type: List[unicode]
logger = logging.getLogger(__name__)
@ -108,8 +169,7 @@ class LaTeXBuilder(Builder):
def write_stylesheet(self):
# type: () -> None
highlighter = highlighting.PygmentsBridge(
'latex', self.config.pygments_style, self.config.trim_doctest_flags)
highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style)
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
with open(stylesheet, 'w') as f:
f.write('\\NeedsTeXFormat{LaTeX2e}[1995/12/01]\n')
@ -232,7 +292,23 @@ class LaTeXBuilder(Builder):
self.copy_image_files()
# copy TeX support files from texinputs
context = {'latex_engine': self.config.latex_engine}
# configure usage of xindy (impacts Makefile and latexmkrc)
# FIXME: convert this rather to a confval with suitable default
# according to language ? but would require extra documentation
if self.config.language:
xindy_lang_option = \
XINDY_LANG_OPTIONS.get(self.config.language[:2],
'-L general -C utf8 ')
xindy_cyrillic = self.config.language[:2] in XINDY_CYRILLIC_SCRIPTS
else:
xindy_lang_option = '-L english -C utf8 '
xindy_cyrillic = False
context = {
'latex_engine': self.config.latex_engine,
'xindy_use': self.config.latex_use_xindy,
'xindy_lang_option': xindy_lang_option,
'xindy_cyrillic': xindy_cyrillic,
}
logger.info(bold(__('copying TeX support files...')))
staticdirname = path.join(package_dir, 'texinputs')
for filename in os.listdir(staticdirname):
@ -297,6 +373,12 @@ def validate_config_values(app, config):
'Please use u"..." notation instead): %r') % (document,)
)
for key in list(config.latex_elements):
if key not in DEFAULT_SETTINGS:
msg = __("Unknown configure key: latex_elements[%r]. ignored.")
logger.warning(msg % key)
config.latex_elements.pop(key)
def default_latex_engine(config):
# type: (Config) -> unicode
@ -317,6 +399,12 @@ def default_latex_docclass(config):
return {}
def default_latex_use_xindy(config):
# type: (Config) -> bool
""" Better default latex_use_xindy settings for specific engines. """
return config.latex_engine in {'xelatex', 'lualatex'}
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_builder(LaTeXBuilder)
@ -334,6 +422,7 @@ def setup(app):
app.add_config_value('latex_logo', None, None, string_classes)
app.add_config_value('latex_appendices', [], None)
app.add_config_value('latex_use_latex_multicolumn', False, None)
app.add_config_value('latex_use_xindy', default_latex_use_xindy, None)
app.add_config_value('latex_toplevel_sectioning', None, None,
ENUM(None, 'part', 'chapter', 'section'))
app.add_config_value('latex_domain_indices', True, None, [list])

View File

@ -561,7 +561,7 @@ class MathReferenceTransform(SphinxTransform):
equations = self.env.get_domain('math').data['objects']
for node in self.document.traverse(addnodes.pending_xref):
if node['refdomain'] == 'math' and node['reftype'] == 'eq':
if node['refdomain'] == 'math' and node['reftype'] in ('eq', 'numref'):
docname, _ = equations.get(node['reftarget'], (None, None))
if docname:
refnode = math_reference('', docname=docname, target=node['reftarget'])

View File

@ -120,12 +120,15 @@ class CheckExternalLinksBuilder(Builder):
def check_thread(self):
# type: () -> None
kwargs = {}
kwargs = {
'allow_redirects': True,
'headers': {
'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8'
},
}
if self.app.config.linkcheck_timeout:
kwargs['timeout'] = self.app.config.linkcheck_timeout
kwargs['allow_redirects'] = True
def check_uri():
# type: () -> Tuple[unicode, unicode, int]
# split off anchor
@ -160,7 +163,7 @@ class CheckExternalLinksBuilder(Builder):
# the server and the network
response = requests.head(req_url, config=self.app.config, **kwargs)
response.raise_for_status()
except HTTPError as err:
except HTTPError:
# retry with GET request if that fails, some servers
# don't like HEAD requests.
response = requests.get(req_url, stream=True, config=self.app.config,

View File

@ -140,7 +140,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
else:
nspace = 'org.sphinx.%s.%s' % (outname, self.config.version)
nspace = re.sub('[^a-zA-Z0-9.]', '', nspace)
nspace = re.sub(r'[^a-zA-Z0-9.\-]', '', nspace)
nspace = re.sub(r'\.+', '.', nspace).strip('.')
nspace = nspace.lower()

View File

@ -189,6 +189,8 @@ files can be built by specifying individual filenames.
help=__('write warnings (and errors) to given file'))
group.add_argument('-W', action='store_true', dest='warningiserror',
help=__('turn warnings into errors'))
group.add_argument('--keep-going', action='store_true', dest='keep_going',
help=__("With -W, Keep going when getting warnings"))
group.add_argument('-T', action='store_true', dest='traceback',
help=__('show full traceback on exception'))
group.add_argument('-P', action='store_true', dest='pdb',
@ -200,7 +202,7 @@ files can be built by specifying individual filenames.
def make_main(argv=sys.argv[1:]): # type: ignore
# type: (List[unicode]) -> int
"""Sphinx build "make mode" entry."""
from sphinx import make_mode
from sphinx.cmd import make_mode
return make_mode.run_make_mode(argv[1:])
@ -298,7 +300,7 @@ def build_main(argv=sys.argv[1:]): # type: ignore
app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
args.doctreedir, args.builder, confoverrides, status,
warning, args.freshenv, args.warningiserror,
args.tags, args.verbosity, args.jobs)
args.tags, args.verbosity, args.jobs, args.keep_going)
app.build(args.force_all, filenames)
return app.statuscode
except (Exception, KeyboardInterrupt) as exc:
@ -311,7 +313,7 @@ def main(argv=sys.argv[1:]): # type: ignore
locale.setlocale(locale.LC_ALL, '')
sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx')
if sys.argv[1:2] == ['-M']:
if argv[:1] == ['-M']:
return make_main(argv)
else:
return build_main(argv)

175
sphinx/cmd/make_mode.py Normal file
View File

@ -0,0 +1,175 @@
# -*- coding: utf-8 -*-
"""
sphinx.cmd.make_mode
~~~~~~~~~~~~~~~~~~~~
sphinx-build -M command-line handling.
This replaces the old, platform-dependent and once-generated content
of Makefile / make.bat.
This is in its own module so that importing it is fast. It should not
import the main Sphinx modules (like sphinx.applications, sphinx.builders).
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
import os
import subprocess
import sys
from os import path
import sphinx
from sphinx.cmd.build import build_main
from sphinx.util.console import color_terminal, nocolor, bold, blue # type: ignore
from sphinx.util.osutil import cd, rmtree
if False:
# For type annotation
from typing import List # NOQA
BUILDERS = [
("", "html", "to make standalone HTML files"),
("", "dirhtml", "to make HTML files named index.html in directories"),
("", "singlehtml", "to make a single large HTML file"),
("", "pickle", "to make pickle files"),
("", "json", "to make JSON files"),
("", "htmlhelp", "to make HTML files and an HTML help project"),
("", "qthelp", "to make HTML files and a qthelp project"),
("", "devhelp", "to make HTML files and a Devhelp project"),
("", "epub", "to make an epub"),
("", "latex", "to make LaTeX files, you can set PAPER=a4 or PAPER=letter"),
("posix", "latexpdf", "to make LaTeX and PDF files (default pdflatex)"),
("posix", "latexpdfja", "to make LaTeX files and run them through platex/dvipdfmx"),
("", "text", "to make text files"),
("", "man", "to make manual pages"),
("", "texinfo", "to make Texinfo files"),
("posix", "info", "to make Texinfo files and run them through makeinfo"),
("", "gettext", "to make PO message catalogs"),
("", "changes", "to make an overview of all changed/added/deprecated items"),
("", "xml", "to make Docutils-native XML files"),
("", "pseudoxml", "to make pseudoxml-XML files for display purposes"),
("", "linkcheck", "to check all external links for integrity"),
("", "doctest", "to run all doctests embedded in the documentation "
"(if enabled)"),
("", "coverage", "to run coverage check of the documentation (if enabled)"),
]
class Make(object):
def __init__(self, srcdir, builddir, opts):
# type: (unicode, unicode, List[unicode]) -> None
self.srcdir = srcdir
self.builddir = builddir
self.opts = opts
self.makecmd = os.environ.get('MAKE', 'make') # refer $MAKE to determine make command
def builddir_join(self, *comps):
# type: (unicode) -> unicode
return path.join(self.builddir, *comps)
def build_clean(self):
# type: () -> int
if not path.exists(self.builddir):
return 0
elif not path.isdir(self.builddir):
print("Error: %r is not a directory!" % self.builddir)
return 1
print("Removing everything under %r..." % self.builddir)
for item in os.listdir(self.builddir):
rmtree(self.builddir_join(item))
return 0
def build_help(self):
# type: () -> None
if not color_terminal():
nocolor()
print(bold("Sphinx v%s" % sphinx.__display_version__))
print("Please use `make %s' where %s is one of" % ((blue('target'),) * 2)) # type: ignore # NOQA
for osname, bname, description in BUILDERS:
if not osname or os.name == osname:
print(' %s %s' % (blue(bname.ljust(10)), description))
def build_latexpdf(self):
# type: () -> int
if self.run_generic_build('latex') > 0:
return 1
if sys.platform == 'win32':
makecmd = os.environ.get('MAKE', 'make.bat')
else:
makecmd = self.makecmd
try:
with cd(self.builddir_join('latex')):
return subprocess.call([makecmd, 'all-pdf'])
except OSError:
print('Error: Failed to run: %s' % makecmd)
return 1
def build_latexpdfja(self):
# type: () -> int
if self.run_generic_build('latex') > 0:
return 1
if sys.platform == 'win32':
makecmd = os.environ.get('MAKE', 'make.bat')
else:
makecmd = self.makecmd
try:
with cd(self.builddir_join('latex')):
return subprocess.call([makecmd, 'all-pdf'])
except OSError:
print('Error: Failed to run: %s' % makecmd)
return 1
def build_info(self):
# type: () -> int
if self.run_generic_build('texinfo') > 0:
return 1
try:
with cd(self.builddir_join('texinfo')):
return subprocess.call([self.makecmd, 'info'])
except OSError:
print('Error: Failed to run: %s' % self.makecmd)
return 1
def build_gettext(self):
# type: () -> int
dtdir = self.builddir_join('gettext', '.doctrees')
if self.run_generic_build('gettext', doctreedir=dtdir) > 0:
return 1
return 0
def run_generic_build(self, builder, doctreedir=None):
# type: (unicode, unicode) -> int
# compatibility with old Makefile
papersize = os.getenv('PAPER', '')
opts = self.opts
if papersize in ('a4', 'letter'):
opts.extend(['-D', 'latex_elements.papersize=' + papersize + 'paper'])
if doctreedir is None:
doctreedir = self.builddir_join('doctrees')
args = ['-b', builder,
'-d', doctreedir,
self.srcdir,
self.builddir_join(builder)]
return build_main(args + opts)
def run_make_mode(args):
# type: (List[unicode]) -> int
if len(args) < 3:
print('Error: at least 3 arguments (builder, source '
'dir, build dir) are required.', file=sys.stderr)
return 1
make = Make(args[1], args[2], args[3:])
run_method = 'build_' + args[0]
if hasattr(make, run_method):
return getattr(make, run_method)()
return make.run_generic_build(args[0])

View File

@ -74,13 +74,18 @@ DEFAULTS = {
'language': None,
'suffix': '.rst',
'master': 'index',
'epub': False,
'makefile': True,
'batchfile': True,
}
PROMPT_PREFIX = '> '
if sys.platform == 'win32':
# On Windows, show questions as bold because of color scheme of PowerShell (refs: #5294).
COLOR_QUESTION = 'bold'
else:
COLOR_QUESTION = 'purple'
# function to get input from terminal -- overridden by the test suite
def term_input(prompt):
@ -192,7 +197,7 @@ def do_prompt(text, default=None, validator=nonempty):
prompt = prompt.encode('utf-8')
except UnicodeEncodeError:
prompt = prompt.encode('latin1')
prompt = colorize('purple', prompt, input_mode=True)
prompt = colorize(COLOR_QUESTION, prompt, input_mode=True)
x = term_input(prompt).strip()
if default and not x:
x = default
@ -246,7 +251,6 @@ def ask_user(d):
* language: document language
* suffix: source file suffix
* master: master document name
* epub: use epub (bool)
* extensions: extensions to use (list)
* makefile: make Makefile
* batchfile: make command file
@ -347,12 +351,6 @@ document is a custom template, you can also set this to another filename.'''))
d['master'] = do_prompt(__('Please enter a new file name, or rename the '
'existing file and press Enter'), d['master'])
if 'epub' not in d:
print(__('''
Sphinx can also add configuration for epub output:'''))
d['epub'] = do_prompt(__('Do you want to use the epub builder (y/n)'),
'n', boolean)
if 'extensions' not in d:
print(__('Indicate which of the following Sphinx extensions should be '
'enabled:'))

View File

@ -49,10 +49,6 @@ ConfigValue = NamedTuple('ConfigValue', [('name', str),
('rebuild', Union[bool, unicode])])
#: represents the config value accepts any type of value.
Any = object()
class ENUM(object):
"""represents the config value should be a one of candidates.
@ -129,7 +125,7 @@ class Config(object):
rst_epilog = (None, 'env', string_classes),
rst_prolog = (None, 'env', string_classes),
trim_doctest_flags = (True, 'env', []),
primary_domain = ('py', 'env', [NoneType]),
primary_domain = ('py', 'env', [NoneType]), # type: ignore
needs_sphinx = (None, None, string_classes),
needs_extensions = ({}, None, []),
manpages_url = (None, 'env', []),

View File

@ -17,8 +17,8 @@ from docutils.parsers.rst.directives.misc import Class
from docutils.parsers.rst.directives.misc import Include as BaseInclude
from six.moves import range
from sphinx import addnodes, locale
from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning
from sphinx import addnodes
from sphinx.domains.changeset import VersionChange # NOQA # for compatibility
from sphinx.locale import _
from sphinx.util import url_re, docname_join
from sphinx.util.docutils import SphinxDirective
@ -32,20 +32,7 @@ if False:
from sphinx.application import Sphinx # NOQA
versionlabels = {
'versionadded': _('New in version %s'),
'versionchanged': _('Changed in version %s'),
'deprecated': _('Deprecated since version %s'),
} # type: Dict[unicode, unicode]
locale.versionlabels = DeprecatedDict(
versionlabels,
'sphinx.locale.versionlabels is deprecated. '
'Please use sphinx.directives.other.versionlabels instead.',
RemovedInSphinx30Warning
)
glob_re = re.compile('.*[*?\[].*')
glob_re = re.compile(r'.*[*?\[].*')
def int_or_nothing(argument):
@ -218,54 +205,6 @@ class Index(SphinxDirective):
return [indexnode, targetnode]
class VersionChange(SphinxDirective):
"""
Directive to describe a change/addition/deprecation in a specific version.
"""
has_content = True
required_arguments = 1
optional_arguments = 1
final_argument_whitespace = True
option_spec = {} # type: Dict
def run(self):
# type: () -> List[nodes.Node]
node = addnodes.versionmodified()
node.document = self.state.document
set_source_info(self, node)
node['type'] = self.name
node['version'] = self.arguments[0]
text = versionlabels[self.name] % self.arguments[0]
if len(self.arguments) == 2:
inodes, messages = self.state.inline_text(self.arguments[1],
self.lineno + 1)
para = nodes.paragraph(self.arguments[1], '', *inodes, translatable=False)
set_source_info(self, para)
node.append(para)
else:
messages = []
if self.content:
self.state.nested_parse(self.content, self.content_offset, node)
if len(node):
if isinstance(node[0], nodes.paragraph) and node[0].rawsource:
content = nodes.inline(node[0].rawsource, translatable=True)
content.source = node[0].source
content.line = node[0].line
content += node[0].children
node[0].replace_self(nodes.paragraph('', '', content, translatable=False))
node[0].insert(0, nodes.inline('', '%s: ' % text,
classes=['versionmodified']))
else:
para = nodes.paragraph('', '',
nodes.inline('', '%s.' % text,
classes=['versionmodified']),
translatable=False)
node.append(para)
# XXX should record node.source as well
self.env.note_versionchange(node['type'], node['version'], node, node.line)
return [node] + messages
class SeeAlso(BaseAdmonition):
"""
An admonition mentioning things to look at as reference.
@ -475,9 +414,6 @@ def setup(app):
directives.register_directive('moduleauthor', Author)
directives.register_directive('codeauthor', Author)
directives.register_directive('index', Index)
directives.register_directive('deprecated', VersionChange)
directives.register_directive('versionadded', VersionChange)
directives.register_directive('versionchanged', VersionChange)
directives.register_directive('seealso', SeeAlso)
directives.register_directive('tabularcolumns', TabularColumns)
directives.register_directive('centered', Centered)

159
sphinx/domains/changeset.py Normal file
View File

@ -0,0 +1,159 @@
# -*- coding: utf-8 -*-
"""
sphinx.domains.changeset
~~~~~~~~~~~~~~~~~~~~~~~~
The changeset domain.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from typing import NamedTuple
from docutils import nodes
from six import iteritems
from sphinx import addnodes
from sphinx import locale
from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning
from sphinx.domains import Domain
from sphinx.locale import _
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
if False:
# For type annotation
from typing import Any, Dict, List # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.environment import BuildEnvironment # NOQA
versionlabels = {
'versionadded': _('New in version %s'),
'versionchanged': _('Changed in version %s'),
'deprecated': _('Deprecated since version %s'),
} # type: Dict[unicode, unicode]
locale.versionlabels = DeprecatedDict(
versionlabels,
'sphinx.locale.versionlabels is deprecated. '
'Please use sphinx.domains.changeset.versionlabels instead.',
RemovedInSphinx30Warning
)
ChangeSet = NamedTuple('ChangeSet', [('type', str),
('docname', str),
('lineno', int),
('module', str),
('descname', str),
('content', str)])
class VersionChange(SphinxDirective):
"""
Directive to describe a change/addition/deprecation in a specific version.
"""
has_content = True
required_arguments = 1
optional_arguments = 1
final_argument_whitespace = True
option_spec = {} # type: Dict
def run(self):
# type: () -> List[nodes.Node]
node = addnodes.versionmodified()
node.document = self.state.document
set_source_info(self, node)
node['type'] = self.name
node['version'] = self.arguments[0]
text = versionlabels[self.name] % self.arguments[0]
if len(self.arguments) == 2:
inodes, messages = self.state.inline_text(self.arguments[1],
self.lineno + 1)
para = nodes.paragraph(self.arguments[1], '', *inodes, translatable=False)
set_source_info(self, para)
node.append(para)
else:
messages = []
if self.content:
self.state.nested_parse(self.content, self.content_offset, node)
if len(node):
if isinstance(node[0], nodes.paragraph) and node[0].rawsource:
content = nodes.inline(node[0].rawsource, translatable=True)
content.source = node[0].source
content.line = node[0].line
content += node[0].children
node[0].replace_self(nodes.paragraph('', '', content, translatable=False))
node[0].insert(0, nodes.inline('', '%s: ' % text,
classes=['versionmodified']))
else:
para = nodes.paragraph('', '',
nodes.inline('', '%s.' % text,
classes=['versionmodified']),
translatable=False)
node.append(para)
self.env.get_domain('changeset').note_changeset(node) # type: ignore
return [node] + messages
class ChangeSetDomain(Domain):
"""Domain for changesets."""
name = 'changeset'
label = 'changeset'
initial_data = {
'changes': {}, # version -> list of ChangeSet
} # type: Dict
def clear_doc(self, docname):
# type: (unicode) -> None
for version, changes in iteritems(self.data['changes']):
for changeset in changes[:]:
if changeset.docname == docname:
changes.remove(changeset)
def merge_domaindata(self, docnames, otherdata):
# type: (List[unicode], Dict) -> None
# XXX duplicates?
for version, otherchanges in iteritems(otherdata['changes']):
changes = self.data['changes'].setdefault(version, [])
for changeset in otherchanges:
if changeset.docname in docnames:
changes.append(changeset)
def process_doc(self, env, docname, document):
# type: (BuildEnvironment, unicode, nodes.Node) -> None
pass # nothing to do here. All changesets are registered on calling directive.
def note_changeset(self, node):
# type: (nodes.Node) -> None
version = node['version']
module = self.env.ref_context.get('py:module')
objname = self.env.temp_data.get('object')
changeset = ChangeSet(node['type'], self.env.docname, node.line, # type: ignore
module, objname, node.astext())
self.data['changes'].setdefault(version, []).append(changeset)
def get_changesets_for(self, version):
# type: (unicode) -> List[ChangeSet]
return self.data['changes'].get(version, [])
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_domain(ChangeSetDomain)
app.add_directive('deprecated', VersionChange)
app.add_directive('versionadded', VersionChange)
app.add_directive('versionchanged', VersionChange)
return {
'version': 'builtin',
'env_version': 1,
'parallel_read_safe': True,
'parallel_write_safe': True,
}

File diff suppressed because it is too large Load Diff

View File

@ -21,10 +21,11 @@ from sphinx.util.nodes import make_refnode
if False:
# For type annotation
from typing import Any, Callable, Dict, Iterable, List, Tuple # NOQA
from typing import Any, Callable, Dict, Iterable, List, Tuple, Union # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.builders import Builder # NOQA
from sphinx.environment import BuildEnvironment # NOQA
from sphinx.util.typing import RoleFunction # NOQA
logger = logging.getLogger(__name__)
@ -51,6 +52,9 @@ class MathDomain(Domain):
displaymath: ('displaymath', None),
nodes.math_block: ('displaymath', None),
} # type: Dict[nodes.Node, Tuple[unicode, Callable]]
roles = {
'numref': MathReferenceRole(),
}
def clear_doc(self, docname):
# type: (unicode) -> None
@ -66,7 +70,7 @@ class MathDomain(Domain):
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
# type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA
assert typ == 'eq'
assert typ in ('eq', 'numref')
docname, number = self.data['objects'].get(target, (None, None))
if docname:
# TODO: perhaps use rather a sphinx-core provided prefix here?

View File

@ -168,7 +168,15 @@ class PyXrefMixin(object):
class PyField(PyXrefMixin, Field):
pass
def make_xref(self, rolename, domain, target,
innernode=nodes.emphasis, contnode=None, env=None):
# type: (unicode, unicode, unicode, nodes.Node, nodes.Node, BuildEnvironment) -> nodes.Node # NOQA
if rolename == 'class' and target == 'None':
# None is not a type, so use obj role instead.
rolename = 'obj'
return super(PyField, self).make_xref(rolename, domain, target,
innernode, contnode, env)
class PyGroupedField(PyXrefMixin, GroupedField):

View File

@ -25,7 +25,7 @@ from sphinx import addnodes
from sphinx.deprecation import RemovedInSphinx20Warning, RemovedInSphinx30Warning
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.environment.adapters.toctree import TocTree
from sphinx.errors import SphinxError, BuildEnvironmentError, ExtensionError
from sphinx.errors import SphinxError, BuildEnvironmentError, DocumentError, ExtensionError
from sphinx.locale import __
from sphinx.transforms import SphinxTransformer
from sphinx.util import get_matching_docs, FilenameUniqDict
@ -186,9 +186,6 @@ class BuildEnvironment(object):
self.indexentries = {} # type: Dict[unicode, List[Tuple[unicode, unicode, unicode, unicode, unicode]]] # NOQA
# docname -> list of
# (type, unicode, target, aliasname)
self.versionchanges = {} # type: Dict[unicode, List[Tuple[unicode, unicode, int, unicode, unicode, unicode]]] # NOQA
# version -> list of (type, docname,
# lineno, module, descname, content)
# these map absolute path -> (docnames, unique filename)
self.images = FilenameUniqDict() # type: FilenameUniqDict
@ -319,10 +316,7 @@ class BuildEnvironment(object):
if docname in self.all_docs:
self.all_docs.pop(docname, None)
self.reread_always.discard(docname)
for version, changes in self.versionchanges.items():
new = [change for change in changes if change[1] != docname]
changes[:] = new
self.included.discard(docname)
for domain in self.domains.values():
domain.clear_doc(docname)
@ -340,9 +334,8 @@ class BuildEnvironment(object):
if docname in other.reread_always:
self.reread_always.add(docname)
for version, changes in other.versionchanges.items():
self.versionchanges.setdefault(version, []).extend(
change for change in changes if change[1] in docnames)
for docname in other.included:
self.included.add(docname)
for domainname, domain in self.domains.items():
domain.merge_domaindata(docnames, other.domaindata[domainname])
@ -416,37 +409,40 @@ class BuildEnvironment(object):
"""Find all source files in the source dir and put them in
self.found_docs.
"""
matchers = compile_matchers(
config.exclude_patterns[:] +
config.templates_path +
builder.get_asset_paths() +
['**/_sources', '.#*', '**/.#*', '*.lproj/**']
)
self.found_docs = set()
for docname in get_matching_docs(self.srcdir, config.source_suffix, # type: ignore
exclude_matchers=matchers):
if os.access(self.doc2path(docname), os.R_OK):
self.found_docs.add(docname)
else:
logger.warning(__("document not readable. Ignored."), location=docname)
try:
matchers = compile_matchers(
config.exclude_patterns[:] +
config.templates_path +
builder.get_asset_paths() +
['**/_sources', '.#*', '**/.#*', '*.lproj/**']
)
self.found_docs = set()
for docname in get_matching_docs(self.srcdir, config.source_suffix, # type: ignore
exclude_matchers=matchers):
if os.access(self.doc2path(docname), os.R_OK):
self.found_docs.add(docname)
else:
logger.warning(__("document not readable. Ignored."), location=docname)
# Current implementation is applying translated messages in the reading
# phase.Therefore, in order to apply the updated message catalog, it is
# necessary to re-process from the reading phase. Here, if dependency
# is set for the doc source and the mo file, it is processed again from
# the reading phase when mo is updated. In the future, we would like to
# move i18n process into the writing phase, and remove these lines.
if builder.use_message_catalog:
# add catalog mo file dependency
for docname in self.found_docs:
catalog_files = find_catalog_files(
docname,
self.srcdir,
self.config.locale_dirs,
self.config.language,
self.config.gettext_compact)
for filename in catalog_files:
self.dependencies[docname].add(filename)
# Current implementation is applying translated messages in the reading
# phase.Therefore, in order to apply the updated message catalog, it is
# necessary to re-process from the reading phase. Here, if dependency
# is set for the doc source and the mo file, it is processed again from
# the reading phase when mo is updated. In the future, we would like to
# move i18n process into the writing phase, and remove these lines.
if builder.use_message_catalog:
# add catalog mo file dependency
for docname in self.found_docs:
catalog_files = find_catalog_files(
docname,
self.srcdir,
self.config.locale_dirs,
self.config.language,
self.config.gettext_compact)
for filename in catalog_files:
self.dependencies[docname].add(filename)
except EnvironmentError as exc:
raise DocumentError(__('Failed to scan documents in %s: %r') % (self.srcdir, exc))
def get_outdated_files(self, config_changed):
# type: (bool) -> Tuple[Set[unicode], Set[unicode], Set[unicode]]
@ -565,13 +561,6 @@ class BuildEnvironment(object):
"""
self.reread_always.add(self.docname)
def note_versionchange(self, type, version, node, lineno):
# type: (unicode, unicode, nodes.Node, int) -> None
self.versionchanges.setdefault(version, []).append(
(type, self.temp_data['docname'], lineno,
self.ref_context.get('py:module'),
self.temp_data.get('object'), node.astext()))
def note_toctree(self, docname, toctreenode):
# type: (unicode, addnodes.toctree) -> None
"""Note a TOC tree directive in a document and gather information about
@ -851,3 +840,21 @@ class BuildEnvironment(object):
RemovedInSphinx30Warning)
with open(filename, 'wb') as f:
self.dump(self, f)
@property
def versionchanges(self):
# type: () -> Dict[unicode, List[Tuple[unicode, unicode, int, unicode, unicode, unicode]]] # NOQA
warnings.warn('env.versionchanges() is deprecated. '
'Please use ChangeSetDomain instead.',
RemovedInSphinx30Warning)
return self.domaindata['changeset']['changes']
def note_versionchange(self, type, version, node, lineno):
# type: (unicode, unicode, nodes.Node, int) -> None
warnings.warn('env.note_versionchange() is deprecated. '
'Please use ChangeSetDomain.note_changeset() instead.',
RemovedInSphinx30Warning)
node['type'] = type
node['version'] = version
node.line = lineno
self.get_domain('changeset').note_changeset(node) # type: ignore

View File

@ -82,6 +82,11 @@ class ConfigError(SphinxError):
category = 'Configuration error'
class DocumentError(SphinxError):
"""Document error."""
category = 'Document error'
class ThemeError(SphinxError):
"""Theme error."""
category = 'Theme error'

View File

@ -15,6 +15,7 @@ import inspect
import re
import sys
import warnings
from typing import Any
from docutils.statemachine import ViewList
from six import iteritems, itervalues, text_type, class_types, string_types
@ -32,7 +33,7 @@ from sphinx.util import rpartition, force_decode
from sphinx.util.docstrings import prepare_docstring
from sphinx.util.inspect import Signature, isdescriptor, safe_getmembers, \
safe_getattr, object_description, is_builtin_class_method, \
isenumattribute, isclassmethod, isstaticmethod, getdoc
isenumattribute, isclassmethod, isstaticmethod, isfunction, isbuiltin, ispartial, getdoc
if False:
# For type annotation
@ -41,6 +42,7 @@ if False:
from docutils import nodes # NOQA
from docutils.utils import Reporter # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.config import Config # NOQA
from sphinx.environment import BuildEnvironment # NOQA
from sphinx.ext.autodoc.directive import DocumenterBridge # NOQA
@ -399,7 +401,9 @@ class Documenter(object):
return True
modname = self.get_attr(self.object, '__module__', None)
if modname and modname != self.modname:
if ispartial(self.object) and modname == '_functools': # for pypy
return True
elif modname and modname != self.modname:
return False
return True
@ -473,9 +477,8 @@ class Documenter(object):
def get_doc(self, encoding=None, ignore=1):
# type: (unicode, int) -> List[List[unicode]]
"""Decode and return lines of the docstring(s) for the object."""
docstring = self.get_attr(self.object, '__doc__', None)
if docstring is None and self.env.config.autodoc_inherit_docstrings:
docstring = getdoc(self.object)
docstring = getdoc(self.object, self.get_attr,
self.env.config.autodoc_inherit_docstrings)
# make sure we have Unicode docstrings, then sanitize and split
# into lines
if isinstance(docstring, text_type):
@ -599,9 +602,7 @@ class Documenter(object):
# if isattr is True, the member is documented as an attribute
isattr = False
doc = self.get_attr(member, '__doc__', None)
if doc is None and self.env.config.autodoc_inherit_docstrings:
doc = getdoc(member)
doc = getdoc(member, self.get_attr, self.env.config.autodoc_inherit_docstrings)
# if the member __doc__ is the same as self's __doc__, it's just
# inherited and therefore not the member's doc
@ -679,8 +680,13 @@ class Documenter(object):
# remove members given by exclude-members
if self.options.exclude_members:
members = [(membername, member) for (membername, member) in members
if membername not in self.options.exclude_members]
members = [
(membername, member) for (membername, member) in members
if (
self.options.exclude_members is ALL or
membername not in self.options.exclude_members
)
]
# document non-skipped members
memberdocumenters = [] # type: List[Tuple[Documenter, bool]]
@ -1022,12 +1028,11 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
# type: (Any, unicode, bool, Any) -> bool
return inspect.isfunction(member) or inspect.isbuiltin(member)
return isfunction(member) or isbuiltin(member)
def format_args(self):
# type: () -> unicode
if inspect.isbuiltin(self.object) or \
inspect.ismethoddescriptor(self.object):
if isbuiltin(self.object) or inspect.ismethoddescriptor(self.object):
# cannot introspect arguments of a C function or method
return None
try:
@ -1095,7 +1100,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
# __init__ written in C?
if initmeth is None or \
is_builtin_class_method(self.object, '__init__') or \
not(inspect.ismethod(initmeth) or inspect.isfunction(initmeth)):
not(inspect.ismethod(initmeth) or isfunction(initmeth)):
return None
try:
return Signature(initmeth, bound_method=True, has_retval=False).format_args()
@ -1265,6 +1270,11 @@ class DataDocumenter(ModuleLevelDocumenter):
# type: (bool) -> None
pass
def get_real_modname(self):
# type: () -> str
return self.get_attr(self.parent or self.object, '__module__', None) \
or self.modname
class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore
"""
@ -1305,8 +1315,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
def format_args(self):
# type: () -> unicode
if inspect.isbuiltin(self.object) or \
inspect.ismethoddescriptor(self.object):
if isbuiltin(self.object) or inspect.ismethoddescriptor(self.object):
# can never get arguments of a C function or method
return None
if isstaticmethod(self.object, cls=self.parent, name=self.object_name):
@ -1338,7 +1347,7 @@ class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter):
@staticmethod
def is_function_or_method(obj):
# type: (Any) -> bool
return inspect.isfunction(obj) or inspect.isbuiltin(obj) or inspect.ismethod(obj)
return isfunction(obj) or isbuiltin(obj) or inspect.ismethod(obj)
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
@ -1523,6 +1532,34 @@ def autodoc_attrgetter(app, obj, name, *defargs):
return safe_getattr(obj, name, *defargs)
def convert_autodoc_default_flags(app, config):
# type: (Sphinx, Config) -> None
"""This converts the old list-of-flags (strings) to a dict of Nones."""
if isinstance(config.autodoc_default_flags, dict):
# Already new-style
return
elif not isinstance(config.autodoc_default_flags, list):
# Not old-style list
logger.error(
__("autodoc_default_flags is invalid type %r"),
config.autodoc_default_flags.__class__.__name__
)
return
autodoc_default_flags = {} # type: Dict[unicode, Any]
for option in config.autodoc_default_flags:
if isinstance(option, string_types):
autodoc_default_flags[option] = None
else:
logger.warning(
__("Ignoring invalid option in autodoc_default_flags: %r"),
option
)
config.autodoc_default_flags = autodoc_default_flags # type: ignore
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_autodocumenter(ModuleDocumenter)
@ -1536,7 +1573,7 @@ def setup(app):
app.add_config_value('autoclass_content', 'class', True)
app.add_config_value('autodoc_member_order', 'alphabetic', True)
app.add_config_value('autodoc_default_flags', [], True)
app.add_config_value('autodoc_default_flags', {}, True, Any)
app.add_config_value('autodoc_docstring_signature', True, True)
app.add_config_value('autodoc_mock_imports', [], True)
app.add_config_value('autodoc_warningiserror', True, True)
@ -1545,4 +1582,6 @@ def setup(app):
app.add_event('autodoc-process-signature')
app.add_event('autodoc-skip-member')
app.connect('config-inited', convert_autodoc_default_flags)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -31,7 +31,7 @@ logger = logging.getLogger(__name__)
# common option names for autodoc directives
AUTODOC_DEFAULT_OPTIONS = ['members', 'undoc-members', 'inherited-members',
'show-inheritance', 'private-members', 'special-members',
'ignore-module-all']
'ignore-module-all', 'exclude-members']
class DummyOptionSpec(object):
@ -68,7 +68,7 @@ def process_documenter_options(documenter, config, options):
else:
negated = options.pop('no-' + name, True) is None
if name in config.autodoc_default_flags and not negated:
options[name] = None
options[name] = config.autodoc_default_flags[name]
return Options(assemble_option_dict(options.items(), documenter.option_spec))

View File

@ -167,8 +167,21 @@ def import_object(modname, objpath, objtype='', attrgetter=safe_getattr, warning
logger.debug('[autodoc] import %s', modname)
try:
module = import_module(modname, warningiserror=warningiserror)
logger.debug('[autodoc] => %r', module)
module = None
objpath = list(objpath)
while module is None:
try:
module = import_module(modname, warningiserror=warningiserror)
logger.debug('[autodoc] import %s => %r', modname, module)
except ImportError:
logger.debug('[autodoc] import %s => failed', modname)
if '.' in modname:
# retry with parent module
modname, name = modname.rsplit('.', 1)
objpath.insert(0, name)
else:
raise
obj = module
parent = None
object_name = None
@ -221,12 +234,21 @@ def get_object_members(subject, objpath, attrgetter, analyzer=None):
for name, value in subject.__members__.items():
obj_dict[name] = value
members = {}
members = {} # type: Dict[str, Attribute]
# enum members
if isenumclass(subject):
for name, value in subject.__members__.items():
if name not in members:
members[name] = Attribute(name, True, value)
# other members
for name in dir(subject):
try:
value = attrgetter(subject, name)
directly_defined = name in obj_dict
members[name] = Attribute(name, directly_defined, value)
if name not in members:
members[name] = Attribute(name, directly_defined, value)
except AttributeError:
continue

View File

@ -130,8 +130,11 @@ def formatargspec(function, args, varargs=None, varkw=None, defaults=None,
else:
return value
introspected_hints = (typing.get_type_hints(function) # type: ignore
if typing and hasattr(function, '__code__') else {})
try:
introspected_hints = (typing.get_type_hints(function) # type: ignore
if typing and hasattr(function, '__code__') else {})
except Exception:
introspected_hints = {}
fd = StringIO()
fd.write('(')

View File

@ -78,7 +78,9 @@ from sphinx.ext.autodoc.importer import import_module
from sphinx.locale import __
from sphinx.pycode import ModuleAnalyzer, PycodeError
from sphinx.util import import_object, rst, logging
from sphinx.util.docutils import NullReporter, SphinxDirective, new_document
from sphinx.util.docutils import (
NullReporter, SphinxDirective, new_document, switch_source_input
)
if False:
# For type annotation
@ -92,6 +94,7 @@ logger = logging.getLogger(__name__)
periods_re = re.compile(r'\.(?:\s+)')
literal_re = re.compile(r'::\s*$')
# -- autosummary_toc node ------------------------------------------------------
@ -373,17 +376,19 @@ class Autosummary(SphinxDirective):
def append_row(*column_texts):
# type: (unicode) -> None
row = nodes.row('')
source, line = self.state_machine.get_source_and_line()
for text in column_texts:
node = nodes.paragraph('')
vl = ViewList()
vl.append(text, '<autosummary>')
self.state.nested_parse(vl, 0, node)
try:
if isinstance(node[0], nodes.paragraph):
node = node[0]
except IndexError:
pass
row.append(nodes.entry('', node))
vl.append(text, '%s:%d:<autosummary>' % (source, line))
with switch_source_input(self.state, vl):
self.state.nested_parse(vl, 0, node)
try:
if isinstance(node[0], nodes.paragraph):
node = node[0]
except IndexError:
pass
row.append(nodes.entry('', node))
body.append(row)
for name, sig, summary, real_name in items:
@ -468,21 +473,35 @@ def extract_summary(doc, document):
doc = doc[:i]
break
# Try to find the "first sentence", which may span multiple lines
sentences = periods_re.split(" ".join(doc)) # type: ignore
if len(sentences) == 1:
summary = sentences[0].strip()
if doc == []:
return ''
# parse the docstring
state_machine = RSTStateMachine(state_classes, 'Body')
node = new_document('', document.settings)
node.reporter = NullReporter()
state_machine.run(doc, node)
if not isinstance(node[0], nodes.paragraph):
# document starts with non-paragraph: pick up the first line
summary = doc[0].strip()
else:
summary = ''
state_machine = RSTStateMachine(state_classes, 'Body')
while sentences:
summary += sentences.pop(0) + '.'
node = new_document('', document.settings)
node.reporter = NullReporter()
state_machine.run([summary], node)
if not node.traverse(nodes.system_message):
# considered as that splitting by period does not break inline markups
break
# Try to find the "first sentence", which may span multiple lines
sentences = periods_re.split(" ".join(doc)) # type: ignore
if len(sentences) == 1:
summary = sentences[0].strip()
else:
summary = ''
while sentences:
summary += sentences.pop(0) + '.'
node[:] = []
state_machine.run([summary], node)
if not node.traverse(nodes.system_message):
# considered as that splitting by period does not break inline markups
break
# strip literal notation mark ``::`` from tail of summary
summary = literal_re.sub('.', summary)
return summary

View File

@ -124,7 +124,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
else:
if template_dir:
template_dirs.insert(0, template_dir)
template_loader = FileSystemLoader(template_dirs) # type: ignore
template_loader = FileSystemLoader(template_dirs)
template_env = SandboxedEnvironment(loader=template_loader)
template_env.filters['underline'] = _underline
@ -269,7 +269,7 @@ def find_autosummary_in_docstring(name, module=None, filename=None):
pass
except ImportError as e:
print("Failed to import '%s': %s" % (name, e))
except SystemExit as e:
except SystemExit:
print("Failed to import '%s'; the module executes module level "
"statement and it might call sys.exit()." % name)
return []

View File

@ -90,6 +90,16 @@ class TestDirective(SphinxDirective):
def run(self):
# type: () -> List[nodes.Node]
if 'skipif' in self.options:
condition = self.options['skipif']
context = {} # type: Dict[str, Any]
if self.config.doctest_global_setup:
exec(self.config.doctest_global_setup, context)
should_skip = eval(condition, context)
if self.config.doctest_global_cleanup:
exec(self.config.doctest_global_cleanup, context)
if should_skip:
return []
# use ordinary docutils nodes for test code: they get special attributes
# so that our builder recognizes them, and the other builders are happy.
code = '\n'.join(self.content)
@ -155,11 +165,11 @@ class TestDirective(SphinxDirective):
class TestsetupDirective(TestDirective):
option_spec = {} # type: Dict
option_spec = {'skipif': directives.unchanged_required} # type: Dict
class TestcleanupDirective(TestDirective):
option_spec = {} # type: Dict
option_spec = {'skipif': directives.unchanged_required} # type: Dict
class DoctestDirective(TestDirective):
@ -167,6 +177,7 @@ class DoctestDirective(TestDirective):
'hide': directives.flag,
'options': directives.unchanged,
'pyversion': directives.unchanged_required,
'skipif': directives.unchanged_required,
}
@ -174,6 +185,7 @@ class TestcodeDirective(TestDirective):
option_spec = {
'hide': directives.flag,
'pyversion': directives.unchanged_required,
'skipif': directives.unchanged_required,
}
@ -182,6 +194,7 @@ class TestoutputDirective(TestDirective):
'hide': directives.flag,
'options': directives.unchanged,
'pyversion': directives.unchanged_required,
'skipif': directives.unchanged_required,
}

View File

@ -27,6 +27,7 @@ from sphinx.errors import SphinxError
from sphinx.locale import _, __
from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.i18n import search_image_for_language
from sphinx.util.osutil import ensuredir, ENOENT, EPIPE, EINVAL
@ -155,7 +156,10 @@ class Graphviz(SphinxDirective):
line=self.lineno)]
node = graphviz()
node['code'] = dotcode
node['options'] = {}
node['options'] = {
'docname': path.splitext(self.state.document.current_source)[0],
}
if 'graphviz_dot' in self.options:
node['options']['graphviz_dot'] = self.options['graphviz_dot']
if 'alt' in self.options:
@ -192,7 +196,9 @@ class GraphvizSimple(SphinxDirective):
node = graphviz()
node['code'] = '%s %s {\n%s\n}\n' % \
(self.name, self.arguments[0], '\n'.join(self.content))
node['options'] = {}
node['options'] = {
'docname': path.splitext(self.state.document.current_source)[0],
}
if 'graphviz_dot' in self.options:
node['options']['graphviz_dot'] = self.options['graphviz_dot']
if 'alt' in self.options:
@ -235,10 +241,14 @@ def render_dot(self, code, options, format, prefix='graphviz'):
dot_args = [graphviz_dot]
dot_args.extend(self.builder.config.graphviz_dot_args)
dot_args.extend(['-T' + format, '-o' + outfn])
docname = options.get('docname', 'index')
cwd = path.dirname(path.join(self.builder.srcdir, docname))
if format == 'png':
dot_args.extend(['-Tcmapx', '-o%s.map' % outfn])
try:
p = Popen(dot_args, stdout=PIPE, stdin=PIPE, stderr=PIPE)
p = Popen(dot_args, stdout=PIPE, stdin=PIPE, stderr=PIPE, cwd=cwd)
except OSError as err:
if err.errno != ENOENT: # No such file or directory
raise
@ -281,19 +291,23 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
logger.warning(__('dot code %r: %s'), code, text_type(exc))
raise nodes.SkipNode
if imgcls:
imgcls += " graphviz"
else:
imgcls = "graphviz"
if fname is None:
self.body.append(self.encode(code))
else:
if alt is None:
alt = node.get('alt', self.encode(code).strip())
imgcss = imgcls and 'class="%s"' % imgcls or ''
if 'align' in node:
self.body.append('<div align="%s" class="align-%s">' %
(node['align'], node['align']))
if format == 'svg':
self.body.append('<div class="graphviz">')
self.body.append('<object data="%s" type="image/svg+xml" %s>\n' %
(fname, imgcss))
self.body.append('<object data="%s" type="image/svg+xml" class="%s">\n' %
(fname, imgcls))
self.body.append('<p class="warning">%s</p>' % alt)
self.body.append('</object></div>\n')
else:
@ -302,15 +316,15 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
if imgmap.clickable:
# has a map
self.body.append('<div class="graphviz">')
self.body.append('<img src="%s" alt="%s" usemap="#%s" %s/>' %
(fname, alt, imgmap.id, imgcss))
self.body.append('<img src="%s" alt="%s" usemap="#%s" class="%s" />' %
(fname, alt, imgmap.id, imgcls))
self.body.append('</div>\n')
self.body.append(imgmap.generate_clickable_map())
else:
# nothing in image map
self.body.append('<div class="graphviz">')
self.body.append('<img src="%s" alt="%s" %s/>' %
(fname, alt, imgcss))
self.body.append('<img src="%s" alt="%s" class="%s" />' %
(fname, alt, imgcls))
self.body.append('</div>\n')
if 'align' in node:
self.body.append('</div>\n')
@ -396,6 +410,14 @@ def man_visit_graphviz(self, node):
raise nodes.SkipNode
def on_build_finished(app, exc):
# type: (Sphinx, Exception) -> None
if exc is None:
src = path.join(sphinx.package_dir, 'templates', 'graphviz', 'graphviz.css')
dst = path.join(app.outdir, '_static')
copy_asset_file(src, dst)
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_node(graphviz,
@ -410,4 +432,6 @@ def setup(app):
app.add_config_value('graphviz_dot', 'dot', 'html')
app.add_config_value('graphviz_dot_args', [], 'html')
app.add_config_value('graphviz_output_format', 'png', 'html')
app.add_css_file('graphviz.css')
app.connect('build-finished', on_build_finished)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -22,11 +22,10 @@ from docutils import nodes
from six import text_type
import sphinx
from sphinx.errors import SphinxError, ExtensionError
from sphinx.ext.mathbase import get_node_equation_number
from sphinx.ext.mathbase import setup_math as mathbase_setup, wrap_displaymath
from sphinx.errors import SphinxError
from sphinx.locale import _, __
from sphinx.util import logging
from sphinx.util.math import get_node_equation_number, wrap_displaymath
from sphinx.util.osutil import ensuredir, ENOENT, cd
from sphinx.util.png import read_png_depth, write_png_depth
from sphinx.util.pycompat import sys_encoding
@ -34,10 +33,10 @@ from sphinx.util.pycompat import sys_encoding
if False:
# For type annotation
from typing import Any, Dict, List, Tuple # NOQA
from sphinx.addnodes import displaymath # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.builders import Builder # NOQA
from sphinx.config import Config # NOQA
from sphinx.ext.mathbase import displaymath # NOQA
logger = logging.getLogger(__name__)
@ -315,12 +314,11 @@ def html_visit_math(self, node):
def html_visit_displaymath(self, node):
# type: (nodes.NodeVisitor, displaymath) -> None
# type: (nodes.NodeVisitor, nodes.math_block) -> None
if node['nowrap']:
latex = node.astext()
else:
latex = wrap_displaymath(node.astext(), None,
self.builder.config.math_number_all)
latex = wrap_displaymath(node.astext(), None, False)
try:
fname, depth = render_math(self, latex)
except MathExtError as exc:
@ -349,10 +347,9 @@ def html_visit_displaymath(self, node):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
try:
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
except ExtensionError:
raise ExtensionError('sphinx.ext.imgmath: other math package is already loaded')
app.add_html_math_renderer('imgmath',
(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')

View File

@ -14,9 +14,8 @@ from docutils import nodes
import sphinx
from sphinx.errors import ExtensionError
from sphinx.ext.mathbase import get_node_equation_number
from sphinx.ext.mathbase import setup_math as mathbase_setup
from sphinx.locale import _
from sphinx.util.math import get_node_equation_number
if False:
# For type annotation
@ -61,7 +60,9 @@ def html_visit_displaymath(self, node):
def builder_inited(app):
# type: (Sphinx) -> None
if not app.config.jsmath_path:
if app.builder.format != 'html' or app.builder.math_renderer_name != 'jsmath': # type: ignore # NOQA
pass
elif not app.config.jsmath_path:
raise ExtensionError('jsmath_path config value must be set for the '
'jsmath extension to work')
if app.builder.format == 'html':
@ -70,10 +71,9 @@ def builder_inited(app):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
try:
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
except ExtensionError:
raise ExtensionError('sphinx.ext.jsmath: other math package is already loaded')
app.add_html_math_renderer('jsmath',
(html_visit_math, None),
(html_visit_displaymath, None))
app.add_config_value('jsmath_path', '', False)
app.connect('builder-inited', builder_inited)

View File

@ -13,7 +13,7 @@ import warnings
from docutils import nodes
from sphinx.addnodes import math, math_block as displaymath
from sphinx.addnodes import math, math_block as displaymath # NOQA # to keep compatibility
from sphinx.builders.latex.nodes import math_reference as eqref # NOQA # to keep compatibility
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.domains.math import MathDomain # NOQA # to keep compatibility
@ -28,57 +28,20 @@ if False:
def get_node_equation_number(writer, node):
# type: (Writer, nodes.Node) -> unicode
if writer.builder.config.math_numfig and writer.builder.config.numfig:
figtype = 'displaymath'
if writer.builder.name == 'singlehtml':
key = u"%s/%s" % (writer.docnames[-1], figtype)
else:
key = figtype
id = node['ids'][0]
number = writer.builder.fignumbers.get(key, {}).get(id, ())
number = '.'.join(map(str, number))
else:
number = node['number']
return number
warnings.warn('sphinx.ext.mathbase.get_node_equation_number() is moved to '
'sphinx.util.math package.',
RemovedInSphinx30Warning)
from sphinx.util.math import get_node_equation_number
return get_node_equation_number(writer, node)
def wrap_displaymath(math, label, numbering):
def wrap_displaymath(text, label, numbering):
# type: (unicode, unicode, bool) -> unicode
def is_equation(part):
# type: (unicode) -> unicode
return part.strip()
if label is None:
labeldef = ''
else:
labeldef = r'\label{%s}' % label
numbering = True
parts = list(filter(is_equation, math.split('\n\n')))
equations = []
if len(parts) == 0:
return ''
elif len(parts) == 1:
if numbering:
begin = r'\begin{equation}' + labeldef
end = r'\end{equation}'
else:
begin = r'\begin{equation*}' + labeldef
end = r'\end{equation*}'
equations.append('\\begin{split}%s\\end{split}\n' % parts[0])
else:
if numbering:
begin = r'\begin{align}%s\!\begin{aligned}' % labeldef
end = r'\end{aligned}\end{align}'
else:
begin = r'\begin{align*}%s\!\begin{aligned}' % labeldef
end = r'\end{aligned}\end{align*}'
for part in parts:
equations.append('%s\\\\\n' % part.strip())
return '%s\n%s%s' % (begin, ''.join(equations), end)
warnings.warn('sphinx.ext.mathbase.wrap_displaymath() is moved to '
'sphinx.util.math package.',
RemovedInSphinx30Warning)
from sphinx.util.math import wrap_displaymath
return wrap_displaymath(text, label, numbering)
def is_in_section_title(node):
@ -97,8 +60,9 @@ def is_in_section_title(node):
def setup_math(app, htmlinlinevisitors, htmldisplayvisitors):
# type: (Sphinx, Tuple[Callable, Any], Tuple[Callable, Any]) -> None
app.add_node(math, override=True,
html=htmlinlinevisitors)
app.add_node(displaymath, override=True,
html=htmldisplayvisitors)
# type: (Sphinx, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
warnings.warn('setup_math() is deprecated. '
'Please use app.add_html_math_renderer() instead.',
RemovedInSphinx30Warning)
app.add_html_math_renderer('unknown', htmlinlinevisitors, htmldisplayvisitors)

View File

@ -11,13 +11,14 @@
:license: BSD, see LICENSE for details.
"""
import json
from docutils import nodes
import sphinx
from sphinx.errors import ExtensionError
from sphinx.ext.mathbase import get_node_equation_number
from sphinx.ext.mathbase import setup_math as mathbase_setup
from sphinx.locale import _
from sphinx.util.math import get_node_equation_number
if False:
# For type annotation
@ -69,7 +70,9 @@ def html_visit_displaymath(self, node):
def builder_inited(app):
# type: (Sphinx) -> None
if not app.config.mathjax_path:
if app.builder.format != 'html' or app.builder.math_renderer_name != 'mathjax': # type: ignore # NOQA
pass
elif not app.config.mathjax_path:
raise ExtensionError('mathjax_path config value must be set for the '
'mathjax extension to work')
if app.builder.format == 'html':
@ -78,13 +81,16 @@ def builder_inited(app):
options.update(app.config.mathjax_options)
app.builder.add_js_file(app.config.mathjax_path, **options) # type: ignore
if app.config.mathjax_config:
body = "MathJax.Hub.Config(%s)" % json.dumps(app.config.mathjax_config)
app.builder.add_js_file(None, type="text/x-mathjax-config", body=body) # type: ignore # NOQA
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
try:
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
except ExtensionError:
raise ExtensionError('sphinx.ext.mathjax: other math package is already loaded')
app.add_html_math_renderer('mathjax',
(html_visit_math, None),
(html_visit_displaymath, None))
# more information for mathjax secure url is here:
# https://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn
@ -94,6 +100,7 @@ def setup(app):
app.add_config_value('mathjax_options', {}, 'html')
app.add_config_value('mathjax_inline', [r'\(', r'\)'], 'html')
app.add_config_value('mathjax_display', [r'\[', r'\]'], 'html')
app.add_config_value('mathjax_config', None, 'html')
app.connect('builder-inited', builder_inited)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -556,7 +556,14 @@ class GoogleDocstring(UnicodeMixin):
self._parsed_lines = self._consume_empty()
if self._name and (self._what == 'attribute' or self._what == 'data'):
self._parsed_lines.extend(self._parse_attribute_docstring())
# Implicit stop using StopIteration no longer allowed in
# Python 3.7; see PEP 479
res = [] # type: List[unicode]
try:
res = self._parse_attribute_docstring()
except StopIteration:
pass
self._parsed_lines.extend(res)
return
while self._line_iter.has_next():

View File

@ -9,6 +9,8 @@
:license: BSD, see LICENSE for details.
"""
import warnings
from pygments import highlight
from pygments.filters import ErrorToken
from pygments.formatters import HtmlFormatter, LatexFormatter
@ -20,6 +22,7 @@ from pygments.styles import get_style_by_name
from pygments.util import ClassNotFound
from six import text_type
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.ext import doctest
from sphinx.locale import __
from sphinx.pygments_styles import SphinxStyle, NoneStyle
@ -65,7 +68,7 @@ class PygmentsBridge(object):
html_formatter = HtmlFormatter
latex_formatter = LatexFormatter
def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=False):
def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=None):
# type: (unicode, unicode, bool) -> None
self.dest = dest
if stylename is None or stylename == 'sphinx':
@ -78,7 +81,6 @@ class PygmentsBridge(object):
stylename)
else:
style = get_style_by_name(stylename)
self.trim_doctest_flags = trim_doctest_flags
self.formatter_args = {'style': style} # type: Dict[unicode, Any]
if dest == 'html':
self.formatter = self.html_formatter
@ -86,6 +88,11 @@ class PygmentsBridge(object):
self.formatter = self.latex_formatter
self.formatter_args['commandprefix'] = 'PYG'
self.trim_doctest_flags = trim_doctest_flags
if trim_doctest_flags is not None:
warnings.warn('trim_doctest_flags option for PygmentsBridge is now deprecated.',
RemovedInSphinx30Warning)
def get_formatter(self, **kwargs):
# type: (Any) -> Formatter
kwargs.update(self.formatter_args) # type: ignore
@ -93,6 +100,8 @@ class PygmentsBridge(object):
def unhighlighted(self, source):
# type: (unicode) -> unicode
warnings.warn('PygmentsBridge.unhighlighted() is now deprecated.',
RemovedInSphinx30Warning)
if self.dest == 'html':
return '<pre>' + htmlescape(source) + '</pre>\n'
else:
@ -161,8 +170,6 @@ class PygmentsBridge(object):
if self.dest == 'html':
return hlsource
else:
if not isinstance(hlsource, text_type): # Py2 / Pygments < 1.6
hlsource = hlsource.decode()
return hlsource.translate(tex_hl_escape_map_new)
def get_stylesheet(self):

View File

@ -64,7 +64,7 @@ class _TranslationProxy(UserString, object):
# replace function from UserString; it instantiates a self.__class__
# for the encoding result
def encode(self, encoding=None, errors=None):
def encode(self, encoding=None, errors=None): # type: ignore
# type: (unicode, unicode) -> str
if encoding:
if errors:
@ -88,7 +88,7 @@ class _TranslationProxy(UserString, object):
return dir(text_type)
def __iter__(self):
# type: () -> Iterator[unicode]
# type: () -> Iterator
return iter(self.data)
def __len__(self):
@ -103,15 +103,15 @@ class _TranslationProxy(UserString, object):
# type: () -> unicode
return text_type(self.data)
def __add__(self, other):
def __add__(self, other): # type: ignore
# type: (unicode) -> unicode
return self.data + other
def __radd__(self, other):
def __radd__(self, other): # type: ignore
# type: (unicode) -> unicode
return other + self.data
def __mod__(self, other):
def __mod__(self, other): # type: ignore
# type: (unicode) -> unicode
return self.data % other
@ -119,11 +119,11 @@ class _TranslationProxy(UserString, object):
# type: (unicode) -> unicode
return other % self.data
def __mul__(self, other):
def __mul__(self, other): # type: ignore
# type: (Any) -> unicode
return self.data * other
def __rmul__(self, other):
def __rmul__(self, other): # type: ignore
# type: (Any) -> unicode
return other * self.data
@ -165,7 +165,7 @@ class _TranslationProxy(UserString, object):
# type: (Tuple[Callable, Tuple[unicode]]) -> None
self._func, self._args = tup
def __getitem__(self, key):
def __getitem__(self, key): # type: ignore
# type: (Any) -> unicode
return self.data[key]

View File

@ -14,152 +14,26 @@
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
import os
import subprocess
import sys
from os import path
import warnings
import sphinx
from sphinx.cmd.build import build_main
from sphinx.util.console import color_terminal, nocolor, bold, blue # type: ignore
from sphinx.util.osutil import cd, rmtree
if False:
# For type annotation
from typing import List # NOQA
from sphinx.cmd import make_mode
from sphinx.deprecation import RemovedInSphinx30Warning
BUILDERS = [
("", "html", "to make standalone HTML files"),
("", "dirhtml", "to make HTML files named index.html in directories"),
("", "singlehtml", "to make a single large HTML file"),
("", "pickle", "to make pickle files"),
("", "json", "to make JSON files"),
("", "htmlhelp", "to make HTML files and an HTML help project"),
("", "qthelp", "to make HTML files and a qthelp project"),
("", "devhelp", "to make HTML files and a Devhelp project"),
("", "epub", "to make an epub"),
("", "latex", "to make LaTeX files, you can set PAPER=a4 or PAPER=letter"),
("posix", "latexpdf", "to make LaTeX and PDF files (default pdflatex)"),
("posix", "latexpdfja", "to make LaTeX files and run them through platex/dvipdfmx"),
("", "text", "to make text files"),
("", "man", "to make manual pages"),
("", "texinfo", "to make Texinfo files"),
("posix", "info", "to make Texinfo files and run them through makeinfo"),
("", "gettext", "to make PO message catalogs"),
("", "changes", "to make an overview of all changed/added/deprecated items"),
("", "xml", "to make Docutils-native XML files"),
("", "pseudoxml", "to make pseudoxml-XML files for display purposes"),
("", "linkcheck", "to check all external links for integrity"),
("", "doctest", "to run all doctests embedded in the documentation "
"(if enabled)"),
("", "coverage", "to run coverage check of the documentation (if enabled)"),
]
BUILDERS = make_mode.BUILDERS
class Make(object):
def __init__(self, srcdir, builddir, opts):
# type: (unicode, unicode, List[unicode]) -> None
self.srcdir = srcdir
self.builddir = builddir
self.opts = opts
self.makecmd = os.environ.get('MAKE', 'make') # refer $MAKE to determine make command
def builddir_join(self, *comps):
# type: (unicode) -> unicode
return path.join(self.builddir, *comps)
def build_clean(self):
# type: () -> int
if not path.exists(self.builddir):
return 0
elif not path.isdir(self.builddir):
print("Error: %r is not a directory!" % self.builddir)
return 1
print("Removing everything under %r..." % self.builddir)
for item in os.listdir(self.builddir):
rmtree(self.builddir_join(item))
return 0
def build_help(self):
# type: () -> None
if not color_terminal():
nocolor()
print(bold("Sphinx v%s" % sphinx.__display_version__))
print("Please use `make %s' where %s is one of" % ((blue('target'),) * 2)) # type: ignore # NOQA
for osname, bname, description in BUILDERS:
if not osname or os.name == osname:
print(' %s %s' % (blue(bname.ljust(10)), description))
def build_latexpdf(self):
# type: () -> int
if self.run_generic_build('latex') > 0:
return 1
try:
with cd(self.builddir_join('latex')):
return subprocess.call([self.makecmd, 'all-pdf'])
except OSError:
print('Error: Failed to run: %s' % self.makecmd)
return 1
def build_latexpdfja(self):
# type: () -> int
if self.run_generic_build('latex') > 0:
return 1
try:
with cd(self.builddir_join('latex')):
return subprocess.call([self.makecmd, 'all-pdf-ja'])
except OSError:
print('Error: Failed to run: %s' % self.makecmd)
return 1
def build_info(self):
# type: () -> int
if self.run_generic_build('texinfo') > 0:
return 1
try:
with cd(self.builddir_join('texinfo')):
return subprocess.call([self.makecmd, 'info'])
except OSError:
print('Error: Failed to run: %s' % self.makecmd)
return 1
def build_gettext(self):
# type: () -> int
dtdir = self.builddir_join('gettext', '.doctrees')
if self.run_generic_build('gettext', doctreedir=dtdir) > 0:
return 1
return 0
def run_generic_build(self, builder, doctreedir=None):
# type: (unicode, unicode) -> int
# compatibility with old Makefile
papersize = os.getenv('PAPER', '')
opts = self.opts
if papersize in ('a4', 'letter'):
opts.extend(['-D', 'latex_elements.papersize=' + papersize])
if doctreedir is None:
doctreedir = self.builddir_join('doctrees')
args = ['-b', builder,
'-d', doctreedir,
self.srcdir,
self.builddir_join(builder)]
return build_main(args + opts)
class Make(make_mode.Make):
def __init__(self, *args):
warnings.warn('sphinx.make_mode.Make is deprecated. '
'Please use sphinx.cmd.make_mode.Make instead.',
RemovedInSphinx30Warning)
super(Make, self).__init__(*args)
def run_make_mode(args):
# type: (List[unicode]) -> int
if len(args) < 3:
print('Error: at least 3 arguments (builder, source '
'dir, build dir) are required.', file=sys.stderr)
return 1
make = Make(args[1], args[2], args[3:])
run_method = 'build_' + args[0]
if hasattr(make, run_method):
return getattr(make, run_method)()
return make.run_generic_build(args[0])
warnings.warn('sphinx.make_mode.run_make_mode() is deprecated. '
'Please use sphinx.cmd.make_mode.run_make_mode() instead.',
RemovedInSphinx30Warning)
return make_mode.run_make_mode(args)

View File

@ -39,6 +39,7 @@ if False:
from docutils.transforms import Transform # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.builders import Builder # NOQA
from sphinx.config import Config # NOQA
from sphinx.domains import Domain, Index # NOQA
from sphinx.environment import BuildEnvironment # NOQA
from sphinx.ext.autodoc import Documenter # NOQA
@ -91,6 +92,11 @@ class SphinxComponentRegistry(object):
#: a dict of node class -> tuple of figtype and title_getter function
self.enumerable_nodes = {} # type: Dict[nodes.Node, Tuple[unicode, TitleGetter]]
#: HTML inline and block math renderers
#: a dict of name -> tuple of visit function and depart function
self.html_inline_math_renderers = {} # type: Dict[unicode, Tuple[Callable, Callable]] # NOQA
self.html_block_math_renderers = {} # type: Dict[unicode, Tuple[Callable, Callable]] # NOQA
#: js_files; list of JS paths or URLs
self.js_files = [] # type: List[Tuple[unicode, Dict[unicode, unicode]]]
@ -270,7 +276,7 @@ class SphinxComponentRegistry(object):
# type: (unicode, unicode, bool) -> None
logger.debug('[app] adding source_suffix: %r, %r', suffix, filetype)
if suffix in self.source_suffix and not override:
raise ExtensionError(__('source_parser for %r is already registered') % suffix)
raise ExtensionError(__('source_suffix %r is already registered') % suffix)
else:
self.source_suffix[suffix] = filetype
@ -290,7 +296,7 @@ class SphinxComponentRegistry(object):
parser = args[1]
if suffix:
self.add_source_suffix(suffix, suffix)
self.add_source_suffix(suffix, suffix, override=True)
if len(parser.supported) == 0:
warnings.warn('Old source_parser has been detected. Please fill Parser.supported '
@ -438,6 +444,16 @@ class SphinxComponentRegistry(object):
raise ExtensionError(__('enumerable_node %r already registered') % node)
self.enumerable_nodes[node] = (figtype, title_getter)
def add_html_math_renderer(self, name, inline_renderers, block_renderers):
# type: (unicode, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
logger.debug('[app] adding html_math_renderer: %s, %r, %r',
name, inline_renderers, block_renderers)
if name in self.html_inline_math_renderers:
raise ExtensionError(__('math renderer %s is already registred') % name)
self.html_inline_math_renderers[name] = inline_renderers
self.html_block_math_renderers[name] = block_renderers
def load_extension(self, app, extname):
# type: (Sphinx, unicode) -> None
"""Load a Sphinx extension."""
@ -493,8 +509,8 @@ class SphinxComponentRegistry(object):
return envversion
def merge_source_suffix(app):
# type: (Sphinx) -> None
def merge_source_suffix(app, config):
# type: (Sphinx, Config) -> None
"""Merge source_suffix which specified by user and added by extensions."""
for suffix, filetype in iteritems(app.registry.source_suffix):
if suffix not in app.config.source_suffix:
@ -510,7 +526,7 @@ def merge_source_suffix(app):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.connect('builder-inited', merge_source_suffix)
app.connect('config-inited', merge_source_suffix)
return {
'version': 'builtin',

View File

@ -21,14 +21,14 @@ from distutils.errors import DistutilsOptionError, DistutilsExecError
from six import StringIO, string_types
from sphinx.application import Sphinx
from sphinx.cmdline import handle_exception
from sphinx.cmd.build import handle_exception
from sphinx.util.console import nocolor, color_terminal
from sphinx.util.docutils import docutils_namespace, patch_docutils
from sphinx.util.osutil import abspath
if False:
# For type annotation
from typing import Any, List, Tuple # NOQA
from typing import Any, Dict, List, Tuple # NOQA
class BuildDoc(Command):
@ -87,9 +87,10 @@ class BuildDoc(Command):
('link-index', 'i', 'Link index.html to the master doc'),
('copyright', None, 'The copyright string'),
('pdb', None, 'Start pdb on exception'),
('nitpicky', 'n', 'nit-picky mode, warn about all missing references'),
]
boolean_options = ['fresh-env', 'all-files', 'warning-is-error',
'link-index']
'link-index', 'nitpicky']
def initialize_options(self):
# type: () -> None
@ -107,6 +108,7 @@ class BuildDoc(Command):
self.copyright = ''
self.verbosity = 0
self.traceback = False
self.nitpicky = False
def _guess_source_dir(self):
# type: () -> unicode
@ -163,7 +165,7 @@ class BuildDoc(Command):
status_stream = StringIO()
else:
status_stream = sys.stdout # type: ignore
confoverrides = {}
confoverrides = {} # type: Dict[unicode, Any]
if self.project:
confoverrides['project'] = self.project
if self.version:
@ -174,6 +176,8 @@ class BuildDoc(Command):
confoverrides['today'] = self.today
if self.copyright:
confoverrides['copyright'] = self.copyright
if self.nitpicky:
confoverrides['nitpicky'] = self.nitpicky
for builder, builder_target_dir in self.builder_target_dirs:
app = None

View File

@ -0,0 +1,19 @@
/*
* graphviz.css
* ~~~~~~~~~~~~
*
* Sphinx stylesheet -- graphviz extension.
*
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
img.graphviz {
border: 0;
max-width: 100%;
}
object.graphviz {
max-width: 100%;
}

View File

@ -13,6 +13,11 @@
\ifdefined\pdfpxdimen
\let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen
\fi \sphinxpxdimen=<%= pxunit %>\relax
<% if use_xindy -%>
%% turn off hyperref patch of \index as sphinx.xdy xindy module takes care of
%% suitable \hyperpage mark-up, working around hyperref-xindy incompatibility
\PassOptionsToPackage{hyperindex=false}{hyperref}
<% endif -%>
<%= passoptionstopackages %>
\PassOptionsToPackage{warn}{textcomp}
<%= inputenc %>
@ -31,7 +36,7 @@
<%= hyperref %>
<%= contentsname %>
<%= numfig_format %>
<%= literalblockpto %>
<%= translatablestrings %>
<%= pageautorefname %>
<%= tocdepth %>
<%= secnumdepth %>

View File

@ -9,8 +9,8 @@ SOURCEDIR = {{ rsrcdir }}
BUILDDIR = {{ rbuilddir }}
# Internal variables.
PAPEROPT_a4 = -D latex_elements.papersize=a4
PAPEROPT_letter = -D latex_elements.papersize=letter
PAPEROPT_a4 = -D latex_elements.papersize=a4paper
PAPEROPT_letter = -D latex_elements.papersize=letterpaper
# $(O) is meant as a shortcut for $(SPHINXOPTS)
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(O) $(SOURCEDIR)
# the i18n builder cannot share the environment and doctrees with the others

View File

@ -165,16 +165,12 @@ texinfo_documents = [
author, '{{ project_fn }}', 'One line description of project.',
'Miscellaneous'),
]
{%- if epub %}
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
@ -187,7 +183,6 @@ epub_copyright = copyright
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
{%- endif %}
{%- if extensions %}

View File

@ -12,8 +12,8 @@ set SOURCEDIR={{ rsrcdir }}
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %SOURCEDIR%
set I18NSPHINXOPTS=%SPHINXOPTS% %SOURCEDIR%
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_elements.papersize=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_elements.papersize=%PAPER% %I18NSPHINXOPTS%
set ALLSPHINXOPTS=-D latex_elements.papersize=%PAPER%paper %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_elements.papersize=%PAPER%paper %I18NSPHINXOPTS%
)
if "%1" == "" goto help

View File

@ -223,7 +223,7 @@ class path(text_type):
"""
Joins the path with the argument given and returns the result.
"""
return self.__class__(os.path.join(self, *map(self.__class__, args))) # type: ignore # NOQA
return self.__class__(os.path.join(self, *map(self.__class__, args)))
def listdir(self):
# type: () -> List[unicode]

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