Merge branch 'master' into 5216-update-markdown-doc

This commit is contained in:
Timotheus Kampik
2018-12-23 17:31:01 +01:00
609 changed files with 139977 additions and 27700 deletions

View File

@@ -5,10 +5,8 @@ environment:
PYTHONWARNINGS: all
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

View File

@@ -6,6 +6,6 @@ jobs:
working_directory: /sphinx
steps:
- checkout
- run: /python3.4/bin/pip install -U pip setuptools
- run: /python3.4/bin/pip install -U .[test,websupport]
- run: make test PYTHON=/python3.4/bin/python
- run: /python3.5/bin/pip install -U pip setuptools
- run: /python3.5/bin/pip install -U .[test,websupport]
- run: make test PYTHON=/python3.5/bin/python

2
.gitignore vendored
View File

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

View File

@@ -1,33 +1,25 @@
language: python
sudo: false
dist: trusty
dist: xenial
cache: pip
env:
global:
- PYTHONFAULTHANDLER=x
- SKIP_LATEX_BUILD=1
- IS_PYTHON=true
matrix:
include:
- python: 'pypy'
env: TOXENV=pypy
- python: '2.7'
- python: '3.5'
env:
- TOXENV=du13
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
- python: '3.4'
env: TOXENV=py34
- python: '3.5'
env: TOXENV=py35
- python: '3.6'
env:
- TOXENV=py36
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
- python: '3.7'
env: TOXENV=py37
dist: xenial
sudo: true
- python: 'nightly'
env: TOXENV=py38
- python: '3.6'
@@ -37,11 +29,21 @@ matrix:
- 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

@@ -38,6 +38,7 @@ Other contributors, listed alphabetically, are:
* Zac Hatfield-Dodds -- doctest reporting improvements
* Doug Hellmann -- graphviz improvements
* Tim Hoffmann -- theme improvements
* Antti Kaihola -- doctest extension (skipif option)
* Dave Kuhlman -- original LaTeX writer
* Blaise Laflamme -- pyramid theme
* Chris Lamb -- reproducibility fixes
@@ -56,6 +57,7 @@ Other contributors, listed alphabetically, are:
* Ezio Melotti -- collapsible sidebar JavaScript
* Bruce Mitchener -- Minor epub improvement
* Daniel Neuhäuser -- JavaScript domain, Python 3 support (GSOC)
* Julien Palard -- Colspan and rowspan in text builder
* Christopher Perkins -- autosummary integration
* Benjamin Peterson -- unittests
* \T. Powers -- HTML output improvements
@@ -67,6 +69,7 @@ Other contributors, listed alphabetically, are:
* Antonio Valentino -- qthelp builder, docstring inheritance
* Filip Vavera -- napoleon todo directive
* Pauli Virtanen -- autodoc improvements, autosummary extension
* Eric N. Vander Weele -- autodoc improvements
* Stefan van der Walt -- autosummary extension
* Thomas Waldmann -- apidoc module fixes
* John Waltman -- Texinfo builder
@@ -78,6 +81,7 @@ Other contributors, listed alphabetically, are:
* Hong Xu -- svg support in imgmath extension and various bug fixes
* Stephen Finucane -- setup command improvements and documentation
* Daniel Pizetta -- inheritance diagram improvements
* KINEBUCHI Tomohiko -- typing Sphinx as well as docutils
Many thanks for all contributions!

474
CHANGES
View File

