Merge branch 'master' into 5216-update-markdown-doc
@@ -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
|
||||
|
||||
@@ -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
@@ -29,3 +29,5 @@ doc/locale/
|
||||
tests/.coverage
|
||||
tests/build/
|
||||
utils/regression_test.js
|
||||
|
||||
node_modules/
|
||||
|
||||
28
.travis.yml
@@ -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
|
||||
|
||||
4
AUTHORS
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
2
Makefile
@@ -57,7 +57,7 @@ style-check:
|
||||
|
||||
.PHONY: type-check
|
||||
type-check:
|
||||
mypy sphinx/
|
||||
mypy sphinx
|
||||
|
||||
.PHONY: pylint
|
||||
pylint:
|
||||
|
||||
@@ -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/
|
||||
|
||||
2
doc/_static/conf.py.txt
vendored
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# test documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Jun 26 00:00:43 2016.
|
||||
#
|
||||
|
||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
24
doc/conf.py
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
9
doc/extdev/projectapi.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
.. _project-api:
|
||||
|
||||
Project API
|
||||
===========
|
||||
|
||||
.. currentmodule:: sphinx.project
|
||||
|
||||
.. autoclass:: Project
|
||||
:members:
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
319
doc/theming.rst
@@ -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/
|
||||
|
||||
@@ -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/
|
||||
@@ -65,7 +65,7 @@ The WebSupport Class
|
||||
|
||||
|
||||
Methods
|
||||
~~~~~~~
|
||||
-------
|
||||
|
||||
.. automethod:: sphinxcontrib.websupport.WebSupport.build
|
||||
|
||||
@@ -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
|
||||
@@ -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',
|
||||
@@ -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
|
||||
|
||||
@@ -27,8 +27,8 @@ documentation of the :class:`StorageBackend` class below.
|
||||
sphinx.websupport.storage.
|
||||
|
||||
|
||||
StorageBackend Methods
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. automethod:: StorageBackend.pre_build
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
-----------------------
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
-------------
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -54,7 +54,7 @@ It adds this directive:
|
||||
E D F
|
||||
"""
|
||||
|
||||
class A(object):
|
||||
class A:
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
|
||||
@@ -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
|
||||
------------------------------------------------------
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
-------------
|
||||
|
||||
@@ -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>`
|
||||
|
||||
@@ -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
|
||||
---------------------------
|
||||
|
||||
@@ -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
|
||||
------------
|
||||
|
||||
@@ -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
@@ -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
@@ -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
20
package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
43
setup.py
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:]))
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
@@ -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).
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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('"', '"')
|
||||
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('&', '&')
|
||||
@@ -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)
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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'))
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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('"', '"')
|
||||
title = html.escape(node.astext()).replace('"', '"')
|
||||
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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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('"', '"')
|
||||
# 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('"', '"')
|
||||
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('"', '"')
|
||||
title = html.escape(node.astext()).replace('"', '"')
|
||||
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')
|
||||
|
||||
|
||||