@@ -1,17 +1,296 @@
Release 1.8.0 (in development)
Release 2.0.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)
* LaTeX builder now depends on TeX Live 2015 or above.
* LaTeX builder (with ``'pdflatex'`` :confval:`latex_engine`) will process
Unicode Greek letters in text (not in math mark-up) via the text font and
will not escape them to math mark-up. See the discussion of the
``'fontenc'`` key of :confval:`latex_elements`; such (optional) support for
Greek adds, for example on Ubuntu xenial, the ``texlive-lang-greek`` and (if
default font set-up is not modified) ``cm-super(-minimal)`` as additional
Sphinx LaTeX requirements.
* LaTeX builder with :confval:`latex_engine` set to ``'xelatex'`` or to
``'lualatex'`` requires (by default) the ``FreeFont`` fonts,
which in Ubuntu xenial are provided by package ``fonts-freefont-otf``, and
e.g. in Fedora 29 via package ``texlive-gnu-freefont``.
* requests 2.5.0 or above
Incompatible changes
--------------------
* Drop python 2.7 and 3.4 support
* Drop docutils 0.11 support
* The default setting for :confval:`master_doc` is changed to ``'index'`` which
has been longly used as default of sphinx-quickstart.
* LaTeX: Move message resources to ``sphinxmessage.sty``
* LaTeX: Stop using ``\captions<lang>`` macro for some labels
* LaTeX: for ``'xelatex'`` and ``'lualatex'``, use the ``FreeFont`` OpenType
fonts as default choice (refs: #5645)
* LaTeX: ``'xelatex'`` and ``'lualatex'`` now use ``\small`` in code-blocks
(due to ``FreeMono`` character width) like ``'pdflatex'`` already did (due
to ``Courier`` character width). You may need to adjust this via
:confval:`latex_elements` ``'fvset'`` key, in case of usage of some other
OpenType fonts (refs: #5768)
* LaTeX: Greek letters in text are not escaped to math mode mark-up, and they
will use the text font not the math font. The ``LGR`` font encoding must be
added to the ``'fontenc'`` key of :confval:`latex_elements` for this to work
(only if it is needed by the document, of course).
* LaTeX: setting the :confval:`language` to ``'en'`` triggered ``Sonny`` option
of ``fncychap``, now it is ``Bjarne`` to match case of no language specified.
(refs: #5772)
* #5770: doctest: Follow :confval:`highlight_language` on highlighting doctest
block. As a result, they are highlighted as python3 by default.
* The order of argument for ``HTMLTranslator``, ``HTML5Translator`` and
``ManualPageTranslator`` are changed
* LaTeX: hard-coded redefinitions of ``\l@section`` and ``\l@subsection``
formerly done during loading of ``'manual'`` docclass get executed later, at
time of ``\sphinxtableofcontents``. This means that custom user definitions
from LaTeX preamble now get overwritten. Use ``\sphinxtableofcontentshook``
to insert custom user definitions. See :ref:`latex-macros`.
Deprecated
----------
* Support for evaluating Python 2 syntax is deprecated. This includes
configuration files which should be converted to Python 3.
* The ``encoding`` argument of ``autodoc.Documenter.get_doc()``,
``autodoc.DocstringSignatureMixin.get_doc()``,
``autodoc.DocstringSignatureMixin._find_signature()``, and
``autodoc.ClassDocumenter.get_doc()`` are deprecated.
* The ``importer`` argument of ``sphinx.ext.autodoc.importer._MockModule``
* The ``nodetype`` argument of ``sphinx.search.WordCollector.
is_meta_keywords()``
* The ``suffix`` argument of ``env.doc2path()`` is deprecated.
* The string style ``base`` argument of ``env.doc2path()`` is deprecated.
* The fallback to allow omitting the ``filename`` argument from an overridden
``IndexBuilder.feed()`` method is deprecated.
* ``sphinx.addnodes.abbreviation``
* ``sphinx.application.Sphinx._setting_up_extension``
* ``sphinx.cmd.quickstart.term_decode()``
* ``sphinx.cmd.quickstart.TERM_ENCODING``
* ``sphinx.config.check_unicode()``
* ``sphinx.config.string_classes``
* ``sphinx.domains.cpp.DefinitionError.description``
* ``sphinx.domains.cpp.NoOldIdError.description``
* ``sphinx.domains.cpp.UnsupportedMultiCharacterCharLiteral.decoded``
* ``sphinx.ext.autodoc.importer._MockImporter``
* ``sphinx.ext.autosummary.Autosummary.warn()``
* ``sphinx.ext.autosummary.Autosummary.genopt``
* ``sphinx.ext.autosummary.Autosummary.warnings``
* ``sphinx.ext.autosummary.Autosummary.result``
* ``sphinx.ext.doctest.doctest_encode()``
* ``sphinx.io.SphinxBaseFileInput``
* ``sphinx.io.SphinxFileInput.supported``
* ``sphinx.io.SphinxRSTFileInput``
* ``sphinx.registry.SphinxComponentRegistry.add_source_input()``
* ``sphinx.testing.util.remove_unicode_literal()``
* ``sphinx.util.attrdict``
* ``sphinx.util.force_decode()``
* ``sphinx.util.get_matching_docs()``
* ``sphinx.util.inspect.Parameter``
* ``sphinx.util.osutil.EEXIST``
* ``sphinx.util.osutil.EINVAL``
* ``sphinx.util.osutil.ENOENT``
* ``sphinx.util.osutil.EPIPE``
* ``sphinx.util.osutil.walk()``
* ``sphinx.util.PeekableIterator``
* ``sphinx.util.pycompat.UnicodeMixin``
* ``sphinx.util.pycompat.u``
* ``sphinx.writers.latex.LaTeXTranslator._make_visit_admonition()``
* ``sphinx.writers.latex.LaTeXTranslator.babel_defmacro()``
* ``sphinx.writers.latex.LaTeXTranslator.collect_footnotes()``
* ``sphinx.writers.texinfo.TexinfoTranslator._make_visit_admonition()``
* ``sphinx.writers.text.TextTranslator._make_depart_admonition()``
* template variables for LaTeX template
- ``logo``
- ``pageautorefname``
- ``translatablestrings``
For more details, see :ref:`deprecation APIs list <dev-deprecated-apis>`.
Features added
--------------
* #1618: The search results preview of generated HTML documentation is
reader-friendlier: instead of showing the snippets as raw reStructuredText
markup, Sphinx now renders the corresponding HTML. This means the Sphinx
extension `Sphinx: pretty search results`__ is no longer necessary. Note that
changes to the search function of your custom or 3rd-party HTML template might
overwrite this improvement.
__ https://github.com/sphinx-contrib/sphinx-pretty-searchresults
* #4182: autodoc: Support :confval:`suppress_warnings`
* #5533: autodoc: :confval:`autodoc_default_options` supports ``member-order``
* #4018: htmlhelp: Add :confval:`htmlhelp_file_suffix` and
:confval:`htmlhelp_link_suffix`
* #5559: text: Support complex tables (colspan and rowspan)
* LaTeX: support rendering (not in math, yet) of Greek and Cyrillic Unicode
letters in non-Cyrillic document even with ``'pdflatex'`` as
:confval:`latex_engine` (refs: #5645)
Bugs fixed
----------
* #1682: LaTeX: writer should not translate Greek unicode, but use textgreek
package
* #5247: LaTeX: PDF does not build with default font config for Russian
language and ``'xelatex'`` or ``'lualatex'`` as :confval:`latex_engine`
(refs: #5251)
* #5248: LaTeX: Greek letters in section titles disappear from PDF bookmarks
* #5249: LaTeX: Unicode Greek letters in math directive break PDF build
(fix requires extra set-up, see :confval:`latex_elements` ``'textgreek'`` key
and/or :confval:`latex_engine` setting)
* #5772: LaTeX: should the Bjarne style of fncychap be used for English also
if passed as language option?
* #5179: LaTeX: (lualatex only) escaping of ``>`` by ``\textgreater{}`` is not
enough as ``\textgreater{}\textgreater{}`` applies TeX-ligature
Testing
--------
Release 1.8.3 (in development)
==============================
Dependencies
------------
Incompatible changes
--------------------
Deprecated
----------
Features added
--------------
* LaTeX: it is possible to insert custom material to appear on back of title
page, see discussion of ``'maketitle'`` key of :confval:`latex_elements`
(``'manual'`` docclass only)
Bugs fixed
----------
* #5725: mathjax: Use CDN URL for "latest" version by default
* #5460: html search does not work with some 3rd party themes
* #5520: LaTeX, caption package incompatibility since Sphinx 1.6
* #5614: autodoc: incremental build is broken when builtin modules are imported
* #5627: qthelp: index.html missing in QtHelp
* #5659: linkcheck: crashes for a hyperlink containing multibyte character
* #5754: DOC: Fix some mistakes in :doc:`/latex`
* #5810: LaTeX: sphinxVerbatim requires explicit "hllines" set-up since 1.6.6
(refs: #1238)
* #5636: C++, fix parsing of floating point literals.
* #5496 (again): C++, fix assertion in partial builds with duplicates.
* #5724: quickstart: sphinx-quickstart fails when $LC_ALL is empty
* #1956: Default conf.py is not PEP8-compliant
* #5849: LaTeX: document class ``\maketitle`` is overwritten with no
possibility to use original meaning in place of Sphinx custom one
* #5834: apidoc: wrong help for ``--tocfile``
* #5800: todo: crashed if todo is defined in TextElement
Testing
--------
Release 1.8.2 (released Nov 11, 2018)
=====================================
Incompatible changes
--------------------
* #5497: Do not include MathJax.js and jsmath.js unless it is really needed
Features added
--------------
* #5471: Show appropriate deprecation warnings
Bugs fixed
----------
* #5490: latex: enumerated list causes a crash with recommonmark
* #5492: sphinx-build fails to build docs w/ Python < 3.5.2
* #3704: latex: wrong ``\label`` positioning for figures with a legend
* #5496: C++, fix assertion when a symbol is declared more than twice.
* #5493: gettext: crashed with broken template
* #5495: csv-table directive with file option in included file is broken (refs:
#4821)
* #5498: autodoc: unable to find type hints for a ``functools.partial``
* #5480: autodoc: unable to find type hints for unresolvable Forward references
* #5419: incompatible math_block node has been generated
* #5548: Fix ensuredir() in case of pre-existing file
* #5549: graphviz Correctly deal with non-existing static dir
* #3002: i18n: multiple footnote_references referring same footnote causes
duplicated node_ids
* #5563: latex: footnote_references generated by extension causes LaTeX builder
crashed
* #5561: make all-pdf fails with old xindy version
* #5557: quickstart: --no-batchfile isn't honored
* #3080: texinfo: multiline rubrics are broken
* #3080: texinfo: multiline citations are broken
Release 1.8.1 (released Sep 22, 2018)
=====================================
Incompatible changes
--------------------
* LaTeX ``\pagestyle`` commands have been moved to the LaTeX template. No
changes in PDF, except possibly if ``\sphinxtableofcontents``, which
contained them, had been customized in :file:`conf.py`. (refs: #5455)
Bugs fixed
----------
* #5418: Incorrect default path for sphinx-build -d/doctrees files
* #5421: autodoc emits deprecation warning for :confval:`autodoc_default_flags`
* #5422: lambda object causes PicklingError on storing environment
* #5417: Sphinx fails to build with syntax error in Python 2.7.5
* #4911: add latexpdf to make.bat for non make-mode
* #5436: Autodoc does not work with enum subclasses with properties/methods
* #5437: autodoc: crashed on modules importing eggs
* #5433: latex: ImportError: cannot import name 'DEFAULT_SETTINGS'
* #5431: autodoc: ``autofunction`` emits a warning for callable objects
* #5457: Fix TypeError in error message when override is prohibited
* #5453: PDF builds of 'howto' documents have no page numbers
* #5463: mathbase: math_role and MathDirective was disappeared in 1.8.0
* #5454: latex: Index has disappeared from PDF for Japanese documents
* #5432: py domain: ``:type:`` field can't process ``:term:`` references
* #5426: py domain: TypeError has been raised for class attribute
Release 1.8.0 (released Sep 13, 2018)
=====================================
Dependencies
------------
1.8.0b1
* 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)
* LaTeX: ``latexmk`` is required for ``make latexpdf`` on Windows
Incompatible changes
--------------------
1.8.0b2
* #5282: html theme: refer ``pygments_style`` settings of HTML themes
preferentially
* The URL of download files are changed
* #5127: quickstart: ``Makefile`` and ``make.bat`` are not overwritten if exists
1.8.0b1
* #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`.
@@ -49,15 +328,37 @@ Incompatible changes
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
* #4000: latex: LaTeX template has been chaned. Following elements are moved
into the template:
- ``\begin{document}``
- ``shorthandoff`` variable
- ``maketitle`` variable
- ``tableofcontents`` variable
Deprecated
----------
1.8.0b2
* ``sphinx.io.SphinxI18nReader.set_lineno_for_reporter()`` is deprecated
* ``sphinx.io.SphinxI18nReader.line`` is deprecated
* ``sphinx.util.i18n.find_catalog_source_file()`` has changed; the
*gettext_compact* argument has been deprecated
* #5403: ``sphinx.util.images.guess_mimetype()`` has changed; the *content*
argument has been deprecated
1.8.0b1
* :confval:`source_parsers` is deprecated
* :confval:`autodoc_default_flags` is deprecated
* quickstart: ``--epub`` option becomes default, so it is deprecated
* Drop function based directive support. For now, Sphinx only supports class
based directives.
based directives (see :class:`~Directive`)
* ``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
@@ -82,9 +383,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
@@ -95,14 +398,33 @@ 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.MathDirective`` is deprecated
* ``sphinx.ext.mathbase.math_role`` 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>`_
@@ -110,6 +432,13 @@ For more details, see `deprecation APIs list
Features added
--------------
1.8.0b2
* #5388: Ensure frozen object descriptions are reproducible
* #5362: apidoc: Add ``--tocfile`` option to change the filename of ToC
1.8.0b1
* Add :event:`config-inited` event
* Add ``sphinx.config.Any`` to represent the config value accepts any type of
value
@@ -138,14 +467,22 @@ Features added
* Add ``Config.read()`` classmethod to create a new config object from
configuration file
* #4866: Wrap graphviz diagrams in ``<div>`` tag
* Add :event:`viewcode-find-source` event to viewcode extension.
* viewcode: Add :event:`viewcode-find-source` and
:event:`viewcode-follow-imported` to load source code without loading
* #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)
@@ -154,21 +491,48 @@ Features added
for mathjax
* #4362: latex: Don't overwrite .tex file if document not changed
* #1431: latex: Add alphanumeric enumerated list support
* Extend to all projects not using the Sphinx LaTeX Makefile a workaround for
`issue rtfd/readthedocs.org#2857`__ about insufficient number of
``pdflatex`` runs for index to show up in PDF bookmarks (refs: #3742)
__ https://github.com/rtfd/readthedocs.org/issues/2857
* Add :confval:`latex_use_xindy` for UTF-8 savvy indexing, defaults to ``True``
if :confval:`latex_engine` is ``'xelatex'`` or ``'lualatex'``.
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
* #4075, #5215: autodoc: Add :confval:`autodoc_default_options` which accepts
option values as dict
Bugs fixed
----------
1.8.0b2
* html: search box overrides to other elements if scrolled
* i18n: warnings for translation catalogs have wrong line numbers (refs: #5321)
* #5325: latex: cross references has been broken by multiply labeled objects
* C++, fixes for symbol addition and lookup. Lookup should no longer break
in partial builds. See also #5337.
* #5348: download reference to remote file is not displayed
* #5282: html theme: ``pygments_style`` of theme was overrided by ``conf.py``
by default
* #4379: toctree shows confusible warning when document is excluded
* #2401: autodoc: ``:members:`` causes ``:special-members:`` not to be shown
* autodoc: ImportError is replaced by AttributeError for deeper module
* #2720, #4034: Incorrect links with ``:download:``, duplicate names, and
parallel builds
* #5290: autodoc: failed to analyze source code in egg package
* #5399: Sphinx crashes if unknown po file exists
1.8.0b1
* i18n: message catalogs were reset on each initialization
* #4850: latex: footnote inside footnote was not rendered
* #4945: i18n: fix lang_COUNTRY not fallback correctly for IndexBuilder. Thanks
@@ -179,23 +543,29 @@ Bugs fixed
* #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
Testing
--------
* #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
Features removed
----------------
1.8.0b1
* ``sphinx.ext.pngmath`` extension
Documentation
-------------
1.8.0b1
* #5083: Fix wrong make.bat option for internationalization.
* #5115: napoleon: add admonitions added by #4613 to the docs.
Release 1.7.7 (in development)
==============================
Release 1.7.10 (in development)
===============================
Dependencies
------------
@@ -212,12 +582,64 @@ Features added
Bugs fixed
----------
* #5198: document not in toctree warning when including files only for parallel
builds
Testing
--------
Release 1.7.9 (released Sep 05, 2018)
=====================================
Features added
--------------
* #5359: Make generated texinfo files reproducible by sorting the anchors
Bugs fixed
----------
* #5361: crashed on incremental build if document uses include directive
Release 1.7.8 (released Aug 29, 2018)
=====================================
Incompatible changes
--------------------
* The type of ``env.included`` has been changed to dict of set
Bugs fixed
----------
* #5320: intersphinx: crashed if invalid url given
* #5326: manpage: crashed when invalid docname is specified as ``man_pages``
* #5322: autodoc: ``Any`` typehint causes formatting error
* #5327: "document isn't included in any toctree" warning on rebuild with
generated files
* #5335: quickstart: escape sequence has been displayed with MacPorts' python
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)
=====================================
@@ -1884,7 +2306,7 @@ Incompatible changes
parsing is attempted to distinguish valid code. To get the old behavior back,
add ``highlight_language = "python"`` to conf.py.
* `Locale Date Markup Language
<http://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns>`_ like
<https://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns>`_ like
``"MMMM dd, YYYY"`` is default format for `today_fmt` and `html_last_updated_fmt`.
However strftime format like ``"%B %d, %Y"`` is also supported for backward
compatibility until Sphinx-1.5. Later format will be disabled from Sphinx-1.5.

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.

700
EXAMPLES
View File

@@ -12,388 +12,398 @@ interesting examples.
Documentation using the alabaster theme
---------------------------------------
* Alabaster: https://alabaster.readthedocs.io/
* Blinker: https://pythonhosted.org/blinker/
* Calibre: https://manual.calibre-ebook.com/
* Click: http://click.pocoo.org/ (customized)
* coala: https://docs.coala.io/ (customized)
* CodePy: https://documen.tician.de/codepy/
* Fabric: http://docs.fabfile.org/
* Fityk: http://fityk.nieto.pl/
* Flask: http://flask.pocoo.org/docs/
* Flask-OpenID: https://pythonhosted.org/Flask-OpenID/
* Invoke: http://docs.pyinvoke.org/
* Jinja: http://jinja.pocoo.org/docs/
* Lino: http://www.lino-framework.org/ (customized)
* marbl: https://getmarbl.readthedocs.io/
* MDAnalysis: http://www.mdanalysis.org/docs/ (customized)
* MeshPy: https://documen.tician.de/meshpy/
* PyCUDA: https://documen.tician.de/pycuda/
* PyOpenCL: https://documen.tician.de/pyopencl/
* PyLangAcq: http://pylangacq.org/
* pytest: https://docs.pytest.org/ (customized)
* python-apt: https://apt.alioth.debian.org/python-apt-doc/
* PyVisfile: https://documen.tician.de/pyvisfile/
* Requests: http://www.python-requests.org/
* searx: https://asciimoo.github.io/searx/
* Tablib: http://docs.python-tablib.org/
* urllib3: https://urllib3.readthedocs.io/ (customized)
* Werkzeug: http://werkzeug.pocoo.org/docs/ (customized)
* `Alabaster <https://alabaster.readthedocs.io/>`__
* `Blinker <https://pythonhosted.org/blinker/>`__
* `Calibre <https://manual.calibre-ebook.com/>`__
* `Click <http://click.pocoo.org/>`__ (customized)
* `coala <https://docs.coala.io/>`__ (customized)
* `CodePy <https://documen.tician.de/codepy/>`__
* `Fabric <https://docs.fabfile.org/>`__
* `Fityk <https://fityk.nieto.pl/>`__
* `Flask <http://flask.pocoo.org/docs/>`__
* `Flask-OpenID <https://pythonhosted.org/Flask-OpenID/>`__
* `Invoke <https://docs.pyinvoke.org/>`__
* `Jinja <http://jinja.pocoo.org/docs/>`__
* `Lino <http://www.lino-framework.org/>`__ (customized)
* `marbl <https://getmarbl.readthedocs.io/>`__
* `MDAnalysis <https://www.mdanalysis.org/docs/>`__ (customized)
* `MeshPy <https://documen.tician.de/meshpy/>`__
* `Molecule <https://molecule.readthedocs.io/>`__
* `PyCUDA <https://documen.tician.de/pycuda/>`__
* `PyOpenCL <https://documen.tician.de/pyopencl/>`__
* `PyLangAcq <http://pylangacq.org/>`__
* `pytest <https://docs.pytest.org/>`__ (customized)
* `python-apt <https://apt.alioth.debian.org/python-apt-doc/>`__
* `PyVisfile <https://documen.tician.de/pyvisfile/>`__
* `Requests <http://www.python-requests.org/>`__
* `searx <https://asciimoo.github.io/searx/>`__
* `Spyder <https://docs.spyder-ide.org/>`__ (customized)
* `Tablib <http://docs.python-tablib.org/>`__
* `urllib3 <https://urllib3.readthedocs.io/>`__ (customized)
* `Werkzeug <http://werkzeug.pocoo.org/docs/>`__ (customized)
Documentation using the classic theme
-------------------------------------
* Advanced Generic Widgets: http://xoomer.virgilio.it/infinity77/AGW_Docs/ (customized)
* Apache CouchDB: http://docs.couchdb.org/ (customized)
* APSW: https://rogerbinns.github.io/apsw/
* Arb: http://arblib.org/
* Bazaar: http://doc.bazaar.canonical.com/ (customized)
* Beautiful Soup: https://www.crummy.com/software/BeautifulSoup/bs4/doc/
* Blender: https://docs.blender.org/api/current/
* Bugzilla: https://bugzilla.readthedocs.io/
* Buildbot: https://docs.buildbot.net/latest/
* CMake: https://cmake.org/documentation/ (customized)
* Chaco: http://docs.enthought.com/chaco/ (customized)
* Cormoran: http://cormoran.nhopkg.org/docs/
* DEAP: https://deap.readthedocs.io/ (customized)
* Director: https://pythonhosted.org/director/
* EZ-Draw: https://pageperso.lif.univ-mrs.fr/~edouard.thiel/ez-draw/doc/en/html/ez-manual.html (customized)
* F2py: http://f2py.sourceforge.net/docs/
* Generic Mapping Tools (GMT): http://gmt.soest.hawaii.edu/doc/latest/ (customized)
* Genomedata: https://noble.gs.washington.edu/proj/genomedata/doc/1.3.3/
* GetFEM++: http://getfem.org/ (customized)
* Glasgow Haskell Compiler: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ (customized)
* Grok: http://grok.zope.org/doc/current/ (customized)
* GROMACS: http://manual.gromacs.org/documentation/
* GSL Shell: http://www.nongnu.org/gsl-shell/
* Hands-on Python Tutorial: http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/
* Kaa: http://api.freevo.org/kaa-base/ (customized)
* Leo: http://leoeditor.com/
* LEPL: http://www.acooke.org/lepl/ (customized)
* Mayavi: http://docs.enthought.com/mayavi/mayavi/ (customized)
* MediaGoblin: https://mediagoblin.readthedocs.io/ (customized)
* mpmath: http://mpmath.org/doc/current/
* OpenCV: http://docs.opencv.org/ (customized)
* OpenEXR: http://excamera.com/articles/26/doc/index.html
* OpenGDA: http://www.opengda.org/gdadoc/html/
* Peach^3: https://peach3.nl/doc/latest/userdoc/ (customized)
* Plone: https://docs.plone.org/ (customized)
* PyEMD: https://pyemd.readthedocs.io/
* Pyevolve: http://pyevolve.sourceforge.net/
* Pygame: https://www.pygame.org/docs/ (customized)
* PyMQI: https://pythonhosted.org/pymqi/
* PyQt4: http://pyqt.sourceforge.net/Docs/PyQt4/ (customized)
* PyQt5: http://pyqt.sourceforge.net/Docs/PyQt5/ (customized)
* Python 2: https://docs.python.org/2/
* Python 3: https://docs.python.org/3/ (customized)
* Python Packaging Authority: https://www.pypa.io/ (customized)
* Ring programming language: http://ring-lang.sourceforge.net/doc/ (customized)
* SageMath: https://doc.sagemath.org/ (customized)
* Segway: http://noble.gs.washington.edu/proj/segway/doc/1.1.0/segway.html
* simuPOP: http://simupop.sourceforge.net/manual_release/build/userGuide.html (customized)
* Sprox: http://sprox.org/ (customized)
* SymPy: http://docs.sympy.org/
* TurboGears: https://turbogears.readthedocs.io/ (customized)
* tvtk: http://docs.enthought.com/mayavi/tvtk/
* Varnish: https://www.varnish-cache.org/docs/ (customized, alabaster for index)
* Waf: https://waf.io/apidocs/
* wxPython Phoenix: https://wxpython.org/Phoenix/docs/html/main.html (customized)
* z3c: http://www.ibiblio.org/paulcarduner/z3ctutorial/
* zc.async: https://pythonhosted.org/zc.async/ (customized)
* Zope: https://docs.zope.org/zope2/ (customized)
* `Advanced Generic Widgets <http://xoomer.virgilio.it/infinity77/AGW_Docs/>`__ (customized)
* `Apache CouchDB <http://docs.couchdb.org/>`__ (customized)
* `APSW <https://rogerbinns.github.io/apsw/>`__
* `Arb <http://arblib.org/>`__
* `Bazaar <http://doc.bazaar.canonical.com/>`__ (customized)
* `Beautiful Soup <https://www.crummy.com/software/BeautifulSoup/bs4/doc/>`__
* `Blender <https://docs.blender.org/api/current/>`__
* `Bugzilla <https://bugzilla.readthedocs.io/>`__
* `Buildbot <https://docs.buildbot.net/latest/>`__
* `CMake <https://cmake.org/documentation/>`__ (customized)
* `Chaco <https://docs.enthought.com/chaco/>`__ (customized)
* `CORE <https://downloads.pf.itd.nrl.navy.mil/docs/core/core-html/>`__
* `CORE Python modules <https://downloads.pf.itd.nrl.navy.mil/docs/core/core-python-html/>`__
* `Cormoran <http://cormoran.nhopkg.org/docs/>`__
* `DEAP <https://deap.readthedocs.io/>`__ (customized)
* `Director <https://pythonhosted.org/director/>`__
* `EZ-Draw <https://pageperso.lif.univ-mrs.fr/~edouard.thiel/ez-draw/doc/en/html/ez-manual.html>`__ (customized)
* `F2py <http://f2py.sourceforge.net/docs/>`__
* `Generic Mapping Tools (GMT) <https://gmt.soest.hawaii.edu/doc/latest/>`__ (customized)
* `Genomedata <https://noble.gs.washington.edu/proj/genomedata/doc/1.3.3/>`__
* `GetFEM++ <http://getfem.org/>`__ (customized)
* `Glasgow Haskell Compiler <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/>`__ (customized)
* `Grok <http://grok.zope.org/doc/current/>`__ (customized)
* `GROMACS <http://manual.gromacs.org/documentation/>`__
* `GSL Shell <https://www.nongnu.org/gsl-shell/>`__
* `Hands-on Python Tutorial <https://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/>`__
* `Kaa <https://api.freevo.org/kaa-base/>`__ (customized)
* `Leo <https://leoeditor.com/>`__
* `LEPL <http://www.acooke.org/lepl/>`__ (customized)
* `Mayavi <https://docs.enthought.com/mayavi/mayavi/>`__ (customized)
* `MediaGoblin <https://mediagoblin.readthedocs.io/>`__ (customized)
* `mpmath <http://mpmath.org/doc/current/>`__
* `OpenCV <https://docs.opencv.org/>`__ (customized)
* `OpenEXR <http://excamera.com/articles/26/doc/index.html>`__
* `OpenGDA <http://www.opengda.org/gdadoc/html/>`__
* `Peach^3 <https://peach3.nl/doc/latest/userdoc/>`__ (customized)
* `Plone <https://docs.plone.org/>`__ (customized)
* `PyEMD <https://pyemd.readthedocs.io/>`__
* `Pyevolve <http://pyevolve.sourceforge.net/>`__
* `Pygame <https://www.pygame.org/docs/>`__ (customized)
* `PyMQI <https://pythonhosted.org/pymqi/>`__
* `PyQt4 <http://pyqt.sourceforge.net/Docs/PyQt4/>`__ (customized)
* `PyQt5 <http://pyqt.sourceforge.net/Docs/PyQt5/>`__ (customized)
* `Python 2 <https://docs.python.org/2/>`__
* `Python 3 <https://docs.python.org/3/>`__ (customized)
* `Python Packaging Authority <https://www.pypa.io/>`__ (customized)
* `Ring programming language <http://ring-lang.sourceforge.net/doc/>`__ (customized)
* `SageMath <https://doc.sagemath.org/>`__ (customized)
* `Segway <https://noble.gs.washington.edu/proj/segway/doc/1.1.0/segway.html>`__
* `simuPOP <http://simupop.sourceforge.net/manual_release/build/userGuide.html>`__ (customized)
* `Sprox <http://sprox.org/>`__ (customized)
* `SymPy <https://docs.sympy.org/>`__
* `TurboGears <https://turbogears.readthedocs.io/>`__ (customized)
* `tvtk <https://docs.enthought.com/mayavi/tvtk/>`__
* `Varnish <https://www.varnish-cache.org/docs/>`__ (customized, alabaster for index)
* `Waf <https://waf.io/apidocs/>`__
* `wxPython Phoenix <https://wxpython.org/Phoenix/docs/html/main.html>`__ (customized)
* `Yum <http://yum.baseurl.org/api/yum/>`__
* `z3c <https://www.ibiblio.org/paulcarduner/z3ctutorial/>`__
* `zc.async <https://pythonhosted.org/zc.async/>`__ (customized)
* `Zope <https://docs.zope.org/zope2/>`__ (customized)
Documentation using the sphinxdoc theme
---------------------------------------
* cartopy: http://scitools.org.uk/cartopy/docs/latest/
* Jython: http://www.jython.org/docs/
* Matplotlib: https://matplotlib.org/
* MDAnalysis Tutorial: http://www.mdanalysis.org/MDAnalysisTutorial/
* NetworkX: https://networkx.github.io/
* PyCantonese: http://pycantonese.org/
* Pyre: http://docs.danse.us/pyre/sphinx/
* pySPACE: https://pyspace.github.io/pyspace/
* Pysparse: http://pysparse.sourceforge.net/
* PyTango:
http://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/pytango/latest/
* Python Wild Magic: https://vmlaker.github.io/pythonwildmagic/ (customized)
* Reteisi: http://www.reteisi.org/contents.html (customized)
* Sqlkit: http://sqlkit.argolinux.org/ (customized)
* Turbulenz: http://docs.turbulenz.com/
* `cartopy <https://scitools.org.uk/cartopy/docs/latest/>`__
* `Jython <http://www.jython.org/docs/>`__
* `Matplotlib <https://matplotlib.org/>`__
* `MDAnalysis Tutorial <https://www.mdanalysis.org/MDAnalysisTutorial/>`__
* `NetworkX <https://networkx.github.io/>`__
* `PyCantonese <http://pycantonese.org/>`__
* `Pyre <http://docs.danse.us/pyre/sphinx/>`__
* `pySPACE <https://pyspace.github.io/pyspace/>`__
* `Pysparse <http://pysparse.sourceforge.net/>`__
* `PyTango <https://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/pytango/latest/>`__
* `Python Wild Magic <https://vmlaker.github.io/pythonwildmagic/>`__ (customized)
* `Reteisi <http://www.reteisi.org/contents.html>`__ (customized)
* `Sqlkit <http://sqlkit.argolinux.org/>`__ (customized)
* `Turbulenz <http://docs.turbulenz.com/>`__
Documentation using the nature theme
------------------------------------
* Alembic: http://alembic.zzzcomputing.com/
* Cython: http://docs.cython.org/
* easybuild: https://easybuild.readthedocs.io/
* jsFiddle: http://doc.jsfiddle.net/
* libLAS: https://www.liblas.org/ (customized)
* Lmod: https://lmod.readthedocs.io/
* MapServer: http://mapserver.org/ (customized)
* Pandas: https://pandas.pydata.org/pandas-docs/stable/
* pyglet: https://pyglet.readthedocs.io/ (customized)
* Setuptools: https://setuptools.readthedocs.io/
* Spring Python: https://docs.spring.io/spring-python/1.2.x/sphinx/html/
* StatsModels: http://www.statsmodels.org/ (customized)
* Sylli: http://sylli.sourceforge.net/
* `Alembic <http://alembic.zzzcomputing.com/>`__
* `Cython <http://docs.cython.org/>`__
* `easybuild <https://easybuild.readthedocs.io/>`__
* `jsFiddle <http://doc.jsfiddle.net/>`__
* `libLAS <https://www.liblas.org/>`__ (customized)
* `Lmod <https://lmod.readthedocs.io/>`__
* `MapServer <https://mapserver.org/>`__ (customized)
* `Pandas <https://pandas.pydata.org/pandas-docs/stable/>`__
* `pyglet <https://pyglet.readthedocs.io/>`__ (customized)
* `Setuptools <https://setuptools.readthedocs.io/>`__
* `Spring Python <https://docs.spring.io/spring-python/1.2.x/sphinx/html/>`__
* `StatsModels <https://www.statsmodels.org/>`__ (customized)
* `Sylli <http://sylli.sourceforge.net/>`__
Documentation using another builtin theme
-----------------------------------------
* Breathe: https://breathe.readthedocs.io/ (haiku)
* MPipe: https://vmlaker.github.io/mpipe/ (sphinx13)
* NLTK: http://www.nltk.org/ (agogo)
* Programmieren mit PyGTK und Glade (German):
http://www.florian-diesch.de/doc/python-und-glade/online/ (agogo, customized)
* PyPubSub: https://pypubsub.readthedocs.io/ (bizstyle)
* Pylons: http://docs.pylonsproject.org/projects/pylons-webframework/ (pyramid)
* Pyramid web framework:
https://docs.pylonsproject.org/projects/pyramid/ (pyramid)
* Sphinx: http://www.sphinx-doc.org/ (sphinx13) :-)
* Valence: http://docs.valence.desire2learn.com/ (haiku, customized)
* `Breathe <https://breathe.readthedocs.io/>`__ (haiku)
* `MPipe <https://vmlaker.github.io/mpipe/>`__ (sphinx13)
* `NLTK <https://www.nltk.org/>`__ (agogo)
* `Programmieren mit PyGTK und Glade (German) <https://www.florian-diesch.de/doc/python-und-glade/online/>`__ (agogo, customized)
* `PyPubSub <https://pypubsub.readthedocs.io/>`__ (bizstyle)
* `Pylons <https://docs.pylonsproject.org/projects/pylons-webframework/>`__ (pyramid)
* `Pyramid web framework <https://docs.pylonsproject.org/projects/pyramid/>`__ (pyramid)
* `Sphinx <http://www.sphinx-doc.org/>`__ (sphinx13) :-)
* `Valence <https://docs.valence.desire2learn.com/>`__ (haiku, customized)
Documentation using sphinx_rtd_theme
------------------------------------
* Annotator: http://docs.annotatorjs.org/
* Ansible: https://docs.ansible.com/ (customized)
* Arcade: http://arcade.academy/
* aria2: https://aria2.github.io/manual/en/html/
* ASE: https://wiki.fysik.dtu.dk/ase/
* Autofac: http://docs.autofac.org/
* BigchainDB: https://docs.bigchaindb.com/
* Blocks: https://blocks.readthedocs.io/
* bootstrap-datepicker: https://bootstrap-datepicker.readthedocs.io/
* Certbot: https://letsencrypt.readthedocs.io/
* Chainer: https://docs.chainer.org/ (customized)
* CherryPy: http://docs.cherrypy.org/
* Chainer: https://docs.chainer.org/
* CodeIgniter: https://www.codeigniter.com/user_guide/
* Conda: https://conda.io/docs/
* Corda: https://docs.corda.net/
* Dask: https://dask.pydata.org/
* Databricks: https://docs.databricks.com/ (customized)
* Dataiku DSS: https://doc.dataiku.com/
* edX: http://docs.edx.org/
* Electrum: http://docs.electrum.org/
* Elemental: http://libelemental.org/documentation/dev/
* ESWP3: https://eswp3.readthedocs.io/
* Ethereum Homestead: http://www.ethdocs.org/
* Fidimag: https://fidimag.readthedocs.io/
* Flake8: http://flake8.pycqa.org/
* GeoNode: http://docs.geonode.org/
* Godot: https://godot.readthedocs.io/
* Graylog: http://docs.graylog.org/
* GPAW: https://wiki.fysik.dtu.dk/gpaw/ (customized)
* HDF5 for Python (h5py): http://docs.h5py.org/
* Hyperledger Fabric: https://hyperledger-fabric.readthedocs.io/
* Hyperledger Sawtooth: https://intelledger.github.io/
* IdentityServer: http://docs.identityserver.io/
* Idris: http://docs.idris-lang.org/
* javasphinx: https://bronto-javasphinx.readthedocs.io/
* Julia: https://julia.readthedocs.io/
* Jupyter Notebook: https://jupyter-notebook.readthedocs.io/
* Lasagne: https://lasagne.readthedocs.io/
* latexindent.pl: https://latexindentpl.readthedocs.io/
* Linguistica: https://linguistica-uchicago.github.io/lxa5/
* Linux kernel: https://www.kernel.org/doc/html/latest/index.html
* MathJax: https://docs.mathjax.org/
* MDTraj: http://mdtraj.org/latest/ (customized)
* MICrobial Community Analysis (micca): http://micca.org/docs/latest/
* MicroPython: https://docs.micropython.org/
* Minds: https://www.minds.org/docs/ (customized)
* Mink: http://mink.behat.org/
* Mockery: http://docs.mockery.io/
* mod_wsgi: https://modwsgi.readthedocs.io/
* MoinMoin: https://moin-20.readthedocs.io/
* Mopidy: https://docs.mopidy.com/
* MyHDL: http://docs.myhdl.org/
* Nextflow: https://www.nextflow.io/docs/latest/index.html
* NICOS: https://forge.frm2.tum.de/nicos/doc/nicos-master/ (customized)
* Pelican: http://docs.getpelican.com/
* picamera: https://picamera.readthedocs.io/
* Pillow: https://pillow.readthedocs.io/
* pip: https://pip.pypa.io/
* Paver: https://paver.readthedocs.io/
* peewee: http://docs.peewee-orm.com/
* Phinx: http://docs.phinx.org/
* phpMyAdmin: https://docs.phpmyadmin.net/
* PROS: https://pros.cs.purdue.edu/v5/ (customized)
* Pweave: http://mpastell.com/pweave/
* PyPy: http://doc.pypy.org/
* python-sqlparse: https://sqlparse.readthedocs.io/
* PyVISA: https://pyvisa.readthedocs.io/
* Read The Docs: https://docs.readthedocs.io/
* Free your information from their silos (French):
http://redaction-technique.org/ (customized)
* Releases Sphinx extension: https://releases.readthedocs.io/
* Qtile: http://docs.qtile.org/
* Quex: http://quex.sourceforge.net/doc/html/main.html
* Satchmo: http://docs.satchmoproject.com/
* Scapy: https://scapy.readthedocs.io/
* SimPy: http://simpy.readthedocs.io/
* SlamData: http://docs.slamdata.com/
* Solidity: https://solidity.readthedocs.io/
* Sonos Controller (SoCo): http://docs.python-soco.com/
* Sphinx AutoAPI: https://sphinx-autoapi.readthedocs.io/
* sphinx-argparse: https://sphinx-argparse.readthedocs.io/
* Sphinx-Gallery: https://sphinx-gallery.readthedocs.io/ (customized)
* StarUML: http://docs.staruml.io/
* Sublime Text Unofficial Documentation: http://docs.sublimetext.info/
* SunPy: http://docs.sunpy.org/
* Sylius: http://docs.sylius.org/
* Tango Controls: https://tango-controls.readthedocs.io/ (customized)
* Topshelf: http://docs.topshelf-project.com/
* Theano: http://www.deeplearning.net/software/theano/
* ThreatConnect: https://docs.threatconnect.com/
* Tuleap: https://tuleap.net/doc/en/
* TYPO3: https://docs.typo3.org/ (customized)
* uWSGI: https://uwsgi-docs.readthedocs.io/
* Wagtail: http://docs.wagtail.io/
* Web Application Attack and Audit Framework (w3af): http://docs.w3af.org/
* Weblate: https://docs.weblate.org/
* x265: https://x265.readthedocs.io/
* ZeroNet: https://zeronet.readthedocs.io/
* `Annotator <http://docs.annotatorjs.org/>`__
* `Ansible <https://docs.ansible.com/>`__ (customized)
* `Arcade <http://arcade.academy/>`__
* `aria2 <https://aria2.github.io/manual/en/html/>`__
* `ASE <https://wiki.fysik.dtu.dk/ase/>`__
* `Autofac <http://docs.autofac.org/>`__
* `BigchainDB <https://docs.bigchaindb.com/>`__
* `Blocks <https://blocks.readthedocs.io/>`__
* `bootstrap-datepicker <https://bootstrap-datepicker.readthedocs.io/>`__
* `Certbot <https://letsencrypt.readthedocs.io/>`__
* `Chainer <https://docs.chainer.org/>`__ (customized)
* `CherryPy <https://docs.cherrypy.org/>`__
* `cloud-init <https://cloudinit.readthedocs.io/>`__
* `CodeIgniter <https://www.codeigniter.com/user_guide/>`__
* `Conda <https://conda.io/docs/>`__
* `Corda <https://docs.corda.net/>`__
* `Dask <https://dask.pydata.org/>`__
* `Databricks <https://docs.databricks.com/>`__ (customized)
* `Dataiku DSS <https://doc.dataiku.com/>`__
* `DNF <https://dnf.readthedocs.io/>`__
* `edX <https://docs.edx.org/>`__
* `Electrum <http://docs.electrum.org/>`__
* `Elemental <http://libelemental.org/documentation/dev/>`__
* `ESWP3 <https://eswp3.readthedocs.io/>`__
* `Ethereum Homestead <http://www.ethdocs.org/>`__
* `Fidimag <https://fidimag.readthedocs.io/>`__
* `Flake8 <http://flake8.pycqa.org/>`__
* `FluidDyn <https://fluiddyn.readthedocs.io/>`__
* `Fluidsim <https://fluidsim.readthedocs.io/>`__
* `GeoNode <http://docs.geonode.org/>`__
* `Godot <https://godot.readthedocs.io/>`__
* `Graylog <http://docs.graylog.org/>`__
* `GPAW <https://wiki.fysik.dtu.dk/gpaw/>`__ (customized)
* `HDF5 for Python (h5py) <http://docs.h5py.org/>`__
* `Hyperledger Fabric <https://hyperledger-fabric.readthedocs.io/>`__
* `Hyperledger Sawtooth <https://intelledger.github.io/>`__
* `IdentityServer <http://docs.identityserver.io/>`__
* `Idris <http://docs.idris-lang.org/>`__
* `javasphinx <https://bronto-javasphinx.readthedocs.io/>`__
* `Julia <https://julia.readthedocs.io/>`__
* `Jupyter Notebook <https://jupyter-notebook.readthedocs.io/>`__
* `Lasagne <https://lasagne.readthedocs.io/>`__
* `latexindent.pl <https://latexindentpl.readthedocs.io/>`__
* `Linguistica <https://linguistica-uchicago.github.io/lxa5/>`__
* `Linux kernel <https://www.kernel.org/doc/html/latest/index.html>`__
* `MathJax <https://docs.mathjax.org/>`__
* `MDTraj <http://mdtraj.org/latest/>`__ (customized)
* `MICrobial Community Analysis (micca) <http://micca.org/docs/latest/>`__
* `MicroPython <https://docs.micropython.org/>`__
* `Minds <https://www.minds.org/docs/>`__ (customized)
* `Mink <http://mink.behat.org/>`__
* `Mockery <http://docs.mockery.io/>`__
* `mod_wsgi <https://modwsgi.readthedocs.io/>`__
* `MoinMoin <https://moin-20.readthedocs.io/>`__
* `Mopidy <https://docs.mopidy.com/>`__
* `MyHDL <http://docs.myhdl.org/>`__
* `Nextflow <https://www.nextflow.io/docs/latest/index.html>`__
* `NICOS <https://forge.frm2.tum.de/nicos/doc/nicos-master/>`__ (customized)
* `Pelican <http://docs.getpelican.com/>`__
* `picamera <https://picamera.readthedocs.io/>`__
* `Pillow <https://pillow.readthedocs.io/>`__
* `pip <https://pip.pypa.io/>`__
* `Paver <https://paver.readthedocs.io/>`__
* `peewee <http://docs.peewee-orm.com/>`__
* `Phinx <http://docs.phinx.org/>`__
* `phpMyAdmin <https://docs.phpmyadmin.net/>`__
* `PROS <https://pros.cs.purdue.edu/v5/>`__ (customized)
* `Pweave <http://mpastell.com/pweave/>`__
* `PyPy <http://doc.pypy.org/>`__
* `python-sqlparse <https://sqlparse.readthedocs.io/>`__
* `PyVISA <https://pyvisa.readthedocs.io/>`__
* `Read The Docs <https://docs.readthedocs.io/>`__
* `Free your information from their silos (French) <http://redaction-technique.org/>`__ (customized)
* `Releases Sphinx extension <https://releases.readthedocs.io/>`__
* `Qtile <http://docs.qtile.org/>`__
* `Quex <http://quex.sourceforge.net/doc/html/main.html>`__
* `Satchmo <http://docs.satchmoproject.com/>`__
* `Scapy <https://scapy.readthedocs.io/>`__
* `SimPy <https://simpy.readthedocs.io/>`__
* `six <https://six.readthedocs.io/>`__
* `SlamData <https://newdocs.slamdata.com>`__
* `Solidity <https://solidity.readthedocs.io/>`__
* `Sonos Controller (SoCo) <http://docs.python-soco.com/>`__
* `Sphinx AutoAPI <https://sphinx-autoapi.readthedocs.io/>`__
* `sphinx-argparse <https://sphinx-argparse.readthedocs.io/>`__
* `Sphinx-Gallery <https://sphinx-gallery.readthedocs.io/>`__ (customized)
* `SpotBugs <https://spotbugs.readthedocs.io/>`__
* `StarUML <https://docs.staruml.io/>`__
* `Sublime Text Unofficial Documentation <http://docs.sublimetext.info/>`__
* `SunPy <https://docs.sunpy.org/>`__
* `Sylius <http://docs.sylius.org/>`__
* `Tango Controls <https://tango-controls.readthedocs.io/>`__ (customized)
* `Topshelf <http://docs.topshelf-project.com/>`__
* `Theano <http://www.deeplearning.net/software/theano/>`__
* `ThreatConnect <https://docs.threatconnect.com/>`__
* `Tuleap <https://tuleap.net/doc/en/>`__
* `TYPO3 <https://docs.typo3.org/>`__ (customized)
* `uWSGI <https://uwsgi-docs.readthedocs.io/>`__
* `virtualenv <https://virtualenv.readthedocs.io/>`__
* `Wagtail <https://docs.wagtail.io/>`__
* `Web Application Attack and Audit Framework (w3af) <http://docs.w3af.org/>`__
* `Weblate <https://docs.weblate.org/>`__
* `x265 <https://x265.readthedocs.io/>`__
* `ZeroNet <https://zeronet.readthedocs.io/>`__
Documentation using sphinx_bootstrap_theme
------------------------------------------
* Bootstrap Theme: https://ryan-roemer.github.io/sphinx-bootstrap-theme/
* C/C++ Software Development with Eclipse: http://eclipsebook.in/
* Dataverse: http://guides.dataverse.org/
* e-cidadania: https://e-cidadania.readthedocs.io/
* Hangfire: http://docs.hangfire.io/
* Hedge: https://documen.tician.de/hedge/
* ObsPy: https://docs.obspy.org/
* Open Dylan: https://opendylan.org/documentation/
* Pootle: http://docs.translatehouse.org/projects/pootle/
* PyUblas: https://documen.tician.de/pyublas/
* seaborn: https://seaborn.pydata.org/
* `Bootstrap Theme <https://ryan-roemer.github.io/sphinx-bootstrap-theme/>`__
* `C/C++ Software Development with Eclipse <https://eclipsebook.in/>`__
* `Dataverse <http://guides.dataverse.org/>`__
* `e-cidadania <https://e-cidadania.readthedocs.io/>`__
* `Hangfire <http://docs.hangfire.io/>`__
* `Hedge <https://documen.tician.de/hedge/>`__
* `ObsPy <https://docs.obspy.org/>`__
* `Open Dylan <https://opendylan.org/documentation/>`__
* `Pootle <http://docs.translatehouse.org/projects/pootle/>`__
* `PyUblas <https://documen.tician.de/pyublas/>`__
* `seaborn <https://seaborn.pydata.org/>`__
Documentation using a custom theme or integrated in a website
-------------------------------------------------------------
* Apache Cassandra: https://cassandra.apache.org/doc/
* Astropy: http://docs.astropy.org/
* Bokeh: https://bokeh.pydata.org/
* Boto 3: https://boto3.readthedocs.io/
* CakePHP: https://book.cakephp.org/
* CasperJS: http://docs.casperjs.org/
* Ceph: http://docs.ceph.com/docs/master/
* Chef: https://docs.chef.io/
* CKAN: http://docs.ckan.org/
* Confluent Platform: http://docs.confluent.io/
* Django: https://docs.djangoproject.com/
* Doctrine: http://docs.doctrine-project.org/
* Enterprise Toolkit for Acrobat products:
https://www.adobe.com/devnet-docs/acrobatetk/
* Gameduino: http://excamera.com/sphinx/gameduino/
* gensim: https://radimrehurek.com/gensim/
* GeoServer: http://docs.geoserver.org/
* gevent: http://www.gevent.org/
* GHC - Glasgow Haskell Compiler: http://downloads.haskell.org/~ghc/master/users-guide/
* Guzzle: http://docs.guzzlephp.org/en/stable/
* H2O.ai: http://docs.h2o.ai/
* Istihza (Turkish Python documentation project): https://belgeler.yazbel.com/python-istihza/
* Kombu: http://docs.kombu.me/
* Lasso: http://lassoguide.com/
* Mako: http://docs.makotemplates.org/
* MirrorBrain: http://mirrorbrain.org/docs/
* MongoDB: https://docs.mongodb.com/
* Music21: http://web.mit.edu/music21/doc/
* MyHDL: http://docs.myhdl.org/en/latest/
* nose: https://nose.readthedocs.io/
* ns-3: https://www.nsnam.org/documentation/
* NumPy: https://docs.scipy.org/doc/numpy/reference/
* ObjectListView: http://objectlistview.sourceforge.net/python/
* OpenERP: https://doc.odoo.com/
* OpenCV: http://docs.opencv.org/
* OpenLayers: http://docs.openlayers.org/
* OpenTURNS: http://openturns.github.io/openturns/master/
* Open vSwitch: http://docs.openvswitch.org/
* PlatformIO: http://docs.platformio.org/
* PyEphem: http://rhodesmill.org/pyephem/
* Pygments: http://pygments.org/docs/
* Plone User Manual (German): https://www.hasecke.com/plone-benutzerhandbuch/4.0/
* PSI4: http://www.psicode.org/psi4manual/master/index.html
* PyMOTW: https://pymotw.com/2/
* python-aspectlib: https://python-aspectlib.readthedocs.io/
(`sphinx_py3doc_enhanced_theme <https://pypi.org/project/sphinx_py3doc_enhanced_theme/>`__)
* QGIS: https://qgis.org/en/docs/index.html
* qooxdoo: http://www.qooxdoo.org/current/
* Roundup: http://www.roundup-tracker.org/
* SaltStack: https://docs.saltstack.com/
* scikit-learn: http://scikit-learn.org/stable/
* SciPy: https://docs.scipy.org/doc/scipy/refrence/
* Scrapy: https://doc.scrapy.org/
* Seaborn: https://seaborn.pydata.org/
* Selenium: http://docs.seleniumhq.org/docs/
* Self: http://www.selflanguage.org/
* Substance D: https://docs.pylonsproject.org/projects/substanced/
* Sulu: http://docs.sulu.io/
* SQLAlchemy: https://docs.sqlalchemy.org/
* tinyTiM: http://tinytim.sourceforge.net/docs/2.0/
* Twisted: http://twistedmatrix.com/documents/current/
* Ubuntu Packaging Guide: http://packaging.ubuntu.com/html/
* WebFaction: https://docs.webfaction.com/
* WTForms: https://wtforms.readthedocs.io/
* `Apache Cassandra <https://cassandra.apache.org/doc/>`__
* `Astropy <http://docs.astropy.org/>`__
* `Bokeh <https://bokeh.pydata.org/>`__
* `Boto 3 <https://boto3.readthedocs.io/>`__
* `CakePHP <https://book.cakephp.org/>`__
* `CasperJS <http://docs.casperjs.org/>`__
* `Ceph <http://docs.ceph.com/docs/master/>`__
* `Chef <https://docs.chef.io/>`__
* `CKAN <https://docs.ckan.org/>`__
* `Confluent Platform <https://docs.confluent.io/>`__
* `Django <https://docs.djangoproject.com/>`__
* `Doctrine <https://www.doctrine-project.org/>`__
* `Enterprise Toolkit for Acrobat products <https://www.adobe.com/devnet-docs/acrobatetk/>`__
* `Gameduino <http://excamera.com/sphinx/gameduino/>`__
* `gensim <https://radimrehurek.com/gensim/>`__
* `GeoServer <http://docs.geoserver.org/>`__
* `gevent <http://www.gevent.org/>`__
* `GHC - Glasgow Haskell Compiler <https://downloads.haskell.org/~ghc/master/users-guide/>`__
* `Guzzle <http://docs.guzzlephp.org/>`__
* `H2O.ai <http://docs.h2o.ai/>`__
* `Istihza (Turkish Python documentation project) <https://belgeler.yazbel.com/python-istihza/>`__
* `Kombu <http://docs.kombu.me/>`__
* `Lasso <http://lassoguide.com/>`__
* `Mako <http://docs.makotemplates.org/>`__
* `MirrorBrain <http://mirrorbrain.org/docs/>`__
* `MongoDB <https://docs.mongodb.com/>`__
* `Music21 <https://web.mit.edu/music21/doc/>`__
* `MyHDL <http://docs.myhdl.org/>`__
* `nose <https://nose.readthedocs.io/>`__
* `ns-3 <https://www.nsnam.org/documentation/>`__
* `NumPy <https://docs.scipy.org/doc/numpy/reference/>`__
* `ObjectListView <http://objectlistview.sourceforge.net/python/>`__
* `OpenERP <https://doc.odoo.com/>`__
* `OpenCV <https://docs.opencv.org/>`__
* `OpenLayers <http://docs.openlayers.org/>`__
* `OpenTURNS <https://openturns.github.io/openturns/master/>`__
* `Open vSwitch <http://docs.openvswitch.org/>`__
* `PlatformIO <https://docs.platformio.org/>`__
* `PyEphem <http://rhodesmill.org/pyephem/>`__
* `Pygments <http://pygments.org/docs/>`__
* `Plone User Manual (German) <https://www.hasecke.com/plone-benutzerhandbuch/4.0/>`__
* `PSI4 <http://www.psicode.org/psi4manual/master/index.html>`__
* `PyMOTW <https://pymotw.com/2/>`__
* `python-aspectlib <https://python-aspectlib.readthedocs.io/>`__ (`sphinx_py3doc_enhanced_theme <https://pypi.org/project/sphinx_py3doc_enhanced_theme/>`__)
* `QGIS <https://qgis.org/en/docs/index.html>`__
* `qooxdoo <https://www.qooxdoo.org/current/>`__
* `Roundup <http://www.roundup-tracker.org/>`__
* `SaltStack <https://docs.saltstack.com/>`__
* `scikit-learn <http://scikit-learn.org/stable/>`__
* `SciPy <https://docs.scipy.org/doc/scipy/refrence/>`__
* `Scrapy <https://doc.scrapy.org/>`__
* `Seaborn <https://seaborn.pydata.org/>`__
* `Selenium <https://docs.seleniumhq.org/docs/>`__
* `Self <http://www.selflanguage.org/>`__
* `Substance D <https://docs.pylonsproject.org/projects/substanced/>`__
* `Sulu <http://docs.sulu.io/>`__
* `SQLAlchemy <https://docs.sqlalchemy.org/>`__
* `tinyTiM <http://tinytim.sourceforge.net/docs/2.0/>`__
* `Twisted <https://twistedmatrix.com/documents/current/>`__
* `Ubuntu Packaging Guide <http://packaging.ubuntu.com/html/>`__
* `WebFaction <https://docs.webfaction.com/>`__
* `WTForms <https://wtforms.readthedocs.io/>`__
Homepages and other non-documentation sites
-------------------------------------------
* Arizona State University PHY494/PHY598/CHM598 Simulation approaches to Bio-
and Nanophysics:
https://becksteinlab.physics.asu.edu/pages/courses/2013/SimBioNano/ (classic)
* Benoit Boissinot: https://bboissin.appspot.com/ (classic, customized)
* Computer Networks, Parallelization, and Simulation Laboratory (CNPSLab):
https://lab.miletic.net/ (sphinx_rtd_theme)
* Deep Learning Tutorials: http://www.deeplearning.net/tutorial/ (sphinxdoc)
* Loyola University Chicago COMP 339-439 Distributed Systems course:
http://books.cs.luc.edu/distributedsystems/ (sphinx_bootstrap_theme)
* Pylearn2: http://www.deeplearning.net/software/pylearn2/ (sphinxdoc, customized)
* SciPy Cookbook: https://scipy-cookbook.readthedocs.io/ (sphinx_rtd_theme)
* The Wine Cellar Book: https://www.thewinecellarbook.com/doc/en/ (sphinxdoc)
* Thomas Cokelaer's Python, Sphinx and reStructuredText tutorials:
http://thomas-cokelaer.info/tutorials/ (standard)
* UC Berkeley ME233 Advanced Control Systems II course:
https://berkeley-me233.github.io/ (sphinxdoc)
* `Arizona State University PHY494/PHY598/CHM598 Simulation approaches to Bio-and Nanophysics <https://becksteinlab.physics.asu.edu/pages/courses/2013/SimBioNano/>`__ (classic)
* `Benoit Boissinot <https://bboissin.appspot.com/>`__ (classic, customized)
* `Computer Networks, Parallelization, and Simulation Laboratory (CNPSLab) <https://lab.miletic.net/>`__ (sphinx_rtd_theme)
* `Deep Learning Tutorials <http://www.deeplearning.net/tutorial/>`__ (sphinxdoc)
* `Eric Holscher <http://ericholscher.com/>`__ (alabaster)
* `Lei Ma's Statistical Mechanics lecture notes <http://statisticalphysics.openmetric.org/>`__ (sphinx_bootstrap_theme)
* `Loyola University Chicago COMP 339-439 Distributed Systems course <https://books.cs.luc.edu/distributedsystems/>`__ (sphinx_bootstrap_theme)
* `Pylearn2 <http://www.deeplearning.net/software/pylearn2/>`__ (sphinxdoc, customized)
* `PyXLL <https://www.pyxll.com/>`__ (sphinx_bootstrap_theme, customized)
* `SciPy Cookbook <https://scipy-cookbook.readthedocs.io/>`__ (sphinx_rtd_theme)
* `The Wine Cellar Book <https://www.thewinecellarbook.com/doc/en/>`__ (sphinxdoc)
* `Thomas Cokelaer's Python, Sphinx and reStructuredText tutorials <https://thomas-cokelaer.info/tutorials/>`__ (standard)
* `UC Berkeley ME233 Advanced Control Systems II course <https://berkeley-me233.github.io/>`__ (sphinxdoc)
* `Željko Svedružić's Biomolecular Structure and Function Laboratory (BioSFLab) <https://www.svedruziclab.com/>`__ (sphinx_bootstrap_theme)
Books produced using Sphinx
---------------------------
* "Die Wahrheit des Sehens. Der DEKALOG von Krzysztof Kieślowski":
https://literatur.hasecke.com/post/die-wahrheit-des-sehens-dekalog-kieslowski/
* "Expert Python Programming":
https://www.packtpub.com/application-development/expert-python-programming
* "Expert Python Programming" (Japanese translation):
https://www.amazon.co.jp/dp/4048686291/
* "The Hitchhiker's Guide to Python": http://docs.python-guide.org/en/latest/
* "LassoGuide": http://www.lassosoft.com/Lasso-Documentation
* "Learning Sphinx" (in Japanese):
https://www.oreilly.co.jp/books/9784873116488/
* "Mercurial: the definitive guide (Second edition)":
https://book.mercurial-scm.org/
* "Pioneers and Prominent Men of Utah": http://pioneers.rstebbing.com/
* "Pomodoro Technique Illustrated" (Japanese translation):
https://www.amazon.co.jp/dp/4048689525/
* "Python Professional Programming" (in Japanese):
http://www.amazon.co.jp/dp/4798032948/
* "The ``repoze.bfg`` Web Application Framework":
https://www.amazon.com/repoze-bfg-Web-Application-Framework-Version/dp/0615345379
* "Simple and Steady Way of Learning for Software Engineering" (in Japanese):
https://www.amazon.co.jp/dp/477414259X/
* "Software-Dokumentation mit Sphinx": https://www.amazon.de/dp/1497448689/
* "Theoretical Physics Reference": http://www.theoretical-physics.net/
* "The Varnish Book":
https://info.varnish-software.com/the-varnish-book
* `"The Art of Community" (Japanese translation) <https://www.oreilly.co.jp/books/9784873114958/>`__
* `"Die Wahrheit des Sehens. Der DEKALOG von Krzysztof Kieślowski" <https://literatur.hasecke.com/post/die-wahrheit-des-sehens-dekalog-kieslowski/>`__
* `"Expert Python Programming" <https://www.packtpub.com/application-development/expert-python-programming>`__
* `"Expert Python Programming" (Japanese translation) <https://www.amazon.co.jp/dp/4048686291/>`__
* `"Expert Python Programming 2nd Edition" (Japanese translation) <https://www.amazon.co.jp/dp/4048930613/>`__
* `"The Hitchhiker's Guide to Python" <https://docs.python-guide.org/>`__
* `"LassoGuide" <http://www.lassosoft.com/Lasso-Documentation>`__
* `"Learning Sphinx" (in Japanese) <https://www.oreilly.co.jp/books/9784873116488/>`__
* `"Learning System Programming with Go (Japanese)" <https://www.lambdanote.com/products/go>`__
* `"Mercurial: the definitive guide (Second edition)" <https://book.mercurial-scm.org/>`__
* `"Mithril -- The fastest clientside MVC (Japanese)" <https://www.oreilly.co.jp/books/9784873117447/>`__
* `"Pioneers and Prominent Men of Utah" <http://pioneers.rstebbing.com/>`__
* `"Pomodoro Technique Illustrated" (Japanese translation) <https://www.amazon.co.jp/dp/4048689525/>`__
* `"Python Professional Programming" (in Japanese) <http://www.amazon.co.jp/dp/4798032948/>`__
* `"Python Professional Programming 2nd Edition" (in Japanese) <https://www.amazon.co.jp/dp/479804315X/>`__
* `"Python Professional Programming 3rd Edition" (in Japanese) <https://www.amazon.co.jp/dp/4798053821/>`__
* `"Real World HTTP -- Learning The Internet and Web Technology via its history and code (Japanese)" <https://www.oreilly.co.jp/books/9784873118048/>`__
* `"Redmine Primer 5th Edition (in Japanese)" <https://www.shuwasystem.co.jp/products/7980html/4825.html>`__
* `"The repoze.bfg Web Application Framework" <https://www.amazon.com/repoze-bfg-Web-Application-Framework-Version/dp/0615345379>`__
* `"The Self-Taught Programmer" (Japanese translation) <https://www.amazon.co.jp/dp/4822292274/>`__
* `"Simple and Steady Way of Learning for Software Engineering" (in Japanese) <https://www.amazon.co.jp/dp/477414259X/>`__
* `"Software-Dokumentation mit Sphinx" <https://www.amazon.de/dp/1497448689/>`__
* `"Theoretical Physics Reference" <https://www.theoretical-physics.net/>`__
* `"The Varnish Book" <https://info.varnish-software.com/the-varnish-book>`__
Theses produced using Sphinx
----------------------------
* "A Web-Based System for Comparative Analysis of OpenStreetMap Data by the Use
of CouchDB":
https://www.yumpu.com/et/document/view/11722645/masterthesis-markusmayr-0542042
* "Content Conditioning and Distribution for Dynamic Virtual Worlds":
https://www.cs.princeton.edu/research/techreps/TR-941-12
* "The Sphinx Thesis Resource": https://jterrace.github.io/sphinxtr/
* `"A Web-Based System for Comparative Analysis of OpenStreetMap Data by the Use
of CouchDB" <https://www.yumpu.com/et/document/view/11722645/masterthesis-markusmayr-0542042>`__
* `"Content Conditioning and Distribution for Dynamic Virtual Worlds" <https://www.cs.princeton.edu/research/techreps/TR-941-12>`__
* `"The Sphinx Thesis Resource" <https://jterrace.github.io/sphinxtr/>`__
Projects integrating Sphinx functionality
-----------------------------------------
* `Read the Docs <https://readthedocs.org/>`__, a software-as-a-service documentation hosting platform, uses
Sphinx to automatically build documentation updates that are pushed to GitHub.
* `Spyder <https://docs.spyder-ide.org/help.html>`__, the Scientific Python Development Environment, uses Sphinx in its
help pane to render rich documentation for functions, classes and methods
automatically or on-demand.

View File

@@ -57,7 +57,7 @@ style-check:
.PHONY: type-check
type-check:
mypy sphinx/
mypy sphinx
.PHONY: pylint
pylint:

View File

@@ -4,7 +4,7 @@
.. image:: https://img.shields.io/pypi/v/sphinx.svg
:target: https://pypi.org/project/Sphinx/
:alt: Package on PyPi
:alt: Package on PyPI
.. image:: https://readthedocs.org/projects/sphinx/badge/?version=master
:target: http://www.sphinx-doc.org/

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# test documentation build configuration file, created by
# sphinx-quickstart on Sun Jun 26 00:00:43 2016.
#

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

View File

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 86 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# Sphinx documentation build configuration file
import re
@@ -44,6 +42,7 @@ epub_post_files = [('usage/installation.xhtml', 'Installing Sphinx'),
epub_exclude_files = ['_static/opensearch.xml', '_static/doctools.js',
'_static/jquery.js', '_static/searchtools.js',
'_static/underscore.js', '_static/basic.css',
'_static/language_data.js',
'search.html', '_static/websupport.js']
epub_fix_images = False
epub_max_image_width = 0
@@ -56,15 +55,27 @@ latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation',
'Georg Brandl', 'manual', 1)]
latex_logo = '_static/sphinx.png'
latex_elements = {
'fontenc': r'\usepackage[LGR,X2,T1]{fontenc}',
'fontpkg': r'''
\usepackage[sc]{mathpazo}
\usepackage[scaled]{helvet}
\usepackage{courier}
\substitutefont{LGR}{\rmdefault}{cmr}
\substitutefont{LGR}{\sfdefault}{cmss}
\substitutefont{LGR}{\ttdefault}{cmtt}
\substitutefont{X2}{\rmdefault}{cmr}
\substitutefont{X2}{\sfdefault}{cmss}
\substitutefont{X2}{\ttdefault}{cmtt}
''',
'passoptionstopackages': '\\PassOptionsToPackage{svgnames}{xcolor}',
'preamble': '\\DeclareUnicodeCharacter{229E}{\\ensuremath{\\boxplus}}',
'fvset': '\\fvset{fontsize=auto}',
'printindex': '\\footnotesize\\raggedright\\sphinxprintindex',
# fix missing index entry due to RTD doing only once pdflatex after makeindex
'printindex': r'''
\IfFileExists{\jobname.ind}
{\footnotesize\raggedright\printindex}
{\begin{sphinxtheindex}\end{sphinxtheindex}}
''',
}
latex_show_urls = 'footnote'
latex_use_xindy = True
@@ -139,3 +150,10 @@ def setup(app):
names=['param'], can_collapse=True)
app.add_object_type('event', 'event', 'pair: %s; event', parse_event,
doc_field_types=[fdesc])
# workaround for RTD
from sphinx.util import logging
logger = logging.getLogger(__name__)
app.info = lambda *args, **kwargs: logger.info(*args, **kwargs)
app.warn = lambda *args, **kwargs: logger.warning(*args, **kwargs)
app.debug = lambda *args, **kwargs: logger.debug(*args, **kwargs)

View File

@@ -14,16 +14,17 @@ Sphinx documentation contents
usage/configuration
usage/builders/index
usage/extensions/index
usage/theming
usage/advanced/intl
usage/advanced/setuptools
usage/advanced/websupport/index
intro
man/index
intl
theming
setuptools
templating
latex
extdev/index
websupport
faq
glossary

View File

@@ -127,7 +127,7 @@ own extensions.
.. _NumPy style: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
.. _hyphenator: https://github.com/mnater/hyphenator
.. _exceltable: https://pythonhosted.org/sphinxcontrib-exceltable/
.. _YouTube: http://www.youtube.com/
.. _YouTube: https://www.youtube.com/
.. _ClearQuest: https://www.ibm.com/us-en/marketplace/rational-clearquest
.. _Zope interfaces: https://zopeinterface.readthedocs.io/en/latest/README.html
.. _slideshare: https://www.slideshare.net/

View File

@@ -115,37 +115,15 @@ Emitting events
.. automethod:: emit_firstresult(event, \*arguments)
Producing messages / logging
----------------------------
The application object also provides support for emitting leveled messages.
.. note::
There is no "error" call: in Sphinx, errors are defined as things that stop
the build; just raise an exception (:exc:`sphinx.errors.SphinxError` or a
custom subclass) to do that.
.. deprecated:: 1.6
Please use :ref:`logging-api` instead.
.. automethod:: Sphinx.warn
.. automethod:: Sphinx.info
.. automethod:: Sphinx.verbose
.. automethod:: Sphinx.debug
.. automethod:: Sphinx.debug2
Sphinx runtime information
--------------------------
The application object also provides runtime information as attributes.
.. attribute:: Sphinx.project
Target project. See :class:`.Project`.
.. attribute:: Sphinx.srcdir
Source directory.

View File

@@ -15,6 +15,10 @@ Build environment API
Reference to the :class:`.Config` object.
.. attribute:: project
Target project. See :class:`.Project`.
.. attribute:: srcdir
Source directory.
@@ -39,10 +43,6 @@ Build environment API
**Utility methods**
.. automethod:: warn
.. automethod:: warn_node
.. automethod:: doc2path
.. automethod:: relfn2path

View File

@@ -85,6 +85,7 @@ APIs used for writing extensions
tutorial
appapi
projectapi
envapi
builderapi
collectorapi
@@ -96,6 +97,8 @@ APIs used for writing extensions
i18n
utils
.. _dev-deprecated-apis:
Deprecated APIs
---------------
@@ -104,7 +107,13 @@ But, sometimes, the change of interface are needed for some reasons. In such
cases, we've marked them as deprecated. And they are kept during the two
major versions (for more details, please see :ref:`deprecation-policy`).
The following is a list of deprecated interface.
The following is a list of deprecated interfaces.
.. tabularcolumns:: |>{\raggedright}\Y{.4}|>{\centering}\Y{.1}|>{\centering}\Y{.12}|>{\raggedright\arraybackslash}\Y{.38}|
.. |LaTeXHyphenate| raw:: latex
\hspace{0pt}
.. list-table:: deprecated APIs
:header-rows: 1
@@ -112,10 +121,230 @@ The following is a list of deprecated interface.
:widths: 40, 10, 10, 40
* - Target
- Deprecated
- (will be) Removed
- |LaTeXHyphenate|\ Deprecated
- (will be) Removed
- Alternatives
* - ``encoding`` argument of ``autodoc.Documenter.get_doc()``,
``autodoc.DocstringSignatureMixin.get_doc()``,
``autodoc.DocstringSignatureMixin._find_signature()``, and
``autodoc.ClassDocumenter.get_doc()``
- 2.0
- 4.0
- N/A
* - ``nodetype`` argument of
``sphinx.search.WordCollector.is_meta_keywords()``
- 2.0
- 4.0
- N/A
* - ``suffix`` argument of ``BuildEnvironment.doc2path()``
- 2.0
- 4.0
- N/A
* - string style ``base`` argument of ``BuildEnvironment.doc2path()``
- 2.0
- 4.0
- ``os.path.join()``
* - ``sphinx.addnodes.abbreviation``
- 2.0
- 4.0
- ``docutils.nodes.abbreviation``
* - ``sphinx.cmd.quickstart.term_decode()``
- 2.0
- 4.0
- N/A
* - ``sphinx.cmd.quickstart.TERM_ENCODING``
- 2.0
- 4.0
- ``sys.stdin.encoding``
* - ``sphinx.config.check_unicode()``
- 2.0
- 4.0
- N/A
* - ``sphinx.config.string_classes``
- 2.0
- 4.0
- ``[str]``
* - ``sphinx.domains.cpp.DefinitionError.description``
- 2.0
- 4.0
- ``str(exc)``
* - ``sphinx.domains.cpp.NoOldIdError.description``
- 2.0
- 4.0
- ``str(exc)``
* - ``sphinx.domains.cpp.UnsupportedMultiCharacterCharLiteral.decoded``
- 2.0
- 4.0
- ``str(exc)``
* - ``sphinx.ext.autosummary.Autosummary.warn()``
- 2.0
- 4.0
- N/A
* - ``sphinx.ext.autosummary.Autosummary.genopt``
- 2.0
- 4.0
- N/A
* - ``sphinx.ext.autosummary.Autosummary.warnings``
- 2.0
- 4.0
- N/A
* - ``sphinx.ext.autosummary.Autosummary.result``
- 2.0
- 4.0
- N/A
* - ``sphinx.ext.doctest.doctest_encode()``
- 2.0
- 4.0
- N/A
* - ``sphinx.testing.util.remove_unicode_literal()``
- 2.0
- 4.0
- N/A
* - ``sphinx.util.attrdict``
- 2.0
- 4.0
- N/A
* - ``sphinx.util.force_decode()``
- 2.0
- 4.0
- N/A
* - ``sphinx.util.get_matching_docs()``
- 2.0
- 4.0
- ``sphinx.util.get_matching_files()``
* - ``sphinx.util.inspect.Parameter``
- 2.0
- 3.0
- N/A
* - ``sphinx.util.osutil.EEXIST``
- 2.0
- 4.0
- ``errno.EEXIST`` or ``FileExistsError``
* - ``sphinx.util.osutil.EINVAL``
- 2.0
- 4.0
- ``errno.EINVAL``
* - ``sphinx.util.osutil.ENOENT``
- 2.0
- 4.0
- ``errno.ENOENT`` or ``FileNotFoundError``
* - ``sphinx.util.osutil.EPIPE``
- 2.0
- 4.0
- ``errno.ENOENT`` or ``BrokenPipeError``
* - ``sphinx.util.osutil.walk()``
- 2.0
- 4.0
- ``os.walk()``
* - ``sphinx.util.pycompat.UnicodeMixin``
- 2.0
- 4.0
- N/A
* - ``sphinx.util.pycompat.u``
- 2.0
- 4.0
- N/A
* - ``sphinx.util.PeekableIterator``
- 2.0
- 4.0
- N/A
* - Omitting the ``filename`` argument in an overriddent
``IndexBuilder.feed()`` method.
- 2.0
- 4.0
- ``IndexBuilder.feed(docname, filename, title, doctree)``
* - ``sphinx.writers.latex.LaTeXTranslator.babel_defmacro()``
- 2.0
- 4.0
- N/A
* - ``sphinx.application.Sphinx._setting_up_extension``
- 2.0
- 3.0
- N/A
* - The ``importer`` argument of ``sphinx.ext.autodoc.importer._MockModule``
- 2.0
- 3.0
- N/A
* - ``sphinx.ext.autodoc.importer._MockImporter``
- 2.0
- 3.0
- N/A
* - ``sphinx.io.SphinxBaseFileInput``
- 2.0
- 3.0
- N/A
* - ``sphinx.io.SphinxFileInput.supported``
- 2.0
- 3.0
- N/A
* - ``sphinx.io.SphinxRSTFileInput``
- 2.0
- 3.0
- N/A
* - ``sphinx.registry.SphinxComponentRegistry.add_source_input()``
- 2.0
- 3.0
- N/A
* - ``sphinx.writers.latex.LaTeXTranslator._make_visit_admonition()``
- 2.0
- 3.0
- N/A
* - ``sphinx.writers.latex.LaTeXTranslator.collect_footnotes()``
- 2.0
- 4.0
- N/A
* - ``sphinx.writers.texinfo.TexinfoTranslator._make_visit_admonition()``
- 2.0
- 3.0
- N/A
* - ``sphinx.writers.text.TextTranslator._make_depart_admonition()``
- 2.0
- 3.0
- N/A
* - :rst:dir:`highlightlang`
- 1.8
- 4.0
@@ -131,11 +360,68 @@ The following is a list of deprecated interface.
- 4.0
- :meth:`~sphinx.application.Sphinx.add_js_file()`
* - :confval:`autodoc_default_flags`
- 1.8
- 4.0
- :confval:`autodoc_default_options`
* - ``content`` arguments of ``sphinx.util.image.guess_mimetype()``
- 1.8
- 3.0
- N/A
* - ``gettext_compact`` arguments of
``sphinx.util.i18n.find_catalog_source_files()``
- 1.8
- 3.0
- N/A
* - ``sphinx.io.SphinxI18nReader.set_lineno_for_reporter()``
- 1.8
- 3.0
- N/A
* - ``sphinx.io.SphinxI18nReader.line``
- 1.8
- 3.0
- N/A
* - ``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.MathDirective``
- 1.8
- 3.0
- ``sphinx.directives.patches.MathDirective``
* - ``sphinx.ext.mathbase.math_role()``
- 1.8
- 3.0
- ``docutils.parsers.rst.roles.math_role()``
* - ``sphinx.ext.mathbase.setup_math()``
- 1.8
- 3.0
@@ -146,6 +432,16 @@ The following is a list of deprecated interface.
- 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
@@ -221,11 +517,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
@@ -309,6 +655,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
@@ -334,6 +685,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
@@ -354,6 +710,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

@@ -9,9 +9,9 @@ Logging API
.. autoclass:: SphinxLoggerAdapter(logging.LoggerAdapter)
.. method:: SphinxLoggerAdapter.error(level, msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.critical(level, msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.warning(level, msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.error(msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.critical(msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.warning(msg, *args, **kwargs)
Logs a message on this logger with the specified level.
Basically, the arguments are as with python's logging module.
@@ -33,13 +33,14 @@ Logging API
logger.warning('Warning happened!', location=some_node)
**color**
The color of logs. By default, warning level logs are
colored as ``"darkred"``. The others are not colored.
The color of logs. By default, error level logs are colored as
``"darkred"``, critical level ones is not colored, and warning level
ones are colored as ``"red"``.
.. method:: SphinxLoggerAdapter.log(level, msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.info(level, msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.verbose(level, msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.debug(level, msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.info(msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.verbose(msg, *args, **kwargs)
.. method:: SphinxLoggerAdapter.debug(msg, *args, **kwargs)
Logs a message to this logger with the specified level.
Basically, the arguments are as with python's logging module.
@@ -55,10 +56,11 @@ Logging API
:meth:`SphinxLoggerAdapter.warning`.
**color**
The color of logs. By default, debug level logs are
colored as ``"darkgray"``, and debug2 level ones are ``"lightgray"``.
The others are not colored.
The color of logs. By default, info and verbose level logs are not colored,
and deug level ones are colored as ``"darkgray"``.
.. autofunction:: pending_logging()
.. autofunction:: pending_warnings()
.. autofunction:: prefixed_warnings()

View File

@@ -0,0 +1,9 @@
.. _project-api:
Project API
===========
.. currentmodule:: sphinx.project
.. autoclass:: Project
:members:

View File

@@ -20,7 +20,7 @@ How do I...
the :rst:dir:`toctree` directive where you want to start numbering.
... customize the look of the built HTML files?
Use themes, see :doc:`theming`.
Use themes, see :doc:`/usage/theming`.
... add global substitutions or includes?
Add them in the :confval:`rst_prolog` or :confval:`rst_epilog` config value.
@@ -205,7 +205,7 @@ The following list gives some hints for the creation of epub files:
.. _Epubcheck: https://github.com/IDPF/epubcheck
.. _Calibre: https://calibre-ebook.com/
.. _FBreader: https://fbreader.org/
.. _Bookworm: http://www.oreilly.com/bookworm/index.html
.. _Bookworm: https://www.oreilly.com/bookworm/index.html
.. _kindlegen: https://www.amazon.com/gp/feature.html?docId=1000765211
.. _texinfo-faq:

View File

@@ -55,15 +55,13 @@ See the :ref:`pertinent section in the FAQ list <usingwith>`.
Prerequisites
-------------
Sphinx needs at least **Python 2.7** or **Python 3.4** to run, as well as the
docutils_ and Jinja2_ libraries. Sphinx should work with docutils version 0.10
or some (not broken) SVN trunk snapshot. If you like to have source code
highlighting support, you must also install the Pygments_ library.
Sphinx needs at least **Python 3.5** to run, as well as the docutils_ and
Jinja2_ libraries. Sphinx should work with docutils version 0.12 or some (not
broken) SVN trunk snapshot.
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
.. _docutils: http://docutils.sourceforge.net/
.. _Jinja2: http://jinja.pocoo.org/
.. _Pygments: http://pygments.org/
Usage

View File

@@ -55,7 +55,7 @@ example::
\setlength{\cftsecnumwidth}{1.25cm}
''',
'fncychap': r'\usepackage[Bjornstrup]{fncychap}',
'printindex': r'\footnotesize\raggedright\sphinxprintindex',
'printindex': r'\footnotesize\raggedright\printindex',
}
latex_show_urls = 'footnote'
@@ -209,7 +209,7 @@ The available styling options
the default changed from ``false`` to ``true``.
``verbatimcontinuedalign``, ``verbatimcontinuesalign``
default ``c``. Horizontal position relative to the framed contents:
default ``r``. Horizontal position relative to the framed contents:
either ``l`` (left aligned), ``r`` (right aligned) or ``c`` (centered).
.. versionadded:: 1.7
@@ -354,9 +354,9 @@ The available styling options
``attentionBgColor``, ``dangerBgColor``,
``errorBgColor``
.. |warningborders| replace:: ``warningBorder``, ``cautionBorder``,
``attentionBorder``, ``dangerBorder``,
``errorBorder``
.. |warningborders| replace:: ``warningborder``, ``cautionborder``,
``attentionborder``, ``dangerborder``,
``errorborder``
LaTeX macros and environments
-----------------------------
@@ -365,6 +365,8 @@ Here are some macros from the package file :file:`sphinx.sty` and class files
:file:`sphinxhowto.cls`, :file:`sphinxmanual.cls`, which have public names
thus allowing redefinitions. Check the respective files for the defaults.
.. _latex-macros:
Macros
~~~~~~
@@ -390,32 +392,34 @@ Macros
.. versionadded:: 1.6.3
``\sphinxstylecodecontinued`` and ``\sphinxstylecodecontinues``.
- the table of contents is typeset via ``\sphinxtableofcontents`` which is a
wrapper (whose definition can be found in :file:`sphinxhowto.cls` or in
:file:`sphinxmanual.cls`) of standard ``\tableofcontents``.
wrapper (defined differently in :file:`sphinxhowto.cls` and in
:file:`sphinxmanual.cls`) of standard ``\tableofcontents``. The macro
``\sphinxtableofcontentshook`` is executed during its expansion right before
``\tableofcontents`` itself.
.. versionchanged:: 1.5
formerly, the meaning of ``\tableofcontents`` was modified by Sphinx.
- the ``\maketitle`` command is redefined by the class files
:file:`sphinxmanual.cls` and :file:`sphinxhowto.cls`.
.. versionchanged:: 2.0
hard-coded redefinitions of ``\l@section`` and ``\l@subsection`` formerly
done during loading of ``'manual'`` docclass are now executed later via
``\sphinxtableofcontentshook``. This macro is also executed by the
``'howto'`` docclass, but defaults to empty with it.
- a custom ``\sphinxmaketitle`` is defined in the class files
:file:`sphinxmanual.cls` and :file:`sphinxhowto.cls` and is used as
default setting of ``'maketitle'`` :confval:`latex_elements` key.
.. versionchanged:: 1.8.3
formerly, ``\maketitle`` from LaTeX document class was modified by
Sphinx.
- for ``'manual'`` docclass a macro ``\sphinxbackoftitlepage``, if it is
defined, gets executed at end of ``\sphinxmaketitle``, before the final
``\clearpage``. Use either the ``'maketitle'`` key or the ``'preamble'`` key
of :confval:`latex_elements` to add a custom definition of
``\sphinxbackoftitlepage``.
.. versionadded:: 1.8.3
- the citation reference is typeset via ``\sphinxcite`` which is a wrapper
of standard ``\cite``.
- regarding the general index, the :confval:`latex_elements` dictionary has a
``'printindex'`` key which defaults to ``'\\sphinxprintindex'``. It often
proves advantageous to use::
'printindex': '\\footnotesize\\raggedright\\sphinxprintindex',
especially if the index contains long entries. The LaTeX class for Japanese
``'manual'``-type documents already does the font size and text
justification change, so the above is not needed then.
.. tip::
Advanced LaTeX users can also, via :confval:`latex_additional_files`, use
a custom :program:`makeindex` style file :file:`python.ist`, or a custom
:program:`xindy` style file :file:`sphinx.xdy` (see
:confval:`latex_use_xindy`) in order to modify how the general index is
typeset.
Environments
~~~~~~~~~~~~
@@ -470,8 +474,7 @@ Environments
- the bibliography uses ``sphinxthebibliography`` and the Python Module index
as well as the general index both use ``sphinxtheindex``; these environments
are wrappers of the ``thebibliography`` and respectively ``theindex``
environments, needed mainly to insert a corresponding entry in the PDF
bookmarks and table of contents.
environments as provided by the document class (or packages).
.. versionchanged:: 1.5
formerly, the original environments were modified by Sphinx.

View File

@@ -58,6 +58,10 @@ Options
Maximum depth for the generated table of contents file.
.. option:: --tocfile
Filename for a table of contents file. Defaults to ``modules``.
.. option:: -T, --no-toc
Do not create a table of contents file. Ignored when :option:`--full` is

View File

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

@@ -200,6 +200,10 @@ Overriding works like this::
{% set script_files = script_files + ["_static/myscript.js"] %}
.. deprecated:: 1.8.0
Please use ``.Sphinx.add_js_file()`` instead.
Helper Functions
~~~~~~~~~~~~~~~~

View File

@@ -5,6 +5,12 @@ HTML theming support
.. versionadded:: 0.6
.. note::
This document provides information about creating your own theme. If you
simply wish to use a pre-existing HTML themes, refer to
:doc:`/usage/theming`.
Sphinx supports changing the appearance of its HTML output via *themes*. A
theme is a collection of HTML templates, stylesheet(s) and other static files.
Additionally, it has a configuration file which specifies from which theme to
@@ -15,265 +21,13 @@ Themes are meant to be project-unaware, so they can be used for different
projects without change.
Using a theme
-------------
Using an existing theme is easy. If the theme is builtin to Sphinx, you only
need to set the :confval:`html_theme` config value. With the
:confval:`html_theme_options` config value you can set theme-specific options
that change the look and feel. For example, you could have the following in
your :file:`conf.py`::
html_theme = "classic"
html_theme_options = {
"rightsidebar": "true",
"relbarbgcolor": "black"
}
That would give you the classic theme, but with a sidebar on the right side and
a black background for the relation bar (the bar with the navigation links at
the page's top and bottom).
If the theme does not come with Sphinx, it can be in two static forms: either a
directory (containing :file:`theme.conf` and other needed files), or a zip file
with the same contents. Either of them must be put where Sphinx can find it;
for this there is the config value :confval:`html_theme_path`. It gives a list
of directories, relative to the directory containing :file:`conf.py`, that can
contain theme directories or zip files. For example, if you have a theme in the
file :file:`blue.zip`, you can put it right in the directory containing
:file:`conf.py` and use this configuration::
html_theme = "blue"
html_theme_path = ["."]
The third form is a python package. If a theme you want to use is distributed
as a python package, you can use it after installing
.. code-block:: bash
# installing theme package
$ pip install sphinxjp.themes.dotted
# use it in your conf.py
html_theme = "dotted"
.. _builtin-themes:
Builtin themes
--------------
.. cssclass:: longtable
+--------------------+--------------------+
| **Theme overview** | |
+--------------------+--------------------+
| |alabaster| | |classic| |
| | |
| *alabaster* | *classic* |
+--------------------+--------------------+
| |sphinxdoc| | |scrolls| |
| | |
| *sphinxdoc* | *scrolls* |
+--------------------+--------------------+
| |agogo| | |traditional| |
| | |
| *agogo* | *traditional* |
+--------------------+--------------------+
| |nature| | |haiku| |
| | |
| *nature* | *haiku* |
+--------------------+--------------------+
| |pyramid| | |bizstyle| |
| | |
| *pyramid* | *bizstyle* |
+--------------------+--------------------+
.. |alabaster| image:: themes/alabaster.png
.. |classic| image:: themes/classic.png
.. |sphinxdoc| image:: themes/sphinxdoc.png
.. |scrolls| image:: themes/scrolls.png
.. |agogo| image:: themes/agogo.png
.. |traditional| image:: themes/traditional.png
.. |nature| image:: themes/nature.png
.. |haiku| image:: themes/haiku.png
.. |pyramid| image:: themes/pyramid.png
.. |bizstyle| image:: themes/bizstyle.png
Sphinx comes with a selection of themes to choose from.
.. cssclass:: clear
These themes are:
* **basic** -- This is a basically unstyled layout used as the base for the
other themes, and usable as the base for custom themes as well. The HTML
contains all important elements like sidebar and relation bar. There are
these options (which are inherited by the other themes):
- **nosidebar** (true or false): Don't include the sidebar. Defaults to
``False``.
- **sidebarwidth** (int or str): Width of the sidebar in pixels.
This can be an int, which is interpreted as pixels or a valid CSS
dimension string such as '70em' or '50%'. Defaults to 230 pixels.
- **body_min_width** (int or str): Minimal width of the document body.
This can be an int, which is interpreted as pixels or a valid CSS
dimension string such as '70em' or '50%'. Use 0 if you don't want
a width limit. Defaults may depend on the theme (often 450px).
- **body_max_width** (int or str): Maximal width of the document body.
This can be an int, which is interpreted as pixels or a valid CSS
dimension string such as '70em' or '50%'. Use 'none' if you don't
want a width limit. Defaults may depend on the theme (often 800px).
* **alabaster** -- `Alabaster theme`_ is a modified "Kr" Sphinx theme from @kennethreitz
(especially as used in his Requests project), which was itself originally based on
@mitsuhiko's theme used for Flask & related projects.
Check out at its `installation page`_ how to set up properly
:confval:`html_sidebars` for its use.
.. _Alabaster theme: https://pypi.org/project/alabaster/
.. _installation page: https://alabaster.readthedocs.io/en/latest/installation.html
* **classic** -- This is the classic theme, which looks like `the Python 2
documentation <https://docs.python.org/2/>`_. It can be customized via
these options:
- **rightsidebar** (true or false): Put the sidebar on the right side.
Defaults to ``False``.
- **stickysidebar** (true or false): Make the sidebar "fixed" so that it
doesn't scroll out of view for long body content. This may not work well
with all browsers. Defaults to ``False``.
- **collapsiblesidebar** (true or false): Add an *experimental* JavaScript
snippet that makes the sidebar collapsible via a button on its side.
Defaults to ``False``.
- **externalrefs** (true or false): Display external links differently from
internal links. Defaults to ``False``.
There are also various color and font options that can change the color scheme
without having to write a custom stylesheet:
- **footerbgcolor** (CSS color): Background color for the footer line.
- **footertextcolor** (CSS color): Text color for the footer line.
- **sidebarbgcolor** (CSS color): Background color for the sidebar.
- **sidebarbtncolor** (CSS color): Background color for the sidebar collapse
button (used when *collapsiblesidebar* is ``True``).
- **sidebartextcolor** (CSS color): Text color for the sidebar.
- **sidebarlinkcolor** (CSS color): Link color for the sidebar.
- **relbarbgcolor** (CSS color): Background color for the relation bar.
- **relbartextcolor** (CSS color): Text color for the relation bar.
- **relbarlinkcolor** (CSS color): Link color for the relation bar.
- **bgcolor** (CSS color): Body background color.
- **textcolor** (CSS color): Body text color.
- **linkcolor** (CSS color): Body link color.
- **visitedlinkcolor** (CSS color): Body color for visited links.
- **headbgcolor** (CSS color): Background color for headings.
- **headtextcolor** (CSS color): Text color for headings.
- **headlinkcolor** (CSS color): Link color for headings.
- **codebgcolor** (CSS color): Background color for code blocks.
- **codetextcolor** (CSS color): Default text color for code blocks, if not
set differently by the highlighting style.
- **bodyfont** (CSS font-family): Font for normal text.
- **headfont** (CSS font-family): Font for headings.
* **sphinxdoc** -- The theme originally used by this documentation. It features
a sidebar on the right side. There are currently no options beyond
*nosidebar* and *sidebarwidth*.
.. note::
The Sphinx documentation now uses
`an adjusted version of the sphinxdoc theme
<https://github.com/sphinx-doc/sphinx/tree/master/doc/_themes/sphinx13>`_.
* **scrolls** -- A more lightweight theme, based on `the Jinja documentation
<http://jinja.pocoo.org/>`_. The following color options are available:
- **headerbordercolor**
- **subheadlinecolor**
- **linkcolor**
- **visitedlinkcolor**
- **admonitioncolor**
* **agogo** -- A theme created by Andi Albrecht. The following options are
supported:
- **bodyfont** (CSS font family): Font for normal text.
- **headerfont** (CSS font family): Font for headings.
- **pagewidth** (CSS length): Width of the page content, default 70em.
- **documentwidth** (CSS length): Width of the document (without sidebar),
default 50em.
- **sidebarwidth** (CSS length): Width of the sidebar, default 20em.
- **bgcolor** (CSS color): Background color.
- **headerbg** (CSS value for "background"): background for the header area,
default a grayish gradient.
- **footerbg** (CSS value for "background"): background for the footer area,
default a light gray gradient.
- **linkcolor** (CSS color): Body link color.
- **headercolor1**, **headercolor2** (CSS color): colors for <h1> and <h2>
headings.
- **headerlinkcolor** (CSS color): Color for the backreference link in
headings.
- **textalign** (CSS *text-align* value): Text alignment for the body, default
is ``justify``.
* **nature** -- A greenish theme. There are currently no options beyond
*nosidebar* and *sidebarwidth*.
* **pyramid** -- A theme from the Pyramid web framework project, designed by
Blaise Laflamme. There are currently no options beyond *nosidebar* and
*sidebarwidth*.
* **haiku** -- A theme without sidebar inspired by the `Haiku OS user guide
<https://www.haiku-os.org/docs/userguide/en/contents.html>`_. The following
options are supported:
- **full_logo** (true or false, default ``False``): If this is true, the
header will only show the :confval:`html_logo`. Use this for large logos.
If this is false, the logo (if present) will be shown floating right, and
the documentation title will be put in the header.
- **textcolor**, **headingcolor**, **linkcolor**, **visitedlinkcolor**,
**hoverlinkcolor** (CSS colors): Colors for various body elements.
* **traditional** -- A theme resembling the old Python documentation. There are
currently no options beyond *nosidebar* and *sidebarwidth*.
* **epub** -- A theme for the epub builder. This theme tries to save visual
space which is a sparse resource on ebook readers. The following options
are supported:
- **relbar1** (true or false, default ``True``): If this is true, the
`relbar1` block is inserted in the epub output, otherwise it is omitted.
- **footer** (true or false, default ``True``): If this is true, the
`footer` block is inserted in the epub output, otherwise it is omitted.
- **bizstyle** -- A simple bluish theme. The following options are supported
beyond *nosidebar* and *sidebarwidth*:
- **rightsidebar** (true or false): Put the sidebar on the right side.
Defaults to ``False``.
.. versionadded:: 1.3
'alabaster', 'sphinx_rtd_theme' and 'bizstyle' theme.
.. versionchanged:: 1.3
The 'default' theme has been renamed to 'classic'. 'default' is still
available, however it will emit a notice that it is an alias for the new
'alabaster' theme.
Creating themes
---------------
As said, themes are either a directory or a zipfile (whose name is the theme
name), containing the following:
Themes take the form of either a directory or a zipfile (whose name is the
theme name), containing the following:
* A :file:`theme.conf` file, see below.
* A :file:`theme.conf` file.
* HTML templates, if needed.
* A ``static/`` directory containing any static files that will be copied to the
output static directory on build. These can be images, styles, script files.
@@ -295,7 +49,8 @@ Python :mod:`ConfigParser` module) and has the following structure:
* The **inherit** setting gives the name of a "base theme", or ``none``. The
base theme will be used to locate missing templates (most themes will not have
to supply most templates if they use ``basic`` as the base theme), its options
will be inherited, and all of its static files will be used as well.
will be inherited, and all of its static files will be used as well. If you want
to also inherit the stylesheet, include it via CSS' ``@import`` in your own.
* The **stylesheet** setting gives the name of a CSS file which will be
referenced in the HTML header. If you need more than one CSS file, either
@@ -318,16 +73,17 @@ Python :mod:`ConfigParser` module) and has the following structure:
.. versionadded:: 1.7
sidebar settings
.. _distribute-your-theme:
Distribute your theme as a python package
Distribute your theme as a Python package
-----------------------------------------
As a way to distribute your theme, you can use python package. Python package
As a way to distribute your theme, you can use Python package. Python package
brings to users easy setting up ways.
To distribute your theme as a python package, please define an entry point
called ``sphinx.html_themes`` in your setup.py file, and write a ``setup()``
To distribute your theme as a Python package, please define an entry point
called ``sphinx.html_themes`` in your ``setup.py`` file, and write a ``setup()``
function to register your themes using ``add_html_theme()`` API in it::
# 'setup.py'
@@ -347,9 +103,8 @@ function to register your themes using ``add_html_theme()`` API in it::
def setup(app):
app.add_html_theme('name_of_theme', path.abspath(path.dirname(__file__)))
If your theme package contains two or more themes, please call ``add_html_theme()``
twice or more.
If your theme package contains two or more themes, please call
``add_html_theme()`` twice or more.
.. versionadded:: 1.2
'sphinx_themes' entry_points feature.
@@ -360,8 +115,9 @@ twice or more.
.. versionadded:: 1.6
``sphinx.html_themes`` entry_points feature.
Templating
~~~~~~~~~~
----------
The :doc:`guide to templating <templating>` is helpful if you want to write your
own templates. What is important to keep in mind is the order in which Sphinx
@@ -376,7 +132,6 @@ name as an explicit directory: ``{% extends "basic/layout.html" %}``. From a
user ``templates_path`` template, you can still use the "exclamation mark"
syntax as described in the templating document.
Static templates
~~~~~~~~~~~~~~~~
@@ -393,40 +148,6 @@ templating to put the color options into the stylesheet. When a documentation
is built with the classic theme, the output directory will contain a
``_static/classic.css`` file where all template tags have been processed.
.. [1] It is not an executable Python file, as opposed to :file:`conf.py`,
because that would pose an unnecessary security risk if themes are
shared.
Third Party Themes
------------------
.. cssclass:: longtable
+--------------------+--------------------+
| **Theme overview** | |
+--------------------+--------------------+
| |sphinx_rtd_theme| | |
| | |
| *sphinx_rtd_theme* | |
+--------------------+--------------------+
.. |sphinx_rtd_theme| image:: themes/sphinx_rtd_theme.png
* **sphinx_rtd_theme** -- `Read the Docs Sphinx Theme`_.
This is a mobile-friendly sphinx theme that was made for readthedocs.org.
View a working demo over on readthedocs.org. You can get install and options
information at `Read the Docs Sphinx Theme`_ page.
.. _Read the Docs Sphinx Theme: https://pypi.org/project/sphinx_rtd_theme/
.. versionchanged:: 1.4
**sphinx_rtd_theme** has become optional.
Besides this, there are a lot of third party themes. You can find them on
PyPI__, GitHub__, sphinx-themes.org__ and so on.
.. __: https://pypi.org/search/?q=&o=&c=Framework+%3A%3A+Sphinx+%3A%3A+Theme
.. __: https://github.com/search?utf8=%E2%9C%93&q=sphinx+theme&type=
.. __: https://sphinx-themes.org/

View File

@@ -9,7 +9,7 @@ Complementary to translations provided for Sphinx-generated messages such as
navigation bars, Sphinx provides mechanisms facilitating *document* translations
in itself. See the :ref:`intl-options` for details on configuration.
.. figure:: translation.png
.. figure:: /_static/translation.png
:width: 100%
Workflow visualization of translations in Sphinx. (The stick-figure is taken
@@ -46,14 +46,14 @@ They can be delivered to translators which will transform them to ``.po`` files
--- so called **message catalogs** --- containing a mapping from the original
messages to foreign-language strings.
Gettext compiles them into a binary format known as **binary catalogs** through
:program:`msgfmt` for efficiency reasons. If you make these files discoverable
with :confval:`locale_dirs` for your :confval:`language`, Sphinx will pick them
up automatically.
*gettext* compiles them into a binary format known as **binary catalogs**
through :program:`msgfmt` for efficiency reasons. If you make these files
discoverable with :confval:`locale_dirs` for your :confval:`language`, Sphinx
will pick them up automatically.
An example: you have a document ``usage.rst`` in your Sphinx project. The
gettext builder will put its messages into ``usage.pot``. Imagine you have
Spanish translations [2]_ on your hands in ``usage.po`` --- for your builds to
*gettext* builder will put its messages into ``usage.pot``. Imagine you have
Spanish translations [2]_ stored in ``usage.po`` --- for your builds to
be translated you need to follow these instructions:
* Compile your message catalog to a locale directory, say ``locale``, so it
@@ -63,7 +63,8 @@ be translated you need to follow these instructions:
msgfmt "usage.po" -o "locale/es/LC_MESSAGES/usage.mo"
* Set :confval:`locale_dirs` to ``["locale/"]``.
* Set :confval:`language` to ``es`` (also possible via :option:`-D <sphinx-build -D>`).
* Set :confval:`language` to ``es`` (also possible via
:option:`-D <sphinx-build -D>`).
* Run your desired build.
@@ -71,118 +72,124 @@ Translating with sphinx-intl
----------------------------
Quick guide
^^^^^^^^^^^
~~~~~~~~~~~
`sphinx-intl`_ is a useful tool to work with Sphinx translation flow.
This section describe an easy way to translate with sphinx-intl.
`sphinx-intl`_ is a useful tool to work with Sphinx translation flow. This
section describe an easy way to translate with *sphinx-intl*.
#. Install `sphinx-intl`_ by :command:`pip install sphinx-intl` or
:command:`easy_install sphinx-intl`.
#. Install `sphinx-intl`_.
#. Add configurations to your `conf.py`::
.. code-block:: console
$ pip install sphinx-intl
#. Add configurations to ``conf.py``.
::
locale_dirs = ['locale/'] # path is example but recommended.
gettext_compact = False # optional.
This case-study assumes that :confval:`locale_dirs` is set to 'locale/' and
:confval:`gettext_compact` is set to `False` (the Sphinx document is
This case-study assumes that :confval:`locale_dirs` is set to ``locale/`` and
:confval:`gettext_compact` is set to ``False`` (the Sphinx document is
already configured as such).
#. Extract document's translatable messages into pot files:
#. Extract translatable messages into pot files.
.. code-block:: console
$ make gettext
As a result, many pot files are generated under ``_build/gettext``
directory.
The generated pot files will be placed in the ``_build/gettext`` directory.
#. Setup/Update your `locale_dir`:
#. Generate po files.
We'll use the pot files generated in the above step.
.. code-block:: console
$ sphinx-intl update -p _build/gettext -l de -l ja
Done. You got these directories that contain po files:
Once completed, the generated po files will be placed in the below
directories:
* `./locale/de/LC_MESSAGES/`
* `./locale/ja/LC_MESSAGES/`
* ``./locale/de/LC_MESSAGES/``
* ``./locale/ja/LC_MESSAGES/``
#. Translate your po files under `./locale/<lang>/LC_MESSAGES/`.
#. Translate po files.
#. make translated document.
AS noted above, these are located in the ``./locale/<lang>/LC_MESSAGES``
directory. An example of one such file, from Sphinx, ``builders.po``, is
given below.
.. code-block:: po
# a5600c3d2e3d48fc8c261ea0284db79b
#: ../../builders.rst:4
msgid "Available builders"
msgstr "<FILL HERE BY TARGET LANGUAGE>"
Another case, msgid is multi-line text and contains reStructuredText syntax:
.. code-block:: po
# 302558364e1d41c69b3277277e34b184
#: ../../builders.rst:9
msgid ""
"These are the built-in Sphinx builders. More builders can be added by "
":ref:`extensions <extensions>`."
msgstr ""
"FILL HERE BY TARGET LANGUAGE FILL HERE BY TARGET LANGUAGE FILL HERE "
"BY TARGET LANGUAGE :ref:`EXTENSIONS <extensions>` FILL HERE."
Please be careful not to break reST notation. Most po-editors will help you
with that.
#. Build translated document.
You need a :confval:`language` parameter in ``conf.py`` or you may also
specify the parameter on the command line (for BSD/GNU make):
specify the parameter on the command line.
For for BSD/GNU make, run:
.. code-block:: console
$ make -e SPHINXOPTS="-D language='de'" html
command line (for Windows cmd.exe):
For Windows :command:`cmd.exe`, run:
.. code-block:: console
> set SPHINXOPTS=-D language=de
> .\make.bat html
command line (for PowerShell):
For PowerShell, run:
.. code-block:: console
> Set-Item env:SPHINXOPTS "-D language=de"
> .\make.bat html
Congratulations! You got the translated documentation in the ``_build/html``
directory.
.. versionadded:: 1.3
sphinx-build that is invoked by make command will build po files into mo files.
If you are using 1.2.x or earlier, please invoke ``sphinx-intl build`` command
before make command.
:program:`sphinx-build` that is invoked by make command will build po files
into mo files.
If you are using 1.2.x or earlier, please invoke :command:`sphinx-intl build`
command before :command:`make` command.
Translating
^^^^^^^^^^^
Translate po file under ``./locale/de/LC_MESSAGES`` directory.
The case of builders.po file for sphinx document:
.. code-block:: po
# a5600c3d2e3d48fc8c261ea0284db79b
#: ../../builders.rst:4
msgid "Available builders"
msgstr "<FILL HERE BY TARGET LANGUAGE>"
Another case, msgid is multi-line text and contains reStructuredText
syntax:
.. code-block:: po
# 302558364e1d41c69b3277277e34b184
#: ../../builders.rst:9
msgid ""
"These are the built-in Sphinx builders. More builders can be added by "
":ref:`extensions <extensions>`."
msgstr ""
"FILL HERE BY TARGET LANGUAGE FILL HERE BY TARGET LANGUAGE FILL HERE "
"BY TARGET LANGUAGE :ref:`EXTENSIONS <extensions>` FILL HERE."
Please be careful not to break reST notation. Most po-editors will help you
with that.
~~~~~~~~~~~
Update your po files by new pot files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If a document is updated, it is necessary to generate updated pot files
and to apply differences to translated po files.
In order to apply the updating difference of a pot file to po file,
use the :command:`sphinx-intl update` command.
If a document is updated, it is necessary to generate updated pot files and to
apply differences to translated po files. In order to apply the updates from a
pot file to the po file, use the :command:`sphinx-intl update` command.
.. code-block:: console
@@ -199,7 +206,7 @@ easy to fetch and push translations.
.. TODO: why use transifex?
#. Install `transifex-client`_
#. Install `transifex-client`_.
You need :command:`tx` command to upload resources (pot files).
@@ -209,8 +216,7 @@ easy to fetch and push translations.
.. seealso:: `Transifex Client documentation`_
#. Create your transifex_ account and create new project for your document
#. Create your transifex_ account and create new project for your document.
Currently, transifex does not allow for a translation project to have more
than one version of the document, so you'd better include a version number in
@@ -221,8 +227,7 @@ easy to fetch and push translations.
:Project ID: ``sphinx-document-test_1_0``
:Project URL: ``https://www.transifex.com/projects/p/sphinx-document-test_1_0/``
#. Create config files for tx command
#. Create config files for :command:`tx` command.
This process will create ``.tx/config`` in the current directory, as well as
a ``~/.transifexrc`` file that includes auth information.
@@ -238,7 +243,7 @@ easy to fetch and push translations.
...
Done.
#. Upload pot files to transifex service
#. Upload pot files to transifex service.
Register pot files to ``.tx/config`` file:
@@ -259,15 +264,14 @@ easy to fetch and push translations.
...
Done.
#. Forward the translation on transifex
#. Forward the translation on transifex.
.. TODO: write this section
#. Pull translated po files and make translated HTML.
#. Pull translated po files and make translated html
Get translated catalogs and build mo files (ex. for 'de'):
Get translated catalogs and build mo files. For example, to build mo files
for German (de):
.. code-block:: console
@@ -278,32 +282,29 @@ easy to fetch and push translations.
...
Done.
Invoke make html (for BSD/GNU make):
Invoke :command:`make html` (for BSD/GNU make):
.. code-block:: console
$ make -e SPHINXOPTS="-D language='de'" html
That's all!
.. tip:: Translating locally and on Transifex
If you want to push all language's po files, you can be done by using
:command:`tx push -t` command.
Watch out! This operation overwrites translations in transifex.
:command:`tx push -t` command. Watch out! This operation overwrites
translations in transifex.
In other words, if you have updated each in the service and local po files,
it would take much time and effort to integrate them.
Contributing to Sphinx reference translation
--------------------------------------------
The recommended way for new contributors to translate Sphinx reference
is to join the translation team on Transifex.
The recommended way for new contributors to translate Sphinx reference is to
join the translation team on Transifex.
There is `sphinx translation page`_ for Sphinx (master) documentation.
@@ -311,8 +312,7 @@ There is `sphinx translation page`_ for Sphinx (master) documentation.
2. Go to `sphinx translation page`_.
3. Click ``Request language`` and fill form.
4. Wait acceptance by transifex sphinx translation maintainers.
5. (after acceptance) translate on transifex.
5. (After acceptance) Translate on transifex.
.. rubric:: Footnotes
@@ -321,9 +321,8 @@ There is `sphinx translation page`_ for Sphinx (master) documentation.
for details on that software suite.
.. [2] Because nobody expects the Spanish Inquisition!
.. _`transifex-client`: https://pypi.org/project/transifex-client/
.. _`sphinx-intl`: https://pypi.org/project/sphinx-intl/
.. _Transifex: https://www.transifex.com/
.. _`sphinx translation page`: https://www.transifex.com/sphinx-doc/sphinx-doc/
.. _`Transifex Client documentation`: http://docs.transifex.com/developer/client/
.. _`Transifex Client documentation`: https://docs.transifex.com/client/introduction/

View File

@@ -65,7 +65,7 @@ The WebSupport Class
Methods
~~~~~~~
-------
.. automethod:: sphinxcontrib.websupport.WebSupport.build

View File

@@ -10,7 +10,7 @@ web application. To learn more read the :ref:`websupportquickstart`.
.. toctree::
web/quickstart
web/api
web/searchadapters
web/storagebackends
quickstart
api
searchadapters
storagebackends

View File

@@ -4,7 +4,7 @@ Web Support Quick Start
=======================
Building Documentation Data
~~~~~~~~~~~~~~~~~~~~~~~~~~~
----------------------------
To make use of the web support package in your application you'll need to build
the data it uses. This data includes pickle files representing documents,
@@ -20,11 +20,11 @@ things are in a document. To do this you will need to create an instance of the
support.build()
This will read reStructuredText sources from `srcdir` and place the necessary
data in `builddir`. The `builddir` will contain two sub-directories: one named
"data" that contains all the data needed to display documents, search through
documents, and add comments to documents. The other directory will be called
"static" and contains static files that should be served from "/static".
This will read reStructuredText sources from ``srcdir`` and place the necessary
data in ``builddir``. The ``builddir`` will contain two sub-directories: one
named "data" that contains all the data needed to display documents, search
through documents, and add comments to documents. The other directory will be
called "static" and contains static files that should be served from "/static".
.. note::
@@ -34,7 +34,7 @@ documents, and add comments to documents. The other directory will be called
Integrating Sphinx Documents Into Your Webapp
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----------------------------------------------
Now that the data is built, it's time to do something useful with it. Start off
by creating a :class:`~.WebSupport` object for your application::
@@ -96,7 +96,7 @@ integrate with your existing templating system. An example using `Jinja2
Authentication
--------------
~~~~~~~~~~~~~~
To use certain features such as voting, it must be possible to authenticate
users. The details of the authentication are left to your application. Once a
@@ -146,13 +146,14 @@ add this data to the ``COMMENT_OPTIONS`` that are used in the template.
Performing Searches
~~~~~~~~~~~~~~~~~~~
-------------------
To use the search form built-in to the Sphinx sidebar, create a function to
handle requests to the url 'search' relative to the documentation root. The
handle requests to the URL 'search' relative to the documentation root. The
user's search query will be in the GET parameters, with the key `q`. Then use
the :meth:`~sphinxcontrib.websupport.WebSupport.get_search_results` method to retrieve
search results. In `Flask <http://flask.pocoo.org/>`_ that would be like this::
the :meth:`~sphinxcontrib.websupport.WebSupport.get_search_results` method to
retrieve search results. In `Flask <http://flask.pocoo.org/>`_ that would be
like this::
@app.route('/search')
def search():
@@ -167,7 +168,7 @@ does.
Comments & Proposals
~~~~~~~~~~~~~~~~~~~~
--------------------
Now that this is done it's time to define the functions that handle the AJAX
calls from the script. You will need three functions. The first function is
@@ -186,9 +187,9 @@ used to add a new comment, and will call the web support method
username=username, proposal=proposal)
return jsonify(comment=comment)
You'll notice that both a `parent_id` and `node_id` are sent with the
request. If the comment is being attached directly to a node, `parent_id`
will be empty. If the comment is a child of another comment, then `node_id`
You'll notice that both a ``parent_id`` and ``node_id`` are sent with the
request. If the comment is being attached directly to a node, ``parent_id``
will be empty. If the comment is a child of another comment, then ``node_id``
will be empty. Then next function handles the retrieval of comments for a
specific node, and is aptly named
:meth:`~sphinxcontrib.websupport.WebSupport.get_data`::
@@ -217,11 +218,11 @@ and will handle user votes on comments::
Comment Moderation
~~~~~~~~~~~~~~~~~~
------------------
By default, all comments added through :meth:`~.WebSupport.add_comment` are
automatically displayed. If you wish to have some form of moderation, you can
pass the `displayed` keyword argument::
pass the ``displayed`` keyword argument::
comment = support.add_comment(text, node_id='node_id',
parent_id='parent_id',

View File

@@ -26,13 +26,13 @@ documentation of the :class:`BaseSearch` class below.
BaseSearch class is moved to sphinxcontrib.websupport.search from
sphinx.websupport.search.
BaseSearch Methods
~~~~~~~~~~~~~~~~~~
Methods
-------
The following methods are defined in the BaseSearch class. Some methods do
not need to be overridden, but some (:meth:`~BaseSearch.add_document` and
:meth:`~BaseSearch.handle_query`) must be overridden in your subclass. For a
working example, look at the built-in adapter for whoosh.
The following methods are defined in the BaseSearch class. Some methods do not
need to be overridden, but some (:meth:`~BaseSearch.add_document` and
:meth:`~BaseSearch.handle_query`) must be overridden in your subclass. For a
working example, look at the built-in adapter for whoosh.
.. automethod:: BaseSearch.init_indexing

View File

@@ -27,8 +27,8 @@ documentation of the :class:`StorageBackend` class below.
sphinx.websupport.storage.
StorageBackend Methods
~~~~~~~~~~~~~~~~~~~~~~
Methods
-------
.. automethod:: StorageBackend.pre_build

View File

@@ -158,23 +158,41 @@ The builder's "name" must be given to the **-b** command-line option of
chapter :ref:`latex-options` for details.
The produced LaTeX file uses several LaTeX packages that may not be present
in a "minimal" TeX distribution installation. For example, on Ubuntu, the
following packages need to be installed for successful PDF builds:
in a "minimal" TeX distribution installation.
On Ubuntu xenial, 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`)
* ``latexmk`` (this is a Sphinx requirement on GNU/Linux and MacOS X
for functioning of ``make latexpdf``)
The testing of Sphinx LaTeX is done on Ubuntu trusty with the above
mentioned packages, which are from a TeXLive 2013 snapshot dated
February 2014.
Additional packages are needed in some circumstances (see the discussion of
the ``'fontpkg'`` key of :confval:`latex_elements` for more information):
* to support occasional Cyrillic letters or words, and a fortiori if
:confval:`language` is set to a Cyrillic language, the package
``texlive-lang-cyrillic`` is required, and, with unmodified ``'fontpkg'``,
also ``cm-super`` or ``cm-super-minimal``,
* to support occasional Greek letters or words (in text, not in
:rst:dir:`math` directive contents), ``texlive-lang-greek`` is required,
and, with unmodified ``'fontpkg'``, also ``cm-super`` or
``cm-super-minimal``,
* for ``'xelatex'`` or ``'lualatex'`` (see :confval:`latex_engine`),
``texlive-xetex`` resp. ``texlive-luatex``, and, if leaving unchanged
``'fontpkg'``, ``fonts-freefont-otf``.
The testing of Sphinx LaTeX is done on Ubuntu xenial whose TeX distribution
is based on a TeXLive 2015 snapshot dated March 2016.
.. versionchanged:: 1.6
Formerly, testing had been done on Ubuntu precise (TeXLive 2009).
.. versionchanged:: 2.0
Formerly, testing had been done on Ubuntu trusty (TeXLive 2013).
.. note::
Since 1.6, ``make latexpdf`` uses ``latexmk`` (not on Windows). This
@@ -190,20 +208,16 @@ The builder's "name" must be given to the **-b** command-line option of
reduces console output to a minimum.
Also, if ``latexmk`` version is 4.52b or higher (Jan 17)
``LATEXMKOPTS="-xelatex"`` will speed up PDF builds via XeLateX in case
Also, if ``latexmk`` is at version 4.52b or higher (January 2017)
``LATEXMKOPTS="-xelatex"`` speeds up PDF builds via XeLateX in case
of numerous graphics inclusions.
.. code-block:: console
make latexpdf LATEXMKOPTS="-xelatex"
To pass options directly to the ``(pdf|xe|lua)latex`` executable, use
variable ``LATEXOPTS``.
To pass options directly to the ``(pdf|xe|lua)latex`` binary, use
variable ``LATEXOPTS``, for example:
.. code-block:: console
make latexpdf LATEXOPTS="--interaction=nonstopmode"
make latexpdf LATEXOPTS="--halt-on-error"
.. autoattribute:: name
@@ -215,7 +229,7 @@ Note that a direct PDF builder is being provided by `rinohtype`_. The builder's
name is ``rinoh``. Refer to the `rinohtype manual`_ for details.
.. _rinohtype: https://github.com/brechtm/rinohtype
.. _rinohtype manual: http://www.mos6581.org/rinohtype/quickstart.html#sphinx-builder
.. _rinohtype manual: https://www.mos6581.org/rinohtype/quickstart.html#sphinx-builder
.. module:: sphinx.builders.text
.. class:: TextBuilder

View File

@@ -40,9 +40,7 @@ Important points to note:
contain the file name extension.
* Since :file:`conf.py` is read as a Python file, the usual rules apply for
encodings and Unicode support: declare the encoding using an encoding cookie
(a comment like ``# -*- coding: utf-8 -*-``) and use Unicode string literals
when you include non-ASCII characters in configuration values.
encodings and Unicode support.
* The contents of the config namespace are pickled (so that Sphinx can find out
when configuration changes), so it may not contain unpickleable values --
@@ -60,6 +58,36 @@ Important points to note:
created *after* the builder is initialized.
Project information
-------------------
.. confval:: project
The documented project's name.
.. confval:: author
The author name(s) of the document. The default value is ``'unknown'``.
.. confval:: copyright
A copyright statement in the style ``'2008, Author Name'``.
.. confval:: version
The major project version, used as the replacement for ``|version|``. For
example, for the Python documentation, this may be something like ``2.6``.
.. confval:: release
The full project version, used as the replacement for ``|release|`` and
e.g. in the HTML templates. For example, for the Python documentation, this
may be something like ``2.6.0rc1``.
If you don't need the separation provided between :confval:`version` and
:confval:`release`, just set them both to the same value.
General configuration
---------------------
@@ -98,7 +126,7 @@ General configuration
'.md': 'markdown',
}
By default, Sphinx only supports ``'restrcturedtext'`` file type. You can
By default, Sphinx only supports ``'restructuredtext'`` file type. You can
add a new file type using source parser extensions. Please read a document
of the extension to know what file type the extension supports.
@@ -149,7 +177,10 @@ General configuration
.. confval:: master_doc
The document name of the "master" document, that is, the document that
contains the root :rst:dir:`toctree` directive. Default is ``'contents'``.
contains the root :rst:dir:`toctree` directive. Default is ``'index'``.
.. versionchanged:: 2.0
The default is changed to ``'index'`` from ``'contents'``.
.. confval:: exclude_patterns
@@ -477,36 +508,6 @@ General configuration
.. versionadded:: 1.5
Project information
-------------------
.. confval:: project
The documented project's name.
.. confval:: author
The author name(s) of the document. The default value is ``'unknown'``.
.. confval:: copyright
A copyright statement in the style ``'2008, Author Name'``.
.. confval:: version
The major project version, used as the replacement for ``|version|``. For
example, for the Python documentation, this may be something like ``2.6``.
.. confval:: release
The full project version, used as the replacement for ``|release|`` and
e.g. in the HTML templates. For example, for the Python documentation, this
may be something like ``2.6.0rc1``.
If you don't need the separation provided between :confval:`version` and
:confval:`release`, just set them both to the same value.
.. confval:: today
today_fmt
@@ -813,7 +814,7 @@ that use Sphinx's HTMLWriter class.
.. confval:: html_theme
The "theme" that the HTML output should use. See the :doc:`section about
theming </theming>`. The default is ``'alabaster'``.
theming </usage/theming>`. The default is ``'alabaster'``.
.. versionadded:: 0.6
@@ -1108,12 +1109,6 @@ that use Sphinx's HTMLWriter class.
If true, the reST sources are included in the HTML build as
:file:`_sources/{name}`. The default is ``True``.
.. warning::
If this config value is set to ``False``, the JavaScript search function
will only display the titles of matching documents, and no excerpt from
the matching contents.
.. confval:: html_show_sourcelink
If true (and :confval:`html_copy_source` is true as well), links to the
@@ -1251,7 +1246,7 @@ that use Sphinx's HTMLWriter class.
:'sphinx.search.ja.DefaultSplitter':
TinySegmenter algorithm. This is default splitter.
:'sphinx.search.ja.MeCabSplitter':
:'sphinx.search.ja.MecabSplitter':
MeCab binding. To use this splitter, 'mecab' python binding or dynamic
link library ('libmecab.so' for linux, 'libmecab.dll' for windows) is
required.
@@ -1333,6 +1328,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:
@@ -1343,6 +1348,19 @@ Options for HTML help output
Output file base name for HTML help builder. Default is ``'pydoc'``.
.. confval:: htmlhelp_file_suffix
This is the file name suffix for generated HTML help files. The
default is ``".html"``.
.. versionadded:: 2.0
.. confval:: htmlhelp_link_suffix
Suffix for generated links to HTML files. The default is ``".html"``.
.. versionadded:: 2.0
.. _applehelp-options:
@@ -1763,8 +1781,8 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
Options for LaTeX output
------------------------
These options influence LaTeX output. For customization of LaTeX
macros and environments, see also :doc:`/latex`.
These options influence LaTeX output. Refer to :doc:`/latex` for more
information.
.. confval:: latex_engine
@@ -1776,24 +1794,29 @@ macros and environments, see also :doc:`/latex`.
* ``'lualatex'`` -- LuaLaTeX
* ``'platex'`` -- pLaTeX (default if :confval:`language` is ``'ja'``)
PDFLaTeX's support for Unicode characters covers those from the document
language (the LaTeX ``babel`` and ``inputenc`` packages map them to glyph
slots in the document font, at various encodings allowing each only 256
characters; Sphinx uses by default (except for Cyrillic languages) the
``times`` package), but stray characters from other scripts or special
symbols may require adding extra LaTeX packages or macros to the LaTeX
preamble.
``'pdflatex'``\ 's support for Unicode characters is limited.
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>`.)
.. note::
2.0 adds to ``'pdflatex'`` support in Latin language document of
occasional Cyrillic or Greek letters or words. This is not automatic,
see the discussion of the :confval:`latex_elements` ``'fontenc'`` key.
If your project uses Unicode characters, setting the engine to
``'xelatex'`` or ``'lualatex'`` and making sure to use an OpenType font
with wide-enough glyph coverage is often easier than trying to make
``'pdflatex'`` work with the extra Unicode characters. Since Sphinx 2.0
the default is the GNU FreeFont which covers well Latin, Cyrillic and Greek.
Contrarily to :ref:`MathJaX math rendering in HTML output <math-support>`,
LaTeX requires some extra configuration to support Unicode literals in
:rst:dir:`math`: the only comprehensive solution (as far as we know) is to
use ``'xelatex'`` or ``'lualatex'`` *and* to add
``r'\usepackage{unicode-math}'`` (e.g. via the :confval:`latex_elements`
``'preamble'`` key). You may prefer
``r'\usepackage[math-style=literal]{unicode-math}'`` to keep a Unicode
literal such as ``α`` (U+03B1) for example as is in output, rather than
being rendered as :math:`\alpha`.
.. confval:: latex_documents
@@ -1926,26 +1949,23 @@ macros and environments, see also :doc:`/latex`.
__ http://xindy.sourceforge.net/
- This option is ignored if :confval:`latex_engine` is ``'platex'``
(Japanese documents) as :program:`mendex` is used in that case.
(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`` file containing invalid bytes for
character, creates ``.ind`` files containing invalid bytes for
UTF-8 encoding. With ``'lualatex'`` this then breaks the PDF
build. Notice that :program:`xindy` supports most but not
all European languages.
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.
Cyrillic scripts are (transparently) supported with
``'pdflatex'`` thanks to a specific Sphinx-contributed ``xindy``
style file :file:`cyrLICRutf8.xdy`.
As :program:`xindy` does not support the same range of languages
as ``LaTeX/babel`` does, the default :program:`makeindex` for
``'pdflatex'`` may be preferred in some circumstances, although
the index will be ill-formed probably.
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
@@ -1998,33 +2018,82 @@ macros and environments, see also :doc:`/latex`.
``english`` is used if no language.) For Japanese documents, the
default is the empty string.
With XeLaTeX and LuaLaTeX, Sphinx configures the LaTeX document to use
`polyglossia`_, but one should be aware that current `babel`_ has
improved its support for Unicode engines in recent years and for some
languages it may make sense to prefer ``babel`` over ``polyglossia``.
.. hint::
After modifiying a core LaTeX key like this one, clean up the LaTeX
build repertory before next PDF build, else left-over auxiliary
files are likely to break the build.
.. _`polyglossia`: https://ctan.org/pkg/polyglossia
.. _`babel`: https://ctan.org/pkg/babel
.. versionchanged:: 1.5
For :confval:`latex_engine` set to ``'xelatex'``, the default
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.
Font package inclusion, the default is ``'\\usepackage{times}'`` which
uses Times for text, Helvetica for sans serif and Courier for monospace.
.. versionchanged:: 1.2
Defaults to ``''`` when the :confval:`language` uses the Cyrillic
script.
.. versionchanged:: 1.5
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}``.
.. versionchanged:: 2.0
Support for individual Greek and Cyrillic letters:
- In order to support occasional Cyrillic (физика частиц)
or Greek letters (Σωματιδιακή φυσική) in
a document whose language is English or a Latin European
one, the default set-up is enhanced (only for ``'pdflatex'``
engine) to do:
.. code-block:: latex
\substitutefont{LGR}{\rmdefault}{cmr}
\substitutefont{LGR}{\sfdefault}{cmss}
\substitutefont{LGR}{\ttdefault}{cmtt}
\substitutefont{X2}{\rmdefault}{cmr}
\substitutefont{X2}{\sfdefault}{cmss}
\substitutefont{X2}{\ttdefault}{cmtt}
but this is activated only under the condition that the
``'fontenc'`` key is configured to load the ``LGR`` (Greek)
and/or ``X2`` (Cyrillic) pdflatex-font encodings (if the
:confval:`language` is set to a Cyrillic language, this
``'fontpkg'`` key must be used as "times" package has no direct
support for it; then keep only ``LGR`` lines from the above,
if support is needed for Greek in the text).
The ``\substitutefont`` command is from the eponymous LaTeX
package, which is loaded by Sphinx if needed (on Ubuntu xenial it
is part of ``texlive-latex-extra`` which is a Sphinx
requirement).
Only if the document actually does contain Unicode Greek letters
(in text) or Cyrillic letters, will the above default set-up
cause additional requirements for the PDF build. On Ubuntu
xenial, ``texlive-lang-greek``, ``texlive-lang-cyrillic``, and
(with the above choice of fonts) the ``cm-super`` (or
``cm-super-minimal``) package.
- For ``'xelatex'`` and ``'lualatex'``, the default is to
use the FreeFont family: this OpenType font family
supports both Cyrillic and Greek scripts and is available as
separate Ubuntu xenial package ``fonts-freefont-otf``, it is not
needed to install the big package ``texlive-fonts-extra``.
- ``'platex'`` (Japanese documents) engine supports individual
Cyrillic and Greek letters with no need of extra user set-up.
``'fncychap'``
Inclusion of the "fncychap" package (which makes fancy chapter titles),
default ``'\\usepackage[Bjarne]{fncychap}'`` for English documentation
@@ -2034,6 +2103,8 @@ macros and environments, see also :doc:`/latex`.
"fncychap" styles you can try are "Lenny", "Glenn", "Conny", "Rejne" and
"Bjornstrup". You can also set this to ``''`` to disable fncychap.
The default is ``''`` for Japanese documents.
``'preamble'``
Additional preamble content, default empty. See :doc:`/latex`.
@@ -2101,14 +2172,69 @@ macros and environments, see also :doc:`/latex`.
.. versionadded:: 1.2
``'fontenc'``
"fontenc" package inclusion, default ``'\\usepackage[T1]{fontenc}'``.
"fontenc" package inclusion, defaults to
``'\\usepackage[T1]{fontenc}'``.
If ``'pdflatex'`` is the :confval:`latex_engine`, one can add ``LGR``
for support of Greek letters in the document, and also ``X2`` (or
``T2A``) for Cyrillic letters, like this:
.. code-block:: latex
r'\usepackage[LGR,X2,T1]{fontenc}'
.. attention::
Prior to 2.0, Unicode Greek letters were escaped to use LaTeX math
mark-up. This is not the case anymore, and the above must be used
(only in case of ``'pdflatex'`` engine) if the source contains such
Unicode Greek.
On Ubuntu xenial, packages ``texlive-lang-greek`` and ``cm-super``
(for the latter, only if the ``'fontpkg'`` setting is left to its
default) are needed for ``LGR`` to work. In place of ``cm-super``
one can install smaller ``cm-super-minimal``, but it requires the
LaTeX document to execute ``\usepackage[10pt]{type1ec}`` before
loading ``fontenc``. Thus, use this key with this extra at its
start if needed.
.. versionchanged:: 1.5
Defaults to ``'\\usepackage{fontspec}'`` when
:confval:`latex_engine` is ``'xelatex'``.
.. versionchanged:: 1.6
``'lualatex'`` also uses ``fontspec`` per default.
``'lualatex'`` uses ``fontspec`` per default like ``'xelatex'``.
.. versionchanged:: 2.0
``'lualatex'`` executes
``\defaultfontfeatures[\rmfamily,\sffamily]{}`` to disable TeX
ligatures.
.. versionchanged:: 2.0
Detection of ``LGR``, ``T2A``, ``X2`` to trigger support of
occasional Greek or Cyrillic (``'pdflatex'`` only, as this support
is provided natively by ``'platex'`` and only requires suitable
font with ``'xelatex'/'lualatex'``).
``'textgreek'``
The default (``'pdflatex'`` only) is
``'\\usepackage{textalpha}'``, but only if ``'fontenc'`` was
modified by user to include ``LGR`` option. If not, the key
value will be forced to be the empty string.
This is needed for ``pdfLaTeX`` to support Unicode input of Greek
letters such as φύσις. Expert users may want to load the ``textalpha``
package with its option ``normalize-symbols``.
.. hint::
Unicode Greek (but no further Unicode symbols) in :rst:dir:`math`
can be supported by ``'pdflatex'`` from setting this key to
``r'\usepackage{textalpha,alphabeta}'``. Then ``:math:`α``` (U+03B1)
will render as :math:`\alpha`. For wider Unicode support in math
input, see the discussion of :confval:`latex_engine`.
With ``'platex'`` (Japanese), ``'xelatex'`` or ``'lualatex'``, this
key is ignored.
.. versionadded:: 2.0
``'geometry'``
"geometry" package inclusion, the default definition is:
@@ -2153,10 +2279,22 @@ macros and environments, see also :doc:`/latex`.
Previously this was done from inside :file:`sphinx.sty`.
``'maketitle'``
"maketitle" call, default ``'\\maketitle'`` (but it has been
redefined by the Sphinx ``manual`` and ``howto`` classes.) Override
if you want to generate a differently-styled title page.
"maketitle" call, default ``'\\sphinxmaketitle'``. Override
if you want to generate a differently styled title page.
.. hint::
If the key value is set to
``r'\newcommand\sphinxbackoftitlepage{<Extra
material>}\sphinxmaketitle'``, then ``<Extra material>`` will be
typeset on back of title page (``'manual'`` docclass only).
.. versionchanged:: 1.8.3
Original ``\maketitle`` from document class is not overwritten,
hence is re-usable as part of some custom setting for this key.
.. versionadded:: 1.8.3
``\sphinxbackoftitlepage`` optional macro. It can also be defined
inside ``'preamble'`` key rather than this one.
``'releasename'``
value that prefixes ``'release'`` element on title page, default
``'Release'``. As for *title* and *author* used in the tuples of
@@ -2185,25 +2323,23 @@ macros and environments, see also :doc:`/latex`.
Remove unneeded ``{}`` after ``\\hrule``.
``'printindex'``
"printindex" call, the last thing in the file.
.. versionchanged:: 1.8
Former default ``'\\printindex'`` now ``'\\sphinxprintindex'``.
This macro works around an issue__ with PDF builds at RTD doing too
few ``pdflatex`` runs.
__ https://github.com/rtfd/readthedocs.org/issues/2857
"printindex" call, the last thing in the file, default
``'\\printindex'``. Override if you want to generate the index
differently or append some content after the index. For example
``'\\footnotesize\\raggedright\\printindex'`` is advisable when the
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).
For ``'xelatex'`` and ``'lualatex'``, defaults to
``'\\fvset{fontsize=auto}'``, because the default fonts are part of
one unified typeface family (Latin Modern OpenType).
Customization of ``fancyvrb`` LaTeX package. Sphinx does by default
``'fvset': '\\fvset{fontsize=\\small}'``, to adjust for the large
character width of the monospace font, used in code-blocks.
You may need to modify this if you use custom fonts.
.. versionadded:: 1.8
.. versionchanged:: 2.0
Due to new default font choice for ``'xelatex'`` and ``'lualatex'``
(FreeFont), Sphinx does ``\\fvset{fontsize=\\small}`` also with these
engines (and not ``\\fvset{fontsize=auto}``).
* Keys that are set by other options and therefore should not be overridden
are:
@@ -2211,10 +2347,8 @@ macros and environments, see also :doc:`/latex`.
``'docclass'``
``'classoptions'``
``'title'``
``'date'``
``'release'``
``'author'``
``'logo'``
``'makeindex'``
.. confval:: latex_docclass

View File

@@ -45,6 +45,10 @@ docstrings to correct reStructuredText before :mod:`autodoc` processes them.
.. _NumPy:
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
Directives
----------
:mod:`autodoc` provides several directives that are versions of the usual
:rst:dir:`py:module`, :rst:dir:`py:class` and so forth. On parsing time, they
import the corresponding module and extract the docstring of the given objects,
@@ -114,8 +118,17 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
.. autoclass:: Noodle
:members: eat, slurp
* If you want to make the ``members`` option (or other flag options described
below) the default, see :confval:`autodoc_default_flags`.
* If you want to make the ``members`` option (or other options described
below) the default, see :confval:`autodoc_default_options`.
.. tip::
You can use a negated form, :samp:`'no-{flag}'`, as an option of
autodoc directive, to disable it temporarily. For example::
.. automodule:: foo
:no-undoc-members:
* Members without docstrings will be left out, unless you give the
``undoc-members`` flag option::
@@ -297,6 +310,9 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
well-behaved decorating functions.
Configuration
-------------
There are also new config values that you can set:
.. confval:: autoclass_content
@@ -341,20 +357,39 @@ 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'``.
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.
For example, if ``autodoc_default_flags`` is set to ``['members',
'undoc-members']``, and you write a directive like this::
.. automodule:: foo
:no-undoc-members:
the directive will be interpreted as if only ``:members:`` was given.
``'inherited-members'``, ``'show-inheritance'``, ``'ignore-module-all'``
and ``'exclude-members'``.
.. versionadded:: 1.0
.. deprecated:: 1.8
Integrated into :confval:`autodoc_default_options`.
.. confval:: autodoc_default_options
The default options for autodoc directives. They are applied to all autodoc
directives automatically. It must be a dictionary which maps option names
to the values. For example::
autodoc_default_options = {
'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").
The supported options are ``'members'``, ``'member-order'``,
``'undoc-members'``, ``'private-members'``, ``'special-members'``,
``'inherited-members'``, ``'show-inheritance'``, ``'ignore-module-all'`` and
``'exclude-members'``.
.. versionadded:: 1.8
.. confval:: autodoc_docstring_signature
Functions imported from C modules cannot be introspected, and therefore the
@@ -405,6 +440,16 @@ There are also new config values that you can set:
.. versionadded:: 1.7
.. confval:: suppress_warnings
:noindex:
:mod:`autodoc` supports to suppress warning messages via
:confval:`suppress_warnings`. It allows following warnings types in
addition:
* autodoc
* autodoc.import_object
Docstring preprocessing
-----------------------

View File

@@ -208,6 +208,8 @@ The following variables available in the templates:
List containing names of all inherited members of class. Only available for
classes.
.. versionadded:: 1.8.0
.. data:: functions
List containing names of "public" functions in the module. Here, "public"

View File

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

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""Example Google style docstrings.
This module demonstrates documentation as specified by the `Google Python
@@ -178,7 +177,7 @@ class ExampleError(Exception):
self.code = code
class ExampleClass(object):
class ExampleClass:
"""The summary line for a class docstring should fit on one line.
If the class has public attributes, they may be documented here

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""Example NumPy style docstrings.
This module demonstrates documentation as specified by the `NumPy
@@ -223,7 +222,7 @@ class ExampleError(Exception):
self.code = code
class ExampleClass(object):
class ExampleClass:
"""The summary line for a class docstring should fit on one line.
If the class has public attributes, they may be documented here

View File

@@ -54,7 +54,7 @@ It adds this directive:
E D F
"""
class A(object):
class A:
pass
class B(A):

View File

@@ -168,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: https://docs.mathjax.org/en/latest/configuration.html#using-in-line-configuration-options
:mod:`sphinx.ext.jsmath` -- Render math via JavaScript
------------------------------------------------------

View File

@@ -409,10 +409,10 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
.. attribute:: attr1
*int*
Description of `attr1`
:type: int
.. confval:: napoleon_use_param
True to use a ``:param:`` role for each function parameter. False to

View File

@@ -25,7 +25,11 @@ from the source to the description will also be inserted.
In addition, if you don't want to import the modules by ``viewcode``,
you can tell the location of the location of source code to ``viewcode``
using :event:`viewcode-find-source` event.
using the :event:`viewcode-find-source` event.
If :confval:`viewcode_follow_imported_members` is enabled,
you will also need to resolve imported attributes
using the :event:`viewcode-follow-imported` event.
This extension works only on HTML related builders like ``html``,
``applehelp``, ``devhelp``, ``htmlhelp``, ``qthelp`` and so on except
@@ -83,3 +87,13 @@ Configuration
:param app: The Sphinx application object.
:param modname: The name of the module to find source code for.
.. event:: viewcode-follow-imported (app, modname, attribute)
.. versionadded:: 1.8
Find the name of the original module for an attribute.
:param app: The Sphinx application object.
:param modname: The name of the module that the attribute belongs to.
:param attribute: The name of the member to follow.

View File

@@ -12,10 +12,9 @@ Installing Sphinx
Overview
--------
Sphinx is written in `Python`__ and supports both Python 2.7 and Python 3.3+.
We recommend the latter.
Sphinx is written in `Python`__ and supports Python 3.5+.
__ http://docs.python-guide.org/en/latest/
__ https://docs.python-guide.org/
Linux
@@ -73,7 +72,7 @@ Homebrew
For more information, refer to the `package overview`__.
__ http://formulae.brew.sh/formula/sphinx-doc
__ https://formulae.brew.sh/formula/sphinx-doc
MacPorts
~~~~~~~~
@@ -121,9 +120,9 @@ Once Python is installed, you can install Sphinx using :command:`pip`. Refer
to the :ref:`pip installation instructions <install-pypi>` below for more
information.
__ http://docs.python-guide.org/en/latest/
__ http://docs.python-guide.org/en/latest/starting/install3/win/
__ http://docs.python-guide.org/en/latest/starting/install/win/
__ https://docs.python-guide.org/
__ https://docs.python-guide.org/starting/install3/win/
__ https://docs.python-guide.org/starting/install/win/
.. _install-pypi:

View File

@@ -15,7 +15,7 @@ parsing the `CommonMark`__ Markdown flavor.
__ https://daringfireball.net/projects/markdown/
__ https://recommonmark.readthedocs.io/en/latest/index.html
__ https://github.com/rtfd/CommonMark-py
__ http://commonmark.org/
__ https://commonmark.org/
Configuration
-------------

View File

@@ -320,8 +320,8 @@ More topics to be covered
- :doc:`Other extensions </usage/extensions/index>`:
- Static files
- :doc:`Selecting a theme </theming>`
- :doc:`/setuptools`
- :doc:`Selecting a theme </usage/theming>`
- :doc:`/usage/advanced/setuptools`
- :ref:`Templating <templating>`
- Using extensions
- :ref:`Writing extensions <dev-extensions>`

View File

@@ -1063,6 +1063,15 @@ or use Python raw strings (``r"raw"``).
.. _AmSMath LaTeX package: https://www.ams.org/publications/authors/tex/amslatex
.. seealso::
:ref:`math-support`
Rendering options for math with HTML builders.
:confval:`latex_engine`
Explains how to configure LaTeX builder to support Unicode literals in
math mark-up.
Grammar production displays
---------------------------

View File

@@ -850,8 +850,8 @@ Note however that no checking is performed with respect to parameter
compatibility. E.g., ``Iterator{A, B, C}`` will be accepted as an introduction
even though it would not be valid C++.
Inline Expressions and Tpes
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Inline Expressions and Types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. rst:role:: cpp:expr
cpp:texpr
@@ -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

@@ -288,13 +288,7 @@ Math
.. 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.
Same as :rst:role:`math:numref`.
Other semantic markup

339
doc/usage/theming.rst Normal file
View File

@@ -0,0 +1,339 @@
.. highlight:: python
HTML
====
Sphinx provides a number of builders for HTML and HTML-based formats.
Builders
--------
.. todo:: Populate when the 'builders' document is split up.
Themes
------
.. versionadded:: 0.6
.. note::
This section provides information about using pre-existing HTML themes. If
you wish to create your own theme, refer to :doc:`/theming`.
Sphinx supports changing the appearance of its HTML output via *themes*. A
theme is a collection of HTML templates, stylesheet(s) and other static files.
Additionally, it has a configuration file which specifies from which theme to
inherit, which highlighting style to use, and what options exist for customizing
the theme's look and feel.
Themes are meant to be project-unaware, so they can be used for different
projects without change.
Using a theme
~~~~~~~~~~~~~
Using a :ref:`theme provided with Sphinx <builtin-themes>` is easy. Since these
do not need to be installed, you only need to set the :confval:`html_theme`
config value. For example, to enable the ``classic`` theme, add the following
to :file:`conf.py`::
html_theme = "classic"
You can also set theme-specific options using the :confval:`html_theme_options`
config value. These options are generally used to change the look and feel of
the theme. For example, to place the sidebar on the right side and a black
background for the relation bar (the bar with the navigation links at the
page's top and bottom), add the following :file:`conf.py`::
html_theme_options = {
"rightsidebar": "true",
"relbarbgcolor": "black"
}
If the theme does not come with Sphinx, it can be in two static forms or as a
Python package. For the static forms, either a directory (containing
:file:`theme.conf` and other needed files), or a zip file with the same
contents is supported. The directory or zipfile must be put where Sphinx can
find it; for this there is the config value :confval:`html_theme_path`. This
can be a list of directories, relative to the directory containing
:file:`conf.py`, that can contain theme directories or zip files. For example,
if you have a theme in the file :file:`blue.zip`, you can put it right in the
directory containing :file:`conf.py` and use this configuration::
html_theme = "blue"
html_theme_path = ["."]
The third form is a Python package. If a theme you want to use is distributed
as a Python package, you can use it after installing
.. code-block:: bash
# installing theme package
$ pip install sphinxjp.themes.dotted
Once installed, this can be used in the same manner as a directory or
zipfile-based theme::
html_theme = "dotted"
For more information on the design of themes, including information about
writing your own themes, refer to :doc:`/theming`.
.. _builtin-themes:
Builtin themes
~~~~~~~~~~~~~~
.. cssclass:: longtable
+--------------------+--------------------+
| **Theme overview** | |
+--------------------+--------------------+
| |alabaster| | |classic| |
| | |
| *alabaster* | *classic* |
+--------------------+--------------------+
| |sphinxdoc| | |scrolls| |
| | |
| *sphinxdoc* | *scrolls* |
+--------------------+--------------------+
| |agogo| | |traditional| |
| | |
| *agogo* | *traditional* |
+--------------------+--------------------+
| |nature| | |haiku| |
| | |
| *nature* | *haiku* |
+--------------------+--------------------+
| |pyramid| | |bizstyle| |
| | |
| *pyramid* | *bizstyle* |
+--------------------+--------------------+
.. |alabaster| image:: /_static/themes/alabaster.png
.. |classic| image:: /_static/themes/classic.png
.. |sphinxdoc| image:: /_static/themes/sphinxdoc.png
.. |scrolls| image:: /_static/themes/scrolls.png
.. |agogo| image:: /_static/themes/agogo.png
.. |traditional| image:: /_static/themes/traditional.png
.. |nature| image:: /_static/themes/nature.png
.. |haiku| image:: /_static/themes/haiku.png
.. |pyramid| image:: /_static/themes/pyramid.png
.. |bizstyle| image:: /_static/themes/bizstyle.png
Sphinx comes with a selection of themes to choose from.
.. cssclass:: clear
These themes are:
**basic**
This is a basically unstyled layout used as the base for the
other themes, and usable as the base for custom themes as well. The HTML
contains all important elements like sidebar and relation bar. There are
these options (which are inherited by the other themes):
- **nosidebar** (true or false): Don't include the sidebar. Defaults to
``False``.
- **sidebarwidth** (int or str): Width of the sidebar in pixels.
This can be an int, which is interpreted as pixels or a valid CSS
dimension string such as '70em' or '50%'. Defaults to 230 pixels.
- **body_min_width** (int or str): Minimal width of the document body.
This can be an int, which is interpreted as pixels or a valid CSS
dimension string such as '70em' or '50%'. Use 0 if you don't want
a width limit. Defaults may depend on the theme (often 450px).
- **body_max_width** (int or str): Maximal width of the document body.
This can be an int, which is interpreted as pixels or a valid CSS
dimension string such as '70em' or '50%'. Use 'none' if you don't
want a width limit. Defaults may depend on the theme (often 800px).
**alabaster**
`Alabaster theme`_ is a modified "Kr" Sphinx theme from @kennethreitz
(especially as used in his Requests project), which was itself originally
based on @mitsuhiko's theme used for Flask & related projects. Refer to its
`installation page`_ for information on how to configure
:confval:`html_sidebars` for its use.
.. _Alabaster theme: https://pypi.org/project/alabaster/
.. _installation page: https://alabaster.readthedocs.io/en/latest/installation.html
**classic**
This is the classic theme, which looks like `the Python 2
documentation <https://docs.python.org/2/>`_. It can be customized via
these options:
- **rightsidebar** (true or false): Put the sidebar on the right side.
Defaults to ``False``.
- **stickysidebar** (true or false): Make the sidebar "fixed" so that it
doesn't scroll out of view for long body content. This may not work well
with all browsers. Defaults to ``False``.
- **collapsiblesidebar** (true or false): Add an *experimental* JavaScript
snippet that makes the sidebar collapsible via a button on its side.
Defaults to ``False``.
- **externalrefs** (true or false): Display external links differently from
internal links. Defaults to ``False``.
There are also various color and font options that can change the color scheme
without having to write a custom stylesheet:
- **footerbgcolor** (CSS color): Background color for the footer line.
- **footertextcolor** (CSS color): Text color for the footer line.
- **sidebarbgcolor** (CSS color): Background color for the sidebar.
- **sidebarbtncolor** (CSS color): Background color for the sidebar collapse
button (used when *collapsiblesidebar* is ``True``).
- **sidebartextcolor** (CSS color): Text color for the sidebar.
- **sidebarlinkcolor** (CSS color): Link color for the sidebar.
- **relbarbgcolor** (CSS color): Background color for the relation bar.
- **relbartextcolor** (CSS color): Text color for the relation bar.
- **relbarlinkcolor** (CSS color): Link color for the relation bar.
- **bgcolor** (CSS color): Body background color.
- **textcolor** (CSS color): Body text color.
- **linkcolor** (CSS color): Body link color.
- **visitedlinkcolor** (CSS color): Body color for visited links.
- **headbgcolor** (CSS color): Background color for headings.
- **headtextcolor** (CSS color): Text color for headings.
- **headlinkcolor** (CSS color): Link color for headings.
- **codebgcolor** (CSS color): Background color for code blocks.
- **codetextcolor** (CSS color): Default text color for code blocks, if not
set differently by the highlighting style.
- **bodyfont** (CSS font-family): Font for normal text.
- **headfont** (CSS font-family): Font for headings.
**sphinxdoc**
The theme originally used by this documentation. It features
a sidebar on the right side. There are currently no options beyond
*nosidebar* and *sidebarwidth*.
.. note::
The Sphinx documentation now uses
`an adjusted version of the sphinxdoc theme
<https://github.com/sphinx-doc/sphinx/tree/master/doc/_themes/sphinx13>`_.
**scrolls**
A more lightweight theme, based on `the Jinja documentation
<http://jinja.pocoo.org/>`_. The following color options are available:
- **headerbordercolor**
- **subheadlinecolor**
- **linkcolor**
- **visitedlinkcolor**
- **admonitioncolor**
**agogo**
A theme created by Andi Albrecht. The following options are supported:
- **bodyfont** (CSS font family): Font for normal text.
- **headerfont** (CSS font family): Font for headings.
- **pagewidth** (CSS length): Width of the page content, default 70em.
- **documentwidth** (CSS length): Width of the document (without sidebar),
default 50em.
- **sidebarwidth** (CSS length): Width of the sidebar, default 20em.
- **bgcolor** (CSS color): Background color.
- **headerbg** (CSS value for "background"): background for the header area,
default a grayish gradient.
- **footerbg** (CSS value for "background"): background for the footer area,
default a light gray gradient.
- **linkcolor** (CSS color): Body link color.
- **headercolor1**, **headercolor2** (CSS color): colors for <h1> and <h2>
headings.
- **headerlinkcolor** (CSS color): Color for the backreference link in
headings.
- **textalign** (CSS *text-align* value): Text alignment for the body, default
is ``justify``.
**nature**
A greenish theme. There are currently no options beyond
*nosidebar* and *sidebarwidth*.
**pyramid**
A theme from the Pyramid web framework project, designed by Blaise Laflamme.
There are currently no options beyond *nosidebar* and *sidebarwidth*.
**haiku**
A theme without sidebar inspired by the `Haiku OS user guide
<https://www.haiku-os.org/docs/userguide/en/contents.html>`_. The following
options are supported:
- **full_logo** (true or false, default ``False``): If this is true, the
header will only show the :confval:`html_logo`. Use this for large logos.
If this is false, the logo (if present) will be shown floating right, and
the documentation title will be put in the header.
- **textcolor**, **headingcolor**, **linkcolor**, **visitedlinkcolor**,
**hoverlinkcolor** (CSS colors): Colors for various body elements.
**traditional**
A theme resembling the old Python documentation. There are
currently no options beyond *nosidebar* and *sidebarwidth*.
**epub**
A theme for the epub builder. This theme tries to save visual
space which is a sparse resource on ebook readers. The following options
are supported:
- **relbar1** (true or false, default ``True``): If this is true, the
`relbar1` block is inserted in the epub output, otherwise it is omitted.
- **footer** (true or false, default ``True``): If this is true, the
`footer` block is inserted in the epub output, otherwise it is omitted.
**bizstyle**
A simple bluish theme. The following options are supported
beyond *nosidebar* and *sidebarwidth*:
- **rightsidebar** (true or false): Put the sidebar on the right side.
Defaults to ``False``.
.. versionadded:: 1.3
'alabaster', 'sphinx_rtd_theme' and 'bizstyle' theme.
.. versionchanged:: 1.3
The 'default' theme has been renamed to 'classic'. 'default' is still
available, however it will emit a notice that it is an alias for the new
'alabaster' theme.
Third Party Themes
~~~~~~~~~~~~~~~~~~
.. cssclass:: longtable
+--------------------+--------------------+
| **Theme overview** | |
+--------------------+--------------------+
| |sphinx_rtd_theme| | |
| | |
| *sphinx_rtd_theme* | |
+--------------------+--------------------+
.. |sphinx_rtd_theme| image:: /_static/themes/sphinx_rtd_theme.png
There are many third-party themes available. Some of these are general use,
while others are specific to an individual project. A section of third-party
themes is listed below. Many more can be found on PyPI__, GitHub__ and
sphinx-themes.org__.
.. cssclass:: clear
**sphinx_rtd_theme**
`Read the Docs Sphinx Theme`_.
This is a mobile-friendly sphinx theme that was made for readthedocs.org.
View a working demo over on readthedocs.org. You can get install and options
information at `Read the Docs Sphinx Theme`_ page.
.. _Read the Docs Sphinx Theme: https://pypi.org/project/sphinx_rtd_theme/
.. versionchanged:: 1.4
**sphinx_rtd_theme** has become optional.
.. __: https://pypi.org/search/?q=&o=&c=Framework+%3A%3A+Sphinx+%3A%3A+Theme
.. __: https://github.com/search?utf8=%E2%9C%93&q=sphinx+theme&type=
.. __: https://sphinx-themes.org/

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

@@ -43,7 +43,6 @@ paths =
.
[mypy]
python_version = 2.7
show_column_numbers = True
show_error_context = True
ignore_missing_imports = True
@@ -55,6 +54,7 @@ strict_optional = False
[tool:pytest]
filterwarnings =
all
ignore::DeprecationWarning:docutils.io
[coverage:run]

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import os
import sys
from distutils import log
@@ -11,23 +10,22 @@ import sphinx
with open('README.rst') as f:
long_desc = f.read()
if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 4):
print('ERROR: Sphinx requires at least Python 2.7 or 3.4 to run.')
if sys.version_info < (3, 5):
print('ERROR: Sphinx requires at least Python 3.5 to run.')
sys.exit(1)
install_requires = [
'six>=1.5',
'Jinja2>=2.3',
'Pygments>=2.0',
'docutils>=0.11',
'docutils>=0.12',
'snowballstemmer>=1.1',
'babel>=1.3,!=2.0',
'alabaster>=0.7,<0.8',
'imagesize',
'requests>=2.0.0',
'requests>=2.5.0',
'setuptools',
'packaging',
'sphinxcontrib-websupport',
]
extras_require = {
@@ -35,9 +33,6 @@ extras_require = {
':sys_platform=="win32"': [
'colorama>=0.3.5',
],
':python_version<"3.5"': [
'typing'
],
'websupport': [
'sqlalchemy>=0.9',
'whoosh>=2.0',
@@ -49,13 +44,8 @@ extras_require = {
'html5lib',
'flake8>=3.5.0',
'flake8-import-order',
],
'test:python_version<"3"': [
'enum34',
],
'test:python_version>="3"': [
'mypy',
'typed_ast',
'mypy>=0.470',
'docutils-stubs',
],
}
@@ -65,7 +55,7 @@ extras_require = {
cmdclass = {}
class Tee(object):
class Tee:
def __init__(self, stream):
self.stream = stream
self.buffer = StringIO()
@@ -142,7 +132,7 @@ else:
domain + '.js'))
for js_file, (locale, po_file) in zip(js_files, po_files):
with open(po_file, 'r') as infile:
with open(po_file) as infile:
catalog = read_po(infile, locale)
if catalog.fuzzy and not self.use_fuzzy:
@@ -162,11 +152,11 @@ else:
with open(js_file, 'wt') as outfile:
outfile.write('Documentation.addTranslations(')
dump(dict(
messages=jscatalog,
plural_expr=catalog.plural_expr,
locale=str(catalog.locale)
), outfile, sort_keys=True)
dump({
'messages': jscatalog,
'plural_expr': catalog.plural_expr,
'locale': str(catalog.locale)
}, outfile, sort_keys=True)
outfile.write(');')
cmdclass['compile_catalog'] = compile_catalog_plusjs
@@ -195,12 +185,11 @@ setup(
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Framework :: Setuptools Plugin',
@@ -235,7 +224,7 @@ setup(
'build_sphinx = sphinx.setup_command:BuildDoc',
],
},
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
python_requires=">=3.5",
install_requires=install_requires,
extras_require=extras_require,
cmdclass=cmdclass,

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
Sphinx
~~~~~~
@@ -12,33 +11,27 @@
# Keep this file executable as-is in Python 3!
# (Otherwise getting the version out of it from setup.py is impossible.)
from __future__ import absolute_import
import os
import sys
import warnings
from os import path
from .deprecation import RemovedInNextVersionWarning
from .deprecation import RemovedInSphinx20Warning
if False:
# For type annotation
# note: Don't use typing.TYPE_CHECK here (for py27 and py34).
from typing import Any # NOQA
# by default, all DeprecationWarning under sphinx package will be emit.
# Users can avoid this by using environment variable: PYTHONWARNINGS=
if 'PYTHONWARNINGS' not in os.environ:
warnings.filterwarnings('default',
category=RemovedInNextVersionWarning, module='sphinx')
warnings.filterwarnings('default', category=RemovedInNextVersionWarning)
# docutils.io using mode='rU' for open
warnings.filterwarnings('ignore', "'U' mode is deprecated",
DeprecationWarning, module='docutils.io')
__version__ = '1.8.0+'
__released__ = '1.8.0' # used when Sphinx builds its own docs
__version__ = '2.0.0+'
__released__ = '2.0.0' # used when Sphinx builds its own docs
#: Version info for better programmatic use.
#:
@@ -48,7 +41,7 @@ __released__ = '1.8.0' # used when Sphinx builds its own docs
#:
#: .. versionadded:: 1.2
#: Before version 1.2, check the string ``sphinx.__version__``.
version_info = (1, 8, 0, 'beta', 0)
version_info = (2, 0, 0, 'beta', 0)
package_dir = path.abspath(path.dirname(__file__))
@@ -61,55 +54,10 @@ if __version__.endswith('+'):
__version__ = __version__[:-1] # remove '+' for PEP-440 version spec.
try:
import subprocess
p = subprocess.Popen(['git', 'show', '-s', '--pretty=format:%h',
path.join(package_dir, '..')],
p = subprocess.Popen(['git', 'show', '-s', '--pretty=format:%h'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if out:
__display_version__ += '/' + out.decode().strip()
except Exception:
pass
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,
)
argv = argv[1:] # skip first argument to adjust arguments (refs: #4615)
return build.main(argv)
def build_main(argv=sys.argv):
"""Sphinx build "main" command-line entry."""
from .cmd import build
warnings.warn(
'`sphinx.build_main()` has moved to `sphinx.cmd.build.build_main()`.',
RemovedInSphinx20Warning,
stacklevel=2,
)
return build.build_main(argv[1:]) # skip first argument to adjust arguments (refs: #4615)
def make_main(argv=sys.argv):
"""Sphinx build "make mode" entry."""
from .cmd import build
warnings.warn(
'`sphinx.build_main()` has moved to `sphinx.cmd.build.make_main()`.',
RemovedInSphinx20Warning,
stacklevel=2,
)
return build.make_main(argv[1:]) # skip first argument to adjust arguments (refs: #4615)
if __name__ == '__main__':
from .cmd import build
warnings.warn(
'`sphinx` has moved to `sphinx.build`.',
RemovedInSphinx20Warning,
stacklevel=2,
)
build.main()

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.__main__
~~~~~~~~~~~~~~~
@@ -13,4 +12,4 @@ import sys
from sphinx.cmd.build import main
sys.exit(main(sys.argv[1:])) # type: ignore
sys.exit(main(sys.argv[1:]))

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.addnodes
~~~~~~~~~~~~~~~
@@ -13,14 +12,15 @@ import warnings
from docutils import nodes
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
if False:
# For type annotation
from typing import List, Sequence # NOQA
from typing import Any, Dict, List, Sequence # NOQA
from sphinx.application import Sphinx # NOQA
class translatable(object):
class translatable(nodes.Node):
"""Node which supports translation.
The translation goes forward with following steps:
@@ -40,12 +40,12 @@ class translatable(object):
raise NotImplementedError
def apply_translated_message(self, original_message, translated_message):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
"""Apply translated message."""
raise NotImplementedError
def extract_original_messages(self):
# type: () -> Sequence[unicode]
# type: () -> Sequence[str]
"""Extract translation messages.
:returns: list of extracted messages or messages generator
@@ -53,7 +53,7 @@ class translatable(object):
raise NotImplementedError
class not_smartquotable(object):
class not_smartquotable:
"""A node which does not support smart-quotes."""
support_smartquotes = False
@@ -67,12 +67,12 @@ class toctree(nodes.General, nodes.Element, translatable):
self['rawcaption'] = self['caption']
def apply_translated_message(self, original_message, translated_message):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
if self.get('rawcaption') == original_message:
self['caption'] = translated_message
def extract_original_messages(self):
# type: () -> List[unicode]
# type: () -> List[str]
if 'rawcaption' in self:
return [self['rawcaption']]
else:
@@ -106,6 +106,7 @@ class desc_signature_line(nodes.Part, nodes.Inline, nodes.FixedTextElement):
It should only be used in a ``desc_signature`` with ``is_multiline`` set.
Set ``add_permalink = True`` for the line that should get the permalink.
"""
sphinx_cpp_tagname = ''
# nodes to use within a desc_signature or desc_signature_line
@@ -125,8 +126,8 @@ class desc_type(nodes.Part, nodes.Inline, nodes.FixedTextElement):
class desc_returns(desc_type):
"""Node for a "returns" annotation (a la -> in Python)."""
def astext(self):
# type: () -> unicode
return ' -> ' + nodes.TextElement.astext(self)
# type: () -> str
return ' -> ' + super().astext()
class desc_name(nodes.Part, nodes.Inline, nodes.FixedTextElement):
@@ -147,8 +148,8 @@ class desc_optional(nodes.Part, nodes.Inline, nodes.FixedTextElement):
child_text_separator = ', '
def astext(self):
# type: () -> unicode
return '[' + nodes.TextElement.astext(self) + ']'
# type: () -> str
return '[' + super().astext() + ']'
class desc_annotation(nodes.Part, nodes.Inline, nodes.FixedTextElement):
@@ -205,10 +206,10 @@ class math(nodes.math):
if key == 'latex' and 'latex' not in self.attributes:
warnings.warn("math node for Sphinx was replaced by docutils'. "
"Therefore please use ``node.astext()`` to get an equation instead.",
RemovedInSphinx30Warning)
RemovedInSphinx30Warning, stacklevel=2)
return self.astext()
else:
return nodes.math.__getitem__(self, key)
return super().__getitem__(key)
class math_block(nodes.math_block):
@@ -224,10 +225,10 @@ class math_block(nodes.math_block):
if key == 'latex' and 'latex' not in self.attributes:
warnings.warn("displaymath node for Sphinx was replaced by docutils'. "
"Therefore please use ``node.astext()`` to get an equation instead.",
RemovedInSphinx30Warning)
RemovedInSphinx30Warning, stacklevel=2)
return self.astext()
else:
return nodes.math_block.__getitem__(self, key)
return super().__getitem__(key)
class displaymath(math_block):
@@ -307,6 +308,7 @@ class meta(nodes.Special, nodes.PreBibliographic, nodes.Element):
"""Node for meta directive -- same as docutils' standard meta node,
but pickleable.
"""
rawcontent = None
# inline nodes
@@ -340,15 +342,65 @@ class literal_strong(nodes.strong, not_smartquotable):
"""
class abbreviation(nodes.Inline, nodes.TextElement):
"""Node for abbreviations with explanations."""
class abbreviation(nodes.abbreviation):
"""Node for abbreviations with explanations.
.. deprecated:: 2.0
"""
def __init__(self, rawsource='', text='', *children, **attributes):
# type: (str, str, *nodes.Node, **Any) -> None
warnings.warn("abbrevition node for Sphinx was replaced by docutils'.",
RemovedInSphinx40Warning, stacklevel=2)
super().__init__(rawsource, text, *children, **attributes)
class manpage(nodes.Inline, nodes.FixedTextElement):
"""Node for references to manpages."""
# make the new nodes known to docutils; needed because the HTML writer will
# choke at some point if these are not added
nodes._add_node_class_names(k for k in globals().keys()
if k != 'nodes' and k[0] != '_')
def setup(app):
# type: (Sphinx) -> Dict[str, Any]
app.add_node(toctree)
app.add_node(desc)
app.add_node(desc_signature)
app.add_node(desc_signature_line)
app.add_node(desc_addname)
app.add_node(desc_type)
app.add_node(desc_returns)
app.add_node(desc_name)
app.add_node(desc_parameterlist)
app.add_node(desc_parameter)
app.add_node(desc_optional)
app.add_node(desc_annotation)
app.add_node(desc_content)
app.add_node(versionmodified)
app.add_node(seealso)
app.add_node(productionlist)
app.add_node(production)
app.add_node(displaymath)
app.add_node(index)
app.add_node(centered)
app.add_node(acks)
app.add_node(hlist)
app.add_node(hlistcol)
app.add_node(compact_paragraph)
app.add_node(glossary)
app.add_node(only)
app.add_node(start_of_file)
app.add_node(highlightlang)
app.add_node(tabular_col_spec)
app.add_node(meta)
app.add_node(pending_xref)
app.add_node(number_reference)
app.add_node(download_reference)
app.add_node(literal_emphasis)
app.add_node(literal_strong)
app.add_node(manpage)
return {
'version': 'builtin',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@@ -1,41 +0,0 @@
# -*- coding: utf-8 -*-
"""
sphinx.apidoc
~~~~~~~~~~~~~
This file has moved to :py:mod:`sphinx.ext.apidoc`.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import sys
import warnings
from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.ext.apidoc import main as _main
if False:
# For type annotation
from typing import List # NOQA
from sphinx.application import Sphinx # NOQA
def main(argv=sys.argv):
# type: (List[str]) -> None
warnings.warn(
'`sphinx.apidoc.main()` has moved to `sphinx.ext.apidoc.main()`.',
RemovedInSphinx20Warning,
stacklevel=2,
)
_main(argv[1:]) # skip first argument to adjust arguments (refs: #4615)
# So program can be started with "python -m sphinx.apidoc ..."
if __name__ == "__main__":
warnings.warn(
'`sphinx.apidoc` has moved to `sphinx.ext.apidoc`.',
RemovedInSphinx20Warning,
stacklevel=2,
)
main()

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.application
~~~~~~~~~~~~~~~~~~
@@ -10,31 +9,30 @@
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
import os
import pickle
import sys
import warnings
from collections import deque
from inspect import isclass
from io import StringIO
from os import path
from docutils.parsers.rst import Directive, directives, roles
from six import itervalues
from six.moves import cPickle as pickle
from six.moves import cStringIO
from docutils.parsers.rst import Directive, roles
import sphinx
from sphinx import package_dir, locale
from sphinx.config import Config, check_unicode
from sphinx.config import Config
from sphinx.config import CONFIG_FILENAME # NOQA # for compatibility (RemovedInSphinx30)
from sphinx.deprecation import (
RemovedInSphinx20Warning, RemovedInSphinx30Warning, RemovedInSphinx40Warning
RemovedInSphinx30Warning, RemovedInSphinx40Warning
)
from sphinx.environment import BuildEnvironment
from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError
from sphinx.events import EventManager
from sphinx.locale import __
from sphinx.project import Project
from sphinx.registry import SphinxComponentRegistry
from sphinx.util import docutils
from sphinx.util import import_object
@@ -44,6 +42,7 @@ from sphinx.util.build_phase import BuildPhase
from sphinx.util.console import bold # type: ignore
from sphinx.util.docutils import directive_helper
from sphinx.util.i18n import find_catalog_source_files
from sphinx.util.logging import prefixed_warnings
from sphinx.util.osutil import abspath, ensuredir, relpath
from sphinx.util.tags import Tags
@@ -62,6 +61,7 @@ if False:
from sphinx.util.typing import RoleFunction, TitleGetter # NOQA
builtin_extensions = (
'sphinx.addnodes',
'sphinx.builders.applehelp',
'sphinx.builders.changes',
'sphinx.builders.epub3',
@@ -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',
@@ -91,11 +92,11 @@ builtin_extensions = (
'sphinx.directives.other',
'sphinx.directives.patches',
'sphinx.extension',
'sphinx.io',
'sphinx.parsers',
'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',
@@ -109,14 +110,14 @@ builtin_extensions = (
# Strictly, alabaster theme is not a builtin extension,
# but it is loaded automatically to use it as default theme.
'alabaster',
) # type: Tuple[unicode, ...]
)
ENV_PICKLE_FILENAME = 'environment.pickle'
logger = logging.getLogger(__name__)
class Sphinx(object):
class Sphinx:
"""The main application class and extensibility interface.
:ivar srcdir: Directory containing source.
@@ -128,21 +129,21 @@ 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: (str, str, str, str, str, Dict, IO, IO, bool, bool, List[str], int, int, bool) -> None # NOQA
self.phase = BuildPhase.INITIALIZATION
self.verbosity = verbosity
self.extensions = {} # type: Dict[unicode, Extension]
self._setting_up_extension = ['?'] # type: List[unicode]
self.extensions = {} # type: Dict[str, Extension]
self.builder = None # type: Builder
self.env = None # type: BuildEnvironment
self.project = None # type: Project
self.registry = SphinxComponentRegistry()
self.html_themes = {} # type: Dict[unicode, unicode]
self.html_themes = {} # type: Dict[str, str]
# validate provided directories
self.srcdir = abspath(srcdir) # type: unicode
self.outdir = abspath(outdir) # type: unicode
self.doctreedir = abspath(doctreedir) # type: unicode
self.srcdir = abspath(srcdir)
self.outdir = abspath(outdir)
self.doctreedir = abspath(doctreedir)
self.confdir = confdir
if self.confdir: # confdir is optional
self.confdir = abspath(self.confdir)
@@ -161,18 +162,22 @@ class Sphinx(object):
self.parallel = parallel
if status is None:
self._status = cStringIO() # type: IO
self._status = StringIO() # type: IO
self.quiet = True
else:
self._status = status
self.quiet = False
if warning is None:
self._warning = cStringIO() # type: IO
self._warning = StringIO() # type: IO
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()
@@ -193,7 +198,6 @@ class Sphinx(object):
self.config = Config({}, confoverrides or {})
else:
self.config = Config.read(self.confdir, confoverrides or {}, self.tags)
check_unicode(self.config)
# initialize some limited config variables before initialize i18n and loading
# extensions
@@ -230,25 +234,23 @@ class Sphinx(object):
# the config file itself can be an extension
if self.config.setup:
self._setting_up_extension = ['conf.py']
if callable(self.config.setup):
self.config.setup(self)
else:
raise ConfigError(
__("'setup' as currently defined in conf.py isn't a Python callable. "
"Please modify its definition to make it a callable function. This is "
"needed for conf.py to behave as a Sphinx extension.")
)
prefix = __('while setting up extension %s:') % "conf.py"
with prefixed_warnings(prefix):
if callable(self.config.setup):
self.config.setup(self)
else:
raise ConfigError(
__("'setup' as currently defined in conf.py isn't a Python callable. "
"Please modify its definition to make it a callable function. "
"This is needed for conf.py to behave as a Sphinx extension.")
)
# now that we know all config values, collect them from conf.py
self.config.init_values()
self.emit('config-inited', self.config)
# check primary_domain if requested
primary_domain = self.config.primary_domain
if primary_domain and not self.registry.has_domain(primary_domain):
logger.warning(__('primary_domain %r not found, ignored.'), primary_domain)
# create the project
self.project = Project(self.srcdir, self.config.source_suffix)
# create the builder
self.builder = self.create_builder(buildername)
# set up the build environment
@@ -271,10 +273,10 @@ class Sphinx(object):
user_locale_dirs, self.config.language, domains=['sphinx'],
charset=self.config.source_encoding):
catinfo.write_mo(self.config.language)
locale_dirs = [None, path.join(package_dir, 'locale')] + user_locale_dirs # type: ignore # NOQA
locale_dirs = [None, path.join(package_dir, 'locale')] + user_locale_dirs
else:
locale_dirs = []
self.translator, has_translation = locale.init(locale_dirs, self.config.language) # type: ignore # NOQA
self.translator, has_translation = locale.init(locale_dirs, self.config.language)
if self.config.language is not None:
if has_translation or self.config.language == 'en':
# "en" never needs to be translated
@@ -301,11 +303,11 @@ class Sphinx(object):
self._init_env(freshenv=True)
def preload_builder(self, name):
# type: (unicode) -> None
# type: (str) -> None
self.registry.preload_builder(self, name)
def create_builder(self, name):
# type: (unicode) -> Builder
# type: (str) -> Builder
if name is None:
logger.info(__('No builder selected, using default: html'))
name = 'html'
@@ -321,7 +323,7 @@ class Sphinx(object):
# ---- main "build" method -------------------------------------------------
def build(self, force_all=False, filenames=None):
# type: (bool, List[unicode]) -> None
# type: (bool, List[str]) -> None
self.phase = BuildPhase.READING
try:
if force_all:
@@ -334,6 +336,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:
@@ -360,76 +365,10 @@ class Sphinx(object):
self.emit('build-finished', None)
self.builder.cleanup()
# ---- logging handling ----------------------------------------------------
def warn(self, message, location=None, type=None, subtype=None):
# type: (unicode, unicode, unicode, unicode) -> None
"""Emit a warning.
If *location* is given, it should either be a tuple of (*docname*,
*lineno*) or a string describing the location of the warning as well as
possible.
*type* and *subtype* are used to suppress warnings with
:confval:`suppress_warnings`.
.. deprecated:: 1.6
Use :mod:`sphinx.util.logging` instead.
"""
warnings.warn('app.warning() is now deprecated. Use sphinx.util.logging instead.',
RemovedInSphinx20Warning)
logger.warning(message, type=type, subtype=subtype, location=location)
def info(self, message='', nonl=False):
# type: (unicode, bool) -> None
"""Emit an informational message.
If *nonl* is true, don't emit a newline at the end (which implies that
more info output will follow soon.)
.. deprecated:: 1.6
Use :mod:`sphinx.util.logging` instead.
"""
warnings.warn('app.info() is now deprecated. Use sphinx.util.logging instead.',
RemovedInSphinx20Warning)
logger.info(message, nonl=nonl)
def verbose(self, message, *args, **kwargs):
# type: (unicode, Any, Any) -> None
"""Emit a verbose informational message.
.. deprecated:: 1.6
Use :mod:`sphinx.util.logging` instead.
"""
warnings.warn('app.verbose() is now deprecated. Use sphinx.util.logging instead.',
RemovedInSphinx20Warning)
logger.verbose(message, *args, **kwargs)
def debug(self, message, *args, **kwargs):
# type: (unicode, Any, Any) -> None
"""Emit a debug-level informational message.
.. deprecated:: 1.6
Use :mod:`sphinx.util.logging` instead.
"""
warnings.warn('app.debug() is now deprecated. Use sphinx.util.logging instead.',
RemovedInSphinx20Warning)
logger.debug(message, *args, **kwargs)
def debug2(self, message, *args, **kwargs):
# type: (unicode, Any, Any) -> None
"""Emit a lowlevel debug-level informational message.
.. deprecated:: 1.6
Use :mod:`sphinx.util.logging` instead.
"""
warnings.warn('app.debug2() is now deprecated. Use debug() instead.',
RemovedInSphinx20Warning)
logger.debug(message, *args, **kwargs)
# ---- general extensibility interface -------------------------------------
def setup_extension(self, extname):
# type: (unicode) -> None
# type: (str) -> None
"""Import and setup a Sphinx extension module.
Load the extension given by the module *name*. Use this if your
@@ -440,7 +379,7 @@ class Sphinx(object):
self.registry.load_extension(self, extname)
def require_sphinx(self, version):
# type: (unicode) -> None
# type: (str) -> None
"""Check the Sphinx version if requested.
Compare *version* (which must be a ``major.minor`` version string, e.g.
@@ -453,7 +392,7 @@ class Sphinx(object):
raise VersionRequirementError(version)
def import_object(self, objname, source=None):
# type: (str, unicode) -> Any
# type: (str, str) -> Any
"""Import an object from a ``module.name`` string.
.. deprecated:: 1.8
@@ -461,12 +400,12 @@ class Sphinx(object):
"""
warnings.warn('app.import_object() is deprecated. '
'Use sphinx.util.add_object_type() instead.',
RemovedInSphinx30Warning)
RemovedInSphinx30Warning, stacklevel=2)
return import_object(objname, source=None)
# event interface
def connect(self, event, callback):
# type: (unicode, Callable) -> int
# type: (str, Callable) -> int
"""Register *callback* to be called when *event* is emitted.
For details on available core events and the arguments of callback
@@ -486,7 +425,7 @@ class Sphinx(object):
self.events.disconnect(listener_id)
def emit(self, event, *args):
# type: (unicode, Any) -> List
# type: (str, Any) -> List
"""Emit *event* and pass *arguments* to the callback functions.
Return the return values of all callbacks as a list. Do not emit core
@@ -501,7 +440,7 @@ class Sphinx(object):
return self.events.emit(event, self, *args)
def emit_firstresult(self, event, *args):
# type: (unicode, Any) -> Any
# type: (str, Any) -> Any
"""Emit *event* and pass *arguments* to the callback functions.
Return the result of the first callback that doesn't return ``None``.
@@ -526,7 +465,7 @@ class Sphinx(object):
# TODO(stephenfin): Describe 'types' parameter
def add_config_value(self, name, default, rebuild, types=()):
# type: (unicode, Any, Union[bool, unicode], Any) -> None
# type: (str, Any, Union[bool, str], Any) -> None
"""Register a configuration value.
This is necessary for Sphinx to recognize new values and set default
@@ -559,7 +498,7 @@ class Sphinx(object):
self.config.add(name, default, rebuild, types)
def add_event(self, name):
# type: (unicode) -> None
# type: (str) -> None
"""Register an event called *name*.
This is needed to be able to emit it.
@@ -568,7 +507,7 @@ class Sphinx(object):
self.events.add(name)
def set_translator(self, name, translator_class, override=False):
# type: (unicode, Type[nodes.NodeVisitor], bool) -> None
# type: (str, Type[nodes.NodeVisitor], bool) -> None
"""Register or override a Docutils translator class.
This is used to register a custom output translator or to replace a
@@ -582,7 +521,7 @@ class Sphinx(object):
self.registry.add_translator(name, translator_class, override=override)
def add_node(self, node, override=False, **kwds):
# type: (nodes.Node, bool, Any) -> None
# type: (Type[nodes.Element], bool, Any) -> None
"""Register a Docutils node class.
This is necessary for Docutils internals. It may also be used in the
@@ -614,15 +553,14 @@ class Sphinx(object):
"""
logger.debug('[app] adding node: %r', (node, kwds))
if not override and docutils.is_node_registered(node):
logger.warning(__('while setting up extension %s: node class %r is '
'already registered, its visitors will be overridden'),
self._setting_up_extension, node.__name__,
type='app', subtype='add_node')
logger.warning(__('node class %r is already registered, '
'its visitors will be overridden'),
node.__name__, type='app', subtype='add_node')
docutils.register_node(node)
self.registry.add_translation_handlers(node, **kwds)
def add_enumerable_node(self, node, figtype, title_getter=None, override=False, **kwds):
# type: (nodes.Node, unicode, TitleGetter, bool, Any) -> None
# type: (Type[nodes.Element], str, TitleGetter, bool, Any) -> None
"""Register a Docutils node class as a numfig target.
Sphinx numbers the node automatically. And then the users can refer it
@@ -651,14 +589,14 @@ class Sphinx(object):
@property
def enumerable_nodes(self):
# type: () -> Dict[nodes.Node, Tuple[unicode, TitleGetter]]
# type: () -> Dict[Type[nodes.Node], Tuple[str, TitleGetter]]
warnings.warn('app.enumerable_nodes() is deprecated. '
'Use app.get_domain("std").enumerable_nodes instead.',
RemovedInSphinx30Warning)
RemovedInSphinx30Warning, stacklevel=2)
return self.registry.enumerable_nodes
def add_directive(self, name, obj, content=None, arguments=None, override=False, **options): # NOQA
# type: (unicode, Any, bool, Tuple[int, int, bool], bool, Any) -> None
# type: (str, Any, bool, Tuple[int, int, bool], bool, Any) -> None
"""Register a Docutils directive.
*name* must be the prospective directive name. There are two possible
@@ -711,20 +649,18 @@ class Sphinx(object):
"""
logger.debug('[app] adding directive: %r',
(name, obj, content, arguments, options))
if name in directives._directives and not override:
logger.warning(__('while setting up extension %s: directive %r is '
'already registered, it will be overridden'),
self._setting_up_extension[-1], name,
type='app', subtype='add_directive')
if not override and docutils.is_directive_registered(name):
logger.warning(__('directive %r is already registered, it will be overridden'),
name, type='app', subtype='add_directive')
if not isclass(obj) or not issubclass(obj, Directive):
directive = directive_helper(obj, content, arguments, **options)
directives.register_directive(name, directive)
docutils.register_directive(name, directive)
else:
directives.register_directive(name, obj)
docutils.register_directive(name, obj)
def add_role(self, name, role, override=False):
# type: (unicode, Any, bool) -> None
# type: (str, Any, bool) -> None
"""Register a Docutils role.
*name* must be the role name that occurs in the source, *role* the role
@@ -736,15 +672,13 @@ class Sphinx(object):
Add *override* keyword.
"""
logger.debug('[app] adding role: %r', (name, role))
if name in roles._roles and not override:
logger.warning(__('while setting up extension %s: role %r is '
'already registered, it will be overridden'),
self._setting_up_extension[-1], name,
type='app', subtype='add_role')
roles.register_local_role(name, role)
if not override and docutils.is_role_registered(name):
logger.warning(__('role %r is already registered, it will be overridden'),
name, type='app', subtype='add_role')
docutils.register_role(name, role)
def add_generic_role(self, name, nodeclass, override=False):
# type: (unicode, Any, bool) -> None
# type: (str, Any, bool) -> None
"""Register a generic Docutils role.
Register a Docutils role that does nothing but wrap its contents in the
@@ -757,13 +691,11 @@ class Sphinx(object):
# Don't use ``roles.register_generic_role`` because it uses
# ``register_canonical_role``.
logger.debug('[app] adding generic role: %r', (name, nodeclass))
if name in roles._roles and not override:
logger.warning(__('while setting up extension %s: role %r is '
'already registered, it will be overridden'),
self._setting_up_extension[-1], name,
type='app', subtype='add_generic_role')
if not override and docutils.is_role_registered(name):
logger.warning(__('role %r is already registered, it will be overridden'),
name, type='app', subtype='add_generic_role')
role = roles.GenericRole(name, nodeclass)
roles.register_local_role(name, role)
docutils.register_role(name, role)
def add_domain(self, domain, override=False):
# type: (Type[Domain], bool) -> None
@@ -792,12 +724,12 @@ class Sphinx(object):
"""
warnings.warn('app.override_domain() is deprecated. '
'Use app.add_domain() with override option instead.',
RemovedInSphinx30Warning)
RemovedInSphinx30Warning, stacklevel=2)
self.registry.add_domain(domain, override=True)
def add_directive_to_domain(self, domain, name, obj, has_content=None, argument_spec=None,
override=False, **option_spec):
# type: (unicode, unicode, Any, bool, Any, bool, Any) -> None
# type: (str, str, Any, bool, Any, bool, Any) -> None
"""Register a Docutils directive in a domain.
Like :meth:`add_directive`, but the directive is added to the domain
@@ -812,7 +744,7 @@ class Sphinx(object):
**option_spec)
def add_role_to_domain(self, domain, name, role, override=False):
# type: (unicode, unicode, Union[RoleFunction, XRefRole], bool) -> None
# type: (str, str, Union[RoleFunction, XRefRole], bool) -> None
"""Register a Docutils role in a domain.
Like :meth:`add_role`, but the role is added to the domain named
@@ -825,7 +757,7 @@ class Sphinx(object):
self.registry.add_role_to_domain(domain, name, role, override=override)
def add_index_to_domain(self, domain, index, override=False):
# type: (unicode, Type[Index], bool) -> None
# type: (str, Type[Index], bool) -> None
"""Register a custom index for a domain.
Add a custom *index* class to the domain named *domain*. *index* must
@@ -840,7 +772,7 @@ class Sphinx(object):
def add_object_type(self, directivename, rolename, indextemplate='',
parse_node=None, ref_nodeclass=None, objname='',
doc_field_types=[], override=False):
# type: (unicode, unicode, unicode, Callable, nodes.Node, unicode, List, bool) -> None
# type: (str, str, str, Callable, Type[nodes.TextElement], str, List, bool) -> None
"""Register a new object type.
This method is a very convenient way to add a new :term:`object` type
@@ -904,24 +836,9 @@ class Sphinx(object):
ref_nodeclass, objname, doc_field_types,
override=override)
def add_description_unit(self, directivename, rolename, indextemplate='',
parse_node=None, ref_nodeclass=None, objname='',
doc_field_types=[]):
# type: (unicode, unicode, unicode, Callable, nodes.Node, unicode, List) -> None
"""Deprecated alias for :meth:`add_object_type`.
.. deprecated:: 1.6
Use :meth:`add_object_type` instead.
"""
warnings.warn('app.add_description_unit() is now deprecated. '
'Use app.add_object_type() instead.',
RemovedInSphinx20Warning)
self.add_object_type(directivename, rolename, indextemplate, parse_node,
ref_nodeclass, objname, doc_field_types)
def add_crossref_type(self, directivename, rolename, indextemplate='',
ref_nodeclass=None, objname='', override=False):
# type: (unicode, unicode, unicode, nodes.Node, unicode, bool) -> None
# type: (str, str, str, Type[nodes.TextElement], str, bool) -> None
"""Register a new crossref object type.
This method is very similar to :meth:`add_object_type` except that the
@@ -1000,15 +917,15 @@ class Sphinx(object):
self.registry.add_post_transform(transform)
def add_javascript(self, filename, **kwargs):
# type: (unicode, **unicode) -> None
# type: (str, **str) -> None
"""An alias of :meth:`add_js_file`."""
warnings.warn('The app.add_javascript() is deprecated. '
'Please use app.add_js_file() instead.',
RemovedInSphinx40Warning)
RemovedInSphinx40Warning, stacklevel=2)
self.add_js_file(filename, **kwargs)
def add_js_file(self, filename, **kwargs):
# type: (unicode, **unicode) -> None
# type: (str, **str) -> None
"""Register a JavaScript file to include in the HTML output.
Add *filename* to the list of JavaScript files that the default HTML
@@ -1031,9 +948,11 @@ class Sphinx(object):
And it allows keyword arguments as attributes of script tag.
"""
self.registry.add_js_file(filename, **kwargs)
if hasattr(self.builder, 'add_js_file'):
self.builder.add_js_file(filename, **kwargs) # type: ignore
def add_css_file(self, filename, **kwargs):
# type: (unicode, **unicode) -> None
# type: (str, **str) -> None
"""Register a stylesheet to include in the HTML output.
Add *filename* to the list of CSS files that the default HTML template
@@ -1069,15 +988,17 @@ class Sphinx(object):
"""
logger.debug('[app] adding stylesheet: %r', filename)
self.registry.add_css_files(filename, **kwargs)
if hasattr(self.builder, 'add_css_file'):
self.builder.add_css_file(filename, **kwargs) # type: ignore
def add_stylesheet(self, filename, alternate=False, title=None):
# type: (unicode, bool, unicode) -> None
# type: (str, bool, str) -> None
"""An alias of :meth:`add_css_file`."""
warnings.warn('The app.add_stylesheet() is deprecated. '
'Please use app.add_css_file() instead.',
RemovedInSphinx40Warning)
RemovedInSphinx40Warning, stacklevel=2)
attributes = {} # type: Dict[unicode, unicode]
attributes = {} # type: Dict[str, str]
if alternate:
attributes['rel'] = 'alternate stylesheet'
else:
@@ -1089,7 +1010,7 @@ class Sphinx(object):
self.add_css_file(filename, **attributes)
def add_latex_package(self, packagename, options=None):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
r"""Register a package to include in the LaTeX source code.
Add *packagename* to the list of packages that LaTeX source code will
@@ -1108,7 +1029,7 @@ class Sphinx(object):
self.registry.add_latex_package(packagename, options)
def add_lexer(self, alias, lexer):
# type: (unicode, Any) -> None
# type: (str, Any) -> None
"""Register a new lexer for source code.
Use *lexer*, which must be an instance of a Pygments lexer class, to
@@ -1142,7 +1063,7 @@ class Sphinx(object):
self.add_directive('auto' + cls.objtype, AutodocDirective)
def add_autodoc_attrgetter(self, typ, getter):
# type: (Type, Callable[[Any, unicode, Any], Any]) -> None
# type: (Type, Callable[[Any, str, Any], Any]) -> None
"""Register a new ``getattr``-like function for the autodoc extension.
Add *getter*, which must be a function with an interface compatible to
@@ -1174,7 +1095,7 @@ class Sphinx(object):
languages[cls.lang] = cls
def add_source_suffix(self, suffix, filetype, override=False):
# type: (unicode, unicode, bool) -> None
# type: (str, str, bool) -> None
"""Register a suffix of source files.
Same as :confval:`source_suffix`. The users can override this
@@ -1209,7 +1130,7 @@ class Sphinx(object):
collector().enable(self)
def add_html_theme(self, name, theme_path):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
"""Register a HTML Theme.
The *name* is a name of theme, and *path* is a full path to the theme
@@ -1221,7 +1142,7 @@ class Sphinx(object):
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
# type: (str, 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
@@ -1235,7 +1156,7 @@ class Sphinx(object):
self.registry.add_html_math_renderer(name, inline_renderers, block_renderers)
def add_message_catalog(self, catalog, locale_dir):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
"""Register a message catalog.
The *catalog* is a name of catalog, and *locale_dir* is a base path
@@ -1249,7 +1170,7 @@ class Sphinx(object):
# ---- other methods -------------------------------------------------
def is_parallel_allowed(self, typ):
# type: (unicode) -> bool
# type: (str) -> bool
"""Check parallel processing is allowed or not.
``typ`` is a type of processing; ``'read'`` or ``'write'``.
@@ -1269,7 +1190,7 @@ class Sphinx(object):
else:
raise ValueError('parallel type %s is not supported' % typ)
for ext in itervalues(self.extensions):
for ext in self.extensions.values():
allowed = getattr(ext, attrname, None)
if allowed is None:
logger.warning(message, ext.name)
@@ -1280,15 +1201,22 @@ class Sphinx(object):
return True
@property
def _setting_up_extension(self):
# type: () -> List[str]
warnings.warn('app._setting_up_extension is deprecated.',
RemovedInSphinx30Warning)
return ['?']
class TemplateBridge(object):
class TemplateBridge:
"""
This class defines the interface for a "template bridge", that is, a class
that renders templates given a template name and a context.
"""
def init(self, builder, theme=None, dirs=None):
# type: (Builder, Theme, List[unicode]) -> None
# type: (Builder, Theme, List[str]) -> None
"""Called by the builder to initialize the template system.
*builder* is the builder object; you'll probably want to look at the
@@ -1308,14 +1236,14 @@ class TemplateBridge(object):
return 0
def render(self, template, context):
# type: (unicode, Dict) -> None
# type: (str, Dict) -> None
"""Called by the builder to render a template given as a filename with
a specified context (a Python dictionary).
"""
raise NotImplementedError('must be implemented in subclasses')
def render_string(self, template, context):
# type: (unicode, Dict) -> unicode
# type: (str, Dict) -> str
"""Called by the builder to render a template given as a string with a
specified context (a Python dictionary).
"""

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders
~~~~~~~~~~~~~~~
@@ -9,14 +8,12 @@
:license: BSD, see LICENSE for details.
"""
import pickle
import time
import warnings
from os import path
from docutils import nodes
from six.moves import cPickle as pickle
from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.environment import CONFIG_OK, CONFIG_CHANGED_REASON
from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.errors import SphinxError
@@ -43,7 +40,7 @@ except ImportError:
if False:
# For type annotation
from typing import Any, Callable, Dict, Iterable, List, Sequence, Set, Tuple, Union # NOQA
from typing import Any, Callable, Dict, Iterable, List, Sequence, Set, Tuple, Type, Union # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.config import Config # NOQA
from sphinx.environment import BuildEnvironment # NOQA
@@ -54,25 +51,25 @@ if False:
logger = logging.getLogger(__name__)
class Builder(object):
class Builder:
"""
Builds target formats from the reST sources.
"""
#: The builder's name, for the -b command line option.
name = '' # type: unicode
name = ''
#: The builder's output format, or '' if no document output is produced.
format = '' # type: unicode
format = ''
#: The message emitted upon successful build completion. This can be a
#: printf-style template string with the following keys: ``outdir``,
#: ``project``
epilog = '' # type: unicode
epilog = ''
#: default translator class for the builder. This can be overrided by
#: :py:meth:`app.set_translator()`.
default_translator_class = None # type: nodes.NodeVisitor
default_translator_class = None # type: Type[nodes.NodeVisitor]
# doctree versioning method
versioning_method = 'none' # type: unicode
versioning_method = 'none'
versioning_compare = False
# allow parallel write_doc() calls
allow_parallel = False
@@ -81,7 +78,7 @@ class Builder(object):
#: The list of MIME types of image formats supported by the builder.
#: Image files are searched in the order in which they appear here.
supported_image_types = [] # type: List[unicode]
supported_image_types = [] # type: List[str]
#: The builder supports remote images or not.
supported_remote_images = False
#: The builder supports data URIs or not.
@@ -97,8 +94,6 @@ class Builder(object):
self.app = app # type: Sphinx
self.env = None # type: BuildEnvironment
self.warn = app.warn # type: Callable
self.info = app.info # type: Callable
self.config = app.config # type: Config
self.tags = app.tags # type: Tags
self.tags.add(self.format)
@@ -107,11 +102,11 @@ class Builder(object):
self.tags.add("builder_%s" % self.name)
# images that need to be copied over (source -> dest)
self.images = {} # type: Dict[unicode, unicode]
self.images = {} # type: Dict[str, str]
# basename of images directory
self.imagedir = ""
# relative path to image directory from current docname (used at writing docs)
self.imgpath = "" # type: unicode
self.imgpath = ""
# these get set later
self.parallel_ok = False
@@ -125,7 +120,7 @@ class Builder(object):
self.versioning_compare)
def get_translator_class(self, *args):
# type: (Any) -> nodes.NodeVisitor
# type: (Any) -> Type[nodes.NodeVisitor]
"""Return a class of translator."""
return self.app.registry.get_translator_class(self)
@@ -138,22 +133,6 @@ class Builder(object):
"""
return self.app.registry.create_translator(self, *args)
@property
def translator_class(self):
# type: () -> Callable[[Any], nodes.NodeVisitor]
"""Return a class of translator.
.. deprecated:: 1.6
"""
translator_class = self.app.registry.get_translator_class(self)
if translator_class is None and self.default_translator_class is None:
warnings.warn('builder.translator_class() is now deprecated. '
'Please use builder.create_translator() and '
'builder.default_translator_class instead.',
RemovedInSphinx20Warning)
return None
return self.create_translator
# helper methods
def init(self):
# type: () -> None
@@ -173,7 +152,7 @@ class Builder(object):
self.templates = BuiltinTemplateLoader()
def get_target_uri(self, docname, typ=None):
# type: (unicode, unicode) -> unicode
# type: (str, str) -> str
"""Return the target URI for a document name.
*typ* can be used to qualify the link characteristic for individual
@@ -182,7 +161,7 @@ class Builder(object):
raise NotImplementedError
def get_relative_uri(self, from_, to, typ=None):
# type: (unicode, unicode, unicode) -> unicode
# type: (str, str, str) -> str
"""Return a relative URI between two source filenames.
May raise environment.NoUri if there's no way to return a sensible URI.
@@ -191,7 +170,7 @@ class Builder(object):
self.get_target_uri(to, typ))
def get_outdated_docs(self):
# type: () -> Union[unicode, Iterable[unicode]]
# type: () -> Union[str, Iterable[str]]
"""Return an iterable of output files that are outdated, or a string
describing what an update build will build.
@@ -202,7 +181,7 @@ class Builder(object):
raise NotImplementedError
def get_asset_paths(self):
# type: () -> List[unicode]
# type: () -> List[str]
"""Return list of paths for assets (ex. templates, CSS, etc.)."""
return []
@@ -241,12 +220,12 @@ class Builder(object):
# compile po methods
def compile_catalogs(self, catalogs, message):
# type: (Set[CatalogInfo], unicode) -> None
# type: (Set[CatalogInfo], str) -> None
if not self.config.gettext_auto_build:
return
def cat2relpath(cat):
# type: (CatalogInfo) -> unicode
# type: (CatalogInfo) -> str
return relpath(cat.mo_path, self.env.srcdir).replace(path.sep, SEP)
logger.info(bold(__('building [mo]: ')) + message)
@@ -261,16 +240,15 @@ class Builder(object):
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
self.config.language,
charset=self.config.source_encoding,
gettext_compact=self.config.gettext_compact,
force_all=True,
excluded=Matcher(['**/.?**']))
message = __('all of %d po files') % len(catalogs)
self.compile_catalogs(catalogs, message)
def compile_specific_catalogs(self, specified_files):
# type: (List[unicode]) -> None
# type: (List[str]) -> None
def to_domain(fpath):
# type: (unicode) -> unicode
# type: (str) -> str
docname = self.env.path2doc(path.abspath(fpath))
if docname:
return find_catalog(docname, self.config.gettext_compact)
@@ -284,7 +262,6 @@ class Builder(object):
self.config.language,
domains=list(specified_domains),
charset=self.config.source_encoding,
gettext_compact=self.config.gettext_compact,
excluded=Matcher(['**/.?**']))
message = __('targets for %d po files that are specified') % len(catalogs)
self.compile_catalogs(catalogs, message)
@@ -295,7 +272,6 @@ class Builder(object):
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
self.config.language,
charset=self.config.source_encoding,
gettext_compact=self.config.gettext_compact,
excluded=Matcher(['**/.?**']))
message = __('targets for %d po files that are out of date') % len(catalogs)
self.compile_catalogs(catalogs, message)
@@ -308,13 +284,13 @@ class Builder(object):
self.build(None, summary=__('all source files'), method='all')
def build_specific(self, filenames):
# type: (List[unicode]) -> None
# type: (List[str]) -> None
"""Only rebuild as much as needed for changes in the *filenames*."""
# bring the filenames to the canonical format, that is,
# relative to the source directory and without source_suffix.
dirlen = len(self.srcdir) + 1
to_write = []
suffixes = None # type: Tuple[unicode]
suffixes = None # type: Tuple[str]
suffixes = tuple(self.config.source_suffix) # type: ignore
for filename in filenames:
filename = path.normpath(path.abspath(filename))
@@ -350,7 +326,7 @@ class Builder(object):
len(to_build))
def build(self, docnames, summary=None, method='update'):
# type: (Iterable[unicode], unicode, unicode) -> None
# type: (Iterable[str], str, str) -> None
"""Main build method.
First updates the environment, and then calls :meth:`write`.
@@ -372,14 +348,14 @@ class Builder(object):
else:
logger.info(__('none found'))
# save the environment
from sphinx.application import ENV_PICKLE_FILENAME
logger.info(bold(__('pickling environment... ')), nonl=True)
with open(path.join(self.doctreedir, ENV_PICKLE_FILENAME), 'wb') as f:
pickle.dump(self.env, f, pickle.HIGHEST_PROTOCOL)
logger.info(__('done'))
if updated_docnames:
# save the environment
from sphinx.application import ENV_PICKLE_FILENAME
logger.info(bold(__('pickling environment... ')), nonl=True)
with open(path.join(self.doctreedir, ENV_PICKLE_FILENAME), 'wb') as f:
pickle.dump(self.env, f, pickle.HIGHEST_PROTOCOL)
logger.info(__('done'))
# global actions
self.app.phase = BuildPhase.CONSISTENCY_CHECK
logger.info(bold(__('checking consistency... ')), nonl=True)
@@ -421,7 +397,7 @@ class Builder(object):
self.finish_tasks.join()
def read(self):
# type: () -> List[unicode]
# type: () -> List[str]
"""(Re-)read all files new or changed since last update.
Store all environment docnames in the canonical format (ie using SEP as
@@ -484,7 +460,7 @@ class Builder(object):
return sorted(docnames)
def _read_serial(self, docnames):
# type: (List[unicode]) -> None
# type: (List[str]) -> None
for docname in status_iterator(docnames, 'reading sources... ', "purple",
len(docnames), self.app.verbosity):
# remove all inventory entries for that file
@@ -493,14 +469,14 @@ class Builder(object):
self.read_doc(docname)
def _read_parallel(self, docnames, nproc):
# type: (List[unicode], int) -> None
# type: (List[str], int) -> None
# clear all outdated docs at once
for docname in docnames:
self.app.emit('env-purge-doc', self.env, docname)
self.env.clear_doc(docname)
def read_process(docs):
# type: (List[unicode]) -> bytes
# type: (List[str]) -> bytes
self.env.app = self.app
for docname in docs:
self.read_doc(docname)
@@ -508,7 +484,7 @@ class Builder(object):
return pickle.dumps(self.env, pickle.HIGHEST_PROTOCOL)
def merge(docs, otherenv):
# type: (List[unicode], bytes) -> None
# type: (List[str], bytes) -> None
env = pickle.loads(otherenv)
self.env.merge_info_from(docs, env, self.app)
@@ -524,7 +500,7 @@ class Builder(object):
tasks.join()
def read_doc(self, docname):
# type: (unicode) -> None
# type: (str) -> None
"""Parse a file and add/update inventory entries for the doctree."""
self.env.prepare_settings(docname)
@@ -550,7 +526,7 @@ class Builder(object):
self.write_doctree(docname, doctree)
def write_doctree(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
# type: (str, nodes.document) -> None
"""Write the doctree to a file."""
# make it picklable
doctree.reporter = None
@@ -559,13 +535,13 @@ class Builder(object):
doctree.settings.env = None
doctree.settings.record_dependencies = None
doctree_filename = self.env.doc2path(docname, self.env.doctreedir, '.doctree')
doctree_filename = path.join(self.doctreedir, docname + '.doctree')
ensuredir(path.dirname(doctree_filename))
with open(doctree_filename, 'wb') as f:
pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
def write(self, build_docnames, updated_docnames, method='update'):
# type: (Iterable[unicode], Sequence[unicode], unicode) -> None
# type: (Iterable[str], Sequence[str], str) -> None
if build_docnames is None or build_docnames == ['__all__']:
# build_all
build_docnames = self.env.found_docs
@@ -596,7 +572,7 @@ class Builder(object):
self._write_serial(sorted(docnames))
def _write_serial(self, docnames):
# type: (Sequence[unicode]) -> None
# type: (Sequence[str]) -> None
with logging.pending_warnings():
for docname in status_iterator(docnames, __('writing output... '), "darkgreen",
len(docnames), self.app.verbosity):
@@ -607,9 +583,9 @@ class Builder(object):
self.write_doc(docname, doctree)
def _write_parallel(self, docnames, nproc):
# type: (Sequence[unicode], int) -> None
# type: (Sequence[str], int) -> None
def write_process(docs):
# type: (List[Tuple[unicode, nodes.Node]]) -> None
# type: (List[Tuple[str, nodes.document]]) -> None
self.app.phase = BuildPhase.WRITING
for docname, doctree in docs:
self.write_doc(docname, doctree)
@@ -640,17 +616,17 @@ class Builder(object):
tasks.join()
def prepare_writing(self, docnames):
# type: (Set[unicode]) -> None
# type: (Set[str]) -> None
"""A place where you can add logic before :meth:`write_doc` is run"""
raise NotImplementedError
def write_doc(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
# type: (str, nodes.document) -> None
"""Where you actually write something to the filesystem."""
raise NotImplementedError
def write_doc_serialized(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
# type: (str, nodes.document) -> None
"""Handle parts of write_doc that must be called in the main process
if parallel build is active.
"""
@@ -673,7 +649,7 @@ class Builder(object):
pass
def get_builder_config(self, option, default):
# type: (unicode, unicode) -> Any
# type: (str, str) -> Any
"""Return a builder specific option.
This method allows customization of common builder settings by

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders._epub_base
~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -50,22 +49,22 @@ logger = logging.getLogger(__name__)
# output but that may be customized by (re-)setting module attributes,
# e.g. from conf.py.
COVERPAGE_NAME = u'epub-cover.xhtml'
COVERPAGE_NAME = 'epub-cover.xhtml'
TOCTREE_TEMPLATE = u'toctree-l%d'
TOCTREE_TEMPLATE = 'toctree-l%d'
LINK_TARGET_TEMPLATE = u' [%(uri)s]'
LINK_TARGET_TEMPLATE = ' [%(uri)s]'
FOOTNOTE_LABEL_TEMPLATE = u'#%d'
FOOTNOTE_LABEL_TEMPLATE = '#%d'
FOOTNOTES_RUBRIC_NAME = u'Footnotes'
FOOTNOTES_RUBRIC_NAME = 'Footnotes'
CSS_LINK_TARGET_CLASS = u'link-target'
CSS_LINK_TARGET_CLASS = 'link-target'
# XXX These strings should be localized according to epub_language
GUIDE_TITLES = {
'toc': u'Table of Contents',
'cover': u'Cover'
'toc': 'Table of Contents',
'cover': 'Cover'
}
MEDIA_TYPES = {
@@ -79,7 +78,7 @@ MEDIA_TYPES = {
'.otf': 'application/x-font-otf',
'.ttf': 'application/x-font-ttf',
'.woff': 'application/font-woff',
} # type: Dict[unicode, unicode]
}
VECTOR_GRAPHICS_EXTENSIONS = ('.svg',)
@@ -96,7 +95,7 @@ NavPoint = namedtuple('NavPoint', ['navpoint', 'playorder', 'text', 'refuri', 'c
def sphinx_smarty_pants(t, language='en'):
# type: (unicode, str) -> unicode
# type: (str, str) -> str
t = t.replace('&quot;', '"')
t = smartquotes.educateDashesOldSchool(t)
t = smartquotes.educateQuotes(t, language)
@@ -151,26 +150,27 @@ class EpubBuilder(StandaloneHTMLBuilder):
def init(self):
# type: () -> None
StandaloneHTMLBuilder.init(self)
super().init()
# the output files for epub must be .html only
self.out_suffix = '.xhtml'
self.link_suffix = '.xhtml'
self.playorder = 0
self.tocid = 0
self.id_cache = {} # type: Dict[unicode, unicode]
self.id_cache = {} # type: Dict[str, str]
self.use_index = self.get_builder_config('use_index', 'epub')
self.refnodes = [] # type: List[Dict[str, Any]]
def create_build_info(self):
# type: () -> BuildInfo
return BuildInfo(self.config, self.tags, ['html', 'epub'])
def get_theme_config(self):
# type: () -> Tuple[unicode, Dict]
# type: () -> Tuple[str, Dict]
return self.config.epub_theme, self.config.epub_theme_options
# generic support functions
def make_id(self, name):
# type: (unicode) -> unicode
# type: (str) -> str
# id_cache is intentionally mutable
"""Return a unique id for name."""
id = self.id_cache.get(name)
@@ -180,7 +180,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
return id
def esc(self, name):
# type: (unicode) -> unicode
# type: (str) -> str
"""Replace all characters not allowed in text an attribute values."""
# Like cgi.escape, but also replace apostrophe
name = name.replace('&', '&amp;')
@@ -191,7 +191,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
return name
def get_refnodes(self, doctree, result):
# type: (nodes.Node, List[Dict[unicode, Any]]) -> List[Dict[unicode, Any]]
# type: (nodes.Node, List[Dict[str, Any]]) -> List[Dict[str, Any]]
"""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?
@@ -209,8 +209,8 @@ class EpubBuilder(StandaloneHTMLBuilder):
'text': ssp(self.esc(doctree.astext()))
})
break
else:
for elem in doctree.children:
elif isinstance(doctree, nodes.Element):
for elem in doctree:
result = self.get_refnodes(elem, result)
return result
@@ -231,7 +231,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
self.toc_add_files(self.refnodes)
def toc_add_files(self, refnodes):
# type: (List[nodes.Node]) -> None
# type: (List[Dict[str, Any]]) -> None
"""Add the master_doc, pre and post files to a list of refnodes.
"""
refnodes.insert(0, {
@@ -254,47 +254,49 @@ class EpubBuilder(StandaloneHTMLBuilder):
})
def fix_fragment(self, prefix, fragment):
# type: (unicode, unicode) -> unicode
# type: (str, str) -> str
"""Return a href/id attribute with colons replaced by hyphens."""
return prefix + fragment.replace(':', '-')
def fix_ids(self, tree):
# type: (nodes.Node) -> None
# type: (nodes.document) -> None
"""Replace colons with hyphens in href and id attributes.
Some readers crash because they interpret the part as a
transport protocol specification.
"""
for node in tree.traverse(nodes.reference):
if 'refuri' in node:
m = self.refuri_re.match(node['refuri'])
for reference in tree.traverse(nodes.reference):
if 'refuri' in reference:
m = self.refuri_re.match(reference['refuri'])
if m:
node['refuri'] = self.fix_fragment(m.group(1), m.group(2))
if 'refid' in node:
node['refid'] = self.fix_fragment('', node['refid'])
for node in tree.traverse(nodes.target):
for i, node_id in enumerate(node['ids']):
if ':' in node_id:
node['ids'][i] = self.fix_fragment('', node_id)
reference['refuri'] = self.fix_fragment(m.group(1), m.group(2))
if 'refid' in reference:
reference['refid'] = self.fix_fragment('', reference['refid'])
next_node = node.next_node(siblings=True)
if next_node and isinstance(next_node, nodes.Element):
for target in tree.traverse(nodes.target):
for i, node_id in enumerate(target['ids']):
if ':' in node_id:
target['ids'][i] = self.fix_fragment('', node_id)
next_node = target.next_node(siblings=True) # type: nodes.Node
if 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']
for desc_signature in tree.traverse(addnodes.desc_signature):
ids = desc_signature.attributes['ids']
newids = []
for id in ids:
newids.append(self.fix_fragment('', id))
node.attributes['ids'] = newids
desc_signature.attributes['ids'] = newids
def add_visible_links(self, tree, show_urls='inline'):
# type: (nodes.Node, unicode) -> None
# type: (nodes.document, str) -> None
"""Add visible link targets for external links"""
def make_footnote_ref(doc, label):
# type: (nodes.Node, unicode) -> nodes.footnote_reference
# type: (nodes.document, str) -> nodes.footnote_reference
"""Create a footnote_reference node with children"""
footnote_ref = nodes.footnote_reference('[#]_')
footnote_ref.append(nodes.Text(label))
@@ -302,7 +304,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
return footnote_ref
def make_footnote(doc, label, uri):
# type: (nodes.Node, unicode, unicode) -> nodes.footnote
# type: (nodes.document, str, str) -> nodes.footnote
"""Create a footnote node with children"""
footnote = nodes.footnote(uri)
para = nodes.paragraph()
@@ -313,7 +315,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
return footnote
def footnote_spot(tree):
# type: (nodes.Node) -> Tuple[nodes.Node, int]
# type: (nodes.document) -> Tuple[nodes.Element, int]
"""Find or create a spot to place footnotes.
The function returns the tuple (parent, index)."""
@@ -326,8 +328,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
fn = fns[-1]
return fn.parent, fn.parent.index(fn) + 1
for node in tree.traverse(nodes.rubric):
if len(node.children) == 1 and \
node.children[0].astext() == FOOTNOTES_RUBRIC_NAME:
if len(node) == 1 and node.astext() == FOOTNOTES_RUBRIC_NAME:
return node.parent, node.parent.index(node) + 1
doc = tree.traverse(nodes.document)[0]
rub = nodes.rubric()
@@ -363,7 +364,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
fn_idx += 1
def write_doc(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
# type: (str, nodes.document) -> None
"""Write one document file.
This method is overwritten in order to fix fragment identifiers
@@ -371,10 +372,10 @@ class EpubBuilder(StandaloneHTMLBuilder):
"""
self.fix_ids(doctree)
self.add_visible_links(doctree, self.config.epub_show_urls)
StandaloneHTMLBuilder.write_doc(self, docname, doctree)
super().write_doc(docname, doctree)
def fix_genindex(self, tree):
# type: (nodes.Node) -> None
# type: (List[Tuple[str, List[Tuple[str, Any]]]]) -> None
"""Fix href attributes for genindex pages."""
# XXX: modifies tree inline
# Logic modeled from themes/basic/genindex.html
@@ -393,7 +394,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
self.fix_fragment(m.group(1), m.group(2)))
def is_vector_graphics(self, filename):
# type: (unicode) -> bool
# type: (str) -> bool
"""Does the filename extension indicate a vector graphic format?"""
ext = path.splitext(filename)[-1]
return ext in VECTOR_GRAPHICS_EXTENSIONS
@@ -410,14 +411,14 @@ class EpubBuilder(StandaloneHTMLBuilder):
dest = self.images[src]
try:
img = Image.open(path.join(self.srcdir, src))
except IOError:
except OSError:
if not self.is_vector_graphics(src):
logger.warning(__('cannot read image file %r: copying it instead'),
path.join(self.srcdir, src))
try:
copyfile(path.join(self.srcdir, src),
path.join(self.outdir, self.imagedir, dest))
except (IOError, OSError) as err:
except OSError as err:
logger.warning(__('cannot copy image file %r: %s'),
path.join(self.srcdir, src), err)
continue
@@ -433,7 +434,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
img = img.resize((nw, nh), Image.BICUBIC)
try:
img.save(path.join(self.outdir, self.imagedir, dest))
except (IOError, OSError) as err:
except OSError as err:
logger.warning(__('cannot write image file %r: %s'),
path.join(self.srcdir, src), err)
@@ -446,11 +447,11 @@ class EpubBuilder(StandaloneHTMLBuilder):
if self.config.epub_fix_images or self.config.epub_max_image_width:
if not Image:
logger.warning(__('PIL not found - copying image files'))
super(EpubBuilder, self).copy_image_files()
super().copy_image_files()
else:
self.copy_image_files_pil()
else:
super(EpubBuilder, self).copy_image_files()
super().copy_image_files()
def copy_download_files(self):
# type: () -> None
@@ -458,7 +459,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
def handle_page(self, pagename, addctx, templatename='page.html',
outfilename=None, event_arg=None):
# type: (unicode, Dict, unicode, unicode, Any) -> None
# type: (str, Dict, str, str, Any) -> None
"""Create a rendered page.
This method is overwritten for genindex pages in order to fix href link
@@ -469,18 +470,17 @@ class EpubBuilder(StandaloneHTMLBuilder):
return
self.fix_genindex(addctx['genindexentries'])
addctx['doctype'] = self.doctype
StandaloneHTMLBuilder.handle_page(self, pagename, addctx, templatename,
outfilename, event_arg)
super().handle_page(pagename, addctx, templatename, outfilename, event_arg)
def build_mimetype(self, outdir, outname):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
"""Write the metainfo file mimetype."""
logger.info(__('writing %s file...'), outname)
copy_asset_file(path.join(self.template_dir, 'mimetype'),
path.join(outdir, outname))
def build_container(self, outdir, outname):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
"""Write the metainfo file META-INF/container.xml."""
logger.info(__('writing %s file...'), outname)
filename = path.join(outdir, outname)
@@ -488,11 +488,11 @@ class EpubBuilder(StandaloneHTMLBuilder):
copy_asset_file(path.join(self.template_dir, 'container.xml'), filename)
def content_metadata(self):
# type: () -> Dict[unicode, Any]
# type: () -> Dict[str, Any]
"""Create a dictionary with all metadata for the content.opf
file properly escaped.
"""
metadata = {} # type: Dict[unicode, Any]
metadata = {} # type: Dict[str, Any]
metadata['title'] = self.esc(self.config.epub_title)
metadata['author'] = self.esc(self.config.epub_author)
metadata['uid'] = self.esc(self.config.epub_uid)
@@ -508,7 +508,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
return metadata
def build_content(self, outdir, outname):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
"""Write the metainfo file content.opf It contains bibliographic data,
a file list and the spine (the reading order).
"""
@@ -519,7 +519,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
if not outdir.endswith(os.sep):
outdir += os.sep
olen = len(outdir)
self.files = [] # type: List[unicode]
self.files = [] # type: List[str]
self.ignored_files = ['.buildinfo', 'mimetype', 'content.opf',
'toc.ncx', 'META-INF/container.xml',
'Thumbs.db', 'ehthumbs.db', '.DS_Store',
@@ -622,7 +622,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
metadata)
def new_navpoint(self, node, level, incr=True):
# type: (nodes.Node, int, bool) -> NavPoint
# type: (Dict[str, Any], int, bool) -> NavPoint
"""Create a new entry in the toc from the node at given level."""
# XXX Modifies the node
if incr:
@@ -632,7 +632,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
node['text'], node['refuri'], [])
def build_navpoints(self, nodes):
# type: (nodes.Node) -> List[NavPoint]
# type: (List[Dict[str, Any]]) -> List[NavPoint]
"""Create the toc navigation structure.
Subelements of a node are nested inside the navpoint. For nested nodes
@@ -677,11 +677,11 @@ class EpubBuilder(StandaloneHTMLBuilder):
return navstack[0].children
def toc_metadata(self, level, navpoints):
# type: (int, List[NavPoint]) -> Dict[unicode, Any]
# type: (int, List[NavPoint]) -> Dict[str, Any]
"""Create a dictionary with all metadata for the toc.ncx file
properly escaped.
"""
metadata = {} # type: Dict[unicode, Any]
metadata = {} # type: Dict[str, Any]
metadata['uid'] = self.config.epub_uid
metadata['title'] = self.esc(self.config.epub_title)
metadata['level'] = level
@@ -689,7 +689,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
return metadata
def build_toc(self, outdir, outname):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
"""Write the metainfo file toc.ncx."""
logger.info(__('writing %s file...'), outname)
@@ -710,7 +710,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
self.toc_metadata(level, navpoints))
def build_epub(self, outdir, outname):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
"""Write the epub file.
It is a zip file with the mimetype file stored uncompressed as the first
@@ -720,7 +720,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
epub_filename = path.join(outdir, outname)
with ZipFile(epub_filename, 'w', ZIP_DEFLATED) as epub:
epub.write(path.join(outdir, 'mimetype'), 'mimetype', ZIP_STORED)
for filename in [u'META-INF/container.xml', u'content.opf', u'toc.ncx']:
for filename in ['META-INF/container.xml', 'content.opf', 'toc.ncx']:
epub.write(path.join(outdir, filename), filename, ZIP_DEFLATED)
for filename in self.files:
epub.write(path.join(outdir, filename), filename, ZIP_DEFLATED)

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.applehelp
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -8,9 +7,8 @@
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
import codecs
import html
import pipes
import plistlib
import shlex
@@ -18,7 +16,6 @@ import subprocess
from os import path, environ
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.config import string_classes
from sphinx.errors import SphinxError
from sphinx.locale import __
from sphinx.util import logging
@@ -26,7 +23,6 @@ from sphinx.util.console import bold # type: ignore
from sphinx.util.fileutil import copy_asset
from sphinx.util.matching import Matcher
from sphinx.util.osutil import copyfile, ensuredir, make_filename
from sphinx.util.pycompat import htmlescape
if False:
# For type annotation
@@ -36,13 +32,6 @@ if False:
logger = logging.getLogger(__name__)
# Use plistlib.dump in 3.4 and above
try:
write_plist = plistlib.dump # type: ignore
except AttributeError:
write_plist = plistlib.writePlist
# False access page (used because helpd expects strict XHTML)
access_page_template = '''\
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\
@@ -95,7 +84,7 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
def init(self):
# type: () -> None
super(AppleHelpBuilder, self).init()
super().init()
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.link_suffix = '.html'
@@ -114,7 +103,7 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
def handle_finish(self):
# type: () -> None
super(AppleHelpBuilder, self).handle_finish()
super().handle_finish()
self.finish_tasks.add_task(self.copy_localized_files)
self.finish_tasks.add_task(self.build_helpbook)
@@ -173,8 +162,8 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
info_plist['HPDBookRemoteURL'] = self.config.applehelp_remote_url
logger.info(bold(__('writing Info.plist... ')), nonl=True)
with open(path.join(contents_dir, 'Info.plist'), 'wb') as f:
write_plist(info_plist, f)
with open(path.join(contents_dir, 'Info.plist'), 'wb') as fb:
plistlib.dump(info_plist, fb)
logger.info(__('done'))
# Copy the icon, if one is supplied
@@ -193,10 +182,10 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
# Build the access page
logger.info(bold(__('building access page...')), nonl=True)
with codecs.open(path.join(language_dir, '_access.html'), 'w') as f: # type: ignore
f.write(access_page_template % {
'toc': htmlescape(toc, quote=True),
'title': htmlescape(self.config.applehelp_title)
with open(path.join(language_dir, '_access.html'), 'w') as ft:
ft.write(access_page_template % {
'toc': html.escape(toc, quote=True),
'title': html.escape(self.config.applehelp_title)
})
logger.info(__('done'))
@@ -277,23 +266,23 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.setup_extension('sphinx.builders.html')
app.add_builder(AppleHelpBuilder)
app.add_config_value('applehelp_bundle_name',
lambda self: make_filename(self.project), 'applehelp')
app.add_config_value('applehelp_bundle_id', None, 'applehelp', string_classes)
app.add_config_value('applehelp_bundle_id', None, 'applehelp', [str])
app.add_config_value('applehelp_dev_region', 'en-us', 'applehelp')
app.add_config_value('applehelp_bundle_version', '1', 'applehelp')
app.add_config_value('applehelp_icon', None, 'applehelp', string_classes)
app.add_config_value('applehelp_icon', None, 'applehelp', [str])
app.add_config_value('applehelp_kb_product',
lambda self: '%s-%s' % (make_filename(self.project), self.release),
'applehelp')
app.add_config_value('applehelp_kb_url', None, 'applehelp', string_classes)
app.add_config_value('applehelp_remote_url', None, 'applehelp', string_classes)
app.add_config_value('applehelp_index_anchors', False, 'applehelp', string_classes)
app.add_config_value('applehelp_min_term_length', None, 'applehelp', string_classes)
app.add_config_value('applehelp_kb_url', None, 'applehelp', [str])
app.add_config_value('applehelp_remote_url', None, 'applehelp', [str])
app.add_config_value('applehelp_index_anchors', False, 'applehelp', [str])
app.add_config_value('applehelp_min_term_length', None, 'applehelp', [str])
app.add_config_value('applehelp_stopwords',
lambda self: self.language or 'en', 'applehelp')
app.add_config_value('applehelp_locale', lambda self: self.language or 'en', 'applehelp')

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.changes
~~~~~~~~~~~~~~~~~~~~~~~
@@ -9,20 +8,19 @@
:license: BSD, see LICENSE for details.
"""
import codecs
import html
from os import path
from six import iteritems
from typing import cast
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
from sphinx.util.console import bold # type: ignore
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.osutil import ensuredir, os_path
from sphinx.util.pycompat import htmlescape
if False:
# For type annotation
@@ -48,40 +46,42 @@ class ChangesBuilder(Builder):
self.templates.init(self, self.theme)
def get_outdated_docs(self):
# type: () -> unicode
# type: () -> str
return self.outdir
typemap = {
'versionadded': 'added',
'versionchanged': 'changed',
'deprecated': 'deprecated',
} # type: Dict[unicode, unicode]
}
def write(self, *ignored):
# type: (Any) -> None
version = self.config.version
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
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
libchanges = {} # type: Dict[str, List[Tuple[str, str, int]]]
apichanges = [] # type: List[Tuple[str, str, int]]
otherchanges = {} # type: Dict[Tuple[str, str], List[Tuple[str, str, int]]]
if version not in self.env.versionchanges:
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,30 +90,30 @@ 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,
'version': version,
'docstitle': self.config.html_title,
'shorttitle': self.config.html_short_title,
'libchanges': sorted(iteritems(libchanges)),
'libchanges': sorted(libchanges.items()),
'apichanges': sorted(apichanges),
'otherchanges': sorted(iteritems(otherchanges)),
'otherchanges': sorted(otherchanges.items()),
'show_copyright': self.config.html_show_copyright,
'show_sphinx': self.config.html_show_sphinx,
}
with codecs.open(path.join(self.outdir, 'index.html'), 'w', 'utf8') as f: # type: ignore # NOQA
with open(path.join(self.outdir, 'index.html'), 'w', encoding='utf8') as f:
f.write(self.templates.render('changes/frameset.html', ctx))
with codecs.open(path.join(self.outdir, 'changes.html'), 'w', 'utf8') as f: # type: ignore # NOQA
with open(path.join(self.outdir, 'changes.html'), 'w', encoding='utf8') as f:
f.write(self.templates.render('changes/versionchanges.html', ctx))
hltext = ['.. versionadded:: %s' % version,
@@ -121,8 +121,8 @@ class ChangesBuilder(Builder):
'.. deprecated:: %s' % version]
def hl(no, line):
# type: (int, unicode) -> unicode
line = '<a name="L%s"> </a>' % no + htmlescape(line)
# type: (int, str) -> str
line = '<a name="L%s"> </a>' % no + html.escape(line)
for x in hltext:
if x in line:
line = '<span class="hl">%s</span>' % line
@@ -131,8 +131,8 @@ class ChangesBuilder(Builder):
logger.info(bold(__('copying source files...')))
for docname in self.env.all_docs:
with codecs.open(self.env.doc2path(docname), 'r', # type: ignore
self.env.config.source_encoding) as f:
with open(self.env.doc2path(docname),
encoding=self.env.config.source_encoding) as f:
try:
lines = f.readlines()
except UnicodeDecodeError:
@@ -140,7 +140,7 @@ class ChangesBuilder(Builder):
continue
targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html'
ensuredir(path.dirname(targetfn))
with codecs.open(targetfn, 'w', 'utf-8') as f: # type: ignore
with open(targetfn, 'w', encoding='utf-8') as f:
text = ''.join(hl(i + 1, line) for (i, line) in enumerate(lines))
ctx = {
'filename': self.env.doc2path(docname, None),
@@ -148,15 +148,15 @@ class ChangesBuilder(Builder):
}
f.write(self.templates.render('changes/rstsource.html', ctx))
themectx = dict(('theme_' + key, val) for (key, val) in
iteritems(self.theme.get_options({})))
self.theme.get_options({}).items())
copy_asset_file(path.join(package_dir, 'themes', 'default', 'static', 'default.css_t'),
self.outdir, context=themectx, renderer=self.templates)
copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'),
self.outdir)
def hl(self, text, version):
# type: (unicode, unicode) -> unicode
text = htmlescape(text)
# type: (str, str) -> str
text = html.escape(text)
for directive in ['versionchanged', 'versionadded', 'deprecated']:
text = text.replace('.. %s:: %s' % (directive, version),
'<b>.. %s:: %s</b>' % (directive, version))
@@ -168,7 +168,7 @@ class ChangesBuilder(Builder):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.add_builder(ChangesBuilder)
return {

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.devhelp
~~~~~~~~~~~~~~~~~~~~~~~
@@ -10,11 +9,11 @@
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import absolute_import
import gzip
import re
from os import path
from typing import Any
from docutils import nodes
@@ -23,6 +22,7 @@ from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.locale import __
from sphinx.util import logging
from sphinx.util.nodes import NodeMatcher
from sphinx.util.osutil import make_filename
try:
@@ -32,7 +32,7 @@ except ImportError:
if False:
# For type annotation
from typing import Any, Dict, List # NOQA
from typing import Dict, List # NOQA
from sphinx.application import Sphinx # NOQA
@@ -60,7 +60,7 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
def init(self):
# type: () -> None
StandaloneHTMLBuilder.init(self)
super().init()
self.out_suffix = '.html'
self.link_suffix = '.html'
@@ -69,7 +69,7 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
self.build_devhelp(self.outdir, self.config.devhelp_basename)
def build_devhelp(self, outdir, outname):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
logger.info(__('dumping devhelp index...'))
# Basic info
@@ -87,7 +87,7 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
self.config.master_doc, self, prune_toctrees=False)
def write_toc(node, parent):
# type: (nodes.Node, nodes.Node) -> None
# type: (nodes.Node, etree.Element) -> None
if isinstance(node, addnodes.compact_paragraph) or \
isinstance(node, nodes.bullet_list):
for subnode in node:
@@ -100,12 +100,8 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
parent.attrib['link'] = node['refuri']
parent.attrib['name'] = node.astext()
def istoctree(node):
# type: (nodes.Node) -> bool
return isinstance(node, addnodes.compact_paragraph) and \
'toctree' in node
for node in tocdoc.traverse(istoctree):
matcher = NodeMatcher(addnodes.compact_paragraph, toctree=Any)
for node in tocdoc.traverse(matcher): # type: addnodes.compact_paragraph
write_toc(node, chapters)
# Index
@@ -113,7 +109,7 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
index = IndexEntries(self.env).create_index(self)
def write_index(title, refs, subitems):
# type: (unicode, List[Any], Any) -> None
# type: (str, List[Any], Any) -> None
if len(refs) == 0:
pass
elif len(refs) == 1:
@@ -137,12 +133,12 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
# Dump the XML file
xmlfile = path.join(outdir, outname + '.devhelp.gz')
with gzip.open(xmlfile, 'w') as f: # type: ignore
with gzip.open(xmlfile, 'w') as f:
tree.write(f, 'utf-8')
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.setup_extension('sphinx.builders.html')
app.add_builder(DevhelpBuilder)

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.dummy
~~~~~~~~~~~~~~~~~~~~~
@@ -31,19 +30,19 @@ class DummyBuilder(Builder):
pass
def get_outdated_docs(self):
# type: () -> Set[unicode]
# type: () -> Set[str]
return self.env.found_docs
def get_target_uri(self, docname, typ=None):
# type: (unicode, unicode) -> unicode
# type: (str, str) -> str
return ''
def prepare_writing(self, docnames):
# type: (Set[unicode]) -> None
# type: (Set[str]) -> None
pass
def write_doc(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
# type: (str, nodes.Node) -> None
pass
def finish(self):
@@ -52,7 +51,7 @@ class DummyBuilder(Builder):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.add_builder(DummyBuilder)
return {

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.epub3
~~~~~~~~~~~~~~~~~~~~~
@@ -13,11 +12,9 @@
from collections import namedtuple
from os import path
from six import string_types
from sphinx import package_dir
from sphinx.builders import _epub_base
from sphinx.config import string_classes, ENUM
from sphinx.config import ENUM
from sphinx.locale import __
from sphinx.util import logging, xmlname_checker
from sphinx.util.fileutil import copy_asset_file
@@ -26,7 +23,7 @@ from sphinx.util.osutil import make_filename
if False:
# For type annotation
from typing import Any, Dict, Iterable, List, Tuple # NOQA
from typing import Any, Dict, Iterable, List, Set, Tuple # NOQA
from docutils import nodes # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.config import Config # NOQA
@@ -53,8 +50,8 @@ THEME_WRITING_MODES = {
DOCTYPE = '''<!DOCTYPE html>'''
HTML_TAG = (
u'<html xmlns="http://www.w3.org/1999/xhtml" '
u'xmlns:epub="http://www.idpf.org/2007/ops">'
'<html xmlns="http://www.w3.org/1999/xhtml" '
'xmlns:epub="http://www.idpf.org/2007/ops">'
)
@@ -131,7 +128,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
"""
writing_mode = self.config.epub_writing_mode
metadata = super(Epub3Builder, self).content_metadata()
metadata = super().content_metadata()
metadata['description'] = self.esc(self.config.epub_description)
metadata['contributor'] = self.esc(self.config.epub_contributor)
metadata['page_progression_direction'] = PAGE_PROGRESSION_DIRECTIONS.get(writing_mode)
@@ -142,8 +139,8 @@ class Epub3Builder(_epub_base.EpubBuilder):
return metadata
def prepare_writing(self, docnames):
# type: (Iterable[unicode]) -> None
super(Epub3Builder, self).prepare_writing(docnames)
# type: (Set[str]) -> None
super().prepare_writing(docnames)
writing_mode = self.config.epub_writing_mode
self.globalcontext['theme_writing_mode'] = THEME_WRITING_MODES.get(writing_mode)
@@ -152,7 +149,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
self.globalcontext['skip_ua_compatible'] = True
def build_navlist(self, navnodes):
# type: (List[nodes.Node]) -> List[NavPoint]
# type: (List[Dict[str, Any]]) -> List[NavPoint]
"""Create the toc navigation structure.
This method is almost same as build_navpoints method in epub.py.
@@ -206,7 +203,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
return metadata
def build_navigation_doc(self, outdir, outname):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
"""Write the metainfo file nav.xhtml."""
logger.info(__('writing %s file...'), outname)
@@ -232,9 +229,9 @@ class Epub3Builder(_epub_base.EpubBuilder):
def convert_epub_css_files(app, config):
# type: (Sphinx, Config) -> None
"""This converts string styled epub_css_files to tuple styled one."""
epub_css_files = [] # type: List[Tuple[unicode, Dict]]
epub_css_files = [] # type: List[Tuple[str, Dict]]
for entry in config.epub_css_files:
if isinstance(entry, string_types):
if isinstance(entry, str):
epub_css_files.append((entry, {}))
else:
try:
@@ -248,7 +245,7 @@ def convert_epub_css_files(app, config):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.add_builder(Epub3Builder)
# config values
@@ -277,8 +274,8 @@ def setup(app):
app.add_config_value('epub_max_image_width', 0, 'env')
app.add_config_value('epub_show_urls', 'inline', 'epub')
app.add_config_value('epub_use_index', lambda self: self.html_use_index, 'epub')
app.add_config_value('epub_description', 'unknown', 'epub', string_classes)
app.add_config_value('epub_contributor', 'unknown', 'epub', string_classes)
app.add_config_value('epub_description', 'unknown', 'epub')
app.add_config_value('epub_contributor', 'unknown', 'epub')
app.add_config_value('epub_writing_mode', 'horizontal', 'epub',
ENUM('horizontal', 'vertical'))

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.gettext
~~~~~~~~~~~~~~~~~~~~~~~
@@ -9,19 +8,17 @@
:license: BSD, see LICENSE for details.
"""
from __future__ import unicode_literals
from codecs import open
from collections import defaultdict, OrderedDict
from datetime import datetime, tzinfo, timedelta
from io import StringIO
from os import path, walk, getenv
from time import time
from uuid import uuid4
from six import iteritems, StringIO
from sphinx.builders import Builder
from sphinx.domains.python import pairindextypes
from sphinx.errors import ThemeError
from sphinx.locale import __
from sphinx.util import split_index_msg, logging, status_iterator
from sphinx.util.console import bold # type: ignore
@@ -32,10 +29,10 @@ from sphinx.util.tags import Tags
if False:
# For type annotation
from typing import Any, DefaultDict, Dict, Iterable, List, Set, Tuple # NOQA
from typing import Any, DefaultDict, Dict, Iterable, List, Set, Tuple, Union # NOQA
from docutils import nodes # NOQA
from sphinx.util.i18n import CatalogInfo # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.util.i18n import CatalogInfo # NOQA
logger = logging.getLogger(__name__)
@@ -62,18 +59,18 @@ msgstr ""
"""[1:]
class Catalog(object):
class Catalog:
"""Catalog of translatable messages."""
def __init__(self):
# type: () -> None
self.messages = [] # type: List[unicode]
self.messages = [] # type: List[str]
# retain insertion order, a la OrderedDict
self.metadata = OrderedDict() # type: Dict[unicode, List[Tuple[unicode, int, unicode]]] # NOQA
self.metadata = OrderedDict() # type: Dict[str, List[Tuple[str, int, str]]]
# msgid -> file, line, uid
def add(self, msg, origin):
# type: (unicode, MsgOrigin) -> None
# type: (str, Union[nodes.Element, MsgOrigin]) -> None
if not hasattr(origin, 'uid'):
# Nodes that are replicated like todo don't have a uid,
# however i18n is also unnecessary.
@@ -81,16 +78,16 @@ class Catalog(object):
if msg not in self.metadata: # faster lookup in hash
self.messages.append(msg)
self.metadata[msg] = []
self.metadata[msg].append((origin.source, origin.line, origin.uid))
self.metadata[msg].append((origin.source, origin.line, origin.uid)) # type: ignore
class MsgOrigin(object):
class MsgOrigin:
"""
Origin holder for Catalog message origin.
"""
def __init__(self, source, line):
# type: (unicode, int) -> None
# type: (str, int) -> None
self.source = source
self.line = line
self.uid = uuid4().hex
@@ -119,32 +116,31 @@ class I18nBuilder(Builder):
def init(self):
# type: () -> None
Builder.init(self)
super().init()
self.env.set_versioning_method(self.versioning_method,
self.env.config.gettext_uuid)
self.tags = I18nTags()
self.catalogs = defaultdict(Catalog) # type: DefaultDict[unicode, Catalog]
self.catalogs = defaultdict(Catalog) # type: DefaultDict[str, Catalog]
def get_target_uri(self, docname, typ=None):
# type: (unicode, unicode) -> unicode
# type: (str, str) -> str
return ''
def get_outdated_docs(self):
# type: () -> Set[unicode]
# type: () -> Set[str]
return self.env.found_docs
def prepare_writing(self, docnames):
# type: (Set[unicode]) -> None
# type: (Set[str]) -> None
return
def compile_catalogs(self, catalogs, message):
# type: (Set[CatalogInfo], unicode) -> None
# type: (Set[CatalogInfo], str) -> None
return
def write_doc(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
catalog = self.catalogs[find_catalog(docname,
self.config.gettext_compact)]
# type: (str, nodes.document) -> None
catalog = self.catalogs[find_catalog(docname, self.config.gettext_compact)]
for node, msg in extract_messages(doctree):
catalog.add(msg, node)
@@ -177,7 +173,7 @@ class LocalTimeZone(tzinfo):
def __init__(self, *args, **kw):
# type: (Any, Any) -> None
super(LocalTimeZone, self).__init__(*args, **kw) # type: ignore
super().__init__(*args, **kw) # type: ignore
self.tzdelta = tzdelta
def utcoffset(self, dt):
@@ -193,11 +189,11 @@ ltz = LocalTimeZone()
def should_write(filepath, new_content):
# type: (unicode, unicode) -> bool
# type: (str, str) -> bool
if not path.exists(filepath):
return True
try:
with open(filepath, 'r', encoding='utf-8') as oldpot: # type: ignore
with open(filepath, encoding='utf-8') as oldpot:
old_content = oldpot.read()
old_header_index = old_content.index('"POT-Creation-Date:')
new_header_index = new_content.index('"POT-Creation-Date:')
@@ -220,12 +216,12 @@ class MessageCatalogBuilder(I18nBuilder):
def init(self):
# type: () -> None
I18nBuilder.init(self)
super().init()
self.create_template_bridge()
self.templates.init(self)
def _collect_templates(self):
# type: () -> Set[unicode]
# type: () -> Set[str]
template_files = set()
for template_path in self.config.templates_path:
tmpl_abs_path = path.join(self.app.srcdir, template_path)
@@ -245,30 +241,33 @@ class MessageCatalogBuilder(I18nBuilder):
extract_translations = self.templates.environment.extract_translations
for template in status_iterator(files, __('reading templates... '), "purple", # type: ignore # NOQA
for template in status_iterator(files, __('reading templates... '), "purple",
len(files), self.app.verbosity):
with open(template, 'r', encoding='utf-8') as f: # type: ignore
context = f.read()
for line, meth, msg in extract_translations(context):
origin = MsgOrigin(template, line)
self.catalogs['sphinx'].add(msg, origin)
try:
with open(template, encoding='utf-8') as f:
context = f.read()
for line, meth, msg in extract_translations(context):
origin = MsgOrigin(template, line)
self.catalogs['sphinx'].add(msg, origin)
except Exception as exc:
raise ThemeError('%s: %r' % (template, exc))
def build(self, docnames, summary=None, method='update'):
# type: (Iterable[unicode], unicode, unicode) -> None
# type: (Iterable[str], str, str) -> None
self._extract_from_template()
I18nBuilder.build(self, docnames, summary, method)
super().build(docnames, summary, method)
def finish(self):
# type: () -> None
I18nBuilder.finish(self)
data = dict(
version = self.config.version,
copyright = self.config.copyright,
project = self.config.project,
ctime = datetime.fromtimestamp(
super().finish()
data = {
'version': self.config.version,
'copyright': self.config.copyright,
'project': self.config.project,
'ctime': datetime.fromtimestamp(
timestamp, ltz).strftime('%Y-%m-%d %H:%M%z'),
)
for textdomain, catalog in status_iterator(iteritems(self.catalogs), # type: ignore
}
for textdomain, catalog in status_iterator(self.catalogs.items(),
__("writing message catalogs... "),
"darkgreen", len(self.catalogs),
self.app.verbosity,
@@ -278,36 +277,35 @@ class MessageCatalogBuilder(I18nBuilder):
pofn = path.join(self.outdir, textdomain + '.pot')
output = StringIO()
output.write(POHEADER % data) # type: ignore
output.write(POHEADER % data)
for message in catalog.messages:
positions = catalog.metadata[message]
if self.config.gettext_location:
# generate "#: file1:line1\n#: file2:line2 ..."
output.write("#: %s\n" % "\n#: ".join( # type: ignore
output.write("#: %s\n" % "\n#: ".join(
"%s:%s" % (canon_path(relpath(source, self.outdir)), line)
for source, line, _ in positions))
if self.config.gettext_uuid:
# generate "# uuid1\n# uuid2\n ..."
output.write("# %s\n" % "\n# ".join( # type: ignore
uid for _, _, uid in positions))
output.write("# %s\n" % "\n# ".join(uid for _, _, uid in positions))
# message contains *one* line of text ready for translation
message = message.replace('\\', r'\\'). \
replace('"', r'\"'). \
replace('\n', '\\n"\n"')
output.write('msgid "%s"\nmsgstr ""\n\n' % message) # type: ignore
output.write('msgid "%s"\nmsgstr ""\n\n' % message)
content = output.getvalue()
if should_write(pofn, content):
with open(pofn, 'w', encoding='utf-8') as pofile: # type: ignore
with open(pofn, 'w', encoding='utf-8') as pofile:
pofile.write(content)
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.add_builder(MessageCatalogBuilder)
app.add_config_value('gettext_compact', True, 'gettext')

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.htmlhelp
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -9,9 +8,8 @@
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
import codecs
import html
import os
from os import path
@@ -22,13 +20,14 @@ from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.locale import __
from sphinx.util import logging
from sphinx.util.osutil import make_filename
from sphinx.util.pycompat import htmlescape
from sphinx.util.nodes import NodeMatcher
from sphinx.util.osutil import make_filename_from_project
if False:
# For type annotation
from typing import Any, Dict, IO, List, Tuple # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.config import Config # NOQA
logger = logging.getLogger(__name__)
@@ -133,8 +132,9 @@ that the their then there these they this to
was will with
""".split()
# The following list includes only languages supported by Sphinx.
# See http://msdn.microsoft.com/en-us/library/ms930130.aspx for more.
# The following list includes only languages supported by Sphinx. See
# https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms930130(v=msdn.10)
# for more.
chm_locales = {
# lang: LCID, encoding
'ca': (0x403, 'cp1252'),
@@ -195,23 +195,23 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
def init(self):
# type: () -> None
StandaloneHTMLBuilder.init(self)
# the output files for HTML help must be .html only
# the output files for HTML help is .html by default
self.out_suffix = '.html'
self.link_suffix = '.html'
super().init()
# determine the correct locale setting
locale = chm_locales.get(self.config.language)
if locale is not None:
self.lcid, self.encoding = locale
def open_file(self, outdir, basename, mode='w'):
# type: (unicode, unicode, unicode) -> IO
# type: (str, str, str) -> IO
# open a file with the correct encoding for the selected language
return codecs.open(path.join(outdir, basename), mode, # type: ignore
self.encoding, 'xmlcharrefreplace')
return open(path.join(outdir, basename), mode, encoding=self.encoding,
errors='xmlcharrefreplace')
def update_page_context(self, pagename, templatename, ctx, event_arg):
# type: (unicode, unicode, Dict, unicode) -> None
# type: (str, str, Dict, str) -> None
ctx['encoding'] = self.encoding
def handle_finish(self):
@@ -219,16 +219,16 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
self.build_hhx(self.outdir, self.config.htmlhelp_basename)
def write_doc(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
# type: (str, nodes.document) -> None
for node in doctree.traverse(nodes.reference):
# add ``target=_blank`` attributes to external links
if node.get('internal') is None and 'refuri' in node:
node['target'] = '_blank'
StandaloneHTMLBuilder.write_doc(self, docname, doctree)
super().write_doc(docname, doctree)
def build_hhx(self, outdir, outname):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
logger.info(__('dumping stopword list...'))
with self.open_file(outdir, outname + '.stp') as f:
for word in sorted(stopwords):
@@ -278,7 +278,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
write_toc(subnode, ullevel)
elif isinstance(node, nodes.reference):
link = node['refuri']
title = htmlescape(node.astext()).replace('"', '&quot;')
title = html.escape(node.astext()).replace('"', '&quot;')
f.write(object_sitemap % (title, link))
elif isinstance(node, nodes.bullet_list):
if ullevel != 0:
@@ -291,11 +291,8 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
for subnode in node:
write_toc(subnode, ullevel)
def istoctree(node):
# type: (nodes.Node) -> bool
return isinstance(node, addnodes.compact_paragraph) and \
'toctree' in node
for node in tocdoc.traverse(istoctree):
matcher = NodeMatcher(addnodes.compact_paragraph, toctree=True)
for node in tocdoc.traverse(matcher): # type: addnodes.compact_paragraph
write_toc(node)
f.write(contents_footer)
@@ -305,13 +302,13 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
f.write('<UL>\n')
def write_index(title, refs, subitems):
# type: (unicode, List[Tuple[unicode, unicode]], List[Tuple[unicode, List[Tuple[unicode, unicode]]]]) -> None # NOQA
# type: (str, List[Tuple[str, str]], List[Tuple[str, List[Tuple[str, str]]]]) -> None # NOQA
def write_param(name, value):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
item = ' <param name="%s" value="%s">\n' % \
(name, value)
f.write(item)
title = htmlescape(title)
title = html.escape(title)
f.write('<LI> <OBJECT type="text/sitemap">\n')
write_param('Keyword', title)
if len(refs) == 0:
@@ -335,12 +332,20 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
f.write('</UL>\n')
def default_htmlhelp_basename(config):
# type: (Config) -> str
"""Better default htmlhelp_basename setting."""
return make_filename_from_project(config.project) + 'doc'
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.setup_extension('sphinx.builders.html')
app.add_builder(HTMLHelpBuilder)
app.add_config_value('htmlhelp_basename', lambda self: make_filename(self.project), None)
app.add_config_value('htmlhelp_basename', default_htmlhelp_basename, None)
app.add_config_value('htmlhelp_file_suffix', None, 'html', [str])
app.add_config_value('htmlhelp_link_suffix', None, 'html', [str])
return {
'version': 'builtin',

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.latex
~~~~~~~~~~~~~~~~~~~~~
@@ -22,7 +21,7 @@ from sphinx.builders.latex.transforms import (
FootnoteDocnameUpdater, LaTeXFootnoteTransform, LiteralBlockTransform,
ShowUrlsTransform, DocumentTargetTransform,
)
from sphinx.config import string_classes, ENUM
from sphinx.config import ENUM
from sphinx.environment import NoUri
from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.errors import SphinxError, ConfigError
@@ -32,9 +31,13 @@ from sphinx.util import texescape, logging, status_iterator
from sphinx.util.console import bold, darkgreen # type: ignore
from sphinx.util.docutils import SphinxFileOutput, new_document
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.i18n import format_date
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.util.template import LaTeXRenderer
from sphinx.writers.latex import (
ADDITIONAL_SETTINGS, DEFAULT_SETTINGS, LaTeXWriter, LaTeXTranslator
)
if False:
# For type annotation
@@ -99,11 +102,11 @@ XINDY_LANG_OPTIONS = {
'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__)
@@ -126,24 +129,27 @@ class LaTeXBuilder(Builder):
def init(self):
# type: () -> None
self.docnames = [] # type: Iterable[unicode]
self.document_data = [] # type: List[Tuple[unicode, unicode, unicode, unicode, unicode, bool]] # NOQA
self.context = {} # type: Dict[str, Any]
self.docnames = [] # type: Iterable[str]
self.document_data = [] # type: List[Tuple[str, str, str, str, str, bool]]
self.usepackages = self.app.registry.latex_packages
texescape.init()
self.init_context()
def get_outdated_docs(self):
# type: () -> Union[unicode, List[unicode]]
# type: () -> Union[str, List[str]]
return 'all documents' # for now
def get_target_uri(self, docname, typ=None):
# type: (unicode, unicode) -> unicode
# type: (str, str) -> str
if docname not in self.docnames:
raise NoUri
else:
return '%' + docname
def get_relative_uri(self, from_, to, typ=None):
# type: (unicode, unicode, unicode) -> unicode
# type: (str, str, str) -> str
# ignore source path
return self.get_target_uri(to, typ)
@@ -155,7 +161,7 @@ class LaTeXBuilder(Builder):
'will be written'))
return
# assign subdirs to titles
self.titles = [] # type: List[Tuple[unicode, unicode]]
self.titles = [] # type: List[Tuple[str, str]]
for entry in preliminary_document_data:
docname = entry[0]
if docname not in self.env.all_docs:
@@ -167,16 +173,52 @@ class LaTeXBuilder(Builder):
docname = docname[:-5]
self.titles.append((docname, entry[2]))
def init_context(self):
# type: () -> None
self.context = DEFAULT_SETTINGS.copy()
# Add special settings for latex_engine
self.context.update(ADDITIONAL_SETTINGS.get(self.config.latex_engine, {}))
# for xelatex+French, don't use polyglossia by default
if self.config.latex_engine == 'xelatex':
if self.config.language:
if self.config.language[:2] == 'fr':
self.context['polyglossia'] = ''
self.context['babel'] = r'\usepackage{babel}'
# Apply extension settings to context
self.context['packages'] = self.usepackages
# Apply user settings to context
self.context.update(self.config.latex_elements)
self.context['release'] = self.config.release
self.context['use_xindy'] = self.config.latex_use_xindy
if self.config.today:
self.context['date'] = self.config.today
else:
self.context['date'] = format_date(self.config.today_fmt or _('%b %d, %Y'),
language=self.config.language)
if self.config.latex_logo:
self.context['logofilename'] = path.basename(self.config.latex_logo)
# for compatibilities
self.context['indexname'] = _('Index')
if self.config.release:
# Show the release label only if release value exists
self.context['releasename'] = _('Release')
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')
f.write('\\ProvidesPackage{sphinxhighlight}'
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
f.write(highlighter.get_stylesheet()) # type: ignore
f.write(highlighter.get_stylesheet())
def write(self, *ignored):
# type: (Any) -> None
@@ -184,7 +226,7 @@ class LaTeXBuilder(Builder):
docsettings = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()
read_config_files=True).get_default_values() # type: Any
self.init_document_data()
self.write_stylesheet()
@@ -211,18 +253,21 @@ class LaTeXBuilder(Builder):
doctree['tocdepth'] = tocdepth
self.apply_transforms(doctree)
self.post_process_images(doctree)
self.update_doc_context(title, author)
logger.info(__("writing... "), nonl=1)
docsettings.author = author
docsettings.title = title
docsettings.contentsname = self.get_contentsname(docname)
docsettings.docname = docname
docsettings.docclass = docclass
doctree.settings = docsettings
doctree.settings.author = author
doctree.settings.title = title
doctree.settings.contentsname = self.get_contentsname(docname)
doctree.settings.docname = docname
doctree.settings.docclass = docclass
docwriter.write(doctree, destination)
logger.info("done")
def get_contentsname(self, indexfile):
# type: (unicode) -> unicode
# type: (str) -> str
tree = self.env.get_doctree(indexfile)
contentsname = None
for toctree in tree.traverse(addnodes.toctree):
@@ -232,8 +277,13 @@ class LaTeXBuilder(Builder):
return contentsname
def update_doc_context(self, title, author):
# type: (str, str) -> None
self.context['title'] = title
self.context['author'] = author
def assemble_doctree(self, indexfile, toctree_only, appendices):
# type: (unicode, bool, List[unicode]) -> nodes.Node
# type: (str, bool, List[str]) -> nodes.document
from docutils import nodes # NOQA
self.docnames = set([indexfile] + appendices)
logger.info(darkgreen(indexfile) + " ", nonl=1)
@@ -244,8 +294,8 @@ class LaTeXBuilder(Builder):
# fresh document
new_tree = new_document('<latex output>')
new_sect = nodes.section()
new_sect += nodes.title(u'<Set title in conf.py>',
u'<Set title in conf.py>')
new_sect += nodes.title('<Set title in conf.py>',
'<Set title in conf.py>')
new_tree += new_sect
for node in tree.traverse(addnodes.toctree):
new_sect += node
@@ -265,7 +315,7 @@ class LaTeXBuilder(Builder):
for pendingnode in largetree.traverse(addnodes.pending_xref):
docname = pendingnode['refdocname']
sectname = pendingnode['refsectname']
newnodes = [nodes.emphasis(sectname, sectname)]
newnodes = [nodes.emphasis(sectname, sectname)] # type: List[nodes.Node]
for subdir, title in self.titles:
if docname.startswith(subdir):
newnodes.append(nodes.Text(_(' (in '), _(' (in ')))
@@ -291,6 +341,7 @@ class LaTeXBuilder(Builder):
def finish(self):
# type: () -> None
self.copy_image_files()
self.write_message_catalog()
# copy TeX support files from texinputs
# configure usage of xindy (impacts Makefile and latexmkrc)
@@ -354,6 +405,11 @@ class LaTeXBuilder(Builder):
logger.warning(__('cannot copy image file %r: %s'),
path.join(self.srcdir, src), err)
def write_message_catalog(self):
# type: () -> None
filename = path.join(package_dir, 'templates', 'latex', 'sphinxmessages.sty_t')
copy_asset_file(filename, self.outdir, context={}, renderer=LaTeXRenderer())
def validate_config_values(app, config):
# type: (Sphinx, Config) -> None
@@ -374,9 +430,15 @@ 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
# type: (Config) -> str
""" Better default latex_engine settings for specific languages. """
if config.language == 'ja':
return 'platex'
@@ -385,7 +447,7 @@ def default_latex_engine(config):
def default_latex_docclass(config):
# type: (Config) -> Dict[unicode, unicode]
# type: (Config) -> Dict[str, str]
""" Better default latex_docclass settings for specific languages. """
if config.language == 'ja':
return {'manual': 'jsbook',
@@ -401,7 +463,7 @@ def default_latex_use_xindy(config):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.add_builder(LaTeXBuilder)
app.add_post_transform(CitationReferenceTransform)
app.add_post_transform(MathReferenceTransform)
@@ -414,7 +476,7 @@ def setup(app):
lambda self: [(self.master_doc, make_filename(self.project) + '.tex',
self.project, '', 'manual')],
None)
app.add_config_value('latex_logo', None, None, string_classes)
app.add_config_value('latex_logo', None, None, [str])
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)

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.latex.nodes
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -35,3 +34,12 @@ class math_reference(nodes.Inline, nodes.Referential, nodes.TextElement):
class thebibliography(nodes.container):
"""A node for wrapping bibliographies."""
pass
HYPERLINK_SUPPORT_NODES = (
nodes.figure,
nodes.literal_block,
nodes.table,
nodes.section,
captioned_literal_block,
)

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.latex.transforms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -9,6 +8,8 @@
:license: BSD, see LICENSE for details.
"""
from typing import cast
from docutils import nodes
from sphinx import addnodes
@@ -16,21 +17,24 @@ from sphinx.builders.latex.nodes import (
captioned_literal_block, footnotemark, footnotetext, math_reference, thebibliography
)
from sphinx.transforms import SphinxTransform
from sphinx.util.nodes import NodeMatcher
if False:
# For type annotation
from typing import Dict, List, Set, Tuple, Union # NOQA
from typing import Any, Dict, List, Set, Tuple, Union # NOQA
URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:')
class FootnoteDocnameUpdater(SphinxTransform):
"""Add docname to footnote and footnote_reference nodes."""
default_priority = 200
default_priority = 700
TARGET_NODES = (nodes.footnote, nodes.footnote_reference)
def apply(self):
for node in self.document.traverse(lambda n: isinstance(n, self.TARGET_NODES)):
def apply(self, **kwargs):
# type: (Any) -> None
matcher = NodeMatcher(*self.TARGET_NODES)
for node in self.document.traverse(matcher): # type: nodes.Element
node['docname'] = self.env.docname
@@ -46,23 +50,24 @@ class ShowUrlsTransform(SphinxTransform):
# references are expanded to footnotes (or not)
expanded = False
def apply(self):
# type: () -> None
def apply(self, **kwargs):
# type: (Any) -> None
try:
# replace id_prefix temporarily
id_prefix = self.document.settings.id_prefix
self.document.settings.id_prefix = 'show_urls'
settings = self.document.settings # type: Any
id_prefix = settings.id_prefix
settings.id_prefix = 'show_urls'
self.expand_show_urls()
if self.expanded:
self.renumber_footnotes()
finally:
# restore id_prefix
self.document.settings.id_prefix = id_prefix
settings.id_prefix = id_prefix
def expand_show_urls(self):
# type: () -> None
show_urls = self.document.settings.env.config.latex_show_urls
show_urls = self.config.latex_show_urls
if show_urls is False or show_urls == 'no':
return
@@ -85,7 +90,7 @@ class ShowUrlsTransform(SphinxTransform):
node.parent.insert(index + 1, textnode)
def get_docname_for_node(self, node):
# type: (nodes.Node) -> unicode
# type: (nodes.Node) -> str
while node:
if isinstance(node, nodes.document):
return self.env.path2doc(node['source'])
@@ -97,17 +102,17 @@ class ShowUrlsTransform(SphinxTransform):
return None # never reached here. only for type hinting
def create_footnote(self, uri, docname):
# type: (unicode, unicode) -> Tuple[nodes.footnote, nodes.footnote_ref]
label = nodes.label('', '#')
para = nodes.paragraph()
para.append(nodes.reference('', nodes.Text(uri), refuri=uri, nolinkurl=True))
footnote = nodes.footnote(uri, label, para, auto=1, docname=docname)
# type: (str, str) -> Tuple[nodes.footnote, nodes.footnote_reference]
reference = nodes.reference('', nodes.Text(uri), refuri=uri, nolinkurl=True)
footnote = nodes.footnote(uri, auto=1, docname=docname)
footnote['names'].append('#')
footnote += nodes.label('', '#')
footnote += nodes.paragraph('', '', reference)
self.document.note_autofootnote(footnote)
label = nodes.Text('#')
footnote_ref = nodes.footnote_reference('[#]_', label, auto=1,
footnote_ref = nodes.footnote_reference('[#]_', auto=1,
refid=footnote['ids'][0], docname=docname)
footnote_ref += nodes.Text('#')
self.document.note_autofootnote_ref(footnote_ref)
footnote.add_backref(footnote_ref['ids'][0])
@@ -127,10 +132,10 @@ class ShowUrlsTransform(SphinxTransform):
break
# assign new footnote number
old_label = footnote[0].astext()
footnote[0].replace_self(nodes.label('', str(num)))
old_label = cast(nodes.label, footnote[0])
old_label.replace_self(nodes.label('', str(num)))
if old_label in footnote['names']:
footnote['names'].remove(old_label)
footnote['names'].remove(old_label.astext())
footnote['names'].append(str(num))
# update footnote_references by new footnote number
@@ -147,9 +152,9 @@ class FootnoteCollector(nodes.NodeVisitor):
def __init__(self, document):
# type: (nodes.document) -> None
self.auto_footnotes = [] # type: List[nodes.footnote]
self.used_footnote_numbers = set() # type: Set[unicode]
self.used_footnote_numbers = set() # type: Set[str]
self.footnote_refs = [] # type: List[nodes.footnote_reference]
nodes.NodeVisitor.__init__(self, document)
super().__init__(document)
def unknown_visit(self, node):
# type: (nodes.Node) -> None
@@ -341,7 +346,8 @@ class LaTeXFootnoteTransform(SphinxTransform):
default_priority = 600
def apply(self):
def apply(self, **kwargs):
# type: (Any) -> None
footnotes = list(self.document.traverse(nodes.footnote))
for node in footnotes:
node.parent.remove(node)
@@ -353,12 +359,12 @@ class LaTeXFootnoteTransform(SphinxTransform):
class LaTeXFootnoteVisitor(nodes.NodeVisitor):
def __init__(self, document, footnotes):
# type: (nodes.document, List[nodes.footnote]) -> None
self.appeared = set() # type: Set[Tuple[unicode, nodes.footnote]]
self.appeared = set() # type: Set[Tuple[str, str]]
self.footnotes = footnotes # type: List[nodes.footnote]
self.pendings = [] # type: List[nodes.Node]
self.table_footnotes = [] # type: List[nodes.Node]
self.restricted = None # type: nodes.Node
nodes.NodeVisitor.__init__(self, document)
self.pendings = [] # type: List[nodes.footnote]
self.table_footnotes = [] # type: List[nodes.footnote]
self.restricted = None # type: nodes.Element
super().__init__(document)
def unknown_visit(self, node):
# type: (nodes.Node) -> None
@@ -369,12 +375,12 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
pass
def restrict(self, node):
# type: (nodes.Node) -> None
# type: (nodes.Element) -> None
if self.restricted is None:
self.restricted = node
def unrestrict(self, node):
# type: (nodes.Node) -> None
# type: (nodes.Element) -> None
if self.restricted == node:
self.restricted = None
pos = node.parent.index(node)
@@ -384,36 +390,36 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
self.pendings = []
def visit_figure(self, node):
# type: (nodes.Node) -> None
# type: (nodes.figure) -> None
self.restrict(node)
def depart_figure(self, node):
# type: (nodes.Node) -> None
# type: (nodes.figure) -> None
self.unrestrict(node)
def visit_term(self, node):
# type: (nodes.Node) -> None
# type: (nodes.term) -> None
self.restrict(node)
def depart_term(self, node):
# type: (nodes.Node) -> None
# type: (nodes.term) -> None
self.unrestrict(node)
def visit_caption(self, node):
# type: (nodes.Node) -> None
# type: (nodes.caption) -> None
self.restrict(node)
def depart_caption(self, node):
# type: (nodes.Node) -> None
# type: (nodes.caption) -> None
self.unrestrict(node)
def visit_title(self, node):
# type: (nodes.Node) -> None
# type: (nodes.title) -> None
if isinstance(node.parent, (nodes.section, nodes.table)):
self.restrict(node)
def depart_title(self, node):
# type: (nodes.Node) -> None
# type: (nodes.title) -> None
if isinstance(node.parent, nodes.section):
self.unrestrict(node)
elif isinstance(node.parent, nodes.table):
@@ -422,17 +428,17 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
self.unrestrict(node)
def visit_thead(self, node):
# type: (nodes.Node) -> None
# type: (nodes.thead) -> None
self.restrict(node)
def depart_thead(self, node):
# type: (nodes.Node) -> None
# type: (nodes.thead) -> None
self.table_footnotes += self.pendings
self.pendings = []
self.unrestrict(node)
def depart_table(self, node):
# type: (nodes.Node) -> None
# type: (nodes.table) -> None
tbody = list(node.traverse(nodes.tbody))[0]
for footnote in reversed(self.table_footnotes):
fntext = footnotetext('', *footnote.children)
@@ -441,15 +447,15 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
self.table_footnotes = []
def visit_footnote(self, node):
# type: (nodes.Node) -> None
# type: (nodes.footnote) -> None
self.restrict(node)
def depart_footnote(self, node):
# type: (nodes.Node) -> None
# type: (nodes.footnote) -> None
self.unrestrict(node)
def visit_footnote_reference(self, node):
# type: (nodes.Node) -> None
# type: (nodes.footnote_reference) -> None
number = node.astext().strip()
docname = node['docname']
if self.restricted:
@@ -471,7 +477,7 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
raise nodes.SkipNode
def get_footnote_by_reference(self, node):
# type: (nodes.Node) -> nodes.Node
# type: (nodes.footnote_reference) -> nodes.footnote
docname = node['docname']
for footnote in self.footnotes:
if docname == footnote['docname'] and footnote['ids'][0] == node['refid']:
@@ -512,8 +518,8 @@ class BibliographyTransform(SphinxTransform):
"""
default_priority = 750
def apply(self):
# type: () -> None
def apply(self, **kwargs):
# type: (Any) -> None
citations = thebibliography()
for node in self.document.traverse(nodes.citation):
node.parent.remove(node)
@@ -531,19 +537,19 @@ class CitationReferenceTransform(SphinxTransform):
"""
default_priority = 5 # before ReferencesResolver
def apply(self):
# type: () -> None
def apply(self, **kwargs):
# type: (Any) -> None
if self.app.builder.name != 'latex':
return
matcher = NodeMatcher(addnodes.pending_xref, refdomain='std', reftype='citation')
citations = self.env.get_domain('std').data['citations']
for node in self.document.traverse(addnodes.pending_xref):
if node['refdomain'] == 'std' and node['reftype'] == 'citation':
docname, labelid, _ = citations.get(node['reftarget'], ('', '', 0))
if docname:
citation_ref = nodes.citation_reference('', *node.children,
docname=docname, refname=labelid)
node.replace_self(citation_ref)
for node in self.document.traverse(matcher): # type: addnodes.pending_xref
docname, labelid, _ = citations.get(node['reftarget'], ('', '', 0))
if docname:
citation_ref = nodes.citation_reference('', '', *node.children,
docname=docname, refname=labelid)
node.replace_self(citation_ref)
class MathReferenceTransform(SphinxTransform):
@@ -554,14 +560,14 @@ class MathReferenceTransform(SphinxTransform):
"""
default_priority = 5 # before ReferencesResolver
def apply(self):
# type: () -> None
def apply(self, **kwargs):
# type: (Any) -> None
if self.app.builder.name != 'latex':
return
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'])
@@ -572,23 +578,23 @@ class LiteralBlockTransform(SphinxTransform):
"""Replace container nodes for literal_block by captioned_literal_block."""
default_priority = 400
def apply(self):
# type: () -> None
def apply(self, **kwargs):
# type: (Any) -> None
if self.app.builder.name != 'latex':
return
for node in self.document.traverse(nodes.container):
if node.get('literal_block') is True:
newnode = captioned_literal_block('', *node.children, **node.attributes)
node.replace_self(newnode)
matcher = NodeMatcher(nodes.container, literal_block=True)
for node in self.document.traverse(matcher): # type: nodes.container
newnode = captioned_literal_block('', *node.children, **node.attributes)
node.replace_self(newnode)
class DocumentTargetTransform(SphinxTransform):
"""Add :doc label to the first section of each document."""
default_priority = 400
def apply(self):
# type: () -> None
def apply(self, **kwargs):
# type: (Any) -> None
if self.app.builder.name != 'latex':
return

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.linkcheck
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -9,26 +8,16 @@
:license: BSD, see LICENSE for details.
"""
import codecs
import queue
import re
import socket
import threading
from html.parser import HTMLParser
from os import path
from urllib.parse import unquote
from docutils import nodes
from requests.exceptions import HTTPError
from six.moves import queue, html_parser
from six.moves.urllib.parse import unquote
# 2015-06-25 barry@python.org. This exception was deprecated in Python 3.3 and
# removed in Python 3.5, however for backward compatibility reasons, we're not
# going to just remove it. If it doesn't exist, define an exception that will
# never be caught but leaves the code in check_anchor() intact.
try:
from six.moves.html_parser import HTMLParseError # type: ignore
except ImportError:
class HTMLParseError(Exception): # type: ignore
pass
from sphinx.builders import Builder
from sphinx.locale import __
@@ -36,6 +25,7 @@ from sphinx.util import encode_uri, requests, logging
from sphinx.util.console import ( # type: ignore
purple, red, darkgreen, darkgray, darkred, turquoise
)
from sphinx.util.nodes import traverse_parent
from sphinx.util.requests import is_ssl_error
if False:
@@ -48,12 +38,12 @@ if False:
logger = logging.getLogger(__name__)
class AnchorCheckParser(html_parser.HTMLParser):
class AnchorCheckParser(HTMLParser):
"""Specialized HTML parser that looks for a specific anchor."""
def __init__(self, search_anchor):
# type: (unicode) -> None
html_parser.HTMLParser.__init__(self)
# type: (str) -> None
super().__init__()
self.search_anchor = search_anchor
self.found = False
@@ -67,23 +57,18 @@ class AnchorCheckParser(html_parser.HTMLParser):
def check_anchor(response, anchor):
# type: (Response, unicode) -> bool
# type: (Response, str) -> bool
"""Reads HTML data from a response object `response` searching for `anchor`.
Returns True if anchor was found, False otherwise.
"""
parser = AnchorCheckParser(anchor)
try:
# Read file in chunks. If we find a matching anchor, we break
# the loop early in hopes not to have to download the whole thing.
for chunk in response.iter_content(chunk_size=4096, decode_unicode=True):
parser.feed(chunk)
if parser.found:
break
parser.close()
except HTMLParseError:
# HTMLParser is usually pretty good with sloppy HTML, but it tends to
# choke on EOF. But we're done then anyway.
pass
# Read file in chunks. If we find a matching anchor, we break
# the loop early in hopes not to have to download the whole thing.
for chunk in response.iter_content(chunk_size=4096, decode_unicode=True):
parser.feed(chunk)
if parser.found:
break
parser.close()
return parser.found
@@ -100,9 +85,9 @@ class CheckExternalLinksBuilder(Builder):
self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
self.anchors_ignore = [re.compile(x)
for x in self.app.config.linkcheck_anchors_ignore]
self.good = set() # type: Set[unicode]
self.broken = {} # type: Dict[unicode, unicode]
self.redirected = {} # type: Dict[unicode, Tuple[unicode, int]]
self.good = set() # type: Set[str]
self.broken = {} # type: Dict[str, str]
self.redirected = {} # type: Dict[str, Tuple[str, int]]
# set a timeout for non-responding servers
socket.setdefaulttimeout(5.0)
# create output file
@@ -120,14 +105,17 @@ 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]
# type: () -> Tuple[str, str, int]
# split off anchor
if '#' in uri:
req_url, anchor = uri.split('#', 1)
@@ -191,7 +179,7 @@ class CheckExternalLinksBuilder(Builder):
return 'redirected', new_url, 0
def check():
# type: () -> Tuple[unicode, unicode, int]
# type: () -> Tuple[str, str, int]
# check for various conditions without bothering the network
if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'ftp:')):
return 'unchecked', '', 0
@@ -230,7 +218,7 @@ class CheckExternalLinksBuilder(Builder):
self.rqueue.put((uri, docname, lineno, status, info, code))
def process_result(self, result):
# type: (Tuple[unicode, unicode, int, unicode, unicode, int]) -> None
# type: (Tuple[str, str, int, str, str, int]) -> None
uri, docname, lineno, status, info, code = result
if status == 'unchecked':
return
@@ -268,19 +256,19 @@ class CheckExternalLinksBuilder(Builder):
logger.info(color('redirect ') + uri + color(' - ' + text + ' to ' + info))
def get_target_uri(self, docname, typ=None):
# type: (unicode, unicode) -> unicode
# type: (str, str) -> str
return ''
def get_outdated_docs(self):
# type: () -> Set[unicode]
# type: () -> Set[str]
return self.env.found_docs
def prepare_writing(self, docnames):
# type: (nodes.Node) -> None
# type: (Set[str]) -> None
return
def write_doc(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
# type: (str, nodes.Node) -> None
logger.info('')
n = 0
for node in doctree.traverse(nodes.reference):
@@ -288,11 +276,10 @@ class CheckExternalLinksBuilder(Builder):
continue
uri = node['refuri']
lineno = None
while lineno is None:
node = node.parent
if node is None:
for parent in traverse_parent(node):
if parent.line:
lineno = parent.line
break
lineno = node.line
self.wqueue.put((uri, docname, lineno), False)
n += 1
done = 0
@@ -304,8 +291,8 @@ class CheckExternalLinksBuilder(Builder):
self.app.statuscode = 1
def write_entry(self, what, docname, line, uri):
# type: (unicode, unicode, int, unicode) -> None
with codecs.open(path.join(self.outdir, 'output.txt'), 'a', 'utf-8') as output: # type: ignore # NOQA
# type: (str, str, int, str) -> None
with open(path.join(self.outdir, 'output.txt'), 'a', encoding='utf-8') as output:
output.write("%s:%s: [%s] %s\n" % (self.env.doc2path(docname, None),
line, what, uri))
@@ -316,7 +303,7 @@ class CheckExternalLinksBuilder(Builder):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.add_builder(CheckExternalLinksBuilder)
app.add_config_value('linkcheck_ignore', [], None)

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.manpage
~~~~~~~~~~~~~~~~~~~~~~~
@@ -13,7 +12,6 @@ from os import path
from docutils.frontend import OptionParser
from docutils.io import FileOutput
from six import string_types
from sphinx import addnodes
from sphinx.builders import Builder
@@ -22,13 +20,14 @@ from sphinx.locale import __
from sphinx.util import logging
from sphinx.util.console import bold, darkgreen # type: ignore
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import make_filename
from sphinx.util.osutil import make_filename_from_project
from sphinx.writers.manpage import ManualPageWriter, ManualPageTranslator
if False:
# For type annotation
from typing import Any, Dict, List, Set, Union # NOQA
from typing import Any, Dict, List, Set, Tuple, Union # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.config import Config # NOQA
logger = logging.getLogger(__name__)
@@ -43,7 +42,7 @@ class ManualPageBuilder(Builder):
epilog = __('The manual pages are in %(outdir)s.')
default_translator_class = ManualPageTranslator
supported_image_types = [] # type: List[unicode]
supported_image_types = [] # type: List[str]
def init(self):
# type: () -> None
@@ -52,11 +51,11 @@ class ManualPageBuilder(Builder):
'will be written'))
def get_outdated_docs(self):
# type: () -> Union[unicode, List[unicode]]
# type: () -> Union[str, List[str]]
return 'all manpages' # for now
def get_target_uri(self, docname, typ=None):
# type: (unicode, unicode) -> unicode
# type: (str, str) -> str
if typ == 'token':
return ''
raise NoUri
@@ -67,18 +66,27 @@ class ManualPageBuilder(Builder):
docsettings = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()
read_config_files=True).get_default_values() # type: Any
logger.info(bold(__('writing... ')), nonl=True)
for info in self.config.man_pages:
docname, name, description, authors, section = info
if isinstance(authors, string_types):
if docname not in self.env.all_docs:
logger.warning(__('"man_pages" config value references unknown '
'document %s'), docname)
continue
if isinstance(authors, str):
if authors:
authors = [authors]
else:
authors = []
docsettings.title = name
docsettings.subtitle = description
docsettings.authors = authors
docsettings.section = section
targetname = '%s.%s' % (name, section)
logger.info(darkgreen(targetname) + ' { ', nonl=True)
destination = FileOutput(
@@ -86,21 +94,16 @@ class ManualPageBuilder(Builder):
encoding='utf-8')
tree = self.env.get_doctree(docname)
docnames = set() # type: Set[unicode]
docnames = set() # type: Set[str]
largetree = inline_all_toctrees(self, docnames, docname, tree,
darkgreen, [docname])
largetree.settings = docsettings
logger.info('} ', nonl=True)
self.env.resolve_references(largetree, docname, self)
# remove pending_xref nodes
for pendingnode in largetree.traverse(addnodes.pending_xref):
pendingnode.replace_self(pendingnode.children)
largetree.settings = docsettings
largetree.settings.title = name
largetree.settings.subtitle = description
largetree.settings.authors = authors
largetree.settings.section = section
docwriter.write(largetree, destination)
logger.info('')
@@ -109,14 +112,19 @@ class ManualPageBuilder(Builder):
pass
def default_man_pages(config):
# type: (Config) -> List[Tuple[str, str, str, List[str], int]]
""" Better default man_pages settings. """
filename = make_filename_from_project(config.project)
return [(config.master_doc, filename, '%s %s' % (config.project, config.release),
[config.author], 1)]
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.add_builder(ManualPageBuilder)
app.add_config_value('man_pages',
lambda self: [(self.master_doc, make_filename(self.project).lower(),
'%s %s' % (self.project, self.release), [], 1)],
None)
app.add_config_value('man_pages', default_man_pages, None)
app.add_config_value('man_show_urls', False, None)
return {

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.qthelp
~~~~~~~~~~~~~~~~~~~~~~
@@ -9,24 +8,23 @@
:license: BSD, see LICENSE for details.
"""
import codecs
import html
import os
import posixpath
import re
from os import path
from typing import Iterable, cast
from docutils import nodes
from six import text_type
from sphinx import addnodes
from sphinx import package_dir
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.config import string_classes
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.locale import __
from sphinx.util import force_decode, logging
from sphinx.util import logging
from sphinx.util.nodes import NodeMatcher
from sphinx.util.osutil import make_filename
from sphinx.util.pycompat import htmlescape
from sphinx.util.template import SphinxRenderer
if False:
@@ -46,7 +44,7 @@ section_template = '<section title="%(title)s" ref="%(ref)s"/>'
def render_file(filename, **kwargs):
# type: (unicode, Any) -> unicode
# type: (str, Any) -> str
pathname = os.path.join(package_dir, 'templates', 'qthelp', filename)
return SphinxRenderer.render_from_file(pathname, kwargs)
@@ -80,14 +78,14 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
def init(self):
# type: () -> None
StandaloneHTMLBuilder.init(self)
super().init()
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.link_suffix = '.html'
# self.config.html_style = 'traditional.css'
def get_theme_config(self):
# type: () -> Tuple[unicode, Dict]
# type: () -> Tuple[str, Dict]
return self.config.qthelp_theme, self.config.qthelp_theme_options
def handle_finish(self):
@@ -95,34 +93,23 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
self.build_qhp(self.outdir, self.config.qthelp_basename)
def build_qhp(self, outdir, outname):
# type: (unicode, unicode) -> None
# type: (str, str) -> None
logger.info(__('writing project file...'))
# sections
tocdoc = self.env.get_and_resolve_doctree(self.config.master_doc, self,
prune_toctrees=False)
def istoctree(node):
# type: (nodes.Node) -> bool
return isinstance(node, addnodes.compact_paragraph) and \
'toctree' in node
sections = []
for node in tocdoc.traverse(istoctree):
matcher = NodeMatcher(addnodes.compact_paragraph, toctree=True)
for node in tocdoc.traverse(matcher): # type: addnodes.compact_paragraph
sections.extend(self.write_toc(node))
for indexname, indexcls, content, collapse in self.domain_indices:
item = section_template % {'title': indexcls.localname,
'ref': '%s.html' % indexname}
sections.append(' ' * 4 * 4 + item)
# sections may be unicode strings or byte strings, we have to make sure
# they are all unicode strings before joining them
new_sections = []
for section in sections:
if not isinstance(section, text_type):
new_sections.append(force_decode(section, None))
else:
new_sections.append(section)
sections = u'\n'.join(new_sections) # type: ignore
sections = '\n'.join(sections) # type: ignore
# keywords
keywords = []
@@ -130,7 +117,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
for (key, group) in index:
for title, (refs, subitems, key_) in group:
keywords.extend(self.build_keywords(title, refs, subitems))
keywords = u'\n'.join(keywords) # type: ignore
keywords = '\n'.join(keywords) # type: ignore
# it seems that the "namespace" may not contain non-alphanumeric
# characters, and more than one successive dot, or leading/trailing
@@ -145,7 +132,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
nspace = nspace.lower()
# write the project file
with codecs.open(path.join(outdir, outname + '.qhp'), 'w', 'utf-8') as f: # type: ignore # NOQA
with open(path.join(outdir, outname + '.qhp'), 'w', encoding='utf-8') as f:
body = render_file('project.qhp', outname=outname,
title=self.config.html_title, version=self.config.version,
project=self.config.project, namespace=nspace,
@@ -159,7 +146,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
startpage = 'qthelp://' + posixpath.join(nspace, 'doc', 'index.html')
logger.info(__('writing collection project file...'))
with codecs.open(path.join(outdir, outname + '.qhcp'), 'w', 'utf-8') as f: # type: ignore # NOQA
with open(path.join(outdir, outname + '.qhcp'), 'w', encoding='utf-8') as f:
body = render_file('project.qhcp', outname=outname,
title=self.config.html_short_title,
homepage=homepage, startpage=startpage)
@@ -171,37 +158,40 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
return False
if len(node.children) != 2:
return False
if not isinstance(node.children[0], addnodes.compact_paragraph):
if not isinstance(node[0], addnodes.compact_paragraph):
return False
if not isinstance(node.children[0][0], nodes.reference):
if not isinstance(node[0][0], nodes.reference):
return False
if not isinstance(node.children[1], nodes.bullet_list):
if not isinstance(node[1], nodes.bullet_list):
return False
return True
def write_toc(self, node, indentlevel=4):
# type: (nodes.Node, int) -> List[unicode]
# XXX this should return a Unicode string, not a bytestring
parts = [] # type: List[unicode]
if self.isdocnode(node):
refnode = node.children[0][0]
link = refnode['refuri']
title = htmlescape(refnode.astext()).replace('"', '&quot;')
# type: (nodes.Node, int) -> List[str]
parts = [] # type: List[str]
if isinstance(node, nodes.list_item) and self.isdocnode(node):
compact_paragraph = cast(addnodes.compact_paragraph, node[0])
reference = cast(nodes.reference, compact_paragraph[0])
link = reference['refuri']
title = html.escape(reference.astext()).replace('"', '&quot;')
item = '<section title="%(title)s" ref="%(ref)s">' % \
{'title': title, 'ref': link}
parts.append(' ' * 4 * indentlevel + item)
for subnode in node.children[1]:
parts.extend(self.write_toc(subnode, indentlevel + 1))
bullet_list = cast(nodes.bullet_list, node[1])
list_items = cast(Iterable[nodes.list_item], bullet_list)
for list_item in list_items:
parts.extend(self.write_toc(list_item, indentlevel + 1))
parts.append(' ' * 4 * indentlevel + '</section>')
elif isinstance(node, nodes.list_item):
for subnode in node:
parts.extend(self.write_toc(subnode, indentlevel))
elif isinstance(node, nodes.reference):
link = node['refuri']
title = htmlescape(node.astext()).replace('"', '&quot;')
title = html.escape(node.astext()).replace('"', '&quot;')
item = section_template % {'title': title, 'ref': link}
item = u' ' * 4 * indentlevel + item
parts.append(item.encode('ascii', 'xmlcharrefreplace'))
item = ' ' * 4 * indentlevel + item
parts.append(item.encode('ascii', 'xmlcharrefreplace').decode())
elif isinstance(node, nodes.bullet_list):
for subnode in node:
parts.extend(self.write_toc(subnode, indentlevel))
@@ -212,8 +202,8 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
return parts
def keyword_item(self, name, ref):
# type: (unicode, Any) -> unicode
matchobj = _idpattern.match(name) # type: ignore
# type: (str, Any) -> str
matchobj = _idpattern.match(name)
if matchobj:
groupdict = matchobj.groupdict()
shortname = groupdict['title']
@@ -225,8 +215,8 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
else:
id = None
nameattr = htmlescape(name, quote=True)
refattr = htmlescape(ref[1], quote=True)
nameattr = html.escape(name, quote=True)
refattr = html.escape(ref[1], quote=True)
if id:
item = ' ' * 12 + '<keyword name="%s" id="%s" ref="%s"/>' % (nameattr, id, refattr)
else:
@@ -235,8 +225,8 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
return item
def build_keywords(self, title, refs, subitems):
# type: (unicode, List[Any], Any) -> List[unicode]
keywords = [] # type: List[unicode]
# type: (str, List[Any], Any) -> List[str]
keywords = [] # type: List[str]
# if len(refs) == 0: # XXX
# write_param('See Also', title)
@@ -258,7 +248,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
return keywords
def get_project_files(self, outdir):
# type: (unicode) -> List[unicode]
# type: (str) -> List[str]
if not outdir.endswith(os.sep):
outdir += os.sep
olen = len(outdir)
@@ -269,19 +259,19 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
resourcedir = root.startswith((staticdir, imagesdir))
for fn in sorted(files):
if (resourcedir and not fn.endswith('.js')) or fn.endswith('.html'):
filename = posixpath.join(root, fn)[olen:]
filename = path.join(root, fn)[olen:]
project_files.append(filename)
return project_files
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# type: (Sphinx) -> Dict[str, Any]
app.setup_extension('sphinx.builders.html')
app.add_builder(QtHelpBuilder)
app.add_config_value('qthelp_basename', lambda self: make_filename(self.project), None)
app.add_config_value('qthelp_namespace', None, 'html', string_classes)
app.add_config_value('qthelp_namespace', None, 'html', [str])
app.add_config_value('qthelp_theme', 'nonav', 'html')
app.add_config_value('qthelp_theme_options', {}, 'html')

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