Merge remote-tracking branch 'upstream/2.0' into propogate_citeref_classes
@ -5,8 +5,6 @@ environment:
|
|||||||
PYTHONWARNINGS: all
|
PYTHONWARNINGS: all
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
- PYTHON: 27
|
|
||||||
TEST_IGNORE: --ignore py35
|
|
||||||
- PYTHON: 37
|
- PYTHON: 37
|
||||||
- PYTHON: 37-x64
|
- PYTHON: 37-x64
|
||||||
|
|
||||||
@ -37,7 +35,7 @@ test_script:
|
|||||||
if (-not $tests) { $tests = '' }
|
if (-not $tests) { $tests = '' }
|
||||||
& "C:\Python$($env:PYTHON)\python.exe" -m pytest $test_ignore.Split(' ') --junitxml .junit.xml $tests.Split(' ')
|
& "C:\Python$($env:PYTHON)\python.exe" -m pytest $test_ignore.Split(' ') --junitxml .junit.xml $tests.Split(' ')
|
||||||
Pop-Location
|
Pop-Location
|
||||||
if ($LastExitCode -eq 1) { Write-Host "Test Failures Occurred, leaving for test result parsing" }
|
if ($LastExitCode -eq 1) { Write-Host "Test Failures Occurred, leaving for test result parsing"; exit $LastExitCode }
|
||||||
elseif ($LastExitCode -ne 0) { Write-Host "Other Error Occurred, aborting"; exit $LastExitCode }
|
elseif ($LastExitCode -ne 0) { Write-Host "Other Error Occurred, aborting"; exit $LastExitCode }
|
||||||
|
|
||||||
after_test:
|
after_test:
|
||||||
|
35
.github/ISSUE_TEMPLATE.md
vendored
@ -1,35 +0,0 @@
|
|||||||
Subject: <what happen when you do on which document project>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Important: This is a list of issues for Sphinx, not a forum.
|
|
||||||
If you'd like to post a question, please move to sphinx-users group.
|
|
||||||
https://groups.google.com/forum/#!forum/sphinx-users
|
|
||||||
|
|
||||||
Thanks,
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Problem
|
|
||||||
- <Detail of problem>
|
|
||||||
|
|
||||||
#### Procedure to reproduce the problem
|
|
||||||
```
|
|
||||||
<Paste your command-line here which cause the problem>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Error logs / results
|
|
||||||
```
|
|
||||||
<Paste your error log here>
|
|
||||||
```
|
|
||||||
- <public link of unexpected result if you have>
|
|
||||||
|
|
||||||
#### Expected results
|
|
||||||
<Describe what to actually do>
|
|
||||||
|
|
||||||
### Reproducible project / your project
|
|
||||||
- <link to your project, or attach zipped small project sample>
|
|
||||||
|
|
||||||
### Environment info
|
|
||||||
- OS: <Unix/Linux/Mac/Win/other with version>
|
|
||||||
- Python version:
|
|
||||||
- Sphinx version:
|
|
||||||
- <Extra tools e.g.: Browser, tex or something else>
|
|
46
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: '<what happen when you do on which document project>'
|
||||||
|
labels: 'bug'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
```
|
||||||
|
<Paste your command-line here which cause the problem>
|
||||||
|
|
||||||
|
$ git clone htps://github.com/.../some_project
|
||||||
|
$ cd some_project
|
||||||
|
$ pip install -r requirements.txt
|
||||||
|
$ cd docs
|
||||||
|
$ make html SPHINXOPTS="-D language=de"
|
||||||
|
$ # open _build/html/index and see bla bla
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Your project**
|
||||||
|
Link to your sphinx project, or attach zipped small project sample.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Environment info**
|
||||||
|
- OS: [e.g. Unix/Linux/Mac/Win/other with version]
|
||||||
|
- Python version: [e.g. 3.7.1]
|
||||||
|
- Sphinx version: [e.g. 1.8.2]
|
||||||
|
- Sphinx extensions: [e.g. sphinx.ext.autodoc, recommonmark]
|
||||||
|
- Extra tools: [e.g. Browser, tex or something else]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
|
|
||||||
|
- [e.g. URL or Ticket]
|
||||||
|
|
23
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: '<short description for the feature>'
|
||||||
|
labels: 'enhancement'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
|
|
||||||
|
- [e.g. URL or Ticket]
|
||||||
|
|
17
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: Question
|
||||||
|
about: For Q&A purpose, please use https://groups.google.com/forum/#!forum/sphinx-users
|
||||||
|
title: For Q&A purpose, please use sphinx-users group
|
||||||
|
labels: 'question'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Important
|
||||||
|
|
||||||
|
This is a list of issues for Sphinx, **not a forum**.
|
||||||
|
If you'd like to post a question, please move to sphinx-users group.
|
||||||
|
https://groups.google.com/forum/#!forum/sphinx-users
|
||||||
|
|
||||||
|
Thanks,
|
||||||
|
|
30
.travis.yml
@ -1,6 +1,6 @@
|
|||||||
language: python
|
language: python
|
||||||
sudo: false
|
sudo: false
|
||||||
dist: trusty
|
dist: xenial
|
||||||
cache: pip
|
cache: pip
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@ -11,42 +11,30 @@ env:
|
|||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- python: 'pypy'
|
|
||||||
env: TOXENV=pypy
|
|
||||||
- python: '2.7'
|
|
||||||
env:
|
|
||||||
- TOXENV=du13
|
|
||||||
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
|
|
||||||
- python: '3.4'
|
|
||||||
env: TOXENV=py34
|
|
||||||
- python: '3.5'
|
- python: '3.5'
|
||||||
env: TOXENV=py35
|
env:
|
||||||
|
- TOXENV=du12
|
||||||
- python: '3.6'
|
- python: '3.6'
|
||||||
env:
|
env:
|
||||||
- TOXENV=py36
|
- TOXENV=du13
|
||||||
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
|
|
||||||
- python: '3.7'
|
- python: '3.7'
|
||||||
env: TOXENV=py37
|
env:
|
||||||
dist: xenial
|
- TOXENV=py37
|
||||||
sudo: true
|
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
|
||||||
- python: 'nightly'
|
- python: 'nightly'
|
||||||
env: TOXENV=py38
|
env: TOXENV=py38
|
||||||
dist: xenial
|
|
||||||
sudo: true
|
|
||||||
- python: '3.6'
|
- python: '3.6'
|
||||||
env: TOXENV=docs
|
env: TOXENV=docs
|
||||||
- python: '3.6'
|
- python: '3.6'
|
||||||
env: TOXENV=mypy
|
env: TOXENV=mypy
|
||||||
- python: '2.7'
|
- python: '3.6'
|
||||||
env: TOXENV=flake8
|
env: TOXENV=flake8
|
||||||
|
|
||||||
- language: node_js
|
- language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- 10.7
|
- 10.7
|
||||||
env: IS_PYTHON=false
|
env: IS_PYTHON=false
|
||||||
before_script:
|
services: xvfb
|
||||||
- export DISPLAY=:99.0
|
|
||||||
- sh -e /etc/init.d/xvfb start
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- if [ $IS_PYTHON = true ]; then pip install -U tox codecov; fi
|
- if [ $IS_PYTHON = true ]; then pip install -U tox codecov; fi
|
||||||
|
4
AUTHORS
@ -38,6 +38,7 @@ Other contributors, listed alphabetically, are:
|
|||||||
* Zac Hatfield-Dodds -- doctest reporting improvements
|
* Zac Hatfield-Dodds -- doctest reporting improvements
|
||||||
* Doug Hellmann -- graphviz improvements
|
* Doug Hellmann -- graphviz improvements
|
||||||
* Tim Hoffmann -- theme improvements
|
* Tim Hoffmann -- theme improvements
|
||||||
|
* Antti Kaihola -- doctest extension (skipif option)
|
||||||
* Dave Kuhlman -- original LaTeX writer
|
* Dave Kuhlman -- original LaTeX writer
|
||||||
* Blaise Laflamme -- pyramid theme
|
* Blaise Laflamme -- pyramid theme
|
||||||
* Chris Lamb -- reproducibility fixes
|
* Chris Lamb -- reproducibility fixes
|
||||||
@ -56,6 +57,7 @@ Other contributors, listed alphabetically, are:
|
|||||||
* Ezio Melotti -- collapsible sidebar JavaScript
|
* Ezio Melotti -- collapsible sidebar JavaScript
|
||||||
* Bruce Mitchener -- Minor epub improvement
|
* Bruce Mitchener -- Minor epub improvement
|
||||||
* Daniel Neuhäuser -- JavaScript domain, Python 3 support (GSOC)
|
* Daniel Neuhäuser -- JavaScript domain, Python 3 support (GSOC)
|
||||||
|
* Julien Palard -- Colspan and rowspan in text builder
|
||||||
* Christopher Perkins -- autosummary integration
|
* Christopher Perkins -- autosummary integration
|
||||||
* Benjamin Peterson -- unittests
|
* Benjamin Peterson -- unittests
|
||||||
* \T. Powers -- HTML output improvements
|
* \T. Powers -- HTML output improvements
|
||||||
@ -67,6 +69,7 @@ Other contributors, listed alphabetically, are:
|
|||||||
* Antonio Valentino -- qthelp builder, docstring inheritance
|
* Antonio Valentino -- qthelp builder, docstring inheritance
|
||||||
* Filip Vavera -- napoleon todo directive
|
* Filip Vavera -- napoleon todo directive
|
||||||
* Pauli Virtanen -- autodoc improvements, autosummary extension
|
* Pauli Virtanen -- autodoc improvements, autosummary extension
|
||||||
|
* Eric N. Vander Weele -- autodoc improvements
|
||||||
* Stefan van der Walt -- autosummary extension
|
* Stefan van der Walt -- autosummary extension
|
||||||
* Thomas Waldmann -- apidoc module fixes
|
* Thomas Waldmann -- apidoc module fixes
|
||||||
* John Waltman -- Texinfo builder
|
* John Waltman -- Texinfo builder
|
||||||
@ -78,6 +81,7 @@ Other contributors, listed alphabetically, are:
|
|||||||
* Hong Xu -- svg support in imgmath extension and various bug fixes
|
* Hong Xu -- svg support in imgmath extension and various bug fixes
|
||||||
* Stephen Finucane -- setup command improvements and documentation
|
* Stephen Finucane -- setup command improvements and documentation
|
||||||
* Daniel Pizetta -- inheritance diagram improvements
|
* Daniel Pizetta -- inheritance diagram improvements
|
||||||
|
* KINEBUCHI Tomohiko -- typing Sphinx as well as docutils
|
||||||
|
|
||||||
Many thanks for all contributions!
|
Many thanks for all contributions!
|
||||||
|
|
||||||
|
276
CHANGES
@ -1,3 +1,276 @@
|
|||||||
|
Release 2.0.0 beta2 (in development)
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* texinfo: image files are copied into ``name-figure`` directory
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #6096: html: Anchor links are not added to figures
|
||||||
|
* #3620: html: Defer searchindex.js rather than loading it via ajax
|
||||||
|
* #6113: html: Table cells and list items have large margins
|
||||||
|
* #5508: ``linenothreshold`` option for ``highlight`` directive was ignored
|
||||||
|
* texinfo: ``make install-info`` causes syntax error
|
||||||
|
* texinfo: ``make install-info`` fails on macOS
|
||||||
|
* #3079: texinfo: image files are not copied on ``make install-info``
|
||||||
|
* #5391: A cross reference in heading is rendered as literal
|
||||||
|
* #5946: C++, fix ``cpp:alias`` problems in LaTeX (and singlehtml)
|
||||||
|
|
||||||
|
Testing
|
||||||
|
--------
|
||||||
|
|
||||||
|
Release 2.0.0 beta1 (in development)
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
* 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
|
||||||
|
* The six package is no longer a dependency
|
||||||
|
* The sphinxcontrib-websupport package is no longer a dependency
|
||||||
|
* Some packages are separated to sub packages:
|
||||||
|
|
||||||
|
- sphinxcontrib.applehelp
|
||||||
|
- sphinxcontrib.devhelp
|
||||||
|
- sphinxcontrib.htmlhelp
|
||||||
|
- sphinxcontrib.jsmath
|
||||||
|
- sphinxcontrib.serializinghtml
|
||||||
|
- sphinxcontrib.qthelp
|
||||||
|
|
||||||
|
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`.
|
||||||
|
* quickstart: Simplify generated ``conf.py``
|
||||||
|
* #4148: quickstart: some questions are removed. They are still able to specify
|
||||||
|
via command line options
|
||||||
|
* websupport: unbundled from sphinx core. Please use sphinxcontrib-websupport
|
||||||
|
* C++, the visibility of base classes is now always rendered as present in the
|
||||||
|
input. That is, ``private`` is now shown, where it was ellided before.
|
||||||
|
* LaTeX: graphics inclusion of oversized images rescales to not exceed
|
||||||
|
the text width and height, even if width and/or height option were used.
|
||||||
|
(refs: #5956)
|
||||||
|
* epub: ``epub_title`` defaults to the :confval:`project` option
|
||||||
|
* #4550: All tables and figures without ``align`` option are displayed to center
|
||||||
|
* #4587: html: Output HTML5 by default
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
* Support for evaluating Python 2 syntax is deprecated. This includes
|
||||||
|
configuration files which should be converted to Python 3.
|
||||||
|
* The arguments of ``EpubBuilder.build_mimetype()``,
|
||||||
|
``EpubBuilder.build_container()``, ``EpubBuilder.bulid_content()``,
|
||||||
|
``EpubBuilder.build_toc()`` and ``EpubBuilder.build_epub()``
|
||||||
|
* The arguments of ``Epub3Builder.build_navigation_doc()``
|
||||||
|
* The config variables
|
||||||
|
|
||||||
|
- :confval:`html_experimental_html5_writer`
|
||||||
|
|
||||||
|
* 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.builders.epub3.Epub3Builder.validate_config_value()``
|
||||||
|
* ``sphinx.builders.html.SingleFileHTMLBuilder``
|
||||||
|
* ``sphinx.builders.htmlhelp.HTMLHelpBuilder.open_file()``
|
||||||
|
* ``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.roles.abbr_role()``
|
||||||
|
* ``sphinx.roles.emph_literal_role()``
|
||||||
|
* ``sphinx.roles.menusel_role()``
|
||||||
|
* ``sphinx.roles.index_role()``
|
||||||
|
* ``sphinx.roles.indexmarkup_role()``
|
||||||
|
* ``sphinx.testing.util.remove_unicode_literal()``
|
||||||
|
* ``sphinx.util.attrdict``
|
||||||
|
* ``sphinx.util.force_decode()``
|
||||||
|
* ``sphinx.util.get_matching_docs()``
|
||||||
|
* ``sphinx.util.inspect.Parameter``
|
||||||
|
* ``sphinx.util.jsonimpl``
|
||||||
|
* ``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.NoneType``
|
||||||
|
* ``sphinx.util.pycompat.TextIOWrapper``
|
||||||
|
* ``sphinx.util.pycompat.UnicodeMixin``
|
||||||
|
* ``sphinx.util.pycompat.htmlescape``
|
||||||
|
* ``sphinx.util.pycompat.indent``
|
||||||
|
* ``sphinx.util.pycompat.sys_encoding``
|
||||||
|
* ``sphinx.util.pycompat.terminal_safe()``
|
||||||
|
* ``sphinx.util.pycompat.u``
|
||||||
|
* ``sphinx.writers.latex.ExtBabel``
|
||||||
|
* ``sphinx.writers.latex.LaTeXTranslator._make_visit_admonition()``
|
||||||
|
* ``sphinx.writers.latex.LaTeXTranslator.babel_defmacro()``
|
||||||
|
* ``sphinx.writers.latex.LaTeXTranslator.collect_footnotes()``
|
||||||
|
* ``sphinx.writers.latex.LaTeXTranslator.generate_numfig_format()``
|
||||||
|
* ``sphinx.writers.texinfo.TexinfoTranslator._make_visit_admonition()``
|
||||||
|
* ``sphinx.writers.text.TextTranslator._make_depart_admonition()``
|
||||||
|
* template variables for LaTeX template
|
||||||
|
|
||||||
|
- ``logo``
|
||||||
|
- ``numfig_format``
|
||||||
|
- ``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``
|
||||||
|
* #5394: autodoc: Display readable names in type annotations for mocked objects
|
||||||
|
* #5459: autodoc: :confval:`autodoc_default_options` accepts ``True`` as a value
|
||||||
|
* #1148: autodoc: Add :rst:dir:`autodecorator` directive for decorators
|
||||||
|
* #5635: autosummary: Add :confval:`autosummary_mock_imports` to mock external
|
||||||
|
libraries on importing targets
|
||||||
|
* #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)
|
||||||
|
* #5660: The ``versionadded``, ``versionchanged`` and ``deprecated`` directives
|
||||||
|
are now generated with their own specific CSS classes
|
||||||
|
(``added``, ``changed`` and ``deprecated``, respectively) in addition to the
|
||||||
|
generic ``versionmodified`` class.
|
||||||
|
* #5841: apidoc: Add --extensions option to sphinx-apidoc
|
||||||
|
* #4981: C++, added an alias directive for inserting lists of declarations,
|
||||||
|
that references existing declarations (e.g., for making a synopsis).
|
||||||
|
* C++: add ``cpp:struct`` to complement ``cpp:class``.
|
||||||
|
* #1341 the HTML search considers words that contain a search term of length
|
||||||
|
three or longer a match.
|
||||||
|
* #4611: epub: Show warning for duplicated ToC entries
|
||||||
|
* #1851: Allow to omit an argument for :rst:dir:`code-block` directive. If
|
||||||
|
omitted, it follows :rst:dir:`highlight` or :confval:`highlight_language`
|
||||||
|
* #4587: html: Add :confval:`html4_writer` to use old HTML4 writer
|
||||||
|
* #6016: HTML search: A placeholder for the search summary prevents search
|
||||||
|
result links from changing their position when the search terminates. This
|
||||||
|
makes navigating search results easier.
|
||||||
|
* #5196: linkcheck also checks remote images exist
|
||||||
|
* #5924: githubpages: create CNAME file for custom domains when
|
||||||
|
:confval:`html_baseurl` set
|
||||||
|
* #4261: autosectionlabel: restrict the labeled sections by new config value;
|
||||||
|
:confval:`autosectionlabel_maxdepth`
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
* LaTeX: project name is not escaped if :confval:`latex_documents` omitted
|
||||||
|
* LaTeX: authors are not shown if :confval:`latex_documents` omitted
|
||||||
|
* HTML: Invalid HTML5 file is generated for a glossary having multiple terms for
|
||||||
|
one description (refs: #4611)
|
||||||
|
* QtHelp: OS dependent path separator is used in .qhp file
|
||||||
|
* HTML search: search always returns nothing when multiple search terms are
|
||||||
|
used and one term is shorter than three characters
|
||||||
|
|
||||||
|
Testing
|
||||||
|
--------
|
||||||
|
|
||||||
|
* Stop to use ``SPHINX_TEST_TEMPDIR`` envvar
|
||||||
|
|
||||||
Release 1.8.5 (in development)
|
Release 1.8.5 (in development)
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
@ -51,6 +324,7 @@ Bugs fixed
|
|||||||
in an admonition
|
in an admonition
|
||||||
* #5231: "make html" does not read and build "po" files in "locale" dir
|
* #5231: "make html" does not read and build "po" files in "locale" dir
|
||||||
* #5954: ``:scale:`` image option may break PDF build if image in an admonition
|
* #5954: ``:scale:`` image option may break PDF build if image in an admonition
|
||||||
|
* #5966: mathjax has not been loaded on incremental build
|
||||||
* #5960: LaTeX: modified PDF layout since September 2018 TeXLive update of
|
* #5960: LaTeX: modified PDF layout since September 2018 TeXLive update of
|
||||||
:file:`parskip.sty`
|
:file:`parskip.sty`
|
||||||
* #5948: LaTeX: duplicated labels are generated for sections
|
* #5948: LaTeX: duplicated labels are generated for sections
|
||||||
@ -2179,7 +2453,7 @@ Incompatible changes
|
|||||||
parsing is attempted to distinguish valid code. To get the old behavior back,
|
parsing is attempted to distinguish valid code. To get the old behavior back,
|
||||||
add ``highlight_language = "python"`` to conf.py.
|
add ``highlight_language = "python"`` to conf.py.
|
||||||
* `Locale Date Markup Language
|
* `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`.
|
``"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
|
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.
|
compatibility until Sphinx-1.5. Later format will be disabled from Sphinx-1.5.
|
||||||
|
@ -61,8 +61,8 @@ of the core developers before it is merged into the main repository.
|
|||||||
#. If you feel uncomfortable or uncertain about an issue or your changes, feel
|
#. If you feel uncomfortable or uncertain about an issue or your changes, feel
|
||||||
free to email the *sphinx-dev* mailing list.
|
free to email the *sphinx-dev* mailing list.
|
||||||
#. Fork `the repository`_ on GitHub to start making your changes to the
|
#. Fork `the repository`_ on GitHub to start making your changes to the
|
||||||
``master`` branch for next major version, or ``X.Y`` branch for next
|
``master`` branch for next MAJOR version, or ``X.Y`` branch for next
|
||||||
minor version (see `Branch Model`_).
|
MINOR version (see `Branch Model`_).
|
||||||
#. Write a test which shows that the bug was fixed or that the feature works
|
#. Write a test which shows that the bug was fixed or that the feature works
|
||||||
as expected.
|
as expected.
|
||||||
#. Send a pull request and bug the maintainer until it gets merged and
|
#. Send a pull request and bug the maintainer until it gets merged and
|
||||||
@ -91,14 +91,19 @@ These are the basic steps needed to start developing on Sphinx.
|
|||||||
|
|
||||||
#. Checkout the appropriate branch.
|
#. Checkout the appropriate branch.
|
||||||
|
|
||||||
For changes that should be included in the next minor release (namely bug
|
Sphinx adopts Semantic Versioning 2.0.0 (refs: https://semver.org/ ).
|
||||||
fixes), use the ``X.Y`` branch. ::
|
|
||||||
|
For changes that preserves backwards-compatibility of API and features,
|
||||||
|
they should be included in the next MINOR release, use the ``X.Y`` branch.
|
||||||
|
::
|
||||||
|
|
||||||
git checkout X.Y
|
git checkout X.Y
|
||||||
|
|
||||||
For new features or other substantial changes that should wait until the
|
For incompatible or other substantial changes that should wait until the
|
||||||
next major release, use the ``master`` branch (see `Branch Model`_ for
|
next MAJOR release, use the ``master`` branch.
|
||||||
detail).
|
|
||||||
|
For urgent release, a new PATCH branch must be branched from the newest
|
||||||
|
release tag (see `Branch Model`_ for detail).
|
||||||
|
|
||||||
#. Setup a virtual environment.
|
#. Setup a virtual environment.
|
||||||
|
|
||||||
@ -272,10 +277,7 @@ Coding Guide
|
|||||||
generated output.
|
generated output.
|
||||||
|
|
||||||
* When adding a new configuration variable, be sure to document it and update
|
* When adding a new configuration variable, be sure to document it and update
|
||||||
:file:`sphinx/quickstart.py` if it's important enough.
|
:file:`sphinx/cmd/quickstart.py` if it's important enough.
|
||||||
|
|
||||||
* Use the included :program:`utils/check_sources.py` script to check for
|
|
||||||
common formatting issues (trailing whitespace, lengthy lines, etc).
|
|
||||||
|
|
||||||
* Add appropriate unit tests.
|
* Add appropriate unit tests.
|
||||||
|
|
||||||
@ -315,18 +317,32 @@ Debugging Tips
|
|||||||
Branch Model
|
Branch Model
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Sphinx project uses following branches for developing.
|
Sphinx project uses following branches for developing that conforms to Semantic
|
||||||
|
Versioning 2.0.0 (refs: https://semver.org/ ).
|
||||||
|
|
||||||
``master``
|
``master``
|
||||||
Used for main development. All improvement and refactoring, bug fixes
|
Development for MAJOR version.
|
||||||
are allowed.
|
All changes including incompatible behaviors and public API updates are
|
||||||
|
allowed.
|
||||||
|
|
||||||
``X.Y``
|
``X.Y``
|
||||||
Where ``X.Y`` is the ``MAJOR.MINOR`` release. Used to maintain current
|
Where ``X.Y`` is the ``MAJOR.MINOR`` release. Used to maintain current
|
||||||
stable release. Only bug fixes and stable changes are allowed. Only the
|
MINOR release. All changes are allowed if the change preserves
|
||||||
most recent stable release is currently retained. When a new version is
|
backwards-compatibility of API and features.
|
||||||
released, the old release branch will be deleted and replaced by an
|
|
||||||
equivalent tag.
|
Only the most recent ``MAJOR.MINOR`` branch is currently retained. When a
|
||||||
|
new MAJOR version is released, the old ``MAJOR.MINOR`` branch will be
|
||||||
|
deleted and replaced by an equivalent tag.
|
||||||
|
|
||||||
|
``X.Y.Z``
|
||||||
|
Where ``X.Y.Z`` is the ``MAJOR.MINOR.PATCH`` release. Only
|
||||||
|
backwards-compatible bug fixes are allowed. In Sphinx project, PATCH
|
||||||
|
version is used for urgent bug fix.
|
||||||
|
|
||||||
|
``MAJOR.MINOR.PATCH`` branch will be branched from the ``v`` prefixed
|
||||||
|
release tag (ex. make 2.3.1 that branched from v2.3.0) when a urgent
|
||||||
|
release is needed. When new PATCH version is released, the branch will be
|
||||||
|
deleted and replaced by an equivalent tag (ex. v2.3.1).
|
||||||
|
|
||||||
|
|
||||||
Deprecating a feature
|
Deprecating a feature
|
||||||
@ -359,23 +375,22 @@ silence any warnings generated when running the tests.
|
|||||||
Deprecation policy
|
Deprecation policy
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
A feature release may deprecate certain features from previous releases. If a
|
MAJOR and MINOR releases may deprecate certain features from previous
|
||||||
feature is deprecated in feature release 1.A, it will continue to work in all
|
releases. If a feature is deprecated in a release A.x, it will continue to
|
||||||
1.A.x versions (for all versions of x) but raise warnings. Deprecated features
|
work in all A.x.x versions (for all versions of x). It will continue to work
|
||||||
will be removed in the first 1.B release, or 1.B.1 for features deprecated in
|
in all B.x.x versions but raise deprecation warnings. Deprecated features
|
||||||
the last 1.A.x feature release to ensure deprecations are done over at least 2
|
will be removed at the C.0.0. It means the deprecated feature will work during
|
||||||
feature releases.
|
2 MAJOR releases at least.
|
||||||
|
|
||||||
So, for example, if we decided to start the deprecation of a function in
|
So, for example, if we decided to start the deprecation of a function in
|
||||||
Sphinx 1.4:
|
Sphinx 2.x:
|
||||||
|
|
||||||
* Sphinx 1.4.x will contain a backwards-compatible replica of the function
|
* Sphinx 2.x will contain a backwards-compatible replica of the function
|
||||||
which will raise a ``RemovedInSphinx16Warning``.
|
which will raise a ``RemovedInSphinx40Warning``.
|
||||||
|
|
||||||
* Sphinx 1.5 (the version that follows 1.4) will still contain the
|
* Sphinx 3.x will still contain the backwards-compatible replica.
|
||||||
backwards-compatible replica.
|
|
||||||
|
|
||||||
* Sphinx 1.6 will remove the feature outright.
|
* Sphinx 4.0 will remove the feature outright.
|
||||||
|
|
||||||
The warnings are displayed by default. You can turn off display of these
|
The warnings are displayed by default. You can turn off display of these
|
||||||
warnings with:
|
warnings with:
|
||||||
|
2
Makefile
@ -57,7 +57,7 @@ style-check:
|
|||||||
|
|
||||||
.PHONY: type-check
|
.PHONY: type-check
|
||||||
type-check:
|
type-check:
|
||||||
mypy sphinx/
|
mypy sphinx
|
||||||
|
|
||||||
.PHONY: pylint
|
.PHONY: pylint
|
||||||
pylint:
|
pylint:
|
||||||
|
15
bindep.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
texlive [platform:rpm]
|
||||||
|
texlive-fncychap [platform:rpm]
|
||||||
|
texlive-titlesec [platform:rpm]
|
||||||
|
texlive-tabulary [platform:rpm]
|
||||||
|
texlive-framed [platform:rpm]
|
||||||
|
texlive-wrapfig [platform:rpm]
|
||||||
|
texlive-upquote [platform:rpm]
|
||||||
|
texlive-capt-of [platform:rpm]
|
||||||
|
texlive-needspace [platform:rpm]
|
||||||
|
texlive-polyglossia [platform:rpm]
|
||||||
|
texlive-luatex85 [platform:rpm]
|
||||||
|
texlive-anyfontsize [platform:rpm]
|
||||||
|
texlive-ctablestack [platform:rpm]
|
||||||
|
texlive-gnu-freefont [platform:rpm]
|
||||||
|
latexmk [platform:rpm]
|
2
doc/_static/conf.py.txt
vendored
@ -1,5 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# test documentation build configuration file, created by
|
# test documentation build configuration file, created by
|
||||||
# sphinx-quickstart on Sun Jun 26 00:00:43 2016.
|
# 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 |
23
doc/_themes/sphinx13/static/sphinx13.css
vendored
@ -337,7 +337,7 @@ a tt:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
font-family: 'Consolas', 'DejaVu Sans Mono',
|
font-family: 'Consolas', 'Courier New', 'DejaVu Sans Mono',
|
||||||
'Bitstream Vera Sans Mono', monospace;
|
'Bitstream Vera Sans Mono', monospace;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
letter-spacing: 0.015em;
|
letter-spacing: 0.015em;
|
||||||
@ -388,32 +388,29 @@ div.admonition, div.warning {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.admonition p, div.warning p {
|
div.admonition > p, div.warning > p {
|
||||||
margin: 0.5em 1em 0.5em 1em;
|
margin: 0.5em 1em 0.5em 1em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.admonition pre, div.warning pre {
|
div.admonition > pre, div.warning > pre {
|
||||||
margin: 0.4em 1em 0.4em 1em;
|
margin: 0.4em 1em 0.4em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.admonition p.admonition-title,
|
div.admonition > p.admonition-title,
|
||||||
div.warning p.admonition-title {
|
div.warning > p.admonition-title {
|
||||||
margin-top: 1em;
|
margin-top: 0.5em;
|
||||||
padding-top: 0.5em;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.warning {
|
div.warning {
|
||||||
border: 1px solid #940000;
|
border: 1px solid #940000;
|
||||||
/* background-color: #FFCCCF;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
div.warning p.admonition-title {
|
div.admonition > ul,
|
||||||
}
|
div.admonition > ol,
|
||||||
|
div.warning > ul,
|
||||||
div.admonition ul, div.admonition ol,
|
div.warning > ol {
|
||||||
div.warning ul, div.warning ol {
|
|
||||||
margin: 0.1em 0.5em 0.5em 3em;
|
margin: 0.1em 0.5em 0.5em 3em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
16
doc/conf.py
@ -1,5 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# Sphinx documentation build configuration file
|
# Sphinx documentation build configuration file
|
||||||
|
|
||||||
import re
|
import re
|
||||||
@ -57,10 +55,17 @@ latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation',
|
|||||||
'Georg Brandl', 'manual', 1)]
|
'Georg Brandl', 'manual', 1)]
|
||||||
latex_logo = '_static/sphinx.png'
|
latex_logo = '_static/sphinx.png'
|
||||||
latex_elements = {
|
latex_elements = {
|
||||||
|
'fontenc': r'\usepackage[LGR,X2,T1]{fontenc}',
|
||||||
'fontpkg': r'''
|
'fontpkg': r'''
|
||||||
\usepackage[sc]{mathpazo}
|
\usepackage[sc]{mathpazo}
|
||||||
\usepackage[scaled]{helvet}
|
\usepackage[scaled]{helvet}
|
||||||
\usepackage{courier}
|
\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}',
|
'passoptionstopackages': '\\PassOptionsToPackage{svgnames}{xcolor}',
|
||||||
'preamble': '\\DeclareUnicodeCharacter{229E}{\\ensuremath{\\boxplus}}',
|
'preamble': '\\DeclareUnicodeCharacter{229E}{\\ensuremath{\\boxplus}}',
|
||||||
@ -145,3 +150,10 @@ def setup(app):
|
|||||||
names=['param'], can_collapse=True)
|
names=['param'], can_collapse=True)
|
||||||
app.add_object_type('event', 'event', 'pair: %s; event', parse_event,
|
app.add_object_type('event', 'event', 'pair: %s; event', parse_event,
|
||||||
doc_field_types=[fdesc])
|
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)
|
||||||
|
@ -7,6 +7,8 @@ Sphinx documentation contents
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
intro
|
||||||
|
|
||||||
usage/installation
|
usage/installation
|
||||||
usage/quickstart
|
usage/quickstart
|
||||||
usage/restructuredtext/index
|
usage/restructuredtext/index
|
||||||
@ -14,16 +16,17 @@ Sphinx documentation contents
|
|||||||
usage/configuration
|
usage/configuration
|
||||||
usage/builders/index
|
usage/builders/index
|
||||||
usage/extensions/index
|
usage/extensions/index
|
||||||
|
usage/theming
|
||||||
|
usage/advanced/intl
|
||||||
|
usage/advanced/setuptools
|
||||||
|
usage/advanced/websupport/index
|
||||||
|
|
||||||
intro
|
|
||||||
man/index
|
man/index
|
||||||
intl
|
|
||||||
theming
|
theming
|
||||||
setuptools
|
|
||||||
templating
|
templating
|
||||||
latex
|
latex
|
||||||
extdev/index
|
extdev/index
|
||||||
websupport
|
development/tutorials/index
|
||||||
|
|
||||||
faq
|
faq
|
||||||
glossary
|
glossary
|
||||||
|
@ -100,7 +100,7 @@ This is the current list of contributed extensions in that repository:
|
|||||||
- zopeext: provide an ``autointerface`` directive for using `Zope interfaces`_
|
- zopeext: provide an ``autointerface`` directive for using `Zope interfaces`_
|
||||||
|
|
||||||
|
|
||||||
See the :ref:`extension tutorial <exttut>` on getting started with writing your
|
See the :doc:`extension tutorials <../development/tutorials/index>` on getting started with writing your
|
||||||
own extensions.
|
own extensions.
|
||||||
|
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ own extensions.
|
|||||||
.. _NumPy style: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
|
.. _NumPy style: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
|
||||||
.. _hyphenator: https://github.com/mnater/hyphenator
|
.. _hyphenator: https://github.com/mnater/hyphenator
|
||||||
.. _exceltable: https://pythonhosted.org/sphinxcontrib-exceltable/
|
.. _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
|
.. _ClearQuest: https://www.ibm.com/us-en/marketplace/rational-clearquest
|
||||||
.. _Zope interfaces: https://zopeinterface.readthedocs.io/en/latest/README.html
|
.. _Zope interfaces: https://zopeinterface.readthedocs.io/en/latest/README.html
|
||||||
.. _slideshare: https://www.slideshare.net/
|
.. _slideshare: https://www.slideshare.net/
|
||||||
|
162
doc/development/tutorials/helloworld.rst
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
Developing a "Hello world" directive
|
||||||
|
====================================
|
||||||
|
|
||||||
|
The objective of this tutorial is to create a very basic extension that adds a new
|
||||||
|
directive that outputs a paragraph containing `hello world`.
|
||||||
|
|
||||||
|
Only basic information is provided in this tutorial. For more information,
|
||||||
|
refer to the :doc:`other tutorials <index>` that go into more
|
||||||
|
details.
|
||||||
|
|
||||||
|
.. warning:: For this extension, you will need some basic understanding of docutils_
|
||||||
|
and Python.
|
||||||
|
|
||||||
|
Creating a new extension file
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Your extension file could be in any folder of your project. In our case,
|
||||||
|
let's do the following:
|
||||||
|
|
||||||
|
#. Create an :file:`_ext` folder in :file:`source`.
|
||||||
|
#. Create a new Python file in the :file:`_ext` folder called
|
||||||
|
:file:`helloworld.py`.
|
||||||
|
|
||||||
|
Here is an example of the folder structure you might obtain:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
└── source
|
||||||
|
├── _ext
|
||||||
|
│ └── helloworld.py
|
||||||
|
├── _static
|
||||||
|
├── _themes
|
||||||
|
├── conf.py
|
||||||
|
├── somefolder
|
||||||
|
├── somefile.rst
|
||||||
|
└── someotherfile.rst
|
||||||
|
|
||||||
|
Writing the extension
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Open :file:`helloworld.py` and paste the following code in it:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from docutils import nodes
|
||||||
|
from docutils.parsers.rst import Directive
|
||||||
|
|
||||||
|
|
||||||
|
class HelloWorld(Directive):
|
||||||
|
def run(self):
|
||||||
|
paragraph_node = nodes.paragraph(text='Hello World!')
|
||||||
|
return [paragraph_node]
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_directive("helloworld", HelloWorld)
|
||||||
|
|
||||||
|
|
||||||
|
Some essential things are happening in this example, and you will see them
|
||||||
|
in all directives:
|
||||||
|
|
||||||
|
.. rubric:: Directive declaration
|
||||||
|
|
||||||
|
Our new directive is declared in the ``HelloWorld`` class, it extends
|
||||||
|
docutils_' ``Directive`` class. All extensions that create directives
|
||||||
|
should extend this class.
|
||||||
|
|
||||||
|
.. rubric:: ``run`` method
|
||||||
|
|
||||||
|
This method is a requirement and it is part of every directive. It contains
|
||||||
|
the main logic of the directive and it returns a list of docutils nodes to
|
||||||
|
be processed by Sphinx.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
:doc:`todo`
|
||||||
|
|
||||||
|
.. rubric:: docutils nodes
|
||||||
|
|
||||||
|
The ``run`` method returns a list of nodes. Nodes are docutils' way of
|
||||||
|
representing the content of a document. There are many types of nodes
|
||||||
|
available: text, paragraph, reference, table, etc.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
`The docutils documentation on nodes <docutils nodes>`_
|
||||||
|
|
||||||
|
The ``nodes.paragraph`` class creates a new paragraph node. A paragraph
|
||||||
|
node typically contains some text that we can set during instantiation using
|
||||||
|
the ``text`` parameter.
|
||||||
|
|
||||||
|
.. rubric:: ``setup`` function
|
||||||
|
|
||||||
|
This function is a requirement. We use it to plug our new directive into
|
||||||
|
Sphinx.
|
||||||
|
The simplest thing you can do it call the ``app.add_directive`` method.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The first argument is the name of the directive itself as used in an rST file.
|
||||||
|
|
||||||
|
In our case, we would use ``helloworld``:
|
||||||
|
|
||||||
|
.. code-block:: rst
|
||||||
|
|
||||||
|
Some intro text here...
|
||||||
|
|
||||||
|
.. helloworld::
|
||||||
|
|
||||||
|
Some more text here...
|
||||||
|
|
||||||
|
|
||||||
|
Updating the conf.py file
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
The extension file has to be declared in your :file:`conf.py` file to make
|
||||||
|
Sphinx aware of it:
|
||||||
|
|
||||||
|
#. Open :file:`conf.py`. It is in the :file:`source` folder by default.
|
||||||
|
#. Add ``sys.path.append(os.path.abspath("./_ext"))`` before
|
||||||
|
the ``extensions`` variable declaration (if it exists).
|
||||||
|
#. Update or create the ``extensions`` list and add the
|
||||||
|
extension file name to the list:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
extensions.append('helloworld')
|
||||||
|
|
||||||
|
You can now use the extension.
|
||||||
|
|
||||||
|
.. admonition:: Example
|
||||||
|
|
||||||
|
.. code-block:: rst
|
||||||
|
|
||||||
|
Some intro text here...
|
||||||
|
|
||||||
|
.. helloworld::
|
||||||
|
|
||||||
|
Some more text here...
|
||||||
|
|
||||||
|
The sample above would generate:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
Some intro text here...
|
||||||
|
|
||||||
|
Hello World!
|
||||||
|
|
||||||
|
Some more text here...
|
||||||
|
|
||||||
|
This is the very basic principle of an extension that creates a new directive.
|
||||||
|
|
||||||
|
For a more advanced example, refer to :doc:`todo`.
|
||||||
|
|
||||||
|
Further reading
|
||||||
|
---------------
|
||||||
|
|
||||||
|
You can create your own nodes if needed, refer to the
|
||||||
|
:doc:`todo` for more information.
|
||||||
|
|
||||||
|
.. _docutils: http://docutils.sourceforge.net/
|
||||||
|
.. _`docutils nodes`: http://docutils.sourceforge.net/docs/ref/doctree.html
|
11
doc/development/tutorials/index.rst
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
Extension tutorials
|
||||||
|
===================
|
||||||
|
|
||||||
|
Refer to the following tutorials to get started with extension development.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Directive tutorials
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
helloworld
|
||||||
|
todo
|
@ -1,7 +1,5 @@
|
|||||||
.. _exttut:
|
Developing a "TODO" extension
|
||||||
|
=============================
|
||||||
Tutorial: Writing a simple extension
|
|
||||||
====================================
|
|
||||||
|
|
||||||
This section is intended as a walkthrough for the creation of custom extensions.
|
This section is intended as a walkthrough for the creation of custom extensions.
|
||||||
It covers the basics of writing and activating an extension, as well as
|
It covers the basics of writing and activating an extension, as well as
|
||||||
@ -12,112 +10,12 @@ include todo entries in the documentation, and to collect these in a central
|
|||||||
place. (A similar "todo" extension is distributed with Sphinx.)
|
place. (A similar "todo" extension is distributed with Sphinx.)
|
||||||
|
|
||||||
|
|
||||||
Important objects
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
There are several key objects whose API you will use while writing an
|
|
||||||
extension. These are:
|
|
||||||
|
|
||||||
**Application**
|
|
||||||
The application object (usually called ``app``) is an instance of
|
|
||||||
:class:`.Sphinx`. It controls most high-level functionality, such as the
|
|
||||||
setup of extensions, event dispatching and producing output (logging).
|
|
||||||
|
|
||||||
If you have the environment object, the application is available as
|
|
||||||
``env.app``.
|
|
||||||
|
|
||||||
**Environment**
|
|
||||||
The build environment object (usually called ``env``) is an instance of
|
|
||||||
:class:`.BuildEnvironment`. It is responsible for parsing the source
|
|
||||||
documents, stores all metadata about the document collection and is
|
|
||||||
serialized to disk after each build.
|
|
||||||
|
|
||||||
Its API provides methods to do with access to metadata, resolving references,
|
|
||||||
etc. It can also be used by extensions to cache information that should
|
|
||||||
persist for incremental rebuilds.
|
|
||||||
|
|
||||||
If you have the application or builder object, the environment is available
|
|
||||||
as ``app.env`` or ``builder.env``.
|
|
||||||
|
|
||||||
**Builder**
|
|
||||||
The builder object (usually called ``builder``) is an instance of a specific
|
|
||||||
subclass of :class:`.Builder`. Each builder class knows how to convert the
|
|
||||||
parsed documents into an output format, or otherwise process them (e.g. check
|
|
||||||
external links).
|
|
||||||
|
|
||||||
If you have the application object, the builder is available as
|
|
||||||
``app.builder``.
|
|
||||||
|
|
||||||
**Config**
|
|
||||||
The config object (usually called ``config``) provides the values of
|
|
||||||
configuration values set in :file:`conf.py` as attributes. It is an instance
|
|
||||||
of :class:`.Config`.
|
|
||||||
|
|
||||||
The config is available as ``app.config`` or ``env.config``.
|
|
||||||
|
|
||||||
|
|
||||||
Build Phases
|
|
||||||
------------
|
|
||||||
|
|
||||||
One thing that is vital in order to understand extension mechanisms is the way
|
|
||||||
in which a Sphinx project is built: this works in several phases.
|
|
||||||
|
|
||||||
**Phase 0: Initialization**
|
|
||||||
|
|
||||||
In this phase, almost nothing of interest to us happens. The source
|
|
||||||
directory is searched for source files, and extensions are initialized.
|
|
||||||
Should a stored build environment exist, it is loaded, otherwise a new one is
|
|
||||||
created.
|
|
||||||
|
|
||||||
**Phase 1: Reading**
|
|
||||||
|
|
||||||
In Phase 1, all source files (and on subsequent builds, those that are new or
|
|
||||||
changed) are read and parsed. This is the phase where directives and roles
|
|
||||||
are encountered by docutils, and the corresponding code is executed. The
|
|
||||||
output of this phase is a *doctree* for each source file; that is a tree of
|
|
||||||
docutils nodes. For document elements that aren't fully known until all
|
|
||||||
existing files are read, temporary nodes are created.
|
|
||||||
|
|
||||||
There are nodes provided by docutils, which are documented `in the docutils
|
|
||||||
documentation <http://docutils.sourceforge.net/docs/ref/doctree.html>`__.
|
|
||||||
Additional nodes are provided by Sphinx and :ref:`documented here <nodes>`.
|
|
||||||
|
|
||||||
During reading, the build environment is updated with all meta- and cross
|
|
||||||
reference data of the read documents, such as labels, the names of headings,
|
|
||||||
described Python objects and index entries. This will later be used to
|
|
||||||
replace the temporary nodes.
|
|
||||||
|
|
||||||
The parsed doctrees are stored on the disk, because it is not possible to
|
|
||||||
hold all of them in memory.
|
|
||||||
|
|
||||||
**Phase 2: Consistency checks**
|
|
||||||
|
|
||||||
Some checking is done to ensure no surprises in the built documents.
|
|
||||||
|
|
||||||
**Phase 3: Resolving**
|
|
||||||
|
|
||||||
Now that the metadata and cross-reference data of all existing documents is
|
|
||||||
known, all temporary nodes are replaced by nodes that can be converted into
|
|
||||||
output using components called transforms. For example, links are created for
|
|
||||||
object references that exist, and simple literal nodes are created for those
|
|
||||||
that don't.
|
|
||||||
|
|
||||||
**Phase 4: Writing**
|
|
||||||
|
|
||||||
This phase converts the resolved doctrees to the desired output format, such
|
|
||||||
as HTML or LaTeX. This happens via a so-called docutils writer that visits
|
|
||||||
the individual nodes of each doctree and produces some output in the process.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Some builders deviate from this general build plan, for example, the builder
|
|
||||||
that checks external links does not need anything more than the parsed
|
|
||||||
doctrees and therefore does not have phases 2--4.
|
|
||||||
|
|
||||||
|
|
||||||
Extension Design
|
Extension Design
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
.. note:: To understand the design this extension, refer to
|
||||||
|
:ref:`important-objects` and :ref:`build-phases`.
|
||||||
|
|
||||||
We want the extension to add the following to Sphinx:
|
We want the extension to add the following to Sphinx:
|
||||||
|
|
||||||
* A "todo" directive, containing some content that is marked with "TODO", and
|
* A "todo" directive, containing some content that is marked with "TODO", and
|
||||||
@ -174,12 +72,13 @@ the individual calls do is the following:
|
|||||||
|
|
||||||
If the third argument was ``'html'``, HTML documents would be full rebuild if the
|
If the third argument was ``'html'``, HTML documents would be full rebuild if the
|
||||||
config value changed its value. This is needed for config values that
|
config value changed its value. This is needed for config values that
|
||||||
influence reading (build phase 1).
|
influence reading (build :ref:`phase 1 <build-phases>`).
|
||||||
|
|
||||||
* :meth:`~Sphinx.add_node` adds a new *node class* to the build system. It also
|
* :meth:`~Sphinx.add_node` adds a new *node class* to the build system. It also
|
||||||
can specify visitor functions for each supported output format. These visitor
|
can specify visitor functions for each supported output format. These visitor
|
||||||
functions are needed when the new nodes stay until phase 4 -- since the
|
functions are needed when the new nodes stay until :ref:`phase 4 <build-phases>`
|
||||||
``todolist`` node is always replaced in phase 3, it doesn't need any.
|
-- since the ``todolist`` node is always replaced in :ref:`phase 3 <build-phases>`,
|
||||||
|
it doesn't need any.
|
||||||
|
|
||||||
We need to create the two node classes ``todo`` and ``todolist`` later.
|
We need to create the two node classes ``todo`` and ``todolist`` later.
|
||||||
|
|
||||||
@ -276,7 +175,7 @@ The ``todo`` directive function looks like this::
|
|||||||
return [targetnode, todo_node]
|
return [targetnode, todo_node]
|
||||||
|
|
||||||
Several important things are covered here. First, as you can see, you can refer
|
Several important things are covered here. First, as you can see, you can refer
|
||||||
to the build environment instance using ``self.state.document.settings.env``.
|
to the :ref:`build environment instance <important-objects>` using ``self.state.document.settings.env``.
|
||||||
|
|
||||||
Then, to act as a link target (from the todolist), the todo directive needs to
|
Then, to act as a link target (from the todolist), the todo directive needs to
|
||||||
return a target node in addition to the todo node. The target ID (in HTML, this
|
return a target node in addition to the todo node. The target ID (in HTML, this
|
||||||
@ -340,7 +239,8 @@ Here we clear out all todos whose docname matches the given one from the
|
|||||||
added again during parsing.
|
added again during parsing.
|
||||||
|
|
||||||
The other handler belongs to the :event:`doctree-resolved` event. This event is
|
The other handler belongs to the :event:`doctree-resolved` event. This event is
|
||||||
emitted at the end of phase 3 and allows custom resolving to be done::
|
emitted at the end of :ref:`phase 3 <build-phases>` and allows custom resolving
|
||||||
|
to be done::
|
||||||
|
|
||||||
def process_todo_nodes(app, doctree, fromdocname):
|
def process_todo_nodes(app, doctree, fromdocname):
|
||||||
if not app.config.todo_include_todos:
|
if not app.config.todo_include_todos:
|
@ -115,37 +115,15 @@ Emitting events
|
|||||||
.. automethod:: emit_firstresult(event, \*arguments)
|
.. 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
|
Sphinx runtime information
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
The application object also provides runtime information as attributes.
|
The application object also provides runtime information as attributes.
|
||||||
|
|
||||||
|
.. attribute:: Sphinx.project
|
||||||
|
|
||||||
|
Target project. See :class:`.Project`.
|
||||||
|
|
||||||
.. attribute:: Sphinx.srcdir
|
.. attribute:: Sphinx.srcdir
|
||||||
|
|
||||||
Source directory.
|
Source directory.
|
||||||
|
@ -15,6 +15,10 @@ Build environment API
|
|||||||
|
|
||||||
Reference to the :class:`.Config` object.
|
Reference to the :class:`.Config` object.
|
||||||
|
|
||||||
|
.. attribute:: project
|
||||||
|
|
||||||
|
Target project. See :class:`.Project`.
|
||||||
|
|
||||||
.. attribute:: srcdir
|
.. attribute:: srcdir
|
||||||
|
|
||||||
Source directory.
|
Source directory.
|
||||||
@ -39,10 +43,6 @@ Build environment API
|
|||||||
|
|
||||||
**Utility methods**
|
**Utility methods**
|
||||||
|
|
||||||
.. automethod:: warn
|
|
||||||
|
|
||||||
.. automethod:: warn_node
|
|
||||||
|
|
||||||
.. automethod:: doc2path
|
.. automethod:: doc2path
|
||||||
|
|
||||||
.. automethod:: relfn2path
|
.. automethod:: relfn2path
|
||||||
|
@ -52,6 +52,115 @@ Note that it is still necessary to register the builder using
|
|||||||
|
|
||||||
.. _entry points: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
|
.. _entry points: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
|
||||||
|
|
||||||
|
.. _important-objects:
|
||||||
|
|
||||||
|
Important objects
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
There are several key objects whose API you will use while writing an
|
||||||
|
extension. These are:
|
||||||
|
|
||||||
|
**Application**
|
||||||
|
The application object (usually called ``app``) is an instance of
|
||||||
|
:class:`.Sphinx`. It controls most high-level functionality, such as the
|
||||||
|
setup of extensions, event dispatching and producing output (logging).
|
||||||
|
|
||||||
|
If you have the environment object, the application is available as
|
||||||
|
``env.app``.
|
||||||
|
|
||||||
|
**Environment**
|
||||||
|
The build environment object (usually called ``env``) is an instance of
|
||||||
|
:class:`.BuildEnvironment`. It is responsible for parsing the source
|
||||||
|
documents, stores all metadata about the document collection and is
|
||||||
|
serialized to disk after each build.
|
||||||
|
|
||||||
|
Its API provides methods to do with access to metadata, resolving references,
|
||||||
|
etc. It can also be used by extensions to cache information that should
|
||||||
|
persist for incremental rebuilds.
|
||||||
|
|
||||||
|
If you have the application or builder object, the environment is available
|
||||||
|
as ``app.env`` or ``builder.env``.
|
||||||
|
|
||||||
|
**Builder**
|
||||||
|
The builder object (usually called ``builder``) is an instance of a specific
|
||||||
|
subclass of :class:`.Builder`. Each builder class knows how to convert the
|
||||||
|
parsed documents into an output format, or otherwise process them (e.g. check
|
||||||
|
external links).
|
||||||
|
|
||||||
|
If you have the application object, the builder is available as
|
||||||
|
``app.builder``.
|
||||||
|
|
||||||
|
**Config**
|
||||||
|
The config object (usually called ``config``) provides the values of
|
||||||
|
configuration values set in :file:`conf.py` as attributes. It is an instance
|
||||||
|
of :class:`.Config`.
|
||||||
|
|
||||||
|
The config is available as ``app.config`` or ``env.config``.
|
||||||
|
|
||||||
|
To see an example of use of these objects, refer to :doc:`../development/tutorials/index`.
|
||||||
|
|
||||||
|
.. _build-phases:
|
||||||
|
|
||||||
|
Build Phases
|
||||||
|
------------
|
||||||
|
|
||||||
|
One thing that is vital in order to understand extension mechanisms is the way
|
||||||
|
in which a Sphinx project is built: this works in several phases.
|
||||||
|
|
||||||
|
**Phase 0: Initialization**
|
||||||
|
|
||||||
|
In this phase, almost nothing of interest to us happens. The source
|
||||||
|
directory is searched for source files, and extensions are initialized.
|
||||||
|
Should a stored build environment exist, it is loaded, otherwise a new one is
|
||||||
|
created.
|
||||||
|
|
||||||
|
**Phase 1: Reading**
|
||||||
|
|
||||||
|
In Phase 1, all source files (and on subsequent builds, those that are new or
|
||||||
|
changed) are read and parsed. This is the phase where directives and roles
|
||||||
|
are encountered by docutils, and the corresponding code is executed. The
|
||||||
|
output of this phase is a *doctree* for each source file; that is a tree of
|
||||||
|
docutils nodes. For document elements that aren't fully known until all
|
||||||
|
existing files are read, temporary nodes are created.
|
||||||
|
|
||||||
|
There are nodes provided by docutils, which are documented `in the docutils
|
||||||
|
documentation <http://docutils.sourceforge.net/docs/ref/doctree.html>`__.
|
||||||
|
Additional nodes are provided by Sphinx and :ref:`documented here <nodes>`.
|
||||||
|
|
||||||
|
During reading, the build environment is updated with all meta- and cross
|
||||||
|
reference data of the read documents, such as labels, the names of headings,
|
||||||
|
described Python objects and index entries. This will later be used to
|
||||||
|
replace the temporary nodes.
|
||||||
|
|
||||||
|
The parsed doctrees are stored on the disk, because it is not possible to
|
||||||
|
hold all of them in memory.
|
||||||
|
|
||||||
|
**Phase 2: Consistency checks**
|
||||||
|
|
||||||
|
Some checking is done to ensure no surprises in the built documents.
|
||||||
|
|
||||||
|
**Phase 3: Resolving**
|
||||||
|
|
||||||
|
Now that the metadata and cross-reference data of all existing documents is
|
||||||
|
known, all temporary nodes are replaced by nodes that can be converted into
|
||||||
|
output using components called transforms. For example, links are created for
|
||||||
|
object references that exist, and simple literal nodes are created for those
|
||||||
|
that don't.
|
||||||
|
|
||||||
|
**Phase 4: Writing**
|
||||||
|
|
||||||
|
This phase converts the resolved doctrees to the desired output format, such
|
||||||
|
as HTML or LaTeX. This happens via a so-called docutils writer that visits
|
||||||
|
the individual nodes of each doctree and produces some output in the process.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Some builders deviate from this general build plan, for example, the builder
|
||||||
|
that checks external links does not need anything more than the parsed
|
||||||
|
doctrees and therefore does not have phases 2--4.
|
||||||
|
|
||||||
|
To see an example of application, refer to :doc:`../development/tutorials/todo`.
|
||||||
|
|
||||||
.. _ext-metadata:
|
.. _ext-metadata:
|
||||||
|
|
||||||
Extension metadata
|
Extension metadata
|
||||||
@ -82,9 +191,10 @@ APIs used for writing extensions
|
|||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
tutorial
|
|
||||||
appapi
|
appapi
|
||||||
|
projectapi
|
||||||
envapi
|
envapi
|
||||||
builderapi
|
builderapi
|
||||||
collectorapi
|
collectorapi
|
||||||
@ -96,6 +206,8 @@ APIs used for writing extensions
|
|||||||
i18n
|
i18n
|
||||||
utils
|
utils
|
||||||
|
|
||||||
|
.. _dev-deprecated-apis:
|
||||||
|
|
||||||
Deprecated APIs
|
Deprecated APIs
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
@ -122,6 +234,368 @@ The following is a list of deprecated interfaces.
|
|||||||
- (will be) Removed
|
- (will be) Removed
|
||||||
- Alternatives
|
- 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
|
||||||
|
|
||||||
|
* - arguments of ``EpubBuilder.build_mimetype()``,
|
||||||
|
``EpubBuilder.build_container()``, ``EpubBuilder.build_content()``,
|
||||||
|
``EpubBuilder.build_toc()`` and ``EpubBuilder.build_epub()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - arguments of ``Epub3Builder.build_navigation_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.builders.applehelp``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinxcontrib.applehelp``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.devhelp``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinxcontrib.devhelp``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.epub3.Epub3Builder.validate_config_value()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.epub3.validate_config_values()``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.html.JSONHTMLBuilder``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.serializinghtml.JSONHTMLBuilder``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.html.PickleHTMLBuilder``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.serializinghtml.PickleHTMLBuilder``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.html.SerializingHTMLBuilder``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.serializinghtml.SerializingHTMLBuilder``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.html.SingleFileHTMLBuilder``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.singlehtml.SingleFileHTMLBuilder``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.html.WebHTMLBuilder``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.serializinghtml.PickleHTMLBuilder``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.htmlhelp``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinxcontrib.htmlhelp``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.htmlhelp.HTMLHelpBuilder.open_file()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``open()``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.qthelp``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinxcontrib.qthelp``
|
||||||
|
|
||||||
|
* - ``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.ext.jsmath``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinxcontrib.jsmath``
|
||||||
|
|
||||||
|
* - ``sphinx.roles.abbr_role()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.roles.Abbreviation``
|
||||||
|
|
||||||
|
* - ``sphinx.roles.emph_literal_role()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.roles.EmphasizedLiteral``
|
||||||
|
|
||||||
|
* - ``sphinx.roles.menusel_role()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.roles.GUILabel`` or ``sphinx.roles.MenuSelection``
|
||||||
|
|
||||||
|
* - ``sphinx.roles.index_role()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.roles.Index``
|
||||||
|
|
||||||
|
* - ``sphinx.roles.indexmarkup_role()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.roles.PEP`` or ``sphinx.roles.RFC``
|
||||||
|
|
||||||
|
* - ``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.jsonimpl``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinxcontrib.serializinghtml.jsonimpl``
|
||||||
|
|
||||||
|
* - ``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.NoneType``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.util.typing.NoneType``
|
||||||
|
|
||||||
|
* - ``sphinx.util.pycompat.TextIOWrapper``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``io.TextIOWrapper``
|
||||||
|
|
||||||
|
* - ``sphinx.util.pycompat.UnicodeMixin``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.util.pycompat.htmlescape()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``html.escape()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.pycompat.indent()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``textwrap.indent()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.pycompat.sys_encoding``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sys.getdefaultencoding()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.pycompat.terminal_safe()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.util.console.terminal_safe()``
|
||||||
|
|
||||||
|
* - ``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.ExtBabel``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.latex.util.ExtBabel``
|
||||||
|
|
||||||
|
* - ``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
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXTranslator.generate_numfig_format()``
|
||||||
|
- 2.0
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
* - :rst:dir:`highlightlang`
|
* - :rst:dir:`highlightlang`
|
||||||
- 1.8
|
- 1.8
|
||||||
- 4.0
|
- 4.0
|
||||||
|
@ -62,3 +62,5 @@ Logging API
|
|||||||
.. autofunction:: pending_logging()
|
.. autofunction:: pending_logging()
|
||||||
|
|
||||||
.. autofunction:: pending_warnings()
|
.. 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:
|
@ -18,5 +18,11 @@ components (e.g. :class:`.Config`, :class:`.BuildEnvironment` and so on) easily.
|
|||||||
.. autoclass:: sphinx.util.docutils.SphinxDirective
|
.. autoclass:: sphinx.util.docutils.SphinxDirective
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: sphinx.util.docutils.SphinxRole
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: sphinx.util.docutils.ReferenceRole
|
||||||
|
:members:
|
||||||
|
|
||||||
.. autoclass:: sphinx.transforms.post_transforms.images.ImageConverter
|
.. autoclass:: sphinx.transforms.post_transforms.images.ImageConverter
|
||||||
:members:
|
:members:
|
||||||
|
@ -20,7 +20,7 @@ How do I...
|
|||||||
the :rst:dir:`toctree` directive where you want to start numbering.
|
the :rst:dir:`toctree` directive where you want to start numbering.
|
||||||
|
|
||||||
... customize the look of the built HTML files?
|
... 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 global substitutions or includes?
|
||||||
Add them in the :confval:`rst_prolog` or :confval:`rst_epilog` config value.
|
Add them in the :confval:`rst_prolog` or :confval:`rst_epilog` config value.
|
||||||
@ -30,7 +30,7 @@ How do I...
|
|||||||
``sidebartoc`` block.
|
``sidebartoc`` block.
|
||||||
|
|
||||||
... write my own extension?
|
... write my own extension?
|
||||||
See the :ref:`extension tutorial <exttut>`.
|
See the :doc:`/development/tutorials/index`.
|
||||||
|
|
||||||
... convert from my existing docs using MoinMoin markup?
|
... convert from my existing docs using MoinMoin markup?
|
||||||
The easiest way is to convert to xhtml, then convert `xhtml to reST`_.
|
The easiest way is to convert to xhtml, then convert `xhtml to reST`_.
|
||||||
@ -205,7 +205,7 @@ The following list gives some hints for the creation of epub files:
|
|||||||
.. _Epubcheck: https://github.com/IDPF/epubcheck
|
.. _Epubcheck: https://github.com/IDPF/epubcheck
|
||||||
.. _Calibre: https://calibre-ebook.com/
|
.. _Calibre: https://calibre-ebook.com/
|
||||||
.. _FBreader: https://fbreader.org/
|
.. _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
|
.. _kindlegen: https://www.amazon.com/gp/feature.html?docId=1000765211
|
||||||
|
|
||||||
.. _texinfo-faq:
|
.. _texinfo-faq:
|
||||||
|
@ -55,15 +55,13 @@ See the :ref:`pertinent section in the FAQ list <usingwith>`.
|
|||||||
Prerequisites
|
Prerequisites
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Sphinx needs at least **Python 2.7** or **Python 3.4** to run, as well as the
|
Sphinx needs at least **Python 3.5** to run, as well as the docutils_ and
|
||||||
docutils_ and Jinja2_ libraries. Sphinx should work with docutils version 0.10
|
Jinja2_ libraries. Sphinx should work with docutils version 0.12 or some (not
|
||||||
or some (not broken) SVN trunk snapshot. If you like to have source code
|
broken) SVN trunk snapshot.
|
||||||
highlighting support, you must also install the Pygments_ library.
|
|
||||||
|
|
||||||
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
|
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
|
||||||
.. _docutils: http://docutils.sourceforge.net/
|
.. _docutils: http://docutils.sourceforge.net/
|
||||||
.. _Jinja2: http://jinja.pocoo.org/
|
.. _Jinja2: http://jinja.pocoo.org/
|
||||||
.. _Pygments: http://pygments.org/
|
|
||||||
|
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
|
467
doc/latex.rst
@ -8,9 +8,6 @@ LaTeX customization
|
|||||||
.. module:: latex
|
.. module:: latex
|
||||||
:synopsis: LaTeX specifics.
|
:synopsis: LaTeX specifics.
|
||||||
|
|
||||||
For details of the LaTeX/PDF builder command line invocation, refer to
|
|
||||||
:py:class:`~sphinx.builders.latex.LaTeXBuilder`.
|
|
||||||
|
|
||||||
.. raw:: latex
|
.. raw:: latex
|
||||||
|
|
||||||
\begingroup
|
\begingroup
|
||||||
@ -29,15 +26,24 @@ For details of the LaTeX/PDF builder command line invocation, refer to
|
|||||||
cautionBgColor={named}{LightCyan}}
|
cautionBgColor={named}{LightCyan}}
|
||||||
\relax
|
\relax
|
||||||
|
|
||||||
.. _latex-basic:
|
|
||||||
|
|
||||||
Basic customization
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
The *latex* target does not benefit from prepared themes.
|
The *latex* target does not benefit from prepared themes.
|
||||||
|
|
||||||
Basic customization is obtained via usage of the :ref:`latex-options`. For
|
The :ref:`latex-options`, and particularly among them the
|
||||||
example::
|
:ref:`latex_elements <latex_elements_confval>` variable
|
||||||
|
provides much of the interface for customization.
|
||||||
|
|
||||||
|
For some details of the LaTeX/PDF builder command line
|
||||||
|
invocation, refer to :py:class:`~sphinx.builders.latex.LaTeXBuilder`.
|
||||||
|
|
||||||
|
.. _latex-basic:
|
||||||
|
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
|
||||||
|
Keep in mind that backslashes must be doubled in Python string literals to
|
||||||
|
avoid interpretation as escape sequences, or use raw strings (as is done here).
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
# inside conf.py
|
# inside conf.py
|
||||||
latex_engine = 'xelatex'
|
latex_engine = 'xelatex'
|
||||||
@ -59,49 +65,412 @@ example::
|
|||||||
}
|
}
|
||||||
latex_show_urls = 'footnote'
|
latex_show_urls = 'footnote'
|
||||||
|
|
||||||
.. the above was tested on Sphinx's own 1.5a2 documentation with good effect!
|
|
||||||
|
|
||||||
.. highlight:: latex
|
.. highlight:: latex
|
||||||
|
|
||||||
If the size of the ``'preamble'`` contents becomes inconvenient, one may move
|
.. _latex_elements_confval:
|
||||||
all needed macros into some file :file:`mystyle.tex.txt` of the project source
|
|
||||||
repertory, and get LaTeX to import it at run time::
|
|
||||||
|
|
||||||
'preamble': r'\input{mystyle.tex.txt}',
|
The latex_elements configuration setting
|
||||||
# or, if the \ProvidesPackage LaTeX macro is used in a file mystyle.sty
|
----------------------------------------
|
||||||
'preamble': r'\usepackage{mystyle}',
|
|
||||||
|
|
||||||
It is then needed to set appropriately :confval:`latex_additional_files`, for
|
A dictionary that contains LaTeX snippets overriding those Sphinx usually puts
|
||||||
example::
|
into the generated ``.tex`` files. Its ``'sphinxsetup'`` key is described
|
||||||
|
:ref:`separately <latexsphinxsetup>`.
|
||||||
|
|
||||||
|
* Keys that you may want to override include:
|
||||||
|
|
||||||
|
``'papersize'``
|
||||||
|
Paper size option of the document class (``'a4paper'`` or
|
||||||
|
``'letterpaper'``), default ``'letterpaper'``.
|
||||||
|
|
||||||
|
``'pointsize'``
|
||||||
|
Point size option of the document class (``'10pt'``, ``'11pt'`` or
|
||||||
|
``'12pt'``), default ``'10pt'``.
|
||||||
|
|
||||||
|
``'pxunit'``
|
||||||
|
the value of the ``px`` when used in image attributes ``width`` and
|
||||||
|
``height``. The default value is ``'0.75bp'`` which achieves
|
||||||
|
``96px=1in`` (in TeX ``1in = 72bp = 72.27pt``.) To obtain for
|
||||||
|
example ``100px=1in`` use ``'0.01in'`` or ``'0.7227pt'`` (the latter
|
||||||
|
leads to TeX computing a more precise value, due to the smaller unit
|
||||||
|
used in the specification); for ``72px=1in``, simply use ``'1bp'``; for
|
||||||
|
``90px=1in``, use ``'0.8bp'`` or ``'0.803pt'``.
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
``'passoptionstopackages'``
|
||||||
|
A string which will be positioned early in the preamble, designed to
|
||||||
|
contain ``\\PassOptionsToPackage{options}{foo}`` commands. Default empty.
|
||||||
|
|
||||||
|
.. versionadded:: 1.4
|
||||||
|
|
||||||
|
``'babel'``
|
||||||
|
"babel" package inclusion, default ``'\\usepackage{babel}'`` (the
|
||||||
|
suitable document language string is passed as class option, and
|
||||||
|
``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, 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:: 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
|
||||||
|
(this option is slightly customized by Sphinx),
|
||||||
|
``'\\usepackage[Sonny]{fncychap}'`` for internationalized docs (because
|
||||||
|
the "Bjarne" style uses numbers spelled out in English). Other
|
||||||
|
"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. One may move all needed
|
||||||
|
macros into some file :file:`mystyle.tex.txt` of the project source
|
||||||
|
repertory, and get LaTeX to import it at run time::
|
||||||
|
|
||||||
|
'preamble': r'\input{mystyle.tex.txt}',
|
||||||
|
# or, if the \ProvidesPackage LaTeX macro is used in a file mystyle.sty
|
||||||
|
'preamble': r'\usepackage{mystyle}',
|
||||||
|
|
||||||
|
It is then needed to set appropriately
|
||||||
|
:confval:`latex_additional_files`, for example::
|
||||||
|
|
||||||
|
latex_additional_files = ["mystyle.sty"]
|
||||||
|
|
||||||
|
|
||||||
|
``'figure_align'``
|
||||||
|
Latex figure float alignment, default 'htbp' (here, top, bottom, page).
|
||||||
|
Whenever an image doesn't fit into the current page, it will be
|
||||||
|
'floated' into the next page but may be preceded by any other text.
|
||||||
|
If you don't like this behavior, use 'H' which will disable floating
|
||||||
|
and position figures strictly in the order they appear in the source.
|
||||||
|
|
||||||
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
``'atendofbody'``
|
||||||
|
Additional document content (right before the indices), default empty.
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
``'footer'``
|
||||||
|
Additional footer content (before the indices), default empty.
|
||||||
|
|
||||||
|
.. deprecated:: 1.5
|
||||||
|
Use ``'atendofbody'`` key instead.
|
||||||
|
|
||||||
|
* Keys that don't need to be overridden unless in special cases are:
|
||||||
|
|
||||||
|
``'extraclassoptions'``
|
||||||
|
The default is the empty string. Example: ``'extraclassoptions':
|
||||||
|
'openany'`` will allow chapters (for documents of the ``'manual'``
|
||||||
|
type) to start on any page.
|
||||||
|
|
||||||
|
.. versionadded:: 1.2
|
||||||
|
.. versionchanged:: 1.6
|
||||||
|
Added this documentation.
|
||||||
|
|
||||||
|
``'maxlistdepth'``
|
||||||
|
LaTeX allows by default at most 6 levels for nesting list and
|
||||||
|
quote-like environments, with at most 4 enumerated lists, and 4 bullet
|
||||||
|
lists. Setting this key for example to ``'10'`` (as a string) will
|
||||||
|
allow up to 10 nested levels (of all sorts). Leaving it to the empty
|
||||||
|
string means to obey the LaTeX default.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
- Using this key may prove incompatible with some LaTeX packages
|
||||||
|
or special document classes which do their own list customization.
|
||||||
|
|
||||||
|
- The key setting is silently *ignored* if ``\usepackage{enumitem}``
|
||||||
|
is executed inside the document preamble. Use then rather the
|
||||||
|
dedicated commands of this LaTeX package.
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
``'inputenc'``
|
||||||
|
"inputenc" package inclusion, defaults to
|
||||||
|
``'\\usepackage[utf8]{inputenc}'`` when using pdflatex.
|
||||||
|
Otherwise empty.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.4.3
|
||||||
|
Previously ``'\\usepackage[utf8]{inputenc}'`` was used for all
|
||||||
|
compilers.
|
||||||
|
|
||||||
|
``'cmappkg'``
|
||||||
|
"cmap" package inclusion, default ``'\\usepackage{cmap}'``.
|
||||||
|
|
||||||
|
.. versionadded:: 1.2
|
||||||
|
|
||||||
|
``'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'`` 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:
|
||||||
|
|
||||||
|
``'\\usepackage{geometry}'``
|
||||||
|
|
||||||
|
with an additional ``[dvipdfm]`` for Japanese documents.
|
||||||
|
The Sphinx LaTeX style file executes:
|
||||||
|
|
||||||
|
``\PassOptionsToPackage{hmargin=1in,vmargin=1in,marginpar=0.5in}{geometry}``
|
||||||
|
|
||||||
|
which can be customized via corresponding :ref:`'sphinxsetup' options
|
||||||
|
<latexsphinxsetup>`.
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
.. versionchanged:: 1.5.2
|
||||||
|
``dvipdfm`` option if :confval:`latex_engine` is ``'platex'``.
|
||||||
|
|
||||||
|
.. versionadded:: 1.5.3
|
||||||
|
The :ref:`'sphinxsetup' keys for the margins
|
||||||
|
<latexsphinxsetuphmargin>`.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.5.3
|
||||||
|
The location in the LaTeX file has been moved to after
|
||||||
|
``\usepackage{sphinx}`` and ``\sphinxsetup{..}``, hence also after
|
||||||
|
insertion of ``'fontpkg'`` key. This is in order to handle the paper
|
||||||
|
layout options in a special way for Japanese documents: the text
|
||||||
|
width will be set to an integer multiple of the *zenkaku* width, and
|
||||||
|
the text height to an integer multiple of the baseline. See the
|
||||||
|
:ref:`hmargin <latexsphinxsetuphmargin>` documentation for more.
|
||||||
|
|
||||||
|
``'hyperref'``
|
||||||
|
"hyperref" package inclusion; also loads package "hypcap" and issues
|
||||||
|
``\urlstyle{same}``. This is done after :file:`sphinx.sty` file is
|
||||||
|
loaded and before executing the contents of ``'preamble'`` key.
|
||||||
|
|
||||||
|
.. attention::
|
||||||
|
|
||||||
|
Loading of packages "hyperref" and "hypcap" is mandatory.
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
Previously this was done from inside :file:`sphinx.sty`.
|
||||||
|
|
||||||
|
``'maketitle'``
|
||||||
|
"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
|
||||||
|
:confval:`latex_documents`, it is inserted as LaTeX markup.
|
||||||
|
|
||||||
|
``'tableofcontents'``
|
||||||
|
"tableofcontents" call, default ``'\\sphinxtableofcontents'`` (it is a
|
||||||
|
wrapper of unmodified ``\tableofcontents``, which may itself be
|
||||||
|
customized by user loaded packages.)
|
||||||
|
Override if
|
||||||
|
you want to generate a different table of contents or put content
|
||||||
|
between the title page and the TOC.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.5
|
||||||
|
Previously the meaning of ``\tableofcontents`` itself was modified
|
||||||
|
by Sphinx. This created an incompatibility with dedicated packages
|
||||||
|
modifying it also such as "tocloft" or "etoc".
|
||||||
|
|
||||||
|
``'transition'``
|
||||||
|
Commands used to display transitions, default
|
||||||
|
``'\n\n\\bigskip\\hrule\\bigskip\n\n'``. Override if you want to
|
||||||
|
display transitions differently.
|
||||||
|
|
||||||
|
.. versionadded:: 1.2
|
||||||
|
.. versionchanged:: 1.6
|
||||||
|
Remove unneeded ``{}`` after ``\\hrule``.
|
||||||
|
|
||||||
|
``'printindex'``
|
||||||
|
"printindex" call, the last thing in the file, default
|
||||||
|
``'\\printindex'``. Override if you want to generate the index
|
||||||
|
differently or append some content after the index. For example
|
||||||
|
``'\\footnotesize\\raggedright\\printindex'`` is advisable when the
|
||||||
|
index is full of long entries.
|
||||||
|
|
||||||
|
``'fvset'``
|
||||||
|
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:
|
||||||
|
|
||||||
|
``'docclass'``
|
||||||
|
``'classoptions'``
|
||||||
|
``'title'``
|
||||||
|
``'release'``
|
||||||
|
``'author'``
|
||||||
|
``'makeindex'``
|
||||||
|
|
||||||
latex_additional_files = ["mystyle.sty"]
|
|
||||||
|
|
||||||
.. _latexsphinxsetup:
|
.. _latexsphinxsetup:
|
||||||
|
|
||||||
The LaTeX style file options
|
\\'sphinxsetup\\' key
|
||||||
----------------------------
|
---------------------
|
||||||
|
|
||||||
Additional customization is possible via LaTeX options of the Sphinx style
|
The ``'sphinxsetup'`` key of :ref:`latex_elements <latex_elements_confval>`
|
||||||
file.
|
provides a LaTeX-type customization interface::
|
||||||
|
|
||||||
The sphinxsetup interface
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The ``'sphinxsetup'`` key of :confval:`latex_elements` provides a convenient
|
|
||||||
interface::
|
|
||||||
|
|
||||||
latex_elements = {
|
latex_elements = {
|
||||||
'sphinxsetup': 'key1=value1, key2=value2, ...',
|
'sphinxsetup': 'key1=value1, key2=value2, ...',
|
||||||
}
|
}
|
||||||
|
|
||||||
- some values may be LaTeX macros, then the backslashes must be
|
It defaults to empty. If non-empty, it will be passed as argument to the
|
||||||
Python-escaped, or the whole must be a Python raw string,
|
``\sphinxsetup`` macro inside the document preamble, like this::
|
||||||
- LaTeX boolean keys require *lowercase* ``true`` or ``false`` values,
|
|
||||||
- spaces around the commas and equal signs are ignored, spaces inside LaTeX
|
|
||||||
macros may be significant.
|
|
||||||
|
|
||||||
If non-empty, it will be passed as argument to the ``\sphinxsetup`` macro
|
|
||||||
inside the document preamble, like this::
|
|
||||||
|
|
||||||
\usepackage{sphinx}
|
\usepackage{sphinx}
|
||||||
\sphinxsetup{key1=value1, key2=value2,...}
|
\sphinxsetup{key1=value1, key2=value2,...}
|
||||||
@ -112,7 +481,7 @@ inside the document preamble, like this::
|
|||||||
|
|
||||||
It is possible to insert further uses of the ``\sphinxsetup`` LaTeX macro
|
It is possible to insert further uses of the ``\sphinxsetup`` LaTeX macro
|
||||||
directly into the body of the document, via the help of the :rst:dir:`raw`
|
directly into the body of the document, via the help of the :rst:dir:`raw`
|
||||||
directive. Here is how this present chapter in PDF is styled::
|
directive. Here is how this present chapter is styled in the PDF output::
|
||||||
|
|
||||||
.. raw:: latex
|
.. raw:: latex
|
||||||
|
|
||||||
@ -147,8 +516,9 @@ inside the document preamble, like this::
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
The available styling options
|
LaTeX boolean keys require *lowercase* ``true`` or ``false`` values.
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
Spaces around the commas and equal signs are ignored, spaces inside LaTeX
|
||||||
|
macros may be significant.
|
||||||
|
|
||||||
.. _latexsphinxsetuphmargin:
|
.. _latexsphinxsetuphmargin:
|
||||||
|
|
||||||
@ -365,6 +735,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
|
:file:`sphinxhowto.cls`, :file:`sphinxmanual.cls`, which have public names
|
||||||
thus allowing redefinitions. Check the respective files for the defaults.
|
thus allowing redefinitions. Check the respective files for the defaults.
|
||||||
|
|
||||||
|
.. _latex-macros:
|
||||||
|
|
||||||
Macros
|
Macros
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
@ -390,11 +762,18 @@ Macros
|
|||||||
.. versionadded:: 1.6.3
|
.. versionadded:: 1.6.3
|
||||||
``\sphinxstylecodecontinued`` and ``\sphinxstylecodecontinues``.
|
``\sphinxstylecodecontinued`` and ``\sphinxstylecodecontinues``.
|
||||||
- the table of contents is typeset via ``\sphinxtableofcontents`` which is a
|
- the table of contents is typeset via ``\sphinxtableofcontents`` which is a
|
||||||
wrapper (whose definition can be found in :file:`sphinxhowto.cls` or in
|
wrapper (defined differently in :file:`sphinxhowto.cls` and in
|
||||||
:file:`sphinxmanual.cls`) of standard ``\tableofcontents``.
|
:file:`sphinxmanual.cls`) of standard ``\tableofcontents``. The macro
|
||||||
|
``\sphinxtableofcontentshook`` is executed during its expansion right before
|
||||||
|
``\tableofcontents`` itself.
|
||||||
|
|
||||||
.. versionchanged:: 1.5
|
.. versionchanged:: 1.5
|
||||||
formerly, the meaning of ``\tableofcontents`` was modified by Sphinx.
|
formerly, the meaning of ``\tableofcontents`` was modified by Sphinx.
|
||||||
|
.. 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
|
- a custom ``\sphinxmaketitle`` is defined in the class files
|
||||||
:file:`sphinxmanual.cls` and :file:`sphinxhowto.cls` and is used as
|
:file:`sphinxmanual.cls` and :file:`sphinxhowto.cls` and is used as
|
||||||
default setting of ``'maketitle'`` :confval:`latex_elements` key.
|
default setting of ``'maketitle'`` :confval:`latex_elements` key.
|
||||||
|
@ -70,10 +70,6 @@ Options
|
|||||||
|
|
||||||
Master document name. (see :confval:`master_doc`).
|
Master document name. (see :confval:`master_doc`).
|
||||||
|
|
||||||
.. option:: --epub
|
|
||||||
|
|
||||||
Use epub.
|
|
||||||
|
|
||||||
.. rubric:: Extension Options
|
.. rubric:: Extension Options
|
||||||
|
|
||||||
.. option:: --ext-autodoc
|
.. option:: --ext-autodoc
|
||||||
|
319
doc/theming.rst
@ -5,6 +5,12 @@ HTML theming support
|
|||||||
|
|
||||||
.. versionadded:: 0.6
|
.. 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
|
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.
|
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
|
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.
|
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
|
Creating themes
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
As said, themes are either a directory or a zipfile (whose name is the theme
|
Themes take the form of either a directory or a zipfile (whose name is the
|
||||||
name), containing the following:
|
theme name), containing the following:
|
||||||
|
|
||||||
* A :file:`theme.conf` file, see below.
|
* A :file:`theme.conf` file.
|
||||||
* HTML templates, if needed.
|
* HTML templates, if needed.
|
||||||
* A ``static/`` directory containing any static files that will be copied to the
|
* 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.
|
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
|
* 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
|
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
|
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
|
* 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
|
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
|
.. versionadded:: 1.7
|
||||||
sidebar settings
|
sidebar settings
|
||||||
|
|
||||||
|
|
||||||
.. _distribute-your-theme:
|
.. _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.
|
brings to users easy setting up ways.
|
||||||
|
|
||||||
To distribute your theme as a python package, please define an entry point
|
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()``
|
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::
|
function to register your themes using ``add_html_theme()`` API in it::
|
||||||
|
|
||||||
# 'setup.py'
|
# 'setup.py'
|
||||||
@ -347,9 +103,8 @@ function to register your themes using ``add_html_theme()`` API in it::
|
|||||||
def setup(app):
|
def setup(app):
|
||||||
app.add_html_theme('name_of_theme', path.abspath(path.dirname(__file__)))
|
app.add_html_theme('name_of_theme', path.abspath(path.dirname(__file__)))
|
||||||
|
|
||||||
|
If your theme package contains two or more themes, please call
|
||||||
If your theme package contains two or more themes, please call ``add_html_theme()``
|
``add_html_theme()`` twice or more.
|
||||||
twice or more.
|
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
.. versionadded:: 1.2
|
||||||
'sphinx_themes' entry_points feature.
|
'sphinx_themes' entry_points feature.
|
||||||
@ -360,8 +115,9 @@ twice or more.
|
|||||||
.. versionadded:: 1.6
|
.. versionadded:: 1.6
|
||||||
``sphinx.html_themes`` entry_points feature.
|
``sphinx.html_themes`` entry_points feature.
|
||||||
|
|
||||||
|
|
||||||
Templating
|
Templating
|
||||||
~~~~~~~~~~
|
----------
|
||||||
|
|
||||||
The :doc:`guide to templating <templating>` is helpful if you want to write your
|
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
|
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"
|
user ``templates_path`` template, you can still use the "exclamation mark"
|
||||||
syntax as described in the templating document.
|
syntax as described in the templating document.
|
||||||
|
|
||||||
|
|
||||||
Static templates
|
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
|
is built with the classic theme, the output directory will contain a
|
||||||
``_static/classic.css`` file where all template tags have been processed.
|
``_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`,
|
.. [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
|
because that would pose an unnecessary security risk if themes are
|
||||||
shared.
|
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
|
navigation bars, Sphinx provides mechanisms facilitating *document* translations
|
||||||
in itself. See the :ref:`intl-options` for details on configuration.
|
in itself. See the :ref:`intl-options` for details on configuration.
|
||||||
|
|
||||||
.. figure:: translation.png
|
.. figure:: /_static/translation.png
|
||||||
:width: 100%
|
:width: 100%
|
||||||
|
|
||||||
Workflow visualization of translations in Sphinx. (The stick-figure is taken
|
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
|
--- so called **message catalogs** --- containing a mapping from the original
|
||||||
messages to foreign-language strings.
|
messages to foreign-language strings.
|
||||||
|
|
||||||
Gettext compiles them into a binary format known as **binary catalogs** through
|
*gettext* compiles them into a binary format known as **binary catalogs**
|
||||||
:program:`msgfmt` for efficiency reasons. If you make these files discoverable
|
through :program:`msgfmt` for efficiency reasons. If you make these files
|
||||||
with :confval:`locale_dirs` for your :confval:`language`, Sphinx will pick them
|
discoverable with :confval:`locale_dirs` for your :confval:`language`, Sphinx
|
||||||
up automatically.
|
will pick them up automatically.
|
||||||
|
|
||||||
An example: you have a document ``usage.rst`` in your Sphinx project. The
|
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
|
*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
|
Spanish translations [2]_ stored in ``usage.po`` --- for your builds to
|
||||||
be translated you need to follow these instructions:
|
be translated you need to follow these instructions:
|
||||||
|
|
||||||
* Compile your message catalog to a locale directory, say ``locale``, so it
|
* 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"
|
msgfmt "usage.po" -o "locale/es/LC_MESSAGES/usage.mo"
|
||||||
|
|
||||||
* Set :confval:`locale_dirs` to ``["locale/"]``.
|
* Set :confval:`locale_dirs` to ``["locale/"]``.
|
||||||
* Set :confval:`language` to ``es`` (also possible via :option:`-D <sphinx-build -D>`).
|
* Set :confval:`language` to ``es`` (also possible via
|
||||||
|
:option:`-D <sphinx-build -D>`).
|
||||||
* Run your desired build.
|
* Run your desired build.
|
||||||
|
|
||||||
|
|
||||||
@ -71,118 +72,124 @@ Translating with sphinx-intl
|
|||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
Quick guide
|
Quick guide
|
||||||
^^^^^^^^^^^
|
~~~~~~~~~~~
|
||||||
|
|
||||||
`sphinx-intl`_ is a useful tool to work with Sphinx translation flow.
|
`sphinx-intl`_ is a useful tool to work with Sphinx translation flow. This
|
||||||
This section describe an easy way to translate with sphinx-intl.
|
section describe an easy way to translate with *sphinx-intl*.
|
||||||
|
|
||||||
#. Install `sphinx-intl`_ by :command:`pip install sphinx-intl` or
|
#. Install `sphinx-intl`_.
|
||||||
:command:`easy_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.
|
locale_dirs = ['locale/'] # path is example but recommended.
|
||||||
gettext_compact = False # optional.
|
gettext_compact = False # optional.
|
||||||
|
|
||||||
This case-study assumes that :confval:`locale_dirs` is set to 'locale/' and
|
This case-study assumes that :confval:`locale_dirs` is set to ``locale/`` and
|
||||||
:confval:`gettext_compact` is set to `False` (the Sphinx document is
|
:confval:`gettext_compact` is set to ``False`` (the Sphinx document is
|
||||||
already configured as such).
|
already configured as such).
|
||||||
|
|
||||||
#. Extract document's translatable messages into pot files:
|
#. Extract translatable messages into pot files.
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ make gettext
|
$ make gettext
|
||||||
|
|
||||||
As a result, many pot files are generated under ``_build/gettext``
|
The generated pot files will be placed in the ``_build/gettext`` directory.
|
||||||
directory.
|
|
||||||
|
|
||||||
#. Setup/Update your `locale_dir`:
|
#. Generate po files.
|
||||||
|
|
||||||
|
We'll use the pot files generated in the above step.
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ sphinx-intl update -p _build/gettext -l de -l ja
|
$ 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/de/LC_MESSAGES/``
|
||||||
* `./locale/ja/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
|
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
|
.. code-block:: console
|
||||||
|
|
||||||
$ make -e SPHINXOPTS="-D language='de'" html
|
$ make -e SPHINXOPTS="-D language='de'" html
|
||||||
|
|
||||||
command line (for Windows cmd.exe):
|
For Windows :command:`cmd.exe`, run:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
> set SPHINXOPTS=-D language=de
|
> set SPHINXOPTS=-D language=de
|
||||||
> .\make.bat html
|
> .\make.bat html
|
||||||
|
|
||||||
command line (for PowerShell):
|
For PowerShell, run:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
> Set-Item env:SPHINXOPTS "-D language=de"
|
> Set-Item env:SPHINXOPTS "-D language=de"
|
||||||
> .\make.bat html
|
> .\make.bat html
|
||||||
|
|
||||||
|
|
||||||
Congratulations! You got the translated documentation in the ``_build/html``
|
Congratulations! You got the translated documentation in the ``_build/html``
|
||||||
directory.
|
directory.
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
sphinx-build that is invoked by make command will build po files into mo files.
|
: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 ``sphinx-intl build`` command
|
|
||||||
before make command.
|
|
||||||
|
|
||||||
|
If you are using 1.2.x or earlier, please invoke :command:`sphinx-intl build`
|
||||||
|
command before :command:`make` command.
|
||||||
|
|
||||||
Translating
|
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
|
Update your po files by new pot files
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If a document is updated, it is necessary to generate updated pot files
|
If a document is updated, it is necessary to generate updated pot files and to
|
||||||
and to apply differences to translated po files.
|
apply differences to translated po files. In order to apply the updates from a
|
||||||
In order to apply the updating difference of a pot file to po file,
|
pot file to the po file, use the :command:`sphinx-intl update` command.
|
||||||
use the :command:`sphinx-intl update` command.
|
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
@ -199,7 +206,7 @@ easy to fetch and push translations.
|
|||||||
.. TODO: why use transifex?
|
.. TODO: why use transifex?
|
||||||
|
|
||||||
|
|
||||||
#. Install `transifex-client`_
|
#. Install `transifex-client`_.
|
||||||
|
|
||||||
You need :command:`tx` command to upload resources (pot files).
|
You need :command:`tx` command to upload resources (pot files).
|
||||||
|
|
||||||
@ -209,8 +216,7 @@ easy to fetch and push translations.
|
|||||||
|
|
||||||
.. seealso:: `Transifex Client documentation`_
|
.. 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
|
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
|
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 ID: ``sphinx-document-test_1_0``
|
||||||
:Project URL: ``https://www.transifex.com/projects/p/sphinx-document-test_1_0/``
|
:Project URL: ``https://www.transifex.com/projects/p/sphinx-document-test_1_0/``
|
||||||
|
|
||||||
|
#. Create config files for :command:`tx` command.
|
||||||
#. Create config files for tx command
|
|
||||||
|
|
||||||
This process will create ``.tx/config`` in the current directory, as well as
|
This process will create ``.tx/config`` in the current directory, as well as
|
||||||
a ``~/.transifexrc`` file that includes auth information.
|
a ``~/.transifexrc`` file that includes auth information.
|
||||||
@ -238,7 +243,7 @@ easy to fetch and push translations.
|
|||||||
...
|
...
|
||||||
Done.
|
Done.
|
||||||
|
|
||||||
#. Upload pot files to transifex service
|
#. Upload pot files to transifex service.
|
||||||
|
|
||||||
Register pot files to ``.tx/config`` file:
|
Register pot files to ``.tx/config`` file:
|
||||||
|
|
||||||
@ -259,15 +264,14 @@ easy to fetch and push translations.
|
|||||||
...
|
...
|
||||||
Done.
|
Done.
|
||||||
|
|
||||||
|
#. Forward the translation on transifex.
|
||||||
#. Forward the translation on transifex
|
|
||||||
|
|
||||||
.. TODO: write this section
|
.. 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. For example, to build mo files
|
||||||
|
for German (de):
|
||||||
Get translated catalogs and build mo files (ex. for 'de'):
|
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
@ -278,32 +282,29 @@ easy to fetch and push translations.
|
|||||||
...
|
...
|
||||||
Done.
|
Done.
|
||||||
|
|
||||||
Invoke make html (for BSD/GNU make):
|
Invoke :command:`make html` (for BSD/GNU make):
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ make -e SPHINXOPTS="-D language='de'" html
|
$ make -e SPHINXOPTS="-D language='de'" html
|
||||||
|
|
||||||
|
|
||||||
That's all!
|
That's all!
|
||||||
|
|
||||||
|
|
||||||
.. tip:: Translating locally and on Transifex
|
.. tip:: Translating locally and on Transifex
|
||||||
|
|
||||||
If you want to push all language's po files, you can be done by using
|
If you want to push all language's po files, you can be done by using
|
||||||
:command:`tx push -t` command.
|
:command:`tx push -t` command. Watch out! This operation overwrites
|
||||||
Watch out! This operation overwrites translations in transifex.
|
translations in transifex.
|
||||||
|
|
||||||
In other words, if you have updated each in the service and local po files,
|
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.
|
it would take much time and effort to integrate them.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Contributing to Sphinx reference translation
|
Contributing to Sphinx reference translation
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
The recommended way for new contributors to translate Sphinx reference
|
The recommended way for new contributors to translate Sphinx reference is to
|
||||||
is to join the translation team on Transifex.
|
join the translation team on Transifex.
|
||||||
|
|
||||||
There is `sphinx translation page`_ for Sphinx (master) documentation.
|
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`_.
|
2. Go to `sphinx translation page`_.
|
||||||
3. Click ``Request language`` and fill form.
|
3. Click ``Request language`` and fill form.
|
||||||
4. Wait acceptance by transifex sphinx translation maintainers.
|
4. Wait acceptance by transifex sphinx translation maintainers.
|
||||||
5. (after acceptance) translate on transifex.
|
5. (After acceptance) Translate on transifex.
|
||||||
|
|
||||||
|
|
||||||
.. rubric:: Footnotes
|
.. rubric:: Footnotes
|
||||||
|
|
||||||
@ -321,9 +321,8 @@ There is `sphinx translation page`_ for Sphinx (master) documentation.
|
|||||||
for details on that software suite.
|
for details on that software suite.
|
||||||
.. [2] Because nobody expects the Spanish Inquisition!
|
.. [2] Because nobody expects the Spanish Inquisition!
|
||||||
|
|
||||||
|
|
||||||
.. _`transifex-client`: https://pypi.org/project/transifex-client/
|
.. _`transifex-client`: https://pypi.org/project/transifex-client/
|
||||||
.. _`sphinx-intl`: https://pypi.org/project/sphinx-intl/
|
.. _`sphinx-intl`: https://pypi.org/project/sphinx-intl/
|
||||||
.. _Transifex: https://www.transifex.com/
|
.. _Transifex: https://www.transifex.com/
|
||||||
.. _`sphinx translation page`: https://www.transifex.com/sphinx-doc/sphinx-doc/
|
.. _`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
|
Methods
|
||||||
~~~~~~~
|
-------
|
||||||
|
|
||||||
.. automethod:: sphinxcontrib.websupport.WebSupport.build
|
.. automethod:: sphinxcontrib.websupport.WebSupport.build
|
||||||
|
|
@ -10,7 +10,7 @@ web application. To learn more read the :ref:`websupportquickstart`.
|
|||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
|
||||||
web/quickstart
|
quickstart
|
||||||
web/api
|
api
|
||||||
web/searchadapters
|
searchadapters
|
||||||
web/storagebackends
|
storagebackends
|
@ -4,7 +4,7 @@ Web Support Quick Start
|
|||||||
=======================
|
=======================
|
||||||
|
|
||||||
Building Documentation Data
|
Building Documentation Data
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
----------------------------
|
||||||
|
|
||||||
To make use of the web support package in your application you'll need to build
|
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,
|
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()
|
support.build()
|
||||||
|
|
||||||
This will read reStructuredText sources from `srcdir` and place the necessary
|
This will read reStructuredText sources from ``srcdir`` and place the necessary
|
||||||
data in `builddir`. The `builddir` will contain two sub-directories: one named
|
data in ``builddir``. The ``builddir`` will contain two sub-directories: one
|
||||||
"data" that contains all the data needed to display documents, search through
|
named "data" that contains all the data needed to display documents, search
|
||||||
documents, and add comments to documents. The other directory will be called
|
through documents, and add comments to documents. The other directory will be
|
||||||
"static" and contains static files that should be served from "/static".
|
called "static" and contains static files that should be served from "/static".
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ documents, and add comments to documents. The other directory will be called
|
|||||||
|
|
||||||
|
|
||||||
Integrating Sphinx Documents Into Your Webapp
|
Integrating Sphinx Documents Into Your Webapp
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
----------------------------------------------
|
||||||
|
|
||||||
Now that the data is built, it's time to do something useful with it. Start off
|
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::
|
by creating a :class:`~.WebSupport` object for your application::
|
||||||
@ -96,7 +96,7 @@ integrate with your existing templating system. An example using `Jinja2
|
|||||||
|
|
||||||
|
|
||||||
Authentication
|
Authentication
|
||||||
--------------
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
To use certain features such as voting, it must be possible to authenticate
|
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
|
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
|
Performing Searches
|
||||||
~~~~~~~~~~~~~~~~~~~
|
-------------------
|
||||||
|
|
||||||
To use the search form built-in to the Sphinx sidebar, create a function to
|
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
|
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
|
the :meth:`~sphinxcontrib.websupport.WebSupport.get_search_results` method to
|
||||||
search results. In `Flask <http://flask.pocoo.org/>`_ that would be like this::
|
retrieve search results. In `Flask <http://flask.pocoo.org/>`_ that would be
|
||||||
|
like this::
|
||||||
|
|
||||||
@app.route('/search')
|
@app.route('/search')
|
||||||
def search():
|
def search():
|
||||||
@ -167,7 +168,7 @@ does.
|
|||||||
|
|
||||||
|
|
||||||
Comments & Proposals
|
Comments & Proposals
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
--------------------
|
||||||
|
|
||||||
Now that this is done it's time to define the functions that handle the AJAX
|
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
|
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)
|
username=username, proposal=proposal)
|
||||||
return jsonify(comment=comment)
|
return jsonify(comment=comment)
|
||||||
|
|
||||||
You'll notice that both a `parent_id` and `node_id` are sent with the
|
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`
|
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. 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
|
will be empty. Then next function handles the retrieval of comments for a
|
||||||
specific node, and is aptly named
|
specific node, and is aptly named
|
||||||
:meth:`~sphinxcontrib.websupport.WebSupport.get_data`::
|
:meth:`~sphinxcontrib.websupport.WebSupport.get_data`::
|
||||||
@ -217,11 +218,11 @@ and will handle user votes on comments::
|
|||||||
|
|
||||||
|
|
||||||
Comment Moderation
|
Comment Moderation
|
||||||
~~~~~~~~~~~~~~~~~~
|
------------------
|
||||||
|
|
||||||
By default, all comments added through :meth:`~.WebSupport.add_comment` are
|
By default, all comments added through :meth:`~.WebSupport.add_comment` are
|
||||||
automatically displayed. If you wish to have some form of moderation, you can
|
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',
|
comment = support.add_comment(text, node_id='node_id',
|
||||||
parent_id='parent_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
|
BaseSearch class is moved to sphinxcontrib.websupport.search from
|
||||||
sphinx.websupport.search.
|
sphinx.websupport.search.
|
||||||
|
|
||||||
BaseSearch Methods
|
Methods
|
||||||
~~~~~~~~~~~~~~~~~~
|
-------
|
||||||
|
|
||||||
The following methods are defined in the BaseSearch class. Some methods do
|
The following methods are defined in the BaseSearch class. Some methods do not
|
||||||
not need to be overridden, but some (:meth:`~BaseSearch.add_document` and
|
need to be overridden, but some (:meth:`~BaseSearch.add_document` and
|
||||||
:meth:`~BaseSearch.handle_query`) must be overridden in your subclass. For a
|
:meth:`~BaseSearch.handle_query`) must be overridden in your subclass. For a
|
||||||
working example, look at the built-in adapter for whoosh.
|
working example, look at the built-in adapter for whoosh.
|
||||||
|
|
||||||
.. automethod:: BaseSearch.init_indexing
|
.. automethod:: BaseSearch.init_indexing
|
||||||
|
|
@ -27,8 +27,8 @@ documentation of the :class:`StorageBackend` class below.
|
|||||||
sphinx.websupport.storage.
|
sphinx.websupport.storage.
|
||||||
|
|
||||||
|
|
||||||
StorageBackend Methods
|
Methods
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
-------
|
||||||
|
|
||||||
.. automethod:: StorageBackend.pre_build
|
.. automethod:: StorageBackend.pre_build
|
||||||
|
|
@ -28,6 +28,7 @@ The builder's "name" must be given to the **-b** command-line option of
|
|||||||
|
|
||||||
.. autoattribute:: supported_image_types
|
.. autoattribute:: supported_image_types
|
||||||
|
|
||||||
|
.. module:: sphinx.builders.dirhtml
|
||||||
.. class:: DirectoryHTMLBuilder
|
.. class:: DirectoryHTMLBuilder
|
||||||
|
|
||||||
This is a subclass of the standard HTML builder. Its output is a directory
|
This is a subclass of the standard HTML builder. Its output is a directory
|
||||||
@ -45,6 +46,7 @@ The builder's "name" must be given to the **-b** command-line option of
|
|||||||
|
|
||||||
.. versionadded:: 0.6
|
.. versionadded:: 0.6
|
||||||
|
|
||||||
|
.. module:: sphinx.builders.singlehtml
|
||||||
.. class:: SingleFileHTMLBuilder
|
.. class:: SingleFileHTMLBuilder
|
||||||
|
|
||||||
This is an HTML builder that combines the whole project in one output file.
|
This is an HTML builder that combines the whole project in one output file.
|
||||||
@ -72,13 +74,17 @@ The builder's "name" must be given to the **-b** command-line option of
|
|||||||
|
|
||||||
.. autoattribute:: supported_image_types
|
.. autoattribute:: supported_image_types
|
||||||
|
|
||||||
.. module:: sphinx.builders.qthelp
|
.. module:: sphinxcontrib.qthelp
|
||||||
.. class:: QtHelpBuilder
|
.. class:: QtHelpBuilder
|
||||||
|
|
||||||
This builder produces the same output as the standalone HTML builder, but
|
This builder produces the same output as the standalone HTML builder, but
|
||||||
also generates `Qt help`_ collection support files that allow the Qt
|
also generates `Qt help`_ collection support files that allow the Qt
|
||||||
collection generator to compile them.
|
collection generator to compile them.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
|
||||||
|
Moved to sphinxcontrib.qthelp from sphinx.builders package.
|
||||||
|
|
||||||
.. autoattribute:: name
|
.. autoattribute:: name
|
||||||
|
|
||||||
.. autoattribute:: format
|
.. autoattribute:: format
|
||||||
@ -87,7 +93,7 @@ The builder's "name" must be given to the **-b** command-line option of
|
|||||||
|
|
||||||
.. _Qt help: https://doc.qt.io/qt-4.8/qthelp-framework.html
|
.. _Qt help: https://doc.qt.io/qt-4.8/qthelp-framework.html
|
||||||
|
|
||||||
.. module:: sphinx.builders.applehelp
|
.. module:: sphinxcontrib.applehelp
|
||||||
.. class:: AppleHelpBuilder
|
.. class:: AppleHelpBuilder
|
||||||
|
|
||||||
This builder produces an Apple Help Book based on the same output as the
|
This builder produces an Apple Help Book based on the same output as the
|
||||||
@ -113,7 +119,11 @@ The builder's "name" must be given to the **-b** command-line option of
|
|||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
.. module:: sphinx.builders.devhelp
|
.. versionchanged:: 2.0
|
||||||
|
|
||||||
|
Moved to sphinxcontrib.applehelp from sphinx.builders package.
|
||||||
|
|
||||||
|
.. module:: sphinxcontrib.devhelp
|
||||||
.. class:: DevhelpBuilder
|
.. class:: DevhelpBuilder
|
||||||
|
|
||||||
This builder produces the same output as the standalone HTML builder, but
|
This builder produces the same output as the standalone HTML builder, but
|
||||||
@ -126,6 +136,10 @@ The builder's "name" must be given to the **-b** command-line option of
|
|||||||
|
|
||||||
.. autoattribute:: supported_image_types
|
.. autoattribute:: supported_image_types
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
|
||||||
|
Moved to sphinxcontrib.devhelp from sphinx.builders package.
|
||||||
|
|
||||||
.. module:: sphinx.builders.epub3
|
.. module:: sphinx.builders.epub3
|
||||||
.. class:: Epub3Builder
|
.. class:: Epub3Builder
|
||||||
|
|
||||||
@ -158,23 +172,41 @@ The builder's "name" must be given to the **-b** command-line option of
|
|||||||
chapter :ref:`latex-options` for details.
|
chapter :ref:`latex-options` for details.
|
||||||
|
|
||||||
The produced LaTeX file uses several LaTeX packages that may not be present
|
The produced LaTeX file uses several LaTeX packages that may not be present
|
||||||
in a "minimal" TeX distribution installation. For example, on Ubuntu, the
|
in a "minimal" TeX distribution installation.
|
||||||
following packages need to be installed for successful PDF builds:
|
|
||||||
|
On Ubuntu xenial, the following packages need to be installed for
|
||||||
|
successful PDF builds:
|
||||||
|
|
||||||
* ``texlive-latex-recommended``
|
* ``texlive-latex-recommended``
|
||||||
* ``texlive-fonts-recommended``
|
* ``texlive-fonts-recommended``
|
||||||
* ``texlive-latex-extra``
|
* ``texlive-latex-extra``
|
||||||
* ``latexmk`` (for ``make latexpdf`` on GNU/Linux and MacOS X)
|
* ``latexmk`` (this is a Sphinx requirement on GNU/Linux and MacOS X
|
||||||
* ``latex-xcolor`` (old Ubuntu)
|
for functioning of ``make latexpdf``)
|
||||||
* ``texlive-luatex``, ``texlive-xetex`` (see :confval:`latex_engine`)
|
|
||||||
|
|
||||||
The testing of Sphinx LaTeX is done on Ubuntu trusty with the above
|
Additional packages are needed in some circumstances (see the discussion of
|
||||||
mentioned packages, which are from a TeXLive 2013 snapshot dated
|
the ``'fontpkg'`` key of :confval:`latex_elements` for more information):
|
||||||
February 2014.
|
|
||||||
|
* 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
|
.. versionchanged:: 1.6
|
||||||
Formerly, testing had been done on Ubuntu precise (TeXLive 2009).
|
Formerly, testing had been done on Ubuntu precise (TeXLive 2009).
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
Formerly, testing had been done on Ubuntu trusty (TeXLive 2013).
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Since 1.6, ``make latexpdf`` uses ``latexmk`` (not on Windows). This
|
Since 1.6, ``make latexpdf`` uses ``latexmk`` (not on Windows). This
|
||||||
@ -190,20 +222,16 @@ The builder's "name" must be given to the **-b** command-line option of
|
|||||||
|
|
||||||
reduces console output to a minimum.
|
reduces console output to a minimum.
|
||||||
|
|
||||||
Also, if ``latexmk`` version is 4.52b or higher (Jan 17)
|
Also, if ``latexmk`` is at version 4.52b or higher (January 2017)
|
||||||
``LATEXMKOPTS="-xelatex"`` will speed up PDF builds via XeLateX in case
|
``LATEXMKOPTS="-xelatex"`` speeds up PDF builds via XeLateX in case
|
||||||
of numerous graphics inclusions.
|
of numerous graphics inclusions.
|
||||||
|
|
||||||
.. code-block:: console
|
To pass options directly to the ``(pdf|xe|lua)latex`` binary, use
|
||||||
|
variable ``LATEXOPTS``, for example:
|
||||||
make latexpdf LATEXMKOPTS="-xelatex"
|
|
||||||
|
|
||||||
To pass options directly to the ``(pdf|xe|lua)latex`` executable, use
|
|
||||||
variable ``LATEXOPTS``.
|
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
make latexpdf LATEXOPTS="--interaction=nonstopmode"
|
make latexpdf LATEXOPTS="--halt-on-error"
|
||||||
|
|
||||||
.. autoattribute:: name
|
.. autoattribute:: name
|
||||||
|
|
||||||
@ -215,7 +243,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.
|
name is ``rinoh``. Refer to the `rinohtype manual`_ for details.
|
||||||
|
|
||||||
.. _rinohtype: https://github.com/brechtm/rinohtype
|
.. _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
|
.. module:: sphinx.builders.text
|
||||||
.. class:: TextBuilder
|
.. class:: TextBuilder
|
||||||
@ -271,7 +299,7 @@ name is ``rinoh``. Refer to the `rinohtype manual`_ for details.
|
|||||||
.. versionadded:: 1.1
|
.. versionadded:: 1.1
|
||||||
|
|
||||||
|
|
||||||
.. currentmodule:: sphinx.builders.html
|
.. currentmodule:: sphinxcontrib.serializinghtml
|
||||||
.. class:: SerializingHTMLBuilder
|
.. class:: SerializingHTMLBuilder
|
||||||
|
|
||||||
This builder uses a module that implements the Python serialization API
|
This builder uses a module that implements the Python serialization API
|
||||||
|
@ -40,9 +40,7 @@ Important points to note:
|
|||||||
contain the file name extension.
|
contain the file name extension.
|
||||||
|
|
||||||
* Since :file:`conf.py` is read as a Python file, the usual rules apply for
|
* 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
|
encodings and Unicode support.
|
||||||
(a comment like ``# -*- coding: utf-8 -*-``) and use Unicode string literals
|
|
||||||
when you include non-ASCII characters in configuration values.
|
|
||||||
|
|
||||||
* The contents of the config namespace are pickled (so that Sphinx can find out
|
* The contents of the config namespace are pickled (so that Sphinx can find out
|
||||||
when configuration changes), so it may not contain unpickleable values --
|
when configuration changes), so it may not contain unpickleable values --
|
||||||
@ -60,6 +58,36 @@ Important points to note:
|
|||||||
created *after* the builder is initialized.
|
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
|
General configuration
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
@ -150,7 +178,10 @@ General configuration
|
|||||||
.. confval:: master_doc
|
.. confval:: master_doc
|
||||||
|
|
||||||
The document name of the "master" document, that is, the document that
|
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
|
.. confval:: exclude_patterns
|
||||||
|
|
||||||
@ -478,36 +509,6 @@ General configuration
|
|||||||
|
|
||||||
.. versionadded:: 1.5
|
.. 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
|
.. confval:: today
|
||||||
today_fmt
|
today_fmt
|
||||||
|
|
||||||
@ -814,7 +815,7 @@ that use Sphinx's HTMLWriter class.
|
|||||||
.. confval:: html_theme
|
.. confval:: html_theme
|
||||||
|
|
||||||
The "theme" that the HTML output should use. See the :doc:`section about
|
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
|
.. versionadded:: 0.6
|
||||||
|
|
||||||
@ -863,6 +864,8 @@ that use Sphinx's HTMLWriter class.
|
|||||||
The URL which points to the root of the HTML documentation. It is used to
|
The URL which points to the root of the HTML documentation. It is used to
|
||||||
indicate the location of document like ``canonical_url``.
|
indicate the location of document like ``canonical_url``.
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
.. confval:: html_context
|
.. confval:: html_context
|
||||||
|
|
||||||
A dictionary of values to pass into the template engine's context for all
|
A dictionary of values to pass into the template engine's context for all
|
||||||
@ -1109,12 +1112,6 @@ that use Sphinx's HTMLWriter class.
|
|||||||
If true, the reST sources are included in the HTML build as
|
If true, the reST sources are included in the HTML build as
|
||||||
:file:`_sources/{name}`. The default is ``True``.
|
: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
|
.. confval:: html_show_sourcelink
|
||||||
|
|
||||||
If true (and :confval:`html_copy_source` is true as well), links to the
|
If true (and :confval:`html_copy_source` is true as well), links to the
|
||||||
@ -1252,7 +1249,7 @@ that use Sphinx's HTMLWriter class.
|
|||||||
|
|
||||||
:'sphinx.search.ja.DefaultSplitter':
|
:'sphinx.search.ja.DefaultSplitter':
|
||||||
TinySegmenter algorithm. This is default splitter.
|
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
|
MeCab binding. To use this splitter, 'mecab' python binding or dynamic
|
||||||
link library ('libmecab.so' for linux, 'libmecab.dll' for windows) is
|
link library ('libmecab.so' for linux, 'libmecab.dll' for windows) is
|
||||||
required.
|
required.
|
||||||
@ -1334,6 +1331,12 @@ that use Sphinx's HTMLWriter class.
|
|||||||
|
|
||||||
.. versionadded:: 1.6
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
|
.. deprecated:: 2.0
|
||||||
|
|
||||||
|
.. confval:: html4_writer
|
||||||
|
|
||||||
|
Output is processed with HTML4 writer. Default is ``False``.
|
||||||
|
|
||||||
Options for Single HTML output
|
Options for Single HTML output
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
@ -1354,6 +1357,19 @@ Options for HTML help output
|
|||||||
|
|
||||||
Output file base name for HTML help builder. Default is ``'pydoc'``.
|
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:
|
.. _applehelp-options:
|
||||||
|
|
||||||
@ -1551,7 +1567,11 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
|
|||||||
.. confval:: epub_title
|
.. confval:: epub_title
|
||||||
|
|
||||||
The title of the document. It defaults to the :confval:`html_title` option
|
The title of the document. It defaults to the :confval:`html_title` option
|
||||||
but can be set independently for epub creation.
|
but can be set independently for epub creation. It defaults to the
|
||||||
|
:confval:`project` option.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
It defaults to the ``project`` option.
|
||||||
|
|
||||||
.. confval:: epub_description
|
.. confval:: epub_description
|
||||||
|
|
||||||
@ -1705,9 +1725,9 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
|
|||||||
|
|
||||||
This flag determines if sphinx should try to fix image formats that are not
|
This flag determines if sphinx should try to fix image formats that are not
|
||||||
supported by some epub readers. At the moment palette images with a small
|
supported by some epub readers. At the moment palette images with a small
|
||||||
color table are upgraded. You need the Python Image Library (Pillow the
|
color table are upgraded. You need Pillow, the Python Image Library,
|
||||||
successor of the PIL) installed to use this option. The default value is
|
installed to use this option. The default value is ``False`` because the
|
||||||
``False`` because the automatic conversion may lose information.
|
automatic conversion may lose information.
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
.. versionadded:: 1.2
|
||||||
|
|
||||||
@ -1774,8 +1794,7 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
|
|||||||
Options for LaTeX output
|
Options for LaTeX output
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
These options influence LaTeX output. Refer to :doc:`/latex` for more
|
These options influence LaTeX output.
|
||||||
information.
|
|
||||||
|
|
||||||
.. confval:: latex_engine
|
.. confval:: latex_engine
|
||||||
|
|
||||||
@ -1787,42 +1806,29 @@ information.
|
|||||||
* ``'lualatex'`` -- LuaLaTeX
|
* ``'lualatex'`` -- LuaLaTeX
|
||||||
* ``'platex'`` -- pLaTeX (default if :confval:`language` is ``'ja'``)
|
* ``'platex'`` -- pLaTeX (default if :confval:`language` is ``'ja'``)
|
||||||
|
|
||||||
PDFLaTeX's support for Unicode characters covers those from the document
|
``'pdflatex'``\ 's support for Unicode characters is limited.
|
||||||
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.
|
|
||||||
|
|
||||||
If your project uses such extra Unicode characters, switching the engine to
|
.. note::
|
||||||
XeLaTeX or LuaLaTeX and setting up the document to use an OpenType font
|
|
||||||
with wide-enough glyph coverage is often easier than sticking with PDFLaTeX
|
|
||||||
and trying to get it to work with the Unicode characters.
|
|
||||||
|
|
||||||
The :confval:`latex_elements` ``'fontpkg'`` key allows to set up the
|
2.0 adds to ``'pdflatex'`` support in Latin language document of
|
||||||
document fonts, see :ref:`this example <latex-basic>`. Currently, for
|
occasional Cyrillic or Greek letters or words. This is not automatic,
|
||||||
XeLaTeX and LuaLaTeX, Sphinx leaves this key empty and LaTeX then defaults
|
see the discussion of the :confval:`latex_elements` ``'fontenc'`` key.
|
||||||
to the `Latin Modern`_ font family (from the TeX distribution fonts). This
|
|
||||||
font family provides good coverage of Latin scripts (European languages,
|
|
||||||
Vietnamese) but Cyrillic requires some other OpenType font; for example
|
|
||||||
Computer Modern Unicode (see `babel-russian`_ documentation on how to load
|
|
||||||
it in the LaTeX document). In future, it is planned Sphinx will provide
|
|
||||||
another default choice of OpenType font than `Latin Modern`_, perhaps
|
|
||||||
`Libertinus`_, which is included in recent TeX distributions and supports
|
|
||||||
Latin and Cyrillic and also has an accompanying math font.
|
|
||||||
|
|
||||||
With XeLaTeX and LuaLaTeX, Sphinx configures the LaTeX document to use
|
If your project uses Unicode characters, setting the engine to
|
||||||
`polyglossia`_. For some languages the `babel`_ support appears
|
``'xelatex'`` or ``'lualatex'`` and making sure to use an OpenType font
|
||||||
preferable; Sphinx uses currently `babel`_ for French and perhaps will also
|
with wide-enough glyph coverage is often easier than trying to make
|
||||||
for some more languages in future. One can use the
|
``'pdflatex'`` work with the extra Unicode characters. Since Sphinx 2.0
|
||||||
:confval:`latex_elements` ``'babel'`` key to override Sphinx's default.
|
the default is the GNU FreeFont which covers well Latin, Cyrillic and Greek.
|
||||||
|
|
||||||
.. _`Latin Modern`: http://www.gust.org.pl/projects/e-foundry/latin-modern
|
Contrarily to :ref:`MathJaX math rendering in HTML output <math-support>`,
|
||||||
.. _`polyglossia`: https://ctan.org/pkg/polyglossia
|
LaTeX requires some extra configuration to support Unicode literals in
|
||||||
.. _`babel`: https://ctan.org/pkg/babel
|
:rst:dir:`math`: the only comprehensive solution (as far as we know) is to
|
||||||
.. _`babel-russian`: https://ctan.org/pkg/babel-russian
|
use ``'xelatex'`` or ``'lualatex'`` *and* to add
|
||||||
.. _`Libertinus`: https://ctan.org/pkg/libertinus
|
``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
|
.. confval:: latex_documents
|
||||||
|
|
||||||
@ -1979,277 +1985,7 @@ information.
|
|||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
|
|
||||||
A dictionary that contains LaTeX snippets that override those Sphinx usually
|
Its :ref:`documentation <latex_elements_confval>` has moved to :doc:`/latex`.
|
||||||
puts into the generated ``.tex`` files.
|
|
||||||
|
|
||||||
Keep in mind that backslashes must be doubled in Python string literals to
|
|
||||||
avoid interpretation as escape sequences.
|
|
||||||
|
|
||||||
* Keys that you may want to override include:
|
|
||||||
|
|
||||||
``'papersize'``
|
|
||||||
Paper size option of the document class (``'a4paper'`` or
|
|
||||||
``'letterpaper'``), default ``'letterpaper'``.
|
|
||||||
|
|
||||||
``'pointsize'``
|
|
||||||
Point size option of the document class (``'10pt'``, ``'11pt'`` or
|
|
||||||
``'12pt'``), default ``'10pt'``.
|
|
||||||
|
|
||||||
``'pxunit'``
|
|
||||||
the value of the ``px`` when used in image attributes ``width`` and
|
|
||||||
``height``. The default value is ``'0.75bp'`` which achieves
|
|
||||||
``96px=1in`` (in TeX ``1in = 72bp = 72.27pt``.) To obtain for
|
|
||||||
example ``100px=1in`` use ``'0.01in'`` or ``'0.7227pt'`` (the latter
|
|
||||||
leads to TeX computing a more precise value, due to the smaller unit
|
|
||||||
used in the specification); for ``72px=1in``, simply use ``'1bp'``; for
|
|
||||||
``90px=1in``, use ``'0.8bp'`` or ``'0.803pt'``.
|
|
||||||
|
|
||||||
.. versionadded:: 1.5
|
|
||||||
|
|
||||||
``'sphinxsetup'``
|
|
||||||
A comma separated list of ``key=value`` package options for the Sphinx
|
|
||||||
LaTeX style, default empty. See :doc:`/latex`.
|
|
||||||
|
|
||||||
.. versionadded:: 1.5
|
|
||||||
|
|
||||||
``'passoptionstopackages'``
|
|
||||||
A string which will be positioned early in the preamble, designed to
|
|
||||||
contain ``\\PassOptionsToPackage{options}{foo}`` commands. Default empty.
|
|
||||||
|
|
||||||
.. versionadded:: 1.4
|
|
||||||
|
|
||||||
``'babel'``
|
|
||||||
"babel" package inclusion, default ``'\\usepackage{babel}'`` (the
|
|
||||||
suitable document language string is passed as class option, and
|
|
||||||
``english`` is used if no language.) For Japanese documents, the
|
|
||||||
default is the empty string.
|
|
||||||
|
|
||||||
.. 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).
|
|
||||||
|
|
||||||
.. 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'``.
|
|
||||||
|
|
||||||
``'fncychap'``
|
|
||||||
Inclusion of the "fncychap" package (which makes fancy chapter titles),
|
|
||||||
default ``'\\usepackage[Bjarne]{fncychap}'`` for English documentation
|
|
||||||
(this option is slightly customized by Sphinx),
|
|
||||||
``'\\usepackage[Sonny]{fncychap}'`` for internationalized docs (because
|
|
||||||
the "Bjarne" style uses numbers spelled out in English). Other
|
|
||||||
"fncychap" styles you can try are "Lenny", "Glenn", "Conny", "Rejne" and
|
|
||||||
"Bjornstrup". You can also set this to ``''`` to disable fncychap.
|
|
||||||
|
|
||||||
``'preamble'``
|
|
||||||
Additional preamble content, default empty. See :doc:`/latex`.
|
|
||||||
|
|
||||||
``'atendofbody'``
|
|
||||||
Additional document content (right before the indices), default empty.
|
|
||||||
|
|
||||||
.. versionadded:: 1.5
|
|
||||||
|
|
||||||
``'figure_align'``
|
|
||||||
Latex figure float alignment, default 'htbp' (here, top, bottom, page).
|
|
||||||
Whenever an image doesn't fit into the current page, it will be
|
|
||||||
'floated' into the next page but may be preceded by any other text.
|
|
||||||
If you don't like this behavior, use 'H' which will disable floating
|
|
||||||
and position figures strictly in the order they appear in the source.
|
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
|
||||||
|
|
||||||
``'footer'``
|
|
||||||
Additional footer content (before the indices), default empty.
|
|
||||||
|
|
||||||
.. deprecated:: 1.5
|
|
||||||
Use ``'atendofbody'`` key instead.
|
|
||||||
|
|
||||||
* Keys that don't need to be overridden unless in special cases are:
|
|
||||||
|
|
||||||
``'extraclassoptions'``
|
|
||||||
The default is the empty string. Example: ``'extraclassoptions':
|
|
||||||
'openany'`` will allow chapters (for documents of the ``'manual'``
|
|
||||||
type) to start on any page.
|
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
|
||||||
.. versionchanged:: 1.6
|
|
||||||
Added this documentation.
|
|
||||||
|
|
||||||
``'maxlistdepth'``
|
|
||||||
LaTeX allows by default at most 6 levels for nesting list and
|
|
||||||
quote-like environments, with at most 4 enumerated lists, and 4 bullet
|
|
||||||
lists. Setting this key for example to ``'10'`` (as a string) will
|
|
||||||
allow up to 10 nested levels (of all sorts). Leaving it to the empty
|
|
||||||
string means to obey the LaTeX default.
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
- Using this key may prove incompatible with some LaTeX packages
|
|
||||||
or special document classes which do their own list customization.
|
|
||||||
|
|
||||||
- The key setting is silently *ignored* if ``\usepackage{enumitem}``
|
|
||||||
is executed inside the document preamble. Use then rather the
|
|
||||||
dedicated commands of this LaTeX package.
|
|
||||||
|
|
||||||
.. versionadded:: 1.5
|
|
||||||
|
|
||||||
``'inputenc'``
|
|
||||||
"inputenc" package inclusion, defaults to
|
|
||||||
``'\\usepackage[utf8]{inputenc}'`` when using pdflatex.
|
|
||||||
Otherwise empty.
|
|
||||||
|
|
||||||
.. versionchanged:: 1.4.3
|
|
||||||
Previously ``'\\usepackage[utf8]{inputenc}'`` was used for all
|
|
||||||
compilers.
|
|
||||||
|
|
||||||
``'cmappkg'``
|
|
||||||
"cmap" package inclusion, default ``'\\usepackage{cmap}'``.
|
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
|
||||||
|
|
||||||
``'fontenc'``
|
|
||||||
"fontenc" package inclusion, default ``'\\usepackage[T1]{fontenc}'``.
|
|
||||||
|
|
||||||
.. versionchanged:: 1.5
|
|
||||||
Defaults to ``'\\usepackage{fontspec}'`` when
|
|
||||||
:confval:`latex_engine` is ``'xelatex'``.
|
|
||||||
.. versionchanged:: 1.6
|
|
||||||
``'lualatex'`` also uses ``fontspec`` per default.
|
|
||||||
|
|
||||||
``'geometry'``
|
|
||||||
"geometry" package inclusion, the default definition is:
|
|
||||||
|
|
||||||
``'\\usepackage{geometry}'``
|
|
||||||
|
|
||||||
with an additional ``[dvipdfm]`` for Japanese documents.
|
|
||||||
The Sphinx LaTeX style file executes:
|
|
||||||
|
|
||||||
``\PassOptionsToPackage{hmargin=1in,vmargin=1in,marginpar=0.5in}{geometry}``
|
|
||||||
|
|
||||||
which can be customized via corresponding :ref:`'sphinxsetup' options
|
|
||||||
<latexsphinxsetup>`.
|
|
||||||
|
|
||||||
.. versionadded:: 1.5
|
|
||||||
|
|
||||||
.. versionchanged:: 1.5.2
|
|
||||||
``dvipdfm`` option if :confval:`latex_engine` is ``'platex'``.
|
|
||||||
|
|
||||||
.. versionadded:: 1.5.3
|
|
||||||
The :ref:`'sphinxsetup' keys for the margins
|
|
||||||
<latexsphinxsetuphmargin>`.
|
|
||||||
|
|
||||||
.. versionchanged:: 1.5.3
|
|
||||||
The location in the LaTeX file has been moved to after
|
|
||||||
``\usepackage{sphinx}`` and ``\sphinxsetup{..}``, hence also after
|
|
||||||
insertion of ``'fontpkg'`` key. This is in order to handle the paper
|
|
||||||
layout options in a special way for Japanese documents: the text
|
|
||||||
width will be set to an integer multiple of the *zenkaku* width, and
|
|
||||||
the text height to an integer multiple of the baseline. See the
|
|
||||||
:ref:`hmargin <latexsphinxsetuphmargin>` documentation for more.
|
|
||||||
|
|
||||||
``'hyperref'``
|
|
||||||
"hyperref" package inclusion; also loads package "hypcap" and issues
|
|
||||||
``\urlstyle{same}``. This is done after :file:`sphinx.sty` file is
|
|
||||||
loaded and before executing the contents of ``'preamble'`` key.
|
|
||||||
|
|
||||||
.. attention::
|
|
||||||
|
|
||||||
Loading of packages "hyperref" and "hypcap" is mandatory.
|
|
||||||
|
|
||||||
.. versionadded:: 1.5
|
|
||||||
Previously this was done from inside :file:`sphinx.sty`.
|
|
||||||
|
|
||||||
``'maketitle'``
|
|
||||||
"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
|
|
||||||
:confval:`latex_documents`, it is inserted as LaTeX markup.
|
|
||||||
|
|
||||||
``'tableofcontents'``
|
|
||||||
"tableofcontents" call, default ``'\\sphinxtableofcontents'`` (it is a
|
|
||||||
wrapper of unmodified ``\tableofcontents``, which may itself be
|
|
||||||
customized by user loaded packages.)
|
|
||||||
Override if
|
|
||||||
you want to generate a different table of contents or put content
|
|
||||||
between the title page and the TOC.
|
|
||||||
|
|
||||||
.. versionchanged:: 1.5
|
|
||||||
Previously the meaning of ``\tableofcontents`` itself was modified
|
|
||||||
by Sphinx. This created an incompatibility with dedicated packages
|
|
||||||
modifying it also such as "tocloft" or "etoc".
|
|
||||||
|
|
||||||
``'transition'``
|
|
||||||
Commands used to display transitions, default
|
|
||||||
``'\n\n\\bigskip\\hrule\\bigskip\n\n'``. Override if you want to
|
|
||||||
display transitions differently.
|
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
|
||||||
.. versionchanged:: 1.6
|
|
||||||
Remove unneeded ``{}`` after ``\\hrule``.
|
|
||||||
|
|
||||||
``'printindex'``
|
|
||||||
"printindex" call, the last thing in the file, default
|
|
||||||
``'\\printindex'``. Override if you want to generate the index
|
|
||||||
differently or append some content after the index. For example
|
|
||||||
``'\\footnotesize\\raggedright\\printindex'`` is advisable when the
|
|
||||||
index is full of long entries.
|
|
||||||
|
|
||||||
``'fvset'``
|
|
||||||
Customization of ``fancyvrb`` LaTeX package. Currently, Sphinx uses
|
|
||||||
this key to set the fontsize in code-blocks according to the
|
|
||||||
:confval:`latex_engine`.
|
|
||||||
|
|
||||||
- ``'pdflatex'`` uses ``'fvset': '\\fvset{fontsize=\\small}'``,
|
|
||||||
to mitigate the size difference between the default monospaced font
|
|
||||||
(Courier) and the default text font (Times). You may need to modify
|
|
||||||
this if you use custom fonts.
|
|
||||||
|
|
||||||
- ``'xelatex'`` and ``'lualatex'`` use ``'\\fvset{fontsize=auto}'``,
|
|
||||||
as there is no size difference between the regular and the
|
|
||||||
monospaced fonts used by default by Sphinx with these engines.
|
|
||||||
|
|
||||||
.. versionadded:: 1.8
|
|
||||||
|
|
||||||
* Keys that are set by other options and therefore should not be overridden
|
|
||||||
are:
|
|
||||||
|
|
||||||
``'docclass'``
|
|
||||||
``'classoptions'``
|
|
||||||
``'title'``
|
|
||||||
``'date'``
|
|
||||||
``'release'``
|
|
||||||
``'author'``
|
|
||||||
``'logo'``
|
|
||||||
``'makeindex'``
|
|
||||||
|
|
||||||
.. confval:: latex_docclass
|
.. confval:: latex_docclass
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@ docstrings to correct reStructuredText before :mod:`autodoc` processes them.
|
|||||||
.. _NumPy:
|
.. _NumPy:
|
||||||
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
|
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
|
||||||
|
|
||||||
|
|
||||||
|
Directives
|
||||||
|
----------
|
||||||
|
|
||||||
:mod:`autodoc` provides several directives that are versions of the usual
|
: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
|
: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,
|
import the corresponding module and extract the docstring of the given objects,
|
||||||
@ -233,6 +237,7 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
|
|
||||||
|
|
||||||
.. rst:directive:: autofunction
|
.. rst:directive:: autofunction
|
||||||
|
autodecorator
|
||||||
autodata
|
autodata
|
||||||
automethod
|
automethod
|
||||||
autoattribute
|
autoattribute
|
||||||
@ -289,10 +294,11 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
docstrings.
|
docstrings.
|
||||||
.. versionchanged:: 1.1
|
.. versionchanged:: 1.1
|
||||||
Comment docs are now allowed on the same line after an assignment.
|
Comment docs are now allowed on the same line after an assignment.
|
||||||
|
|
||||||
.. versionchanged:: 1.2
|
.. versionchanged:: 1.2
|
||||||
:rst:dir:`autodata` and :rst:dir:`autoattribute` have an ``annotation``
|
:rst:dir:`autodata` and :rst:dir:`autoattribute` have an ``annotation``
|
||||||
option.
|
option.
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
:rst:dir:`autodecorator` added.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -306,7 +312,10 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
well-behaved decorating functions.
|
well-behaved decorating functions.
|
||||||
|
|
||||||
|
|
||||||
There are also new config values that you can set:
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
There are also config values that you can set:
|
||||||
|
|
||||||
.. confval:: autoclass_content
|
.. confval:: autoclass_content
|
||||||
|
|
||||||
@ -369,19 +378,23 @@ There are also new config values that you can set:
|
|||||||
'members': 'var1, var2',
|
'members': 'var1, var2',
|
||||||
'member-order': 'bysource',
|
'member-order': 'bysource',
|
||||||
'special-members': '__init__',
|
'special-members': '__init__',
|
||||||
'undoc-members': None,
|
'undoc-members': True,
|
||||||
'exclude-members': '__weakref__'
|
'exclude-members': '__weakref__'
|
||||||
}
|
}
|
||||||
|
|
||||||
Setting ``None`` is equivalent to giving the option name in the list format
|
Setting ``None`` or ``True`` to the value is equivalent to giving only the
|
||||||
(i.e. it means "yes/true/on").
|
option name to the directives.
|
||||||
|
|
||||||
The supported options are ``'members'``, ``'undoc-members'``,
|
The supported options are ``'members'``, ``'member-order'``,
|
||||||
``'private-members'``, ``'special-members'``, ``'inherited-members'``,
|
``'undoc-members'``, ``'private-members'``, ``'special-members'``,
|
||||||
``'show-inheritance'``, ``'ignore-module-all'`` and ``'exclude-members'``.
|
``'inherited-members'``, ``'show-inheritance'``, ``'ignore-module-all'`` and
|
||||||
|
``'exclude-members'``.
|
||||||
|
|
||||||
.. versionadded:: 1.8
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
Accepts ``True`` as a value.
|
||||||
|
|
||||||
.. confval:: autodoc_docstring_signature
|
.. confval:: autodoc_docstring_signature
|
||||||
|
|
||||||
Functions imported from C modules cannot be introspected, and therefore the
|
Functions imported from C modules cannot be introspected, and therefore the
|
||||||
@ -432,6 +445,16 @@ There are also new config values that you can set:
|
|||||||
|
|
||||||
.. versionadded:: 1.7
|
.. 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
|
Docstring preprocessing
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -38,3 +38,10 @@ Configuration
|
|||||||
called ``Introduction`` that appears in document ``index.rst``. Useful for
|
called ``Introduction`` that appears in document ``index.rst``. Useful for
|
||||||
avoiding ambiguity when the same section heading appears in different
|
avoiding ambiguity when the same section heading appears in different
|
||||||
documents.
|
documents.
|
||||||
|
|
||||||
|
.. confval:: autosectionlabel_maxdepth
|
||||||
|
|
||||||
|
If set, autosectionlabel chooses the sections for labeling by its depth. For
|
||||||
|
example, when set 1 to ``autosectionlabel_maxdepth``, labels are generated
|
||||||
|
only for top level sections, and deeper sections are not labeled. It
|
||||||
|
defaults to ``None`` (disabled).
|
||||||
|
@ -131,7 +131,7 @@ Generating stub pages automatically
|
|||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
If you do not want to create stub pages with :program:`sphinx-autogen`, you can
|
If you do not want to create stub pages with :program:`sphinx-autogen`, you can
|
||||||
also use this new config value:
|
also use these config values:
|
||||||
|
|
||||||
.. confval:: autosummary_generate
|
.. confval:: autosummary_generate
|
||||||
|
|
||||||
@ -143,6 +143,11 @@ also use this new config value:
|
|||||||
The new files will be placed in the directories specified in the
|
The new files will be placed in the directories specified in the
|
||||||
``:toctree:`` options of the directives.
|
``:toctree:`` options of the directives.
|
||||||
|
|
||||||
|
.. confval:: autosummary_mock_imports
|
||||||
|
|
||||||
|
This value contains a list of modules to be mocked up. See
|
||||||
|
:confval:`autodoc_mock_imports` for more details. It defaults to
|
||||||
|
:confval:`autodoc_mock_imports`.
|
||||||
|
|
||||||
Customizing templates
|
Customizing templates
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -13,7 +13,7 @@ This extension features one additional builder, the :class:`CoverageBuilder`.
|
|||||||
|
|
||||||
.. todo:: Write this section.
|
.. todo:: Write this section.
|
||||||
|
|
||||||
Several new configuration values can be used to specify what the builder
|
Several configuration values can be used to specify what the builder
|
||||||
should check:
|
should check:
|
||||||
|
|
||||||
.. confval:: coverage_ignore_modules
|
.. confval:: coverage_ignore_modules
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""Example Google style docstrings.
|
"""Example Google style docstrings.
|
||||||
|
|
||||||
This module demonstrates documentation as specified by the `Google Python
|
This module demonstrates documentation as specified by the `Google Python
|
||||||
@ -178,7 +177,7 @@ class ExampleError(Exception):
|
|||||||
self.code = code
|
self.code = code
|
||||||
|
|
||||||
|
|
||||||
class ExampleClass(object):
|
class ExampleClass:
|
||||||
"""The summary line for a class docstring should fit on one line.
|
"""The summary line for a class docstring should fit on one line.
|
||||||
|
|
||||||
If the class has public attributes, they may be documented here
|
If the class has public attributes, they may be documented here
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""Example NumPy style docstrings.
|
"""Example NumPy style docstrings.
|
||||||
|
|
||||||
This module demonstrates documentation as specified by the `NumPy
|
This module demonstrates documentation as specified by the `NumPy
|
||||||
@ -223,7 +222,7 @@ class ExampleError(Exception):
|
|||||||
self.code = code
|
self.code = code
|
||||||
|
|
||||||
|
|
||||||
class ExampleClass(object):
|
class ExampleClass:
|
||||||
"""The summary line for a class docstring should fit on one line.
|
"""The summary line for a class docstring should fit on one line.
|
||||||
|
|
||||||
If the class has public attributes, they may be documented here
|
If the class has public attributes, they may be documented here
|
||||||
|
@ -18,7 +18,7 @@ tracker, at :samp:`https://github.com/sphinx-doc/sphinx/issues/{num}`. Typing
|
|||||||
this URL again and again is tedious, so you can use :mod:`~sphinx.ext.extlinks`
|
this URL again and again is tedious, so you can use :mod:`~sphinx.ext.extlinks`
|
||||||
to avoid repeating yourself.
|
to avoid repeating yourself.
|
||||||
|
|
||||||
The extension adds one new config value:
|
The extension adds a config value:
|
||||||
|
|
||||||
.. confval:: extlinks
|
.. confval:: extlinks
|
||||||
|
|
||||||
|
@ -6,5 +6,11 @@
|
|||||||
|
|
||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
Support ``CNAME`` file
|
||||||
|
|
||||||
This extension creates ``.nojekyll`` file on generated HTML directory to publish
|
This extension creates ``.nojekyll`` file on generated HTML directory to publish
|
||||||
the document on GitHub Pages.
|
the document on GitHub Pages.
|
||||||
|
|
||||||
|
It also creates a ``CNAME`` file for custom domains when :confval:`html_baseurl`
|
||||||
|
set.
|
||||||
|
@ -90,7 +90,7 @@ It adds these directives:
|
|||||||
.. versionadded:: 1.6
|
.. versionadded:: 1.6
|
||||||
All three directives support a ``name`` option to set the label to graph.
|
All three directives support a ``name`` option to set the label to graph.
|
||||||
|
|
||||||
There are also these new config values:
|
There are also these config values:
|
||||||
|
|
||||||
.. confval:: graphviz_dot
|
.. confval:: graphviz_dot
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ It adds this directive:
|
|||||||
E D F
|
E D F
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class A(object):
|
class A:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class B(A):
|
class B(A):
|
||||||
|
@ -43,7 +43,7 @@ Configuration
|
|||||||
-------------
|
-------------
|
||||||
|
|
||||||
To use Intersphinx linking, add ``'sphinx.ext.intersphinx'`` to your
|
To use Intersphinx linking, add ``'sphinx.ext.intersphinx'`` to your
|
||||||
:confval:`extensions` config value, and use these new config values to activate
|
:confval:`extensions` config value, and use these config values to activate
|
||||||
linking:
|
linking:
|
||||||
|
|
||||||
.. confval:: intersphinx_mapping
|
.. confval:: intersphinx_mapping
|
||||||
|
@ -183,7 +183,7 @@ Sphinx.
|
|||||||
|
|
||||||
The default is empty (not configured).
|
The default is empty (not configured).
|
||||||
|
|
||||||
.. _Using in-line configuration options: http://docs.mathjax.org/en/latest/configuration.html#using-in-line-configuration-options
|
.. _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
|
:mod:`sphinx.ext.jsmath` -- Render math via JavaScript
|
||||||
------------------------------------------------------
|
------------------------------------------------------
|
||||||
|
@ -409,10 +409,10 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
|
|||||||
|
|
||||||
.. attribute:: attr1
|
.. attribute:: attr1
|
||||||
|
|
||||||
*int*
|
|
||||||
|
|
||||||
Description of `attr1`
|
Description of `attr1`
|
||||||
|
|
||||||
|
:type: int
|
||||||
|
|
||||||
.. confval:: napoleon_use_param
|
.. confval:: napoleon_use_param
|
||||||
|
|
||||||
True to use a ``:param:`` role for each function parameter. False to
|
True to use a ``:param:`` role for each function parameter. False to
|
||||||
|
@ -41,10 +41,9 @@ Configuration
|
|||||||
|
|
||||||
.. confval:: viewcode_follow_imported_members
|
.. confval:: viewcode_follow_imported_members
|
||||||
|
|
||||||
If this is ``True``, viewcode extension will follow alias objects that
|
If this is ``True``, viewcode extension will emit
|
||||||
imported from another module such as functions, classes and attributes. As
|
:event:`viewcode-follow-imported` event to resolve the name of the module
|
||||||
side effects, this option else they produce nothing. The default is
|
by other extensions. The default is ``True``.
|
||||||
``True``.
|
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
@ -12,10 +12,9 @@ Installing Sphinx
|
|||||||
Overview
|
Overview
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Sphinx is written in `Python`__ and supports both Python 2.7 and Python 3.3+.
|
Sphinx is written in `Python`__ and supports Python 3.5+.
|
||||||
We recommend the latter.
|
|
||||||
|
|
||||||
__ http://docs.python-guide.org/en/latest/
|
__ https://docs.python-guide.org/
|
||||||
|
|
||||||
|
|
||||||
Linux
|
Linux
|
||||||
@ -73,7 +72,7 @@ Homebrew
|
|||||||
|
|
||||||
For more information, refer to the `package overview`__.
|
For more information, refer to the `package overview`__.
|
||||||
|
|
||||||
__ http://formulae.brew.sh/formula/sphinx-doc
|
__ https://formulae.brew.sh/formula/sphinx-doc
|
||||||
|
|
||||||
MacPorts
|
MacPorts
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
@ -114,16 +113,14 @@ Prompt* (:kbd:`⊞Win-r` and type :command:`cmd`). Once the command prompt is
|
|||||||
open, type :command:`python --version` and press Enter. If Python is
|
open, type :command:`python --version` and press Enter. If Python is
|
||||||
available, you will see the version of Python printed to the screen. If you do
|
available, you will see the version of Python printed to the screen. If you do
|
||||||
not have Python installed, refer to the `Hitchhikers Guide to Python's`__
|
not have Python installed, refer to the `Hitchhikers Guide to Python's`__
|
||||||
Python on Windows installation guides. You can install either `Python 3`__ or
|
Python on Windows installation guides. You must install `Python 3`__.
|
||||||
`Python 2.7`__. Python 3 is recommended.
|
|
||||||
|
|
||||||
Once Python is installed, you can install Sphinx using :command:`pip`. Refer
|
Once Python is installed, you can install Sphinx using :command:`pip`. Refer
|
||||||
to the :ref:`pip installation instructions <install-pypi>` below for more
|
to the :ref:`pip installation instructions <install-pypi>` below for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
__ http://docs.python-guide.org/en/latest/
|
__ https://docs.python-guide.org/
|
||||||
__ http://docs.python-guide.org/en/latest/starting/install3/win/
|
__ https://docs.python-guide.org/starting/install3/win/
|
||||||
__ http://docs.python-guide.org/en/latest/starting/install/win/
|
|
||||||
|
|
||||||
|
|
||||||
.. _install-pypi:
|
.. _install-pypi:
|
||||||
|
@ -15,33 +15,44 @@ parsing the `CommonMark`__ Markdown flavor.
|
|||||||
__ https://daringfireball.net/projects/markdown/
|
__ https://daringfireball.net/projects/markdown/
|
||||||
__ https://recommonmark.readthedocs.io/en/latest/index.html
|
__ https://recommonmark.readthedocs.io/en/latest/index.html
|
||||||
__ https://github.com/rtfd/CommonMark-py
|
__ https://github.com/rtfd/CommonMark-py
|
||||||
__ http://commonmark.org/
|
__ https://commonmark.org/
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
To configure your Sphinx project for Markdown support, proceed as follows:
|
To configure your Sphinx project for Markdown support, proceed as follows:
|
||||||
|
|
||||||
#. Install *recommonmark*::
|
#. Install the Markdown parser *recommonmark*::
|
||||||
|
|
||||||
pip install recommonmark
|
pip install --upgrade recommonmark
|
||||||
|
|
||||||
#. Add the Markdown parser to the ``source_parsers`` configuration variable in
|
.. note::
|
||||||
your Sphinx configuration file::
|
|
||||||
|
|
||||||
source_parsers = {
|
The configuration as explained here requires recommonmark version
|
||||||
'.md': 'recommonmark.parser.CommonMarkParser',
|
0.5.0 or later.
|
||||||
|
|
||||||
|
#. Add *recommonmark* to the
|
||||||
|
:confval:`list of configured extensions <extensions>`::
|
||||||
|
|
||||||
|
extensions = ['recommonmark']
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8
|
||||||
|
Version 1.8 deprecates and version 3.0 removes the ``source_parsers``
|
||||||
|
configuration variable that was used by older *recommonmark* versions.
|
||||||
|
|
||||||
|
#. If you want to use Markdown files with extensions other than ``.md``, adjust
|
||||||
|
the :confval:`source_suffix` variable. The following example configures
|
||||||
|
Sphinx to parse all files with the extensions ``.md`` and ``.txt`` as
|
||||||
|
Markdown::
|
||||||
|
|
||||||
|
source_suffix = {
|
||||||
|
'.rst': 'restructuredtext',
|
||||||
|
'.txt': 'markdown',
|
||||||
|
'.md': 'markdown',
|
||||||
}
|
}
|
||||||
|
|
||||||
You can replace ``.md`` with a filename extension of your choice.
|
|
||||||
|
|
||||||
#. Add the Markdown filename extension to the ``source_suffix`` configuration
|
|
||||||
variable::
|
|
||||||
|
|
||||||
source_suffix = ['.rst', '.md']
|
|
||||||
|
|
||||||
#. You can further configure *recommonmark* to allow custom syntax that
|
#. You can further configure *recommonmark* to allow custom syntax that
|
||||||
standard *CommonMark* doesn't support. Read more in the `recommonmark
|
standard *CommonMark* doesn't support. Read more in the `recommonmark
|
||||||
documentation`__.
|
documentation`__.
|
||||||
|
|
||||||
__ https://recommonmark.readthedocs.io/en/latest/auto_structify.html
|
__ https://recommonmark.readthedocs.io/en/latest/auto_structify.html
|
||||||
|
@ -289,7 +289,7 @@ Intersphinx
|
|||||||
-----------
|
-----------
|
||||||
|
|
||||||
Many Sphinx documents including the `Python documentation`_ are published on
|
Many Sphinx documents including the `Python documentation`_ are published on
|
||||||
the internet. When you want to make links to such documents from your
|
the Internet. When you want to make links to such documents from your
|
||||||
documentation, you can do it with :mod:`sphinx.ext.intersphinx`.
|
documentation, you can do it with :mod:`sphinx.ext.intersphinx`.
|
||||||
|
|
||||||
.. _Python documentation: https://docs.python.org/3
|
.. _Python documentation: https://docs.python.org/3
|
||||||
@ -320,8 +320,8 @@ More topics to be covered
|
|||||||
|
|
||||||
- :doc:`Other extensions </usage/extensions/index>`:
|
- :doc:`Other extensions </usage/extensions/index>`:
|
||||||
- Static files
|
- Static files
|
||||||
- :doc:`Selecting a theme </theming>`
|
- :doc:`Selecting a theme </usage/theming>`
|
||||||
- :doc:`/setuptools`
|
- :doc:`/usage/advanced/setuptools`
|
||||||
- :ref:`Templating <templating>`
|
- :ref:`Templating <templating>`
|
||||||
- Using extensions
|
- Using extensions
|
||||||
- :ref:`Writing extensions <dev-extensions>`
|
- :ref:`Writing extensions <dev-extensions>`
|
||||||
|
@ -463,7 +463,7 @@ __ http://pygments.org/docs/lexers/
|
|||||||
|
|
||||||
This will produce line numbers for all code blocks longer than five lines.
|
This will produce line numbers for all code blocks longer than five lines.
|
||||||
|
|
||||||
.. rst:directive:: .. code-block:: language
|
.. rst:directive:: .. code-block:: [language]
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
@ -471,9 +471,11 @@ __ http://pygments.org/docs/lexers/
|
|||||||
|
|
||||||
Some Ruby code.
|
Some Ruby code.
|
||||||
|
|
||||||
The directive's alias name :rst:dir:`sourcecode` works as well. As with
|
The directive's alias name :rst:dir:`sourcecode` works as well. This
|
||||||
:rst:dir:`highlight`\ 's ``language`` option, ``language`` can be any lexer
|
directive takes a language name as an argument. It can be any lexer alias
|
||||||
alias supported by Pygments.
|
supported by Pygments. If it is not given, the setting of
|
||||||
|
:rst:dir:`highlight` directive will be used. If not set,
|
||||||
|
:confval:`highlight_language` will be used.
|
||||||
|
|
||||||
**Additional options**
|
**Additional options**
|
||||||
|
|
||||||
@ -523,15 +525,18 @@ __ http://pygments.org/docs/lexers/
|
|||||||
|
|
||||||
some ruby code
|
some ruby code
|
||||||
|
|
||||||
.. versionchanged:: 1.1
|
.. versionchanged:: 1.1
|
||||||
The ``emphasize-lines`` option has been added.
|
The ``emphasize-lines`` option has been added.
|
||||||
|
|
||||||
.. versionchanged:: 1.3
|
.. versionchanged:: 1.3
|
||||||
The ``lineno-start``, ``caption``, ``name`` and ``dedent`` options have
|
The ``lineno-start``, ``caption``, ``name`` and ``dedent`` options have
|
||||||
been added.
|
been added.
|
||||||
|
|
||||||
.. versionchanged:: 1.6.6
|
.. versionchanged:: 1.6.6
|
||||||
LaTeX supports the ``emphasize-lines`` option.
|
LaTeX supports the ``emphasize-lines`` option.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
The ``language`` argument becomes optional.
|
||||||
|
|
||||||
.. rst:directive:: .. literalinclude:: filename
|
.. rst:directive:: .. literalinclude:: filename
|
||||||
|
|
||||||
@ -1063,6 +1068,15 @@ or use Python raw strings (``r"raw"``).
|
|||||||
|
|
||||||
.. _AmSMath LaTeX package: https://www.ams.org/publications/authors/tex/amslatex
|
.. _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
|
Grammar production displays
|
||||||
---------------------------
|
---------------------------
|
||||||
|
@ -541,18 +541,23 @@ The C++ Domain
|
|||||||
|
|
||||||
The C++ domain (name **cpp**) supports documenting C++ projects.
|
The C++ domain (name **cpp**) supports documenting C++ projects.
|
||||||
|
|
||||||
Directives
|
Directives for Declaring Entities
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The following directives are available. All declarations can start with a
|
The following directives are available. All declarations can start with a
|
||||||
visibility statement (``public``, ``private`` or ``protected``).
|
visibility statement (``public``, ``private`` or ``protected``).
|
||||||
|
|
||||||
.. rst:directive:: .. cpp:class:: class specifier
|
.. rst:directive:: .. cpp:class:: class specifier
|
||||||
|
.. cpp:struct:: class specifier
|
||||||
|
|
||||||
Describe a class/struct, possibly with specification of inheritance, e.g.,::
|
Describe a class/struct, possibly with specification of inheritance, e.g.,::
|
||||||
|
|
||||||
.. cpp:class:: MyClass : public MyBase, MyOtherBase
|
.. cpp:class:: MyClass : public MyBase, MyOtherBase
|
||||||
|
|
||||||
|
The difference between :rst:dir:`cpp:class` and :rst:dir:`cpp:struct` is
|
||||||
|
only cosmetic: the prefix rendered in the output, and the specifier shown
|
||||||
|
in the index.
|
||||||
|
|
||||||
The class can be directly declared inside a nested scope, e.g.,::
|
The class can be directly declared inside a nested scope, e.g.,::
|
||||||
|
|
||||||
.. cpp:class:: OuterScope::MyClass : public MyBase, MyOtherBase
|
.. cpp:class:: OuterScope::MyClass : public MyBase, MyOtherBase
|
||||||
@ -574,6 +579,9 @@ visibility statement (``public``, ``private`` or ``protected``).
|
|||||||
.. cpp:class:: template<typename T> \
|
.. cpp:class:: template<typename T> \
|
||||||
std::array<T, 42>
|
std::array<T, 42>
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
The :rst:dir:`cpp:struct` directive.
|
||||||
|
|
||||||
.. rst:directive:: .. cpp:function:: (member) function prototype
|
.. rst:directive:: .. cpp:function:: (member) function prototype
|
||||||
|
|
||||||
Describe a function or member function, e.g.,::
|
Describe a function or member function, e.g.,::
|
||||||
@ -706,6 +714,8 @@ visibility statement (``public``, ``private`` or ``protected``).
|
|||||||
|
|
||||||
Describe a union.
|
Describe a union.
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
.. rst:directive:: .. cpp:concept:: template-parameter-list name
|
.. rst:directive:: .. cpp:concept:: template-parameter-list name
|
||||||
|
|
||||||
.. warning:: The support for concepts is experimental. It is based on the
|
.. warning:: The support for concepts is experimental. It is based on the
|
||||||
@ -750,6 +760,9 @@ visibility statement (``public``, ``private`` or ``protected``).
|
|||||||
- :cpp:expr:`++r`, with return type :cpp:expr:`It&`, when :cpp:expr:`r`
|
- :cpp:expr:`++r`, with return type :cpp:expr:`It&`, when :cpp:expr:`r`
|
||||||
is incrementable.
|
is incrementable.
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
|
||||||
Options
|
Options
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
@ -759,6 +772,8 @@ Some directives support options:
|
|||||||
- ``:tparam-line-spec:``, for templated declarations.
|
- ``:tparam-line-spec:``, for templated declarations.
|
||||||
If specified, each template parameter will be rendered on a separate line.
|
If specified, each template parameter will be rendered on a separate line.
|
||||||
|
|
||||||
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
Anonymous Entities
|
Anonymous Entities
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -793,6 +808,45 @@ This will be rendered as:
|
|||||||
|
|
||||||
Explicit ref: :cpp:var:`Data::@data::a`. Short-hand ref: :cpp:var:`Data::a`.
|
Explicit ref: :cpp:var:`Data::@data::a`. Short-hand ref: :cpp:var:`Data::a`.
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
|
|
||||||
|
Aliasing Declarations
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Sometimes it may be helpful list declarations elsewhere than their main documentation,
|
||||||
|
e.g., when creating a synopsis of a class interface.
|
||||||
|
The following directive can be used for this purpose.
|
||||||
|
|
||||||
|
.. rst:directive:: .. cpp:alias:: name or function signature
|
||||||
|
|
||||||
|
Insert one or more alias declarations. Each entity can be specified
|
||||||
|
as they can in the :rst:role:`cpp:any` role.
|
||||||
|
If the name of a function is given (as opposed to the complete signature),
|
||||||
|
then all overloads of the function will be listed.
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
.. cpp:alias:: Data::a
|
||||||
|
overload_example::C::f
|
||||||
|
|
||||||
|
becomes
|
||||||
|
|
||||||
|
.. cpp:alias:: Data::a
|
||||||
|
overload_example::C::f
|
||||||
|
|
||||||
|
whereas::
|
||||||
|
|
||||||
|
.. cpp:alias:: void overload_example::C::f(double d) const
|
||||||
|
void overload_example::C::f(double d)
|
||||||
|
|
||||||
|
becomes
|
||||||
|
|
||||||
|
.. cpp:alias:: void overload_example::C::f(double d) const
|
||||||
|
void overload_example::C::f(double d)
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
|
||||||
Constrained Templates
|
Constrained Templates
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -879,6 +933,11 @@ Inline Expressions and Types
|
|||||||
A type: :cpp:expr:`const MySortedContainer<int>&`
|
A type: :cpp:expr:`const MySortedContainer<int>&`
|
||||||
(or as text :cpp:texpr:`const MySortedContainer<int>&`).
|
(or as text :cpp:texpr:`const MySortedContainer<int>&`).
|
||||||
|
|
||||||
|
.. versionadded:: 1.7
|
||||||
|
The :rst:role:`cpp:expr` role.
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
The :rst:role:`cpp:texpr` role.
|
||||||
|
|
||||||
Namespacing
|
Namespacing
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
@ -941,6 +1000,8 @@ The ``cpp:namespace-pop`` directive undoes the most recent
|
|||||||
|
|
||||||
the current scope will be ``A::B::C::D``.
|
the current scope will be ``A::B::C::D``.
|
||||||
|
|
||||||
|
.. versionadded:: 1.4
|
||||||
|
|
||||||
.. rst:directive:: .. cpp:namespace-pop::
|
.. rst:directive:: .. cpp:namespace-pop::
|
||||||
|
|
||||||
Undo the previous ``cpp:namespace-push`` directive (*not* just pop a scope).
|
Undo the previous ``cpp:namespace-push`` directive (*not* just pop a scope).
|
||||||
@ -962,6 +1023,8 @@ The ``cpp:namespace-pop`` directive undoes the most recent
|
|||||||
|
|
||||||
.. cpp:namespace-push:: A::B
|
.. cpp:namespace-push:: A::B
|
||||||
|
|
||||||
|
.. versionadded:: 1.4
|
||||||
|
|
||||||
Info field lists
|
Info field lists
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -982,6 +1045,7 @@ These roles link to the given declaration types:
|
|||||||
|
|
||||||
.. rst:role:: cpp:any
|
.. rst:role:: cpp:any
|
||||||
cpp:class
|
cpp:class
|
||||||
|
cpp:struct
|
||||||
cpp:func
|
cpp:func
|
||||||
cpp:member
|
cpp:member
|
||||||
cpp:var
|
cpp:var
|
||||||
@ -993,6 +1057,9 @@ These roles link to the given declaration types:
|
|||||||
Reference a C++ declaration by name (see below for details). The name must
|
Reference a C++ declaration by name (see below for details). The name must
|
||||||
be properly qualified relative to the position of the link.
|
be properly qualified relative to the position of the link.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
The :rst:role:`cpp:struct` role as alias for the :rst:role:`cpp:class` role.
|
||||||
|
|
||||||
.. admonition:: Note on References with Templates Parameters/Arguments
|
.. admonition:: Note on References with Templates Parameters/Arguments
|
||||||
|
|
||||||
These roles follow the Sphinx :ref:`xref-syntax` rules. This means care must be
|
These roles follow the Sphinx :ref:`xref-syntax` rules. This means care must be
|
||||||
@ -1227,8 +1294,6 @@ The JavaScript domain (name **js**) provides the following directives:
|
|||||||
specified. If this option is specified, the directive will only update the
|
specified. If this option is specified, the directive will only update the
|
||||||
current module name.
|
current module name.
|
||||||
|
|
||||||
To clear the current module, set the module name to ``null`` or ``None``
|
|
||||||
|
|
||||||
.. versionadded:: 1.6
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
.. rst:directive:: .. js:function:: name(signature)
|
.. rst:directive:: .. js:function:: name(signature)
|
||||||
|
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/
|
376
package-lock.json
generated
@ -84,9 +84,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"atob": {
|
"atob": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||||
"integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
|
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"backo2": {
|
"backo2": {
|
||||||
@ -178,21 +178,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"binary-extensions": {
|
"binary-extensions": {
|
||||||
"version": "1.11.0",
|
"version": "1.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz",
|
||||||
"integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
|
"integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"blob": {
|
"blob": {
|
||||||
"version": "0.0.4",
|
"version": "0.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
|
||||||
"integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=",
|
"integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"bluebird": {
|
"bluebird": {
|
||||||
"version": "3.5.1",
|
"version": "3.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
|
||||||
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
|
"integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"body-parser": {
|
"body-parser": {
|
||||||
@ -364,9 +364,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"colors": {
|
"colors": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
|
||||||
"integrity": "sha512-jg/vxRmv430jixZrC+La5kMbUWqIg32/JsYNZb94+JEmzceYbWKTsv1OuTp+7EaqiaWRR2tPcykibwCRgclIsw==",
|
"integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"combine-lists": {
|
"combine-lists": {
|
||||||
@ -433,9 +433,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"core-js": {
|
"core-js": {
|
||||||
"version": "2.5.7",
|
"version": "2.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.2.tgz",
|
||||||
"integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==",
|
"integrity": "sha512-NdBPF/RVwPW6jr0NCILuyN9RiqLo2b1mddWHkUL+VnvcB7dzlnBJ1bXYntjpTGOgkZiiLWj2JxmOr7eGE3qK6g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
@ -549,9 +549,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"engine.io": {
|
"engine.io": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz",
|
||||||
"integrity": "sha512-mRbgmAtQ4GAlKwuPnnAvXXwdPhEx+jkc0OBCLrXuD/CRvwNK3AxRSnqK4FSqmAMRRHryVJP8TopOvmEaA64fKw==",
|
"integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"accepts": "~1.3.4",
|
"accepts": "~1.3.4",
|
||||||
@ -604,15 +604,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"engine.io-parser": {
|
"engine.io-parser": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz",
|
||||||
"integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==",
|
"integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"after": "0.8.2",
|
"after": "0.8.2",
|
||||||
"arraybuffer.slice": "~0.0.7",
|
"arraybuffer.slice": "~0.0.7",
|
||||||
"base64-arraybuffer": "0.1.5",
|
"base64-arraybuffer": "0.1.5",
|
||||||
"blob": "0.0.4",
|
"blob": "0.0.5",
|
||||||
"has-binary2": "~1.0.2"
|
"has-binary2": "~1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -859,13 +859,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flatted": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"follow-redirects": {
|
"follow-redirects": {
|
||||||
"version": "1.5.5",
|
"version": "1.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz",
|
||||||
"integrity": "sha512-GHjtHDlY/ehslqv0Gr5N0PUJppgg/q0rOBvX0na1s7y1A3LWxPqCYU76s3Z1bM4+UZB4QF0usaXLT5wFpof5PA==",
|
"integrity": "sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "^3.1.0"
|
"debug": "=3.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
"debug": {
|
||||||
@ -922,24 +928,28 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"abbrev": {
|
"abbrev": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"aproba": {
|
"aproba": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"are-we-there-yet": {
|
"are-we-there-yet": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -949,12 +959,14 @@
|
|||||||
},
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
@ -963,34 +975,40 @@
|
|||||||
},
|
},
|
||||||
"chownr": {
|
"chownr": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"code-point-at": {
|
"code-point-at": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "2.6.9",
|
"version": "2.6.9",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -999,25 +1017,29 @@
|
|||||||
},
|
},
|
||||||
"deep-extend": {
|
"deep-extend": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"delegates": {
|
"delegates": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"detect-libc": {
|
"detect-libc": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"fs-minipass": {
|
"fs-minipass": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.5",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1026,13 +1048,15 @@
|
|||||||
},
|
},
|
||||||
"fs.realpath": {
|
"fs.realpath": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"gauge": {
|
"gauge": {
|
||||||
"version": "2.7.4",
|
"version": "2.7.4",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1048,7 +1072,8 @@
|
|||||||
},
|
},
|
||||||
"glob": {
|
"glob": {
|
||||||
"version": "7.1.2",
|
"version": "7.1.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1062,13 +1087,15 @@
|
|||||||
},
|
},
|
||||||
"has-unicode": {
|
"has-unicode": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.4.21",
|
"version": "0.4.21",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1077,7 +1104,8 @@
|
|||||||
},
|
},
|
||||||
"ignore-walk": {
|
"ignore-walk": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1086,7 +1114,8 @@
|
|||||||
},
|
},
|
||||||
"inflight": {
|
"inflight": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1096,18 +1125,21 @@
|
|||||||
},
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"is-fullwidth-code-point": {
|
"is-fullwidth-code-point": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"number-is-nan": "^1.0.0"
|
"number-is-nan": "^1.0.0"
|
||||||
@ -1115,13 +1147,15 @@
|
|||||||
},
|
},
|
||||||
"isarray": {
|
"isarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"minimatch": {
|
"minimatch": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
@ -1129,12 +1163,14 @@
|
|||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.2.4",
|
"version": "2.2.4",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.1.1",
|
"safe-buffer": "^5.1.1",
|
||||||
@ -1143,7 +1179,8 @@
|
|||||||
},
|
},
|
||||||
"minizlib": {
|
"minizlib": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1152,7 +1189,8 @@
|
|||||||
},
|
},
|
||||||
"mkdirp": {
|
"mkdirp": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
@ -1160,13 +1198,15 @@
|
|||||||
},
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"needle": {
|
"needle": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1177,7 +1217,8 @@
|
|||||||
},
|
},
|
||||||
"node-pre-gyp": {
|
"node-pre-gyp": {
|
||||||
"version": "0.10.0",
|
"version": "0.10.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1195,7 +1236,8 @@
|
|||||||
},
|
},
|
||||||
"nopt": {
|
"nopt": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1205,13 +1247,15 @@
|
|||||||
},
|
},
|
||||||
"npm-bundled": {
|
"npm-bundled": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"npm-packlist": {
|
"npm-packlist": {
|
||||||
"version": "1.1.10",
|
"version": "1.1.10",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1221,7 +1265,8 @@
|
|||||||
},
|
},
|
||||||
"npmlog": {
|
"npmlog": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1233,18 +1278,21 @@
|
|||||||
},
|
},
|
||||||
"number-is-nan": {
|
"number-is-nan": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"once": {
|
"once": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
@ -1252,19 +1300,22 @@
|
|||||||
},
|
},
|
||||||
"os-homedir": {
|
"os-homedir": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"os-tmpdir": {
|
"os-tmpdir": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"osenv": {
|
"osenv": {
|
||||||
"version": "0.1.5",
|
"version": "0.1.5",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1274,19 +1325,22 @@
|
|||||||
},
|
},
|
||||||
"path-is-absolute": {
|
"path-is-absolute": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"process-nextick-args": {
|
"process-nextick-args": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"rc": {
|
"rc": {
|
||||||
"version": "1.2.7",
|
"version": "1.2.7",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1298,7 +1352,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
}
|
}
|
||||||
@ -1306,7 +1361,8 @@
|
|||||||
},
|
},
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "2.3.6",
|
"version": "2.3.6",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1321,7 +1377,8 @@
|
|||||||
},
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "2.6.2",
|
"version": "2.6.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1330,42 +1387,49 @@
|
|||||||
},
|
},
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"sax": {
|
"sax": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"set-blocking": {
|
"set-blocking": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"signal-exit": {
|
"signal-exit": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
@ -1375,7 +1439,8 @@
|
|||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1384,7 +1449,8 @@
|
|||||||
},
|
},
|
||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-regex": "^2.0.0"
|
"ansi-regex": "^2.0.0"
|
||||||
@ -1392,13 +1458,15 @@
|
|||||||
},
|
},
|
||||||
"strip-json-comments": {
|
"strip-json-comments": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"tar": {
|
"tar": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1413,13 +1481,15 @@
|
|||||||
},
|
},
|
||||||
"util-deprecate": {
|
"util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"wide-align": {
|
"wide-align": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -1428,12 +1498,14 @@
|
|||||||
},
|
},
|
||||||
"wrappy": {
|
"wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"bundled": true,
|
"resolved": false,
|
||||||
|
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1445,9 +1517,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"glob": {
|
"glob": {
|
||||||
"version": "7.1.2",
|
"version": "7.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
||||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fs.realpath": "^1.0.0",
|
"fs.realpath": "^1.0.0",
|
||||||
@ -1480,9 +1552,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"graceful-fs": {
|
"graceful-fs": {
|
||||||
"version": "4.1.11",
|
"version": "4.1.15",
|
||||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
|
||||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
"integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"has-binary2": {
|
"has-binary2": {
|
||||||
@ -1758,9 +1830,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"karma": {
|
"karma": {
|
||||||
"version": "3.0.0",
|
"version": "3.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/karma/-/karma-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/karma/-/karma-3.1.4.tgz",
|
||||||
"integrity": "sha512-ZTjyuDXVXhXsvJ1E4CnZzbCjSxD6sEdzEsFYogLuZM0yqvg/mgz+O+R1jb0J7uAQeuzdY8kJgx6hSNXLwFuHIQ==",
|
"integrity": "sha512-31Vo8Qr5glN+dZEVIpnPCxEGleqE0EY6CtC2X9TagRV3rRQ3SNrvfhddICkJgUK3AgqpeKSZau03QumTGhGoSw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"bluebird": "^3.3.0",
|
"bluebird": "^3.3.0",
|
||||||
@ -1773,11 +1845,12 @@
|
|||||||
"di": "^0.0.1",
|
"di": "^0.0.1",
|
||||||
"dom-serialize": "^2.2.0",
|
"dom-serialize": "^2.2.0",
|
||||||
"expand-braces": "^0.1.1",
|
"expand-braces": "^0.1.1",
|
||||||
|
"flatted": "^2.0.0",
|
||||||
"glob": "^7.1.1",
|
"glob": "^7.1.1",
|
||||||
"graceful-fs": "^4.1.2",
|
"graceful-fs": "^4.1.2",
|
||||||
"http-proxy": "^1.13.0",
|
"http-proxy": "^1.13.0",
|
||||||
"isbinaryfile": "^3.0.0",
|
"isbinaryfile": "^3.0.0",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.5",
|
||||||
"log4js": "^3.0.0",
|
"log4js": "^3.0.0",
|
||||||
"mime": "^2.3.1",
|
"mime": "^2.3.1",
|
||||||
"minimatch": "^3.0.2",
|
"minimatch": "^3.0.2",
|
||||||
@ -1789,7 +1862,7 @@
|
|||||||
"socket.io": "2.1.1",
|
"socket.io": "2.1.1",
|
||||||
"source-map": "^0.6.1",
|
"source-map": "^0.6.1",
|
||||||
"tmp": "0.0.33",
|
"tmp": "0.0.33",
|
||||||
"useragent": "2.2.1"
|
"useragent": "2.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"karma-chrome-launcher": {
|
"karma-chrome-launcher": {
|
||||||
@ -1821,9 +1894,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.10",
|
"version": "4.17.11",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
|
||||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
|
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"lodash.debounce": {
|
"lodash.debounce": {
|
||||||
@ -1857,10 +1930,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lru-cache": {
|
"lru-cache": {
|
||||||
"version": "2.2.4",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
|
||||||
"integrity": "sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0=",
|
"integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"pseudomap": "^1.0.2",
|
||||||
|
"yallist": "^2.1.2"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"map-cache": {
|
"map-cache": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
@ -1911,18 +1988,18 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"mime-db": {
|
"mime-db": {
|
||||||
"version": "1.35.0",
|
"version": "1.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
|
||||||
"integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==",
|
"integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"mime-types": {
|
"mime-types": {
|
||||||
"version": "2.1.19",
|
"version": "2.1.21",
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz",
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
|
||||||
"integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==",
|
"integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"mime-db": "~1.35.0"
|
"mime-db": "~1.37.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimatch": {
|
"minimatch": {
|
||||||
@ -1977,9 +2054,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"nan": {
|
"nan": {
|
||||||
"version": "2.10.0",
|
"version": "2.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
|
||||||
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
|
"integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
@ -2166,6 +2243,12 @@
|
|||||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"pseudomap": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"qjobs": {
|
"qjobs": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
|
||||||
@ -2212,15 +2295,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"readdirp": {
|
"readdirp": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
|
||||||
"integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
|
"integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"graceful-fs": "^4.1.2",
|
"graceful-fs": "^4.1.11",
|
||||||
"minimatch": "^3.0.2",
|
"micromatch": "^3.1.10",
|
||||||
"readable-stream": "^2.0.2",
|
"readable-stream": "^2.0.2"
|
||||||
"set-immediate-shim": "^1.0.1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regex-not": {
|
"regex-not": {
|
||||||
@ -2240,9 +2322,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"repeat-element": {
|
"repeat-element": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
|
||||||
"integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
|
"integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"repeat-string": {
|
"repeat-string": {
|
||||||
@ -2276,12 +2358,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "2.6.2",
|
"version": "2.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
|
||||||
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"glob": "^7.0.5"
|
"glob": "^7.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
@ -2305,12 +2387,6 @@
|
|||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"set-immediate-shim": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
|
|
||||||
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"set-value": {
|
"set-value": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
|
||||||
@ -2811,12 +2887,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"useragent": {
|
"useragent": {
|
||||||
"version": "2.2.1",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/useragent/-/useragent-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
|
||||||
"integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=",
|
"integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"lru-cache": "2.2.x",
|
"lru-cache": "4.1.x",
|
||||||
"tmp": "0.0.x"
|
"tmp": "0.0.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2876,6 +2952,12 @@
|
|||||||
"integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=",
|
"integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||||
|
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"yeast": {
|
"yeast": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
||||||
|
@ -43,12 +43,10 @@ paths =
|
|||||||
.
|
.
|
||||||
|
|
||||||
[mypy]
|
[mypy]
|
||||||
python_version = 2.7
|
|
||||||
show_column_numbers = True
|
show_column_numbers = True
|
||||||
show_error_context = True
|
show_error_context = True
|
||||||
ignore_missing_imports = True
|
ignore_missing_imports = True
|
||||||
follow_imports = skip
|
follow_imports = skip
|
||||||
incremental = True
|
|
||||||
check_untyped_defs = True
|
check_untyped_defs = True
|
||||||
warn_unused_ignores = True
|
warn_unused_ignores = True
|
||||||
strict_optional = False
|
strict_optional = False
|
||||||
|
54
setup.py
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from distutils import log
|
from distutils import log
|
||||||
@ -11,23 +10,27 @@ import sphinx
|
|||||||
with open('README.rst') as f:
|
with open('README.rst') as f:
|
||||||
long_desc = f.read()
|
long_desc = f.read()
|
||||||
|
|
||||||
if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 4):
|
if sys.version_info < (3, 5):
|
||||||
print('ERROR: Sphinx requires at least Python 2.7 or 3.4 to run.')
|
print('ERROR: Sphinx requires at least Python 3.5 to run.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
install_requires = [
|
install_requires = [
|
||||||
'six>=1.5',
|
'sphinxcontrib-applehelp',
|
||||||
|
'sphinxcontrib-devhelp',
|
||||||
|
'sphinxcontrib-jsmath',
|
||||||
|
'sphinxcontrib-htmlhelp',
|
||||||
|
'sphinxcontrib-serializinghtml',
|
||||||
|
'sphinxcontrib-qthelp',
|
||||||
'Jinja2>=2.3',
|
'Jinja2>=2.3',
|
||||||
'Pygments>=2.0',
|
'Pygments>=2.0',
|
||||||
'docutils>=0.11',
|
'docutils>=0.12',
|
||||||
'snowballstemmer>=1.1',
|
'snowballstemmer>=1.1',
|
||||||
'babel>=1.3,!=2.0',
|
'babel>=1.3,!=2.0',
|
||||||
'alabaster>=0.7,<0.8',
|
'alabaster>=0.7,<0.8',
|
||||||
'imagesize',
|
'imagesize',
|
||||||
'requests>=2.0.0',
|
'requests>=2.5.0',
|
||||||
'setuptools',
|
'setuptools',
|
||||||
'packaging',
|
'packaging',
|
||||||
'sphinxcontrib-websupport',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
extras_require = {
|
extras_require = {
|
||||||
@ -35,13 +38,6 @@ extras_require = {
|
|||||||
':sys_platform=="win32"': [
|
':sys_platform=="win32"': [
|
||||||
'colorama>=0.3.5',
|
'colorama>=0.3.5',
|
||||||
],
|
],
|
||||||
':python_version<"3.5"': [
|
|
||||||
'typing'
|
|
||||||
],
|
|
||||||
'websupport': [
|
|
||||||
'sqlalchemy>=0.9',
|
|
||||||
'whoosh>=2.0',
|
|
||||||
],
|
|
||||||
'test': [
|
'test': [
|
||||||
'mock',
|
'mock',
|
||||||
'pytest',
|
'pytest',
|
||||||
@ -49,13 +45,8 @@ extras_require = {
|
|||||||
'html5lib',
|
'html5lib',
|
||||||
'flake8>=3.5.0',
|
'flake8>=3.5.0',
|
||||||
'flake8-import-order',
|
'flake8-import-order',
|
||||||
],
|
'mypy>=0.590',
|
||||||
'test:python_version<"3"': [
|
'docutils-stubs',
|
||||||
'enum34',
|
|
||||||
],
|
|
||||||
'test:python_version>="3"': [
|
|
||||||
'mypy',
|
|
||||||
'typed_ast',
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +56,7 @@ extras_require = {
|
|||||||
cmdclass = {}
|
cmdclass = {}
|
||||||
|
|
||||||
|
|
||||||
class Tee(object):
|
class Tee:
|
||||||
def __init__(self, stream):
|
def __init__(self, stream):
|
||||||
self.stream = stream
|
self.stream = stream
|
||||||
self.buffer = StringIO()
|
self.buffer = StringIO()
|
||||||
@ -142,7 +133,7 @@ else:
|
|||||||
domain + '.js'))
|
domain + '.js'))
|
||||||
|
|
||||||
for js_file, (locale, po_file) in zip(js_files, po_files):
|
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)
|
catalog = read_po(infile, locale)
|
||||||
|
|
||||||
if catalog.fuzzy and not self.use_fuzzy:
|
if catalog.fuzzy and not self.use_fuzzy:
|
||||||
@ -162,11 +153,11 @@ else:
|
|||||||
|
|
||||||
with open(js_file, 'wt') as outfile:
|
with open(js_file, 'wt') as outfile:
|
||||||
outfile.write('Documentation.addTranslations(')
|
outfile.write('Documentation.addTranslations(')
|
||||||
dump(dict(
|
dump({
|
||||||
messages=jscatalog,
|
'messages': jscatalog,
|
||||||
plural_expr=catalog.plural_expr,
|
'plural_expr': catalog.plural_expr,
|
||||||
locale=str(catalog.locale)
|
'locale': str(catalog.locale)
|
||||||
), outfile, sort_keys=True)
|
}, outfile, sort_keys=True)
|
||||||
outfile.write(');')
|
outfile.write(');')
|
||||||
|
|
||||||
cmdclass['compile_catalog'] = compile_catalog_plusjs
|
cmdclass['compile_catalog'] = compile_catalog_plusjs
|
||||||
@ -195,12 +186,11 @@ setup(
|
|||||||
'License :: OSI Approved :: BSD License',
|
'License :: OSI Approved :: BSD License',
|
||||||
'Operating System :: OS Independent',
|
'Operating System :: OS Independent',
|
||||||
'Programming Language :: Python',
|
'Programming Language :: Python',
|
||||||
'Programming Language :: Python :: 2',
|
|
||||||
'Programming Language :: Python :: 2.7',
|
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3 :: Only',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Programming Language :: Python :: Implementation :: CPython',
|
'Programming Language :: Python :: Implementation :: CPython',
|
||||||
'Programming Language :: Python :: Implementation :: PyPy',
|
'Programming Language :: Python :: Implementation :: PyPy',
|
||||||
'Framework :: Setuptools Plugin',
|
'Framework :: Setuptools Plugin',
|
||||||
@ -235,7 +225,7 @@ setup(
|
|||||||
'build_sphinx = sphinx.setup_command:BuildDoc',
|
'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,
|
install_requires=install_requires,
|
||||||
extras_require=extras_require,
|
extras_require=extras_require,
|
||||||
cmdclass=cmdclass,
|
cmdclass=cmdclass,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
Sphinx
|
Sphinx
|
||||||
~~~~~~
|
~~~~~~
|
||||||
@ -12,20 +11,17 @@
|
|||||||
# Keep this file executable as-is in Python 3!
|
# Keep this file executable as-is in Python 3!
|
||||||
# (Otherwise getting the version out of it from setup.py is impossible.)
|
# (Otherwise getting the version out of it from setup.py is impossible.)
|
||||||
|
|
||||||
from __future__ import absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import subprocess
|
||||||
import warnings
|
import warnings
|
||||||
from os import path
|
from os import path
|
||||||
|
from subprocess import PIPE
|
||||||
|
|
||||||
from .deprecation import RemovedInNextVersionWarning
|
from .deprecation import RemovedInNextVersionWarning
|
||||||
from .deprecation import RemovedInSphinx20Warning
|
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
# note: Don't use typing.TYPE_CHECK here (for py27 and py34).
|
from typing import Any # NOQA
|
||||||
from typing import Any, List # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
# by default, all DeprecationWarning under sphinx package will be emit.
|
# by default, all DeprecationWarning under sphinx package will be emit.
|
||||||
@ -36,8 +32,8 @@ if 'PYTHONWARNINGS' not in os.environ:
|
|||||||
warnings.filterwarnings('ignore', "'U' mode is deprecated",
|
warnings.filterwarnings('ignore', "'U' mode is deprecated",
|
||||||
DeprecationWarning, module='docutils.io')
|
DeprecationWarning, module='docutils.io')
|
||||||
|
|
||||||
__version__ = '1.8.5+'
|
__version__ = '2.0.0+'
|
||||||
__released__ = '1.8.5' # used when Sphinx builds its own docs
|
__released__ = '2.0.0' # used when Sphinx builds its own docs
|
||||||
|
|
||||||
#: Version info for better programmatic use.
|
#: Version info for better programmatic use.
|
||||||
#:
|
#:
|
||||||
@ -47,7 +43,7 @@ __released__ = '1.8.5' # used when Sphinx builds its own docs
|
|||||||
#:
|
#:
|
||||||
#: .. versionadded:: 1.2
|
#: .. versionadded:: 1.2
|
||||||
#: Before version 1.2, check the string ``sphinx.__version__``.
|
#: Before version 1.2, check the string ``sphinx.__version__``.
|
||||||
version_info = (1, 8, 5, 'beta', 0)
|
version_info = (2, 0, 0, 'beta', 2)
|
||||||
|
|
||||||
package_dir = path.abspath(path.dirname(__file__))
|
package_dir = path.abspath(path.dirname(__file__))
|
||||||
|
|
||||||
@ -59,55 +55,9 @@ if __version__.endswith('+'):
|
|||||||
__display_version__ = __version__
|
__display_version__ = __version__
|
||||||
__version__ = __version__[:-1] # remove '+' for PEP-440 version spec.
|
__version__ = __version__[:-1] # remove '+' for PEP-440 version spec.
|
||||||
try:
|
try:
|
||||||
import subprocess
|
ret = subprocess.run(['git', 'show', '-s', '--pretty=format:%h'],
|
||||||
p = subprocess.Popen(['git', 'show', '-s', '--pretty=format:%h'],
|
stdout=PIPE, stderr=PIPE, encoding='ascii')
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
if ret.stdout:
|
||||||
out, err = p.communicate()
|
__display_version__ += '/' + ret.stdout.strip()
|
||||||
if out:
|
|
||||||
__display_version__ += '/' + out.decode().strip()
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
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__
|
sphinx.__main__
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
@ -13,4 +12,4 @@ import sys
|
|||||||
|
|
||||||
from sphinx.cmd.build import main
|
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
|
sphinx.addnodes
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
@ -13,14 +12,15 @@ import warnings
|
|||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
from sphinx.deprecation import RemovedInSphinx30Warning
|
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# 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.
|
"""Node which supports translation.
|
||||||
|
|
||||||
The translation goes forward with following steps:
|
The translation goes forward with following steps:
|
||||||
@ -40,12 +40,12 @@ class translatable(object):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def apply_translated_message(self, original_message, translated_message):
|
def apply_translated_message(self, original_message, translated_message):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (str, str) -> None
|
||||||
"""Apply translated message."""
|
"""Apply translated message."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def extract_original_messages(self):
|
def extract_original_messages(self):
|
||||||
# type: () -> Sequence[unicode]
|
# type: () -> Sequence[str]
|
||||||
"""Extract translation messages.
|
"""Extract translation messages.
|
||||||
|
|
||||||
:returns: list of extracted messages or messages generator
|
:returns: list of extracted messages or messages generator
|
||||||
@ -53,7 +53,7 @@ class translatable(object):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class not_smartquotable(object):
|
class not_smartquotable:
|
||||||
"""A node which does not support smart-quotes."""
|
"""A node which does not support smart-quotes."""
|
||||||
support_smartquotes = False
|
support_smartquotes = False
|
||||||
|
|
||||||
@ -67,12 +67,12 @@ class toctree(nodes.General, nodes.Element, translatable):
|
|||||||
self['rawcaption'] = self['caption']
|
self['rawcaption'] = self['caption']
|
||||||
|
|
||||||
def apply_translated_message(self, original_message, translated_message):
|
def apply_translated_message(self, original_message, translated_message):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (str, str) -> None
|
||||||
if self.get('rawcaption') == original_message:
|
if self.get('rawcaption') == original_message:
|
||||||
self['caption'] = translated_message
|
self['caption'] = translated_message
|
||||||
|
|
||||||
def extract_original_messages(self):
|
def extract_original_messages(self):
|
||||||
# type: () -> List[unicode]
|
# type: () -> List[str]
|
||||||
if 'rawcaption' in self:
|
if 'rawcaption' in self:
|
||||||
return [self['rawcaption']]
|
return [self['rawcaption']]
|
||||||
else:
|
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.
|
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.
|
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
|
# 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):
|
class desc_returns(desc_type):
|
||||||
"""Node for a "returns" annotation (a la -> in Python)."""
|
"""Node for a "returns" annotation (a la -> in Python)."""
|
||||||
def astext(self):
|
def astext(self):
|
||||||
# type: () -> unicode
|
# type: () -> str
|
||||||
return ' -> ' + nodes.TextElement.astext(self)
|
return ' -> ' + super().astext()
|
||||||
|
|
||||||
|
|
||||||
class desc_name(nodes.Part, nodes.Inline, nodes.FixedTextElement):
|
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 = ', '
|
child_text_separator = ', '
|
||||||
|
|
||||||
def astext(self):
|
def astext(self):
|
||||||
# type: () -> unicode
|
# type: () -> str
|
||||||
return '[' + nodes.TextElement.astext(self) + ']'
|
return '[' + super().astext() + ']'
|
||||||
|
|
||||||
|
|
||||||
class desc_annotation(nodes.Part, nodes.Inline, nodes.FixedTextElement):
|
class desc_annotation(nodes.Part, nodes.Inline, nodes.FixedTextElement):
|
||||||
@ -208,7 +209,7 @@ class math(nodes.math):
|
|||||||
RemovedInSphinx30Warning, stacklevel=2)
|
RemovedInSphinx30Warning, stacklevel=2)
|
||||||
return self.astext()
|
return self.astext()
|
||||||
else:
|
else:
|
||||||
return nodes.math.__getitem__(self, key)
|
return super().__getitem__(key)
|
||||||
|
|
||||||
|
|
||||||
class math_block(nodes.math_block):
|
class math_block(nodes.math_block):
|
||||||
@ -227,7 +228,7 @@ class math_block(nodes.math_block):
|
|||||||
RemovedInSphinx30Warning, stacklevel=2)
|
RemovedInSphinx30Warning, stacklevel=2)
|
||||||
return self.astext()
|
return self.astext()
|
||||||
else:
|
else:
|
||||||
return nodes.math_block.__getitem__(self, key)
|
return super().__getitem__(key)
|
||||||
|
|
||||||
|
|
||||||
class displaymath(math_block):
|
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,
|
"""Node for meta directive -- same as docutils' standard meta node,
|
||||||
but pickleable.
|
but pickleable.
|
||||||
"""
|
"""
|
||||||
|
rawcontent = None
|
||||||
|
|
||||||
|
|
||||||
# inline nodes
|
# inline nodes
|
||||||
@ -340,15 +342,65 @@ class literal_strong(nodes.strong, not_smartquotable):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class abbreviation(nodes.Inline, nodes.TextElement):
|
class abbreviation(nodes.abbreviation):
|
||||||
"""Node for abbreviations with explanations."""
|
"""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):
|
class manpage(nodes.Inline, nodes.FixedTextElement):
|
||||||
"""Node for references to manpages."""
|
"""Node for references to manpages."""
|
||||||
|
|
||||||
|
|
||||||
# make the new nodes known to docutils; needed because the HTML writer will
|
def setup(app):
|
||||||
# choke at some point if these are not added
|
# type: (Sphinx) -> Dict[str, Any]
|
||||||
nodes._add_node_class_names(k for k in globals().keys()
|
app.add_node(toctree)
|
||||||
if k != 'nodes' and k[0] != '_')
|
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-2019 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
|
sphinx.application
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
@ -10,40 +9,39 @@
|
|||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import pickle
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from inspect import isclass
|
from inspect import isclass
|
||||||
|
from io import StringIO
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
from docutils.parsers.rst import Directive, directives, roles
|
from docutils.parsers.rst import Directive, roles
|
||||||
from six import itervalues
|
|
||||||
from six.moves import cPickle as pickle
|
|
||||||
from six.moves import cStringIO
|
|
||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
from sphinx import package_dir, locale
|
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.config import CONFIG_FILENAME # NOQA # for compatibility (RemovedInSphinx30)
|
||||||
from sphinx.deprecation import (
|
from sphinx.deprecation import (
|
||||||
RemovedInSphinx20Warning, RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
||||||
)
|
)
|
||||||
from sphinx.environment import BuildEnvironment
|
from sphinx.environment import BuildEnvironment
|
||||||
from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError
|
from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError
|
||||||
from sphinx.events import EventManager
|
from sphinx.events import EventManager
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
|
from sphinx.project import Project
|
||||||
from sphinx.registry import SphinxComponentRegistry
|
from sphinx.registry import SphinxComponentRegistry
|
||||||
from sphinx.util import docutils
|
from sphinx.util import docutils
|
||||||
from sphinx.util import import_object
|
from sphinx.util import import_object, progress_message
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util import pycompat # noqa: F401
|
|
||||||
from sphinx.util.build_phase import BuildPhase
|
from sphinx.util.build_phase import BuildPhase
|
||||||
from sphinx.util.console import bold # type: ignore
|
from sphinx.util.console import bold # type: ignore
|
||||||
from sphinx.util.docutils import directive_helper
|
from sphinx.util.docutils import directive_helper
|
||||||
from sphinx.util.i18n import find_catalog_source_files
|
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.osutil import abspath, ensuredir, relpath
|
||||||
from sphinx.util.tags import Tags
|
from sphinx.util.tags import Tags
|
||||||
|
|
||||||
@ -62,21 +60,19 @@ if False:
|
|||||||
from sphinx.util.typing import RoleFunction, TitleGetter # NOQA
|
from sphinx.util.typing import RoleFunction, TitleGetter # NOQA
|
||||||
|
|
||||||
builtin_extensions = (
|
builtin_extensions = (
|
||||||
'sphinx.builders.applehelp',
|
'sphinx.addnodes',
|
||||||
'sphinx.builders.changes',
|
'sphinx.builders.changes',
|
||||||
'sphinx.builders.epub3',
|
'sphinx.builders.epub3',
|
||||||
'sphinx.builders.devhelp',
|
'sphinx.builders.dirhtml',
|
||||||
'sphinx.builders.dummy',
|
'sphinx.builders.dummy',
|
||||||
'sphinx.builders.gettext',
|
'sphinx.builders.gettext',
|
||||||
'sphinx.builders.html',
|
'sphinx.builders.html',
|
||||||
'sphinx.builders.htmlhelp',
|
|
||||||
'sphinx.builders.latex',
|
'sphinx.builders.latex',
|
||||||
'sphinx.builders.linkcheck',
|
'sphinx.builders.linkcheck',
|
||||||
'sphinx.builders.manpage',
|
'sphinx.builders.manpage',
|
||||||
'sphinx.builders.qthelp',
|
'sphinx.builders.singlehtml',
|
||||||
'sphinx.builders.texinfo',
|
'sphinx.builders.texinfo',
|
||||||
'sphinx.builders.text',
|
'sphinx.builders.text',
|
||||||
'sphinx.builders.websupport',
|
|
||||||
'sphinx.builders.xml',
|
'sphinx.builders.xml',
|
||||||
'sphinx.config',
|
'sphinx.config',
|
||||||
'sphinx.domains.c',
|
'sphinx.domains.c',
|
||||||
@ -92,7 +88,6 @@ builtin_extensions = (
|
|||||||
'sphinx.directives.other',
|
'sphinx.directives.other',
|
||||||
'sphinx.directives.patches',
|
'sphinx.directives.patches',
|
||||||
'sphinx.extension',
|
'sphinx.extension',
|
||||||
'sphinx.io',
|
|
||||||
'sphinx.parsers',
|
'sphinx.parsers',
|
||||||
'sphinx.registry',
|
'sphinx.registry',
|
||||||
'sphinx.roles',
|
'sphinx.roles',
|
||||||
@ -108,17 +103,23 @@ builtin_extensions = (
|
|||||||
'sphinx.environment.collectors.title',
|
'sphinx.environment.collectors.title',
|
||||||
'sphinx.environment.collectors.toctree',
|
'sphinx.environment.collectors.toctree',
|
||||||
'sphinx.environment.collectors.indexentries',
|
'sphinx.environment.collectors.indexentries',
|
||||||
|
# 1st party extensions
|
||||||
|
'sphinxcontrib.applehelp',
|
||||||
|
'sphinxcontrib.devhelp',
|
||||||
|
'sphinxcontrib.htmlhelp',
|
||||||
|
'sphinxcontrib.serializinghtml',
|
||||||
|
'sphinxcontrib.qthelp',
|
||||||
# Strictly, alabaster theme is not a builtin extension,
|
# Strictly, alabaster theme is not a builtin extension,
|
||||||
# but it is loaded automatically to use it as default theme.
|
# but it is loaded automatically to use it as default theme.
|
||||||
'alabaster',
|
'alabaster',
|
||||||
) # type: Tuple[unicode, ...]
|
)
|
||||||
|
|
||||||
ENV_PICKLE_FILENAME = 'environment.pickle'
|
ENV_PICKLE_FILENAME = 'environment.pickle'
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Sphinx(object):
|
class Sphinx:
|
||||||
"""The main application class and extensibility interface.
|
"""The main application class and extensibility interface.
|
||||||
|
|
||||||
:ivar srcdir: Directory containing source.
|
:ivar srcdir: Directory containing source.
|
||||||
@ -131,20 +132,20 @@ class Sphinx(object):
|
|||||||
confoverrides=None, status=sys.stdout, warning=sys.stderr,
|
confoverrides=None, status=sys.stdout, warning=sys.stderr,
|
||||||
freshenv=False, warningiserror=False, tags=None, verbosity=0,
|
freshenv=False, warningiserror=False, tags=None, verbosity=0,
|
||||||
parallel=0, keep_going=False):
|
parallel=0, keep_going=False):
|
||||||
# type: (unicode, unicode, unicode, unicode, unicode, Dict, IO, IO, bool, bool, List[unicode], int, int, bool) -> None # NOQA
|
# type: (str, str, str, str, str, Dict, IO, IO, bool, bool, List[str], int, int, bool) -> None # NOQA
|
||||||
self.phase = BuildPhase.INITIALIZATION
|
self.phase = BuildPhase.INITIALIZATION
|
||||||
self.verbosity = verbosity
|
self.verbosity = verbosity
|
||||||
self.extensions = {} # type: Dict[unicode, Extension]
|
self.extensions = {} # type: Dict[str, Extension]
|
||||||
self._setting_up_extension = ['?'] # type: List[unicode]
|
|
||||||
self.builder = None # type: Builder
|
self.builder = None # type: Builder
|
||||||
self.env = None # type: BuildEnvironment
|
self.env = None # type: BuildEnvironment
|
||||||
|
self.project = None # type: Project
|
||||||
self.registry = SphinxComponentRegistry()
|
self.registry = SphinxComponentRegistry()
|
||||||
self.html_themes = {} # type: Dict[unicode, unicode]
|
self.html_themes = {} # type: Dict[str, str]
|
||||||
|
|
||||||
# validate provided directories
|
# validate provided directories
|
||||||
self.srcdir = abspath(srcdir) # type: unicode
|
self.srcdir = abspath(srcdir)
|
||||||
self.outdir = abspath(outdir) # type: unicode
|
self.outdir = abspath(outdir)
|
||||||
self.doctreedir = abspath(doctreedir) # type: unicode
|
self.doctreedir = abspath(doctreedir)
|
||||||
self.confdir = confdir
|
self.confdir = confdir
|
||||||
if self.confdir: # confdir is optional
|
if self.confdir: # confdir is optional
|
||||||
self.confdir = abspath(self.confdir)
|
self.confdir = abspath(self.confdir)
|
||||||
@ -163,14 +164,14 @@ class Sphinx(object):
|
|||||||
self.parallel = parallel
|
self.parallel = parallel
|
||||||
|
|
||||||
if status is None:
|
if status is None:
|
||||||
self._status = cStringIO() # type: IO
|
self._status = StringIO() # type: IO
|
||||||
self.quiet = True
|
self.quiet = True
|
||||||
else:
|
else:
|
||||||
self._status = status
|
self._status = status
|
||||||
self.quiet = False
|
self.quiet = False
|
||||||
|
|
||||||
if warning is None:
|
if warning is None:
|
||||||
self._warning = cStringIO() # type: IO
|
self._warning = StringIO() # type: IO
|
||||||
else:
|
else:
|
||||||
self._warning = warning
|
self._warning = warning
|
||||||
self._warncount = 0
|
self._warncount = 0
|
||||||
@ -199,7 +200,6 @@ class Sphinx(object):
|
|||||||
self.config = Config({}, confoverrides or {})
|
self.config = Config({}, confoverrides or {})
|
||||||
else:
|
else:
|
||||||
self.config = Config.read(self.confdir, confoverrides or {}, self.tags)
|
self.config = Config.read(self.confdir, confoverrides or {}, self.tags)
|
||||||
check_unicode(self.config)
|
|
||||||
|
|
||||||
# initialize some limited config variables before initialize i18n and loading
|
# initialize some limited config variables before initialize i18n and loading
|
||||||
# extensions
|
# extensions
|
||||||
@ -231,30 +231,28 @@ class Sphinx(object):
|
|||||||
self.preload_builder(buildername)
|
self.preload_builder(buildername)
|
||||||
|
|
||||||
if not path.isdir(outdir):
|
if not path.isdir(outdir):
|
||||||
logger.info(__('making output directory...'))
|
with progress_message(__('making output directory')):
|
||||||
ensuredir(outdir)
|
ensuredir(outdir)
|
||||||
|
|
||||||
# the config file itself can be an extension
|
# the config file itself can be an extension
|
||||||
if self.config.setup:
|
if self.config.setup:
|
||||||
self._setting_up_extension = ['conf.py']
|
prefix = __('while setting up extension %s:') % "conf.py"
|
||||||
if callable(self.config.setup):
|
with prefixed_warnings(prefix):
|
||||||
self.config.setup(self)
|
if callable(self.config.setup):
|
||||||
else:
|
self.config.setup(self)
|
||||||
raise ConfigError(
|
else:
|
||||||
__("'setup' as currently defined in conf.py isn't a Python callable. "
|
raise ConfigError(
|
||||||
"Please modify its definition to make it a callable function. This is "
|
__("'setup' as currently defined in conf.py isn't a Python callable. "
|
||||||
"needed for conf.py to behave as a Sphinx extension.")
|
"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
|
# now that we know all config values, collect them from conf.py
|
||||||
self.config.init_values()
|
self.config.init_values()
|
||||||
self.emit('config-inited', self.config)
|
self.emit('config-inited', self.config)
|
||||||
|
|
||||||
# check primary_domain if requested
|
# create the project
|
||||||
primary_domain = self.config.primary_domain
|
self.project = Project(self.srcdir, self.config.source_suffix)
|
||||||
if primary_domain and not self.registry.has_domain(primary_domain):
|
|
||||||
logger.warning(__('primary_domain %r not found, ignored.'), primary_domain)
|
|
||||||
|
|
||||||
# create the builder
|
# create the builder
|
||||||
self.builder = self.create_builder(buildername)
|
self.builder = self.create_builder(buildername)
|
||||||
# set up the build environment
|
# set up the build environment
|
||||||
@ -277,10 +275,10 @@ class Sphinx(object):
|
|||||||
user_locale_dirs, self.config.language, domains=['sphinx'],
|
user_locale_dirs, self.config.language, domains=['sphinx'],
|
||||||
charset=self.config.source_encoding):
|
charset=self.config.source_encoding):
|
||||||
catinfo.write_mo(self.config.language)
|
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:
|
else:
|
||||||
locale_dirs = []
|
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 self.config.language is not None:
|
||||||
if has_translation or self.config.language == 'en':
|
if has_translation or self.config.language == 'en':
|
||||||
# "en" never needs to be translated
|
# "en" never needs to be translated
|
||||||
@ -297,21 +295,20 @@ class Sphinx(object):
|
|||||||
self.env.find_files(self.config, self.builder)
|
self.env.find_files(self.config, self.builder)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
logger.info(bold(__('loading pickled environment... ')), nonl=True)
|
with progress_message(__('loading pickled environment')):
|
||||||
with open(filename, 'rb') as f:
|
with open(filename, 'rb') as f:
|
||||||
self.env = pickle.load(f)
|
self.env = pickle.load(f)
|
||||||
self.env.setup(self)
|
self.env.setup(self)
|
||||||
logger.info(__('done'))
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.info(__('failed: %s'), err)
|
logger.info(__('failed: %s'), err)
|
||||||
self._init_env(freshenv=True)
|
self._init_env(freshenv=True)
|
||||||
|
|
||||||
def preload_builder(self, name):
|
def preload_builder(self, name):
|
||||||
# type: (unicode) -> None
|
# type: (str) -> None
|
||||||
self.registry.preload_builder(self, name)
|
self.registry.preload_builder(self, name)
|
||||||
|
|
||||||
def create_builder(self, name):
|
def create_builder(self, name):
|
||||||
# type: (unicode) -> Builder
|
# type: (str) -> Builder
|
||||||
if name is None:
|
if name is None:
|
||||||
logger.info(__('No builder selected, using default: html'))
|
logger.info(__('No builder selected, using default: html'))
|
||||||
name = 'html'
|
name = 'html'
|
||||||
@ -327,7 +324,7 @@ class Sphinx(object):
|
|||||||
# ---- main "build" method -------------------------------------------------
|
# ---- main "build" method -------------------------------------------------
|
||||||
|
|
||||||
def build(self, force_all=False, filenames=None):
|
def build(self, force_all=False, filenames=None):
|
||||||
# type: (bool, List[unicode]) -> None
|
# type: (bool, List[str]) -> None
|
||||||
self.phase = BuildPhase.READING
|
self.phase = BuildPhase.READING
|
||||||
try:
|
try:
|
||||||
if force_all:
|
if force_all:
|
||||||
@ -369,76 +366,10 @@ class Sphinx(object):
|
|||||||
self.emit('build-finished', None)
|
self.emit('build-finished', None)
|
||||||
self.builder.cleanup()
|
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, stacklevel=2)
|
|
||||||
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, stacklevel=2)
|
|
||||||
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, stacklevel=2)
|
|
||||||
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, stacklevel=2)
|
|
||||||
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, stacklevel=2)
|
|
||||||
logger.debug(message, *args, **kwargs)
|
|
||||||
|
|
||||||
# ---- general extensibility interface -------------------------------------
|
# ---- general extensibility interface -------------------------------------
|
||||||
|
|
||||||
def setup_extension(self, extname):
|
def setup_extension(self, extname):
|
||||||
# type: (unicode) -> None
|
# type: (str) -> None
|
||||||
"""Import and setup a Sphinx extension module.
|
"""Import and setup a Sphinx extension module.
|
||||||
|
|
||||||
Load the extension given by the module *name*. Use this if your
|
Load the extension given by the module *name*. Use this if your
|
||||||
@ -449,7 +380,7 @@ class Sphinx(object):
|
|||||||
self.registry.load_extension(self, extname)
|
self.registry.load_extension(self, extname)
|
||||||
|
|
||||||
def require_sphinx(self, version):
|
def require_sphinx(self, version):
|
||||||
# type: (unicode) -> None
|
# type: (str) -> None
|
||||||
"""Check the Sphinx version if requested.
|
"""Check the Sphinx version if requested.
|
||||||
|
|
||||||
Compare *version* (which must be a ``major.minor`` version string, e.g.
|
Compare *version* (which must be a ``major.minor`` version string, e.g.
|
||||||
@ -462,7 +393,7 @@ class Sphinx(object):
|
|||||||
raise VersionRequirementError(version)
|
raise VersionRequirementError(version)
|
||||||
|
|
||||||
def import_object(self, objname, source=None):
|
def import_object(self, objname, source=None):
|
||||||
# type: (str, unicode) -> Any
|
# type: (str, str) -> Any
|
||||||
"""Import an object from a ``module.name`` string.
|
"""Import an object from a ``module.name`` string.
|
||||||
|
|
||||||
.. deprecated:: 1.8
|
.. deprecated:: 1.8
|
||||||
@ -475,7 +406,7 @@ class Sphinx(object):
|
|||||||
|
|
||||||
# event interface
|
# event interface
|
||||||
def connect(self, event, callback):
|
def connect(self, event, callback):
|
||||||
# type: (unicode, Callable) -> int
|
# type: (str, Callable) -> int
|
||||||
"""Register *callback* to be called when *event* is emitted.
|
"""Register *callback* to be called when *event* is emitted.
|
||||||
|
|
||||||
For details on available core events and the arguments of callback
|
For details on available core events and the arguments of callback
|
||||||
@ -495,7 +426,7 @@ class Sphinx(object):
|
|||||||
self.events.disconnect(listener_id)
|
self.events.disconnect(listener_id)
|
||||||
|
|
||||||
def emit(self, event, *args):
|
def emit(self, event, *args):
|
||||||
# type: (unicode, Any) -> List
|
# type: (str, Any) -> List
|
||||||
"""Emit *event* and pass *arguments* to the callback functions.
|
"""Emit *event* and pass *arguments* to the callback functions.
|
||||||
|
|
||||||
Return the return values of all callbacks as a list. Do not emit core
|
Return the return values of all callbacks as a list. Do not emit core
|
||||||
@ -510,7 +441,7 @@ class Sphinx(object):
|
|||||||
return self.events.emit(event, self, *args)
|
return self.events.emit(event, self, *args)
|
||||||
|
|
||||||
def emit_firstresult(self, event, *args):
|
def emit_firstresult(self, event, *args):
|
||||||
# type: (unicode, Any) -> Any
|
# type: (str, Any) -> Any
|
||||||
"""Emit *event* and pass *arguments* to the callback functions.
|
"""Emit *event* and pass *arguments* to the callback functions.
|
||||||
|
|
||||||
Return the result of the first callback that doesn't return ``None``.
|
Return the result of the first callback that doesn't return ``None``.
|
||||||
@ -535,7 +466,7 @@ class Sphinx(object):
|
|||||||
|
|
||||||
# TODO(stephenfin): Describe 'types' parameter
|
# TODO(stephenfin): Describe 'types' parameter
|
||||||
def add_config_value(self, name, default, rebuild, types=()):
|
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.
|
"""Register a configuration value.
|
||||||
|
|
||||||
This is necessary for Sphinx to recognize new values and set default
|
This is necessary for Sphinx to recognize new values and set default
|
||||||
@ -568,7 +499,7 @@ class Sphinx(object):
|
|||||||
self.config.add(name, default, rebuild, types)
|
self.config.add(name, default, rebuild, types)
|
||||||
|
|
||||||
def add_event(self, name):
|
def add_event(self, name):
|
||||||
# type: (unicode) -> None
|
# type: (str) -> None
|
||||||
"""Register an event called *name*.
|
"""Register an event called *name*.
|
||||||
|
|
||||||
This is needed to be able to emit it.
|
This is needed to be able to emit it.
|
||||||
@ -577,7 +508,7 @@ class Sphinx(object):
|
|||||||
self.events.add(name)
|
self.events.add(name)
|
||||||
|
|
||||||
def set_translator(self, name, translator_class, override=False):
|
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.
|
"""Register or override a Docutils translator class.
|
||||||
|
|
||||||
This is used to register a custom output translator or to replace a
|
This is used to register a custom output translator or to replace a
|
||||||
@ -591,7 +522,7 @@ class Sphinx(object):
|
|||||||
self.registry.add_translator(name, translator_class, override=override)
|
self.registry.add_translator(name, translator_class, override=override)
|
||||||
|
|
||||||
def add_node(self, node, override=False, **kwds):
|
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.
|
"""Register a Docutils node class.
|
||||||
|
|
||||||
This is necessary for Docutils internals. It may also be used in the
|
This is necessary for Docutils internals. It may also be used in the
|
||||||
@ -623,15 +554,14 @@ class Sphinx(object):
|
|||||||
"""
|
"""
|
||||||
logger.debug('[app] adding node: %r', (node, kwds))
|
logger.debug('[app] adding node: %r', (node, kwds))
|
||||||
if not override and docutils.is_node_registered(node):
|
if not override and docutils.is_node_registered(node):
|
||||||
logger.warning(__('while setting up extension %s: node class %r is '
|
logger.warning(__('node class %r is already registered, '
|
||||||
'already registered, its visitors will be overridden'),
|
'its visitors will be overridden'),
|
||||||
self._setting_up_extension[-1], node.__name__,
|
node.__name__, type='app', subtype='add_node')
|
||||||
type='app', subtype='add_node')
|
|
||||||
docutils.register_node(node)
|
docutils.register_node(node)
|
||||||
self.registry.add_translation_handlers(node, **kwds)
|
self.registry.add_translation_handlers(node, **kwds)
|
||||||
|
|
||||||
def add_enumerable_node(self, node, figtype, title_getter=None, override=False, **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.
|
"""Register a Docutils node class as a numfig target.
|
||||||
|
|
||||||
Sphinx numbers the node automatically. And then the users can refer it
|
Sphinx numbers the node automatically. And then the users can refer it
|
||||||
@ -660,14 +590,14 @@ class Sphinx(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def enumerable_nodes(self):
|
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. '
|
warnings.warn('app.enumerable_nodes() is deprecated. '
|
||||||
'Use app.get_domain("std").enumerable_nodes instead.',
|
'Use app.get_domain("std").enumerable_nodes instead.',
|
||||||
RemovedInSphinx30Warning, stacklevel=2)
|
RemovedInSphinx30Warning, stacklevel=2)
|
||||||
return self.registry.enumerable_nodes
|
return self.registry.enumerable_nodes
|
||||||
|
|
||||||
def add_directive(self, name, obj, content=None, arguments=None, override=False, **options): # NOQA
|
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.
|
"""Register a Docutils directive.
|
||||||
|
|
||||||
*name* must be the prospective directive name. There are two possible
|
*name* must be the prospective directive name. There are two possible
|
||||||
@ -720,20 +650,18 @@ class Sphinx(object):
|
|||||||
"""
|
"""
|
||||||
logger.debug('[app] adding directive: %r',
|
logger.debug('[app] adding directive: %r',
|
||||||
(name, obj, content, arguments, options))
|
(name, obj, content, arguments, options))
|
||||||
if name in directives._directives and not override:
|
if not override and docutils.is_directive_registered(name):
|
||||||
logger.warning(__('while setting up extension %s: directive %r is '
|
logger.warning(__('directive %r is already registered, it will be overridden'),
|
||||||
'already registered, it will be overridden'),
|
name, type='app', subtype='add_directive')
|
||||||
self._setting_up_extension[-1], name,
|
|
||||||
type='app', subtype='add_directive')
|
|
||||||
|
|
||||||
if not isclass(obj) or not issubclass(obj, Directive):
|
if not isclass(obj) or not issubclass(obj, Directive):
|
||||||
directive = directive_helper(obj, content, arguments, **options)
|
directive = directive_helper(obj, content, arguments, **options)
|
||||||
directives.register_directive(name, directive)
|
docutils.register_directive(name, directive)
|
||||||
else:
|
else:
|
||||||
directives.register_directive(name, obj)
|
docutils.register_directive(name, obj)
|
||||||
|
|
||||||
def add_role(self, name, role, override=False):
|
def add_role(self, name, role, override=False):
|
||||||
# type: (unicode, Any, bool) -> None
|
# type: (str, Any, bool) -> None
|
||||||
"""Register a Docutils role.
|
"""Register a Docutils role.
|
||||||
|
|
||||||
*name* must be the role name that occurs in the source, *role* the role
|
*name* must be the role name that occurs in the source, *role* the role
|
||||||
@ -745,15 +673,13 @@ class Sphinx(object):
|
|||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
"""
|
"""
|
||||||
logger.debug('[app] adding role: %r', (name, role))
|
logger.debug('[app] adding role: %r', (name, role))
|
||||||
if name in roles._roles and not override:
|
if not override and docutils.is_role_registered(name):
|
||||||
logger.warning(__('while setting up extension %s: role %r is '
|
logger.warning(__('role %r is already registered, it will be overridden'),
|
||||||
'already registered, it will be overridden'),
|
name, type='app', subtype='add_role')
|
||||||
self._setting_up_extension[-1], name,
|
docutils.register_role(name, role)
|
||||||
type='app', subtype='add_role')
|
|
||||||
roles.register_local_role(name, role)
|
|
||||||
|
|
||||||
def add_generic_role(self, name, nodeclass, override=False):
|
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 generic Docutils role.
|
||||||
|
|
||||||
Register a Docutils role that does nothing but wrap its contents in the
|
Register a Docutils role that does nothing but wrap its contents in the
|
||||||
@ -766,13 +692,11 @@ class Sphinx(object):
|
|||||||
# Don't use ``roles.register_generic_role`` because it uses
|
# Don't use ``roles.register_generic_role`` because it uses
|
||||||
# ``register_canonical_role``.
|
# ``register_canonical_role``.
|
||||||
logger.debug('[app] adding generic role: %r', (name, nodeclass))
|
logger.debug('[app] adding generic role: %r', (name, nodeclass))
|
||||||
if name in roles._roles and not override:
|
if not override and docutils.is_role_registered(name):
|
||||||
logger.warning(__('while setting up extension %s: role %r is '
|
logger.warning(__('role %r is already registered, it will be overridden'),
|
||||||
'already registered, it will be overridden'),
|
name, type='app', subtype='add_generic_role')
|
||||||
self._setting_up_extension[-1], name,
|
|
||||||
type='app', subtype='add_generic_role')
|
|
||||||
role = roles.GenericRole(name, nodeclass)
|
role = roles.GenericRole(name, nodeclass)
|
||||||
roles.register_local_role(name, role)
|
docutils.register_role(name, role)
|
||||||
|
|
||||||
def add_domain(self, domain, override=False):
|
def add_domain(self, domain, override=False):
|
||||||
# type: (Type[Domain], bool) -> None
|
# type: (Type[Domain], bool) -> None
|
||||||
@ -806,7 +730,7 @@ class Sphinx(object):
|
|||||||
|
|
||||||
def add_directive_to_domain(self, domain, name, obj, has_content=None, argument_spec=None,
|
def add_directive_to_domain(self, domain, name, obj, has_content=None, argument_spec=None,
|
||||||
override=False, **option_spec):
|
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.
|
"""Register a Docutils directive in a domain.
|
||||||
|
|
||||||
Like :meth:`add_directive`, but the directive is added to the domain
|
Like :meth:`add_directive`, but the directive is added to the domain
|
||||||
@ -821,7 +745,7 @@ class Sphinx(object):
|
|||||||
**option_spec)
|
**option_spec)
|
||||||
|
|
||||||
def add_role_to_domain(self, domain, name, role, override=False):
|
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.
|
"""Register a Docutils role in a domain.
|
||||||
|
|
||||||
Like :meth:`add_role`, but the role is added to the domain named
|
Like :meth:`add_role`, but the role is added to the domain named
|
||||||
@ -834,7 +758,7 @@ class Sphinx(object):
|
|||||||
self.registry.add_role_to_domain(domain, name, role, override=override)
|
self.registry.add_role_to_domain(domain, name, role, override=override)
|
||||||
|
|
||||||
def add_index_to_domain(self, domain, index, override=False):
|
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.
|
"""Register a custom index for a domain.
|
||||||
|
|
||||||
Add a custom *index* class to the domain named *domain*. *index* must
|
Add a custom *index* class to the domain named *domain*. *index* must
|
||||||
@ -849,7 +773,7 @@ class Sphinx(object):
|
|||||||
def add_object_type(self, directivename, rolename, indextemplate='',
|
def add_object_type(self, directivename, rolename, indextemplate='',
|
||||||
parse_node=None, ref_nodeclass=None, objname='',
|
parse_node=None, ref_nodeclass=None, objname='',
|
||||||
doc_field_types=[], override=False):
|
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.
|
"""Register a new object type.
|
||||||
|
|
||||||
This method is a very convenient way to add a new :term:`object` type
|
This method is a very convenient way to add a new :term:`object` type
|
||||||
@ -913,24 +837,9 @@ class Sphinx(object):
|
|||||||
ref_nodeclass, objname, doc_field_types,
|
ref_nodeclass, objname, doc_field_types,
|
||||||
override=override)
|
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, stacklevel=2)
|
|
||||||
self.add_object_type(directivename, rolename, indextemplate, parse_node,
|
|
||||||
ref_nodeclass, objname, doc_field_types)
|
|
||||||
|
|
||||||
def add_crossref_type(self, directivename, rolename, indextemplate='',
|
def add_crossref_type(self, directivename, rolename, indextemplate='',
|
||||||
ref_nodeclass=None, objname='', override=False):
|
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.
|
"""Register a new crossref object type.
|
||||||
|
|
||||||
This method is very similar to :meth:`add_object_type` except that the
|
This method is very similar to :meth:`add_object_type` except that the
|
||||||
@ -1009,7 +918,7 @@ class Sphinx(object):
|
|||||||
self.registry.add_post_transform(transform)
|
self.registry.add_post_transform(transform)
|
||||||
|
|
||||||
def add_javascript(self, filename, **kwargs):
|
def add_javascript(self, filename, **kwargs):
|
||||||
# type: (unicode, **unicode) -> None
|
# type: (str, **str) -> None
|
||||||
"""An alias of :meth:`add_js_file`."""
|
"""An alias of :meth:`add_js_file`."""
|
||||||
warnings.warn('The app.add_javascript() is deprecated. '
|
warnings.warn('The app.add_javascript() is deprecated. '
|
||||||
'Please use app.add_js_file() instead.',
|
'Please use app.add_js_file() instead.',
|
||||||
@ -1017,7 +926,7 @@ class Sphinx(object):
|
|||||||
self.add_js_file(filename, **kwargs)
|
self.add_js_file(filename, **kwargs)
|
||||||
|
|
||||||
def add_js_file(self, 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.
|
"""Register a JavaScript file to include in the HTML output.
|
||||||
|
|
||||||
Add *filename* to the list of JavaScript files that the default HTML
|
Add *filename* to the list of JavaScript files that the default HTML
|
||||||
@ -1044,7 +953,7 @@ class Sphinx(object):
|
|||||||
self.builder.add_js_file(filename, **kwargs) # type: ignore
|
self.builder.add_js_file(filename, **kwargs) # type: ignore
|
||||||
|
|
||||||
def add_css_file(self, filename, **kwargs):
|
def add_css_file(self, filename, **kwargs):
|
||||||
# type: (unicode, **unicode) -> None
|
# type: (str, **str) -> None
|
||||||
"""Register a stylesheet to include in the HTML output.
|
"""Register a stylesheet to include in the HTML output.
|
||||||
|
|
||||||
Add *filename* to the list of CSS files that the default HTML template
|
Add *filename* to the list of CSS files that the default HTML template
|
||||||
@ -1084,13 +993,13 @@ class Sphinx(object):
|
|||||||
self.builder.add_css_file(filename, **kwargs) # type: ignore
|
self.builder.add_css_file(filename, **kwargs) # type: ignore
|
||||||
|
|
||||||
def add_stylesheet(self, filename, alternate=False, title=None):
|
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`."""
|
"""An alias of :meth:`add_css_file`."""
|
||||||
warnings.warn('The app.add_stylesheet() is deprecated. '
|
warnings.warn('The app.add_stylesheet() is deprecated. '
|
||||||
'Please use app.add_css_file() instead.',
|
'Please use app.add_css_file() instead.',
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
|
||||||
attributes = {} # type: Dict[unicode, unicode]
|
attributes = {} # type: Dict[str, str]
|
||||||
if alternate:
|
if alternate:
|
||||||
attributes['rel'] = 'alternate stylesheet'
|
attributes['rel'] = 'alternate stylesheet'
|
||||||
else:
|
else:
|
||||||
@ -1102,7 +1011,7 @@ class Sphinx(object):
|
|||||||
self.add_css_file(filename, **attributes)
|
self.add_css_file(filename, **attributes)
|
||||||
|
|
||||||
def add_latex_package(self, packagename, options=None):
|
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.
|
r"""Register a package to include in the LaTeX source code.
|
||||||
|
|
||||||
Add *packagename* to the list of packages that LaTeX source code will
|
Add *packagename* to the list of packages that LaTeX source code will
|
||||||
@ -1121,7 +1030,7 @@ class Sphinx(object):
|
|||||||
self.registry.add_latex_package(packagename, options)
|
self.registry.add_latex_package(packagename, options)
|
||||||
|
|
||||||
def add_lexer(self, alias, lexer):
|
def add_lexer(self, alias, lexer):
|
||||||
# type: (unicode, Any) -> None
|
# type: (str, Any) -> None
|
||||||
"""Register a new lexer for source code.
|
"""Register a new lexer for source code.
|
||||||
|
|
||||||
Use *lexer*, which must be an instance of a Pygments lexer class, to
|
Use *lexer*, which must be an instance of a Pygments lexer class, to
|
||||||
@ -1155,7 +1064,7 @@ class Sphinx(object):
|
|||||||
self.add_directive('auto' + cls.objtype, AutodocDirective)
|
self.add_directive('auto' + cls.objtype, AutodocDirective)
|
||||||
|
|
||||||
def add_autodoc_attrgetter(self, typ, getter):
|
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.
|
"""Register a new ``getattr``-like function for the autodoc extension.
|
||||||
|
|
||||||
Add *getter*, which must be a function with an interface compatible to
|
Add *getter*, which must be a function with an interface compatible to
|
||||||
@ -1187,7 +1096,7 @@ class Sphinx(object):
|
|||||||
languages[cls.lang] = cls
|
languages[cls.lang] = cls
|
||||||
|
|
||||||
def add_source_suffix(self, suffix, filetype, override=False):
|
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.
|
"""Register a suffix of source files.
|
||||||
|
|
||||||
Same as :confval:`source_suffix`. The users can override this
|
Same as :confval:`source_suffix`. The users can override this
|
||||||
@ -1222,7 +1131,7 @@ class Sphinx(object):
|
|||||||
collector().enable(self)
|
collector().enable(self)
|
||||||
|
|
||||||
def add_html_theme(self, name, theme_path):
|
def add_html_theme(self, name, theme_path):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (str, str) -> None
|
||||||
"""Register a HTML Theme.
|
"""Register a HTML Theme.
|
||||||
|
|
||||||
The *name* is a name of theme, and *path* is a full path to the theme
|
The *name* is a name of theme, and *path* is a full path to the theme
|
||||||
@ -1234,7 +1143,7 @@ class Sphinx(object):
|
|||||||
self.html_themes[name] = theme_path
|
self.html_themes[name] = theme_path
|
||||||
|
|
||||||
def add_html_math_renderer(self, name, inline_renderers=None, block_renderers=None):
|
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.
|
"""Register a math renderer for HTML.
|
||||||
|
|
||||||
The *name* is a name of math renderer. Both *inline_renderers* and
|
The *name* is a name of math renderer. Both *inline_renderers* and
|
||||||
@ -1249,7 +1158,7 @@ class Sphinx(object):
|
|||||||
self.registry.add_html_math_renderer(name, inline_renderers, block_renderers)
|
self.registry.add_html_math_renderer(name, inline_renderers, block_renderers)
|
||||||
|
|
||||||
def add_message_catalog(self, catalog, locale_dir):
|
def add_message_catalog(self, catalog, locale_dir):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (str, str) -> None
|
||||||
"""Register a message catalog.
|
"""Register a message catalog.
|
||||||
|
|
||||||
The *catalog* is a name of catalog, and *locale_dir* is a base path
|
The *catalog* is a name of catalog, and *locale_dir* is a base path
|
||||||
@ -1263,7 +1172,7 @@ class Sphinx(object):
|
|||||||
|
|
||||||
# ---- other methods -------------------------------------------------
|
# ---- other methods -------------------------------------------------
|
||||||
def is_parallel_allowed(self, typ):
|
def is_parallel_allowed(self, typ):
|
||||||
# type: (unicode) -> bool
|
# type: (str) -> bool
|
||||||
"""Check parallel processing is allowed or not.
|
"""Check parallel processing is allowed or not.
|
||||||
|
|
||||||
``typ`` is a type of processing; ``'read'`` or ``'write'``.
|
``typ`` is a type of processing; ``'read'`` or ``'write'``.
|
||||||
@ -1283,7 +1192,7 @@ class Sphinx(object):
|
|||||||
else:
|
else:
|
||||||
raise ValueError('parallel type %s is not supported' % typ)
|
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)
|
allowed = getattr(ext, attrname, None)
|
||||||
if allowed is None:
|
if allowed is None:
|
||||||
logger.warning(message, ext.name)
|
logger.warning(message, ext.name)
|
||||||
@ -1294,15 +1203,22 @@ class Sphinx(object):
|
|||||||
|
|
||||||
return True
|
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
|
This class defines the interface for a "template bridge", that is, a class
|
||||||
that renders templates given a template name and a context.
|
that renders templates given a template name and a context.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def init(self, builder, theme=None, dirs=None):
|
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.
|
"""Called by the builder to initialize the template system.
|
||||||
|
|
||||||
*builder* is the builder object; you'll probably want to look at the
|
*builder* is the builder object; you'll probably want to look at the
|
||||||
@ -1322,14 +1238,14 @@ class TemplateBridge(object):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
def render(self, template, context):
|
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
|
"""Called by the builder to render a template given as a filename with
|
||||||
a specified context (a Python dictionary).
|
a specified context (a Python dictionary).
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('must be implemented in subclasses')
|
raise NotImplementedError('must be implemented in subclasses')
|
||||||
|
|
||||||
def render_string(self, template, context):
|
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
|
"""Called by the builder to render a template given as a string with a
|
||||||
specified context (a Python dictionary).
|
specified context (a Python dictionary).
|
||||||
"""
|
"""
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
sphinx.builders
|
sphinx.builders
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
@ -9,20 +8,18 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import pickle
|
||||||
import time
|
import time
|
||||||
import warnings
|
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
from docutils import nodes
|
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 import CONFIG_OK, CONFIG_CHANGED_REASON
|
||||||
from sphinx.environment.adapters.asset import ImageAdapter
|
from sphinx.environment.adapters.asset import ImageAdapter
|
||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
from sphinx.io import read_doc
|
from sphinx.io import read_doc
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import i18n, import_object, logging, rst, status_iterator
|
from sphinx.util import i18n, import_object, logging, rst, progress_message, status_iterator
|
||||||
from sphinx.util.build_phase import BuildPhase
|
from sphinx.util.build_phase import BuildPhase
|
||||||
from sphinx.util.console import bold # type: ignore
|
from sphinx.util.console import bold # type: ignore
|
||||||
from sphinx.util.docutils import sphinx_domains
|
from sphinx.util.docutils import sphinx_domains
|
||||||
@ -43,7 +40,7 @@ except ImportError:
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Callable, Dict, Iterable, List, Sequence, Set, Tuple, Union # NOQA
|
from typing import Any, Dict, Iterable, List, Sequence, Set, Tuple, Type, Union # NOQA
|
||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
from sphinx.config import Config # NOQA
|
from sphinx.config import Config # NOQA
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
from sphinx.environment import BuildEnvironment # NOQA
|
||||||
@ -54,25 +51,25 @@ if False:
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Builder(object):
|
class Builder:
|
||||||
"""
|
"""
|
||||||
Builds target formats from the reST sources.
|
Builds target formats from the reST sources.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#: The builder's name, for the -b command line option.
|
#: 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.
|
#: 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
|
#: The message emitted upon successful build completion. This can be a
|
||||||
#: printf-style template string with the following keys: ``outdir``,
|
#: printf-style template string with the following keys: ``outdir``,
|
||||||
#: ``project``
|
#: ``project``
|
||||||
epilog = '' # type: unicode
|
epilog = ''
|
||||||
|
|
||||||
#: default translator class for the builder. This can be overridden by
|
#: default translator class for the builder. This can be overridden by
|
||||||
#: :py:meth:`app.set_translator()`.
|
#: :py:meth:`app.set_translator()`.
|
||||||
default_translator_class = None # type: nodes.NodeVisitor
|
default_translator_class = None # type: Type[nodes.NodeVisitor]
|
||||||
# doctree versioning method
|
# doctree versioning method
|
||||||
versioning_method = 'none' # type: unicode
|
versioning_method = 'none'
|
||||||
versioning_compare = False
|
versioning_compare = False
|
||||||
# allow parallel write_doc() calls
|
# allow parallel write_doc() calls
|
||||||
allow_parallel = False
|
allow_parallel = False
|
||||||
@ -81,7 +78,7 @@ class Builder(object):
|
|||||||
|
|
||||||
#: The list of MIME types of image formats supported by the builder.
|
#: The list of MIME types of image formats supported by the builder.
|
||||||
#: Image files are searched in the order in which they appear here.
|
#: 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.
|
#: The builder supports remote images or not.
|
||||||
supported_remote_images = False
|
supported_remote_images = False
|
||||||
#: The builder supports data URIs or not.
|
#: The builder supports data URIs or not.
|
||||||
@ -97,8 +94,6 @@ class Builder(object):
|
|||||||
|
|
||||||
self.app = app # type: Sphinx
|
self.app = app # type: Sphinx
|
||||||
self.env = None # type: BuildEnvironment
|
self.env = None # type: BuildEnvironment
|
||||||
self.warn = app.warn # type: Callable
|
|
||||||
self.info = app.info # type: Callable
|
|
||||||
self.config = app.config # type: Config
|
self.config = app.config # type: Config
|
||||||
self.tags = app.tags # type: Tags
|
self.tags = app.tags # type: Tags
|
||||||
self.tags.add(self.format)
|
self.tags.add(self.format)
|
||||||
@ -107,11 +102,11 @@ class Builder(object):
|
|||||||
self.tags.add("builder_%s" % self.name)
|
self.tags.add("builder_%s" % self.name)
|
||||||
|
|
||||||
# images that need to be copied over (source -> dest)
|
# 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
|
# basename of images directory
|
||||||
self.imagedir = ""
|
self.imagedir = ""
|
||||||
# relative path to image directory from current docname (used at writing docs)
|
# relative path to image directory from current docname (used at writing docs)
|
||||||
self.imgpath = "" # type: unicode
|
self.imgpath = ""
|
||||||
|
|
||||||
# these get set later
|
# these get set later
|
||||||
self.parallel_ok = False
|
self.parallel_ok = False
|
||||||
@ -125,7 +120,7 @@ class Builder(object):
|
|||||||
self.versioning_compare)
|
self.versioning_compare)
|
||||||
|
|
||||||
def get_translator_class(self, *args):
|
def get_translator_class(self, *args):
|
||||||
# type: (Any) -> nodes.NodeVisitor
|
# type: (Any) -> Type[nodes.NodeVisitor]
|
||||||
"""Return a class of translator."""
|
"""Return a class of translator."""
|
||||||
return self.app.registry.get_translator_class(self)
|
return self.app.registry.get_translator_class(self)
|
||||||
|
|
||||||
@ -138,22 +133,6 @@ class Builder(object):
|
|||||||
"""
|
"""
|
||||||
return self.app.registry.create_translator(self, *args)
|
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, stacklevel=2)
|
|
||||||
return None
|
|
||||||
return self.create_translator
|
|
||||||
|
|
||||||
# helper methods
|
# helper methods
|
||||||
def init(self):
|
def init(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
@ -173,7 +152,7 @@ class Builder(object):
|
|||||||
self.templates = BuiltinTemplateLoader()
|
self.templates = BuiltinTemplateLoader()
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname, typ=None):
|
||||||
# type: (unicode, unicode) -> unicode
|
# type: (str, str) -> str
|
||||||
"""Return the target URI for a document name.
|
"""Return the target URI for a document name.
|
||||||
|
|
||||||
*typ* can be used to qualify the link characteristic for individual
|
*typ* can be used to qualify the link characteristic for individual
|
||||||
@ -182,7 +161,7 @@ class Builder(object):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def get_relative_uri(self, from_, to, typ=None):
|
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.
|
"""Return a relative URI between two source filenames.
|
||||||
|
|
||||||
May raise environment.NoUri if there's no way to return a sensible URI.
|
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))
|
self.get_target_uri(to, typ))
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
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
|
"""Return an iterable of output files that are outdated, or a string
|
||||||
describing what an update build will build.
|
describing what an update build will build.
|
||||||
|
|
||||||
@ -202,7 +181,7 @@ class Builder(object):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def get_asset_paths(self):
|
def get_asset_paths(self):
|
||||||
# type: () -> List[unicode]
|
# type: () -> List[str]
|
||||||
"""Return list of paths for assets (ex. templates, CSS, etc.)."""
|
"""Return list of paths for assets (ex. templates, CSS, etc.)."""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@ -241,12 +220,12 @@ class Builder(object):
|
|||||||
# compile po methods
|
# compile po methods
|
||||||
|
|
||||||
def compile_catalogs(self, catalogs, message):
|
def compile_catalogs(self, catalogs, message):
|
||||||
# type: (Set[CatalogInfo], unicode) -> None
|
# type: (Set[CatalogInfo], str) -> None
|
||||||
if not self.config.gettext_auto_build:
|
if not self.config.gettext_auto_build:
|
||||||
return
|
return
|
||||||
|
|
||||||
def cat2relpath(cat):
|
def cat2relpath(cat):
|
||||||
# type: (CatalogInfo) -> unicode
|
# type: (CatalogInfo) -> str
|
||||||
return relpath(cat.mo_path, self.env.srcdir).replace(path.sep, SEP)
|
return relpath(cat.mo_path, self.env.srcdir).replace(path.sep, SEP)
|
||||||
|
|
||||||
logger.info(bold(__('building [mo]: ')) + message)
|
logger.info(bold(__('building [mo]: ')) + message)
|
||||||
@ -267,9 +246,9 @@ class Builder(object):
|
|||||||
self.compile_catalogs(catalogs, message)
|
self.compile_catalogs(catalogs, message)
|
||||||
|
|
||||||
def compile_specific_catalogs(self, specified_files):
|
def compile_specific_catalogs(self, specified_files):
|
||||||
# type: (List[unicode]) -> None
|
# type: (List[str]) -> None
|
||||||
def to_domain(fpath):
|
def to_domain(fpath):
|
||||||
# type: (unicode) -> unicode
|
# type: (str) -> str
|
||||||
docname = self.env.path2doc(path.abspath(fpath))
|
docname = self.env.path2doc(path.abspath(fpath))
|
||||||
if docname:
|
if docname:
|
||||||
return find_catalog(docname, self.config.gettext_compact)
|
return find_catalog(docname, self.config.gettext_compact)
|
||||||
@ -305,13 +284,13 @@ class Builder(object):
|
|||||||
self.build(None, summary=__('all source files'), method='all')
|
self.build(None, summary=__('all source files'), method='all')
|
||||||
|
|
||||||
def build_specific(self, filenames):
|
def build_specific(self, filenames):
|
||||||
# type: (List[unicode]) -> None
|
# type: (List[str]) -> None
|
||||||
"""Only rebuild as much as needed for changes in the *filenames*."""
|
"""Only rebuild as much as needed for changes in the *filenames*."""
|
||||||
# bring the filenames to the canonical format, that is,
|
# bring the filenames to the canonical format, that is,
|
||||||
# relative to the source directory and without source_suffix.
|
# relative to the source directory and without source_suffix.
|
||||||
dirlen = len(self.srcdir) + 1
|
dirlen = len(self.srcdir) + 1
|
||||||
to_write = []
|
to_write = []
|
||||||
suffixes = None # type: Tuple[unicode]
|
suffixes = None # type: Tuple[str]
|
||||||
suffixes = tuple(self.config.source_suffix) # type: ignore
|
suffixes = tuple(self.config.source_suffix) # type: ignore
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
filename = path.normpath(path.abspath(filename))
|
filename = path.normpath(path.abspath(filename))
|
||||||
@ -347,7 +326,7 @@ class Builder(object):
|
|||||||
len(to_build))
|
len(to_build))
|
||||||
|
|
||||||
def build(self, docnames, summary=None, method='update'):
|
def build(self, docnames, summary=None, method='update'):
|
||||||
# type: (Iterable[unicode], unicode, unicode) -> None
|
# type: (Iterable[str], str, str) -> None
|
||||||
"""Main build method.
|
"""Main build method.
|
||||||
|
|
||||||
First updates the environment, and then calls :meth:`write`.
|
First updates the environment, and then calls :meth:`write`.
|
||||||
@ -360,7 +339,7 @@ class Builder(object):
|
|||||||
updated_docnames = set(self.read())
|
updated_docnames = set(self.read())
|
||||||
|
|
||||||
doccount = len(updated_docnames)
|
doccount = len(updated_docnames)
|
||||||
logger.info(bold(__('looking for now-outdated files... ')), nonl=1)
|
logger.info(bold(__('looking for now-outdated files... ')), nonl=True)
|
||||||
for docname in self.env.check_dependents(self.app, updated_docnames):
|
for docname in self.env.check_dependents(self.app, updated_docnames):
|
||||||
updated_docnames.add(docname)
|
updated_docnames.add(docname)
|
||||||
outdated = len(updated_docnames) - doccount
|
outdated = len(updated_docnames) - doccount
|
||||||
@ -372,16 +351,14 @@ class Builder(object):
|
|||||||
if updated_docnames:
|
if updated_docnames:
|
||||||
# save the environment
|
# save the environment
|
||||||
from sphinx.application import ENV_PICKLE_FILENAME
|
from sphinx.application import ENV_PICKLE_FILENAME
|
||||||
logger.info(bold(__('pickling environment... ')), nonl=True)
|
with progress_message(__('pickling environment')):
|
||||||
with open(path.join(self.doctreedir, ENV_PICKLE_FILENAME), 'wb') as f:
|
with open(path.join(self.doctreedir, ENV_PICKLE_FILENAME), 'wb') as f:
|
||||||
pickle.dump(self.env, f, pickle.HIGHEST_PROTOCOL)
|
pickle.dump(self.env, f, pickle.HIGHEST_PROTOCOL)
|
||||||
logger.info(__('done'))
|
|
||||||
|
|
||||||
# global actions
|
# global actions
|
||||||
self.app.phase = BuildPhase.CONSISTENCY_CHECK
|
self.app.phase = BuildPhase.CONSISTENCY_CHECK
|
||||||
logger.info(bold(__('checking consistency... ')), nonl=True)
|
with progress_message(__('checking consistency')):
|
||||||
self.env.check_consistency()
|
self.env.check_consistency()
|
||||||
logger.info(__('done'))
|
|
||||||
else:
|
else:
|
||||||
if method == 'update' and not docnames:
|
if method == 'update' and not docnames:
|
||||||
logger.info(bold(__('no targets are out of date.')))
|
logger.info(bold(__('no targets are out of date.')))
|
||||||
@ -418,13 +395,13 @@ class Builder(object):
|
|||||||
self.finish_tasks.join()
|
self.finish_tasks.join()
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
# type: () -> List[unicode]
|
# type: () -> List[str]
|
||||||
"""(Re-)read all files new or changed since last update.
|
"""(Re-)read all files new or changed since last update.
|
||||||
|
|
||||||
Store all environment docnames in the canonical format (ie using SEP as
|
Store all environment docnames in the canonical format (ie using SEP as
|
||||||
a separator in place of os.path.sep).
|
a separator in place of os.path.sep).
|
||||||
"""
|
"""
|
||||||
logger.info(bold('updating environment: '), nonl=True)
|
logger.info(bold(__('updating environment: ')), nonl=True)
|
||||||
|
|
||||||
self.env.find_files(self.config, self)
|
self.env.find_files(self.config, self)
|
||||||
updated = (self.env.config_status != CONFIG_OK)
|
updated = (self.env.config_status != CONFIG_OK)
|
||||||
@ -443,7 +420,7 @@ class Builder(object):
|
|||||||
if changed:
|
if changed:
|
||||||
reason = CONFIG_CHANGED_REASON.get(self.env.config_status, '')
|
reason = CONFIG_CHANGED_REASON.get(self.env.config_status, '')
|
||||||
logger.info('[%s] ', reason, nonl=True)
|
logger.info('[%s] ', reason, nonl=True)
|
||||||
logger.info('%s added, %s changed, %s removed',
|
logger.info(__('%s added, %s changed, %s removed'),
|
||||||
len(added), len(changed), len(removed))
|
len(added), len(changed), len(removed))
|
||||||
|
|
||||||
# clear all files no longer present
|
# clear all files no longer present
|
||||||
@ -481,8 +458,8 @@ class Builder(object):
|
|||||||
return sorted(docnames)
|
return sorted(docnames)
|
||||||
|
|
||||||
def _read_serial(self, docnames):
|
def _read_serial(self, docnames):
|
||||||
# type: (List[unicode]) -> None
|
# type: (List[str]) -> None
|
||||||
for docname in status_iterator(docnames, 'reading sources... ', "purple",
|
for docname in status_iterator(docnames, __('reading sources... '), "purple",
|
||||||
len(docnames), self.app.verbosity):
|
len(docnames), self.app.verbosity):
|
||||||
# remove all inventory entries for that file
|
# remove all inventory entries for that file
|
||||||
self.app.emit('env-purge-doc', self.env, docname)
|
self.app.emit('env-purge-doc', self.env, docname)
|
||||||
@ -490,14 +467,14 @@ class Builder(object):
|
|||||||
self.read_doc(docname)
|
self.read_doc(docname)
|
||||||
|
|
||||||
def _read_parallel(self, docnames, nproc):
|
def _read_parallel(self, docnames, nproc):
|
||||||
# type: (List[unicode], int) -> None
|
# type: (List[str], int) -> None
|
||||||
# clear all outdated docs at once
|
# clear all outdated docs at once
|
||||||
for docname in docnames:
|
for docname in docnames:
|
||||||
self.app.emit('env-purge-doc', self.env, docname)
|
self.app.emit('env-purge-doc', self.env, docname)
|
||||||
self.env.clear_doc(docname)
|
self.env.clear_doc(docname)
|
||||||
|
|
||||||
def read_process(docs):
|
def read_process(docs):
|
||||||
# type: (List[unicode]) -> bytes
|
# type: (List[str]) -> bytes
|
||||||
self.env.app = self.app
|
self.env.app = self.app
|
||||||
for docname in docs:
|
for docname in docs:
|
||||||
self.read_doc(docname)
|
self.read_doc(docname)
|
||||||
@ -505,23 +482,23 @@ class Builder(object):
|
|||||||
return pickle.dumps(self.env, pickle.HIGHEST_PROTOCOL)
|
return pickle.dumps(self.env, pickle.HIGHEST_PROTOCOL)
|
||||||
|
|
||||||
def merge(docs, otherenv):
|
def merge(docs, otherenv):
|
||||||
# type: (List[unicode], bytes) -> None
|
# type: (List[str], bytes) -> None
|
||||||
env = pickle.loads(otherenv)
|
env = pickle.loads(otherenv)
|
||||||
self.env.merge_info_from(docs, env, self.app)
|
self.env.merge_info_from(docs, env, self.app)
|
||||||
|
|
||||||
tasks = ParallelTasks(nproc)
|
tasks = ParallelTasks(nproc)
|
||||||
chunks = make_chunks(docnames, nproc)
|
chunks = make_chunks(docnames, nproc)
|
||||||
|
|
||||||
for chunk in status_iterator(chunks, 'reading sources... ', "purple",
|
for chunk in status_iterator(chunks, __('reading sources... '), "purple",
|
||||||
len(chunks), self.app.verbosity):
|
len(chunks), self.app.verbosity):
|
||||||
tasks.add_task(read_process, chunk, merge)
|
tasks.add_task(read_process, chunk, merge)
|
||||||
|
|
||||||
# make sure all threads have finished
|
# make sure all threads have finished
|
||||||
logger.info(bold('waiting for workers...'))
|
logger.info(bold(__('waiting for workers...')))
|
||||||
tasks.join()
|
tasks.join()
|
||||||
|
|
||||||
def read_doc(self, docname):
|
def read_doc(self, docname):
|
||||||
# type: (unicode) -> None
|
# type: (str) -> None
|
||||||
"""Parse a file and add/update inventory entries for the doctree."""
|
"""Parse a file and add/update inventory entries for the doctree."""
|
||||||
self.env.prepare_settings(docname)
|
self.env.prepare_settings(docname)
|
||||||
|
|
||||||
@ -547,7 +524,7 @@ class Builder(object):
|
|||||||
self.write_doctree(docname, doctree)
|
self.write_doctree(docname, doctree)
|
||||||
|
|
||||||
def write_doctree(self, docname, doctree):
|
def write_doctree(self, docname, doctree):
|
||||||
# type: (unicode, nodes.Node) -> None
|
# type: (str, nodes.document) -> None
|
||||||
"""Write the doctree to a file."""
|
"""Write the doctree to a file."""
|
||||||
# make it picklable
|
# make it picklable
|
||||||
doctree.reporter = None
|
doctree.reporter = None
|
||||||
@ -556,13 +533,13 @@ class Builder(object):
|
|||||||
doctree.settings.env = None
|
doctree.settings.env = None
|
||||||
doctree.settings.record_dependencies = 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))
|
ensuredir(path.dirname(doctree_filename))
|
||||||
with open(doctree_filename, 'wb') as f:
|
with open(doctree_filename, 'wb') as f:
|
||||||
pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
|
pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
|
||||||
|
|
||||||
def write(self, build_docnames, updated_docnames, method='update'):
|
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__']:
|
if build_docnames is None or build_docnames == ['__all__']:
|
||||||
# build_all
|
# build_all
|
||||||
build_docnames = self.env.found_docs
|
build_docnames = self.env.found_docs
|
||||||
@ -580,9 +557,8 @@ class Builder(object):
|
|||||||
docnames.add(tocdocname)
|
docnames.add(tocdocname)
|
||||||
docnames.add(self.config.master_doc)
|
docnames.add(self.config.master_doc)
|
||||||
|
|
||||||
logger.info(bold(__('preparing documents... ')), nonl=True)
|
with progress_message(__('preparing documents')):
|
||||||
self.prepare_writing(docnames)
|
self.prepare_writing(docnames)
|
||||||
logger.info(__('done'))
|
|
||||||
|
|
||||||
if self.parallel_ok:
|
if self.parallel_ok:
|
||||||
# number of subprocesses is parallel-1 because the main process
|
# number of subprocesses is parallel-1 because the main process
|
||||||
@ -593,7 +569,7 @@ class Builder(object):
|
|||||||
self._write_serial(sorted(docnames))
|
self._write_serial(sorted(docnames))
|
||||||
|
|
||||||
def _write_serial(self, docnames):
|
def _write_serial(self, docnames):
|
||||||
# type: (Sequence[unicode]) -> None
|
# type: (Sequence[str]) -> None
|
||||||
with logging.pending_warnings():
|
with logging.pending_warnings():
|
||||||
for docname in status_iterator(docnames, __('writing output... '), "darkgreen",
|
for docname in status_iterator(docnames, __('writing output... '), "darkgreen",
|
||||||
len(docnames), self.app.verbosity):
|
len(docnames), self.app.verbosity):
|
||||||
@ -604,9 +580,9 @@ class Builder(object):
|
|||||||
self.write_doc(docname, doctree)
|
self.write_doc(docname, doctree)
|
||||||
|
|
||||||
def _write_parallel(self, docnames, nproc):
|
def _write_parallel(self, docnames, nproc):
|
||||||
# type: (Sequence[unicode], int) -> None
|
# type: (Sequence[str], int) -> None
|
||||||
def write_process(docs):
|
def write_process(docs):
|
||||||
# type: (List[Tuple[unicode, nodes.Node]]) -> None
|
# type: (List[Tuple[str, nodes.document]]) -> None
|
||||||
self.app.phase = BuildPhase.WRITING
|
self.app.phase = BuildPhase.WRITING
|
||||||
for docname, doctree in docs:
|
for docname, doctree in docs:
|
||||||
self.write_doc(docname, doctree)
|
self.write_doc(docname, doctree)
|
||||||
@ -637,17 +613,17 @@ class Builder(object):
|
|||||||
tasks.join()
|
tasks.join()
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
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"""
|
"""A place where you can add logic before :meth:`write_doc` is run"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname, doctree):
|
||||||
# type: (unicode, nodes.Node) -> None
|
# type: (str, nodes.document) -> None
|
||||||
"""Where you actually write something to the filesystem."""
|
"""Where you actually write something to the filesystem."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def write_doc_serialized(self, docname, doctree):
|
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
|
"""Handle parts of write_doc that must be called in the main process
|
||||||
if parallel build is active.
|
if parallel build is active.
|
||||||
"""
|
"""
|
||||||
@ -670,7 +646,7 @@ class Builder(object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def get_builder_config(self, option, default):
|
def get_builder_config(self, option, default):
|
||||||
# type: (unicode, unicode) -> Any
|
# type: (str, str) -> Any
|
||||||
"""Return a builder specific option.
|
"""Return a builder specific option.
|
||||||
|
|
||||||
This method allows customization of common builder settings by
|
This method allows customization of common builder settings by
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
sphinx.builders._epub_base
|
sphinx.builders._epub_base
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -11,6 +10,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import warnings
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from os import path
|
from os import path
|
||||||
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile
|
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile
|
||||||
@ -20,6 +20,7 @@ from docutils.utils import smartquotes
|
|||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.builders.html import BuildInfo, StandaloneHTMLBuilder
|
from sphinx.builders.html import BuildInfo, StandaloneHTMLBuilder
|
||||||
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util import status_iterator
|
from sphinx.util import status_iterator
|
||||||
@ -30,15 +31,11 @@ from sphinx.util.osutil import ensuredir, copyfile
|
|||||||
try:
|
try:
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
Image = None
|
||||||
import Image
|
|
||||||
except ImportError:
|
|
||||||
Image = None
|
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, List, Tuple # NOQA
|
from typing import Any, Dict, List, Set, Tuple # NOQA
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -50,22 +47,22 @@ logger = logging.getLogger(__name__)
|
|||||||
# output but that may be customized by (re-)setting module attributes,
|
# output but that may be customized by (re-)setting module attributes,
|
||||||
# e.g. from conf.py.
|
# 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
|
# XXX These strings should be localized according to epub_language
|
||||||
GUIDE_TITLES = {
|
GUIDE_TITLES = {
|
||||||
'toc': u'Table of Contents',
|
'toc': 'Table of Contents',
|
||||||
'cover': u'Cover'
|
'cover': 'Cover'
|
||||||
}
|
}
|
||||||
|
|
||||||
MEDIA_TYPES = {
|
MEDIA_TYPES = {
|
||||||
@ -79,7 +76,7 @@ MEDIA_TYPES = {
|
|||||||
'.otf': 'application/x-font-otf',
|
'.otf': 'application/x-font-otf',
|
||||||
'.ttf': 'application/x-font-ttf',
|
'.ttf': 'application/x-font-ttf',
|
||||||
'.woff': 'application/font-woff',
|
'.woff': 'application/font-woff',
|
||||||
} # type: Dict[unicode, unicode]
|
}
|
||||||
|
|
||||||
VECTOR_GRAPHICS_EXTENSIONS = ('.svg',)
|
VECTOR_GRAPHICS_EXTENSIONS = ('.svg',)
|
||||||
|
|
||||||
@ -96,7 +93,7 @@ NavPoint = namedtuple('NavPoint', ['navpoint', 'playorder', 'text', 'refuri', 'c
|
|||||||
|
|
||||||
|
|
||||||
def sphinx_smarty_pants(t, language='en'):
|
def sphinx_smarty_pants(t, language='en'):
|
||||||
# type: (unicode, str) -> unicode
|
# type: (str, str) -> str
|
||||||
t = t.replace('"', '"')
|
t = t.replace('"', '"')
|
||||||
t = smartquotes.educateDashesOldSchool(t)
|
t = smartquotes.educateDashesOldSchool(t)
|
||||||
t = smartquotes.educateQuotes(t, language)
|
t = smartquotes.educateQuotes(t, language)
|
||||||
@ -136,8 +133,6 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
html_scaled_image_link = False
|
html_scaled_image_link = False
|
||||||
# don't generate search index or include search page
|
# don't generate search index or include search page
|
||||||
search = False
|
search = False
|
||||||
# use html5 translator by default
|
|
||||||
default_html5_translator = True
|
|
||||||
|
|
||||||
coverpage_name = COVERPAGE_NAME
|
coverpage_name = COVERPAGE_NAME
|
||||||
toctree_template = TOCTREE_TEMPLATE
|
toctree_template = TOCTREE_TEMPLATE
|
||||||
@ -151,26 +146,27 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
StandaloneHTMLBuilder.init(self)
|
super().init()
|
||||||
# the output files for epub must be .html only
|
# the output files for epub must be .html only
|
||||||
self.out_suffix = '.xhtml'
|
self.out_suffix = '.xhtml'
|
||||||
self.link_suffix = '.xhtml'
|
self.link_suffix = '.xhtml'
|
||||||
self.playorder = 0
|
self.playorder = 0
|
||||||
self.tocid = 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.use_index = self.get_builder_config('use_index', 'epub')
|
||||||
|
self.refnodes = [] # type: List[Dict[str, Any]]
|
||||||
|
|
||||||
def create_build_info(self):
|
def create_build_info(self):
|
||||||
# type: () -> BuildInfo
|
# type: () -> BuildInfo
|
||||||
return BuildInfo(self.config, self.tags, ['html', 'epub'])
|
return BuildInfo(self.config, self.tags, ['html', 'epub'])
|
||||||
|
|
||||||
def get_theme_config(self):
|
def get_theme_config(self):
|
||||||
# type: () -> Tuple[unicode, Dict]
|
# type: () -> Tuple[str, Dict]
|
||||||
return self.config.epub_theme, self.config.epub_theme_options
|
return self.config.epub_theme, self.config.epub_theme_options
|
||||||
|
|
||||||
# generic support functions
|
# generic support functions
|
||||||
def make_id(self, name):
|
def make_id(self, name):
|
||||||
# type: (unicode) -> unicode
|
# type: (str) -> str
|
||||||
# id_cache is intentionally mutable
|
# id_cache is intentionally mutable
|
||||||
"""Return a unique id for name."""
|
"""Return a unique id for name."""
|
||||||
id = self.id_cache.get(name)
|
id = self.id_cache.get(name)
|
||||||
@ -180,7 +176,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
return id
|
return id
|
||||||
|
|
||||||
def esc(self, name):
|
def esc(self, name):
|
||||||
# type: (unicode) -> unicode
|
# type: (str) -> str
|
||||||
"""Replace all characters not allowed in text an attribute values."""
|
"""Replace all characters not allowed in text an attribute values."""
|
||||||
# Like cgi.escape, but also replace apostrophe
|
# Like cgi.escape, but also replace apostrophe
|
||||||
name = name.replace('&', '&')
|
name = name.replace('&', '&')
|
||||||
@ -191,7 +187,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
return name
|
return name
|
||||||
|
|
||||||
def get_refnodes(self, doctree, result):
|
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."""
|
"""Collect section titles, their depth in the toc and the refuri."""
|
||||||
# XXX: is there a better way than checking the attribute
|
# XXX: is there a better way than checking the attribute
|
||||||
# toctree-l[1-8] on the parent node?
|
# toctree-l[1-8] on the parent node?
|
||||||
@ -209,11 +205,20 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
'text': ssp(self.esc(doctree.astext()))
|
'text': ssp(self.esc(doctree.astext()))
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
else:
|
elif isinstance(doctree, nodes.Element):
|
||||||
for elem in doctree.children:
|
for elem in doctree:
|
||||||
result = self.get_refnodes(elem, result)
|
result = self.get_refnodes(elem, result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def check_refnodes(self, nodes):
|
||||||
|
# type: (List[Dict[str, Any]]) -> None
|
||||||
|
appeared = set() # type: Set[str]
|
||||||
|
for node in nodes:
|
||||||
|
if node['refuri'] in appeared:
|
||||||
|
logger.warning(__('duplicated ToC entry found: %s'), node['refuri'])
|
||||||
|
else:
|
||||||
|
appeared.add(node['refuri'])
|
||||||
|
|
||||||
def get_toc(self):
|
def get_toc(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
"""Get the total table of contents, containing the master_doc
|
"""Get the total table of contents, containing the master_doc
|
||||||
@ -231,7 +236,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
self.toc_add_files(self.refnodes)
|
self.toc_add_files(self.refnodes)
|
||||||
|
|
||||||
def 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.
|
"""Add the master_doc, pre and post files to a list of refnodes.
|
||||||
"""
|
"""
|
||||||
refnodes.insert(0, {
|
refnodes.insert(0, {
|
||||||
@ -254,47 +259,49 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
})
|
})
|
||||||
|
|
||||||
def fix_fragment(self, prefix, fragment):
|
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 a href/id attribute with colons replaced by hyphens."""
|
||||||
return prefix + fragment.replace(':', '-')
|
return prefix + fragment.replace(':', '-')
|
||||||
|
|
||||||
def fix_ids(self, tree):
|
def fix_ids(self, tree):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.document) -> None
|
||||||
"""Replace colons with hyphens in href and id attributes.
|
"""Replace colons with hyphens in href and id attributes.
|
||||||
|
|
||||||
Some readers crash because they interpret the part as a
|
Some readers crash because they interpret the part as a
|
||||||
transport protocol specification.
|
transport protocol specification.
|
||||||
"""
|
"""
|
||||||
for node in tree.traverse(nodes.reference):
|
for reference in tree.traverse(nodes.reference):
|
||||||
if 'refuri' in node:
|
if 'refuri' in reference:
|
||||||
m = self.refuri_re.match(node['refuri'])
|
m = self.refuri_re.match(reference['refuri'])
|
||||||
if m:
|
if m:
|
||||||
node['refuri'] = self.fix_fragment(m.group(1), m.group(2))
|
reference['refuri'] = self.fix_fragment(m.group(1), m.group(2))
|
||||||
if 'refid' in node:
|
if 'refid' in reference:
|
||||||
node['refid'] = self.fix_fragment('', node['refid'])
|
reference['refid'] = self.fix_fragment('', reference['refid'])
|
||||||
for node in tree.traverse(nodes.target):
|
|
||||||
for i, node_id in enumerate(node['ids']):
|
|
||||||
if ':' in node_id:
|
|
||||||
node['ids'][i] = self.fix_fragment('', node_id)
|
|
||||||
|
|
||||||
next_node = node.next_node(siblings=True)
|
for target in tree.traverse(nodes.target):
|
||||||
if next_node and isinstance(next_node, nodes.Element):
|
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']):
|
for i, node_id in enumerate(next_node['ids']):
|
||||||
if ':' in node_id:
|
if ':' in node_id:
|
||||||
next_node['ids'][i] = self.fix_fragment('', 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 = []
|
newids = []
|
||||||
for id in ids:
|
for id in ids:
|
||||||
newids.append(self.fix_fragment('', id))
|
newids.append(self.fix_fragment('', id))
|
||||||
node.attributes['ids'] = newids
|
desc_signature.attributes['ids'] = newids
|
||||||
|
|
||||||
def add_visible_links(self, tree, show_urls='inline'):
|
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"""
|
"""Add visible link targets for external links"""
|
||||||
|
|
||||||
def make_footnote_ref(doc, label):
|
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"""
|
"""Create a footnote_reference node with children"""
|
||||||
footnote_ref = nodes.footnote_reference('[#]_')
|
footnote_ref = nodes.footnote_reference('[#]_')
|
||||||
footnote_ref.append(nodes.Text(label))
|
footnote_ref.append(nodes.Text(label))
|
||||||
@ -302,7 +309,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
return footnote_ref
|
return footnote_ref
|
||||||
|
|
||||||
def make_footnote(doc, label, uri):
|
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"""
|
"""Create a footnote node with children"""
|
||||||
footnote = nodes.footnote(uri)
|
footnote = nodes.footnote(uri)
|
||||||
para = nodes.paragraph()
|
para = nodes.paragraph()
|
||||||
@ -313,7 +320,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
return footnote
|
return footnote
|
||||||
|
|
||||||
def footnote_spot(tree):
|
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.
|
"""Find or create a spot to place footnotes.
|
||||||
|
|
||||||
The function returns the tuple (parent, index)."""
|
The function returns the tuple (parent, index)."""
|
||||||
@ -326,8 +333,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
fn = fns[-1]
|
fn = fns[-1]
|
||||||
return fn.parent, fn.parent.index(fn) + 1
|
return fn.parent, fn.parent.index(fn) + 1
|
||||||
for node in tree.traverse(nodes.rubric):
|
for node in tree.traverse(nodes.rubric):
|
||||||
if len(node.children) == 1 and \
|
if len(node) == 1 and node.astext() == FOOTNOTES_RUBRIC_NAME:
|
||||||
node.children[0].astext() == FOOTNOTES_RUBRIC_NAME:
|
|
||||||
return node.parent, node.parent.index(node) + 1
|
return node.parent, node.parent.index(node) + 1
|
||||||
doc = tree.traverse(nodes.document)[0]
|
doc = tree.traverse(nodes.document)[0]
|
||||||
rub = nodes.rubric()
|
rub = nodes.rubric()
|
||||||
@ -363,7 +369,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
fn_idx += 1
|
fn_idx += 1
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname, doctree):
|
||||||
# type: (unicode, nodes.Node) -> None
|
# type: (str, nodes.document) -> None
|
||||||
"""Write one document file.
|
"""Write one document file.
|
||||||
|
|
||||||
This method is overwritten in order to fix fragment identifiers
|
This method is overwritten in order to fix fragment identifiers
|
||||||
@ -371,10 +377,10 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
"""
|
"""
|
||||||
self.fix_ids(doctree)
|
self.fix_ids(doctree)
|
||||||
self.add_visible_links(doctree, self.config.epub_show_urls)
|
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):
|
def fix_genindex(self, tree):
|
||||||
# type: (nodes.Node) -> None
|
# type: (List[Tuple[str, List[Tuple[str, Any]]]]) -> None
|
||||||
"""Fix href attributes for genindex pages."""
|
"""Fix href attributes for genindex pages."""
|
||||||
# XXX: modifies tree inline
|
# XXX: modifies tree inline
|
||||||
# Logic modeled from themes/basic/genindex.html
|
# Logic modeled from themes/basic/genindex.html
|
||||||
@ -393,37 +399,38 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
self.fix_fragment(m.group(1), m.group(2)))
|
self.fix_fragment(m.group(1), m.group(2)))
|
||||||
|
|
||||||
def is_vector_graphics(self, filename):
|
def is_vector_graphics(self, filename):
|
||||||
# type: (unicode) -> bool
|
# type: (str) -> bool
|
||||||
"""Does the filename extension indicate a vector graphic format?"""
|
"""Does the filename extension indicate a vector graphic format?"""
|
||||||
ext = path.splitext(filename)[-1]
|
ext = path.splitext(filename)[-1]
|
||||||
return ext in VECTOR_GRAPHICS_EXTENSIONS
|
return ext in VECTOR_GRAPHICS_EXTENSIONS
|
||||||
|
|
||||||
def copy_image_files_pil(self):
|
def copy_image_files_pil(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
"""Copy images using the PIL.
|
"""Copy images using Pillow, the Python Imaging Libary.
|
||||||
The method tries to read and write the files with the PIL,
|
The method tries to read and write the files with Pillow, converting
|
||||||
converting the format and resizing the image if necessary/possible.
|
the format and resizing the image if necessary/possible.
|
||||||
"""
|
"""
|
||||||
ensuredir(path.join(self.outdir, self.imagedir))
|
ensuredir(path.join(self.outdir, self.imagedir))
|
||||||
for src in status_iterator(self.images, 'copying images... ', "brown",
|
for src in status_iterator(self.images, __('copying images... '), "brown",
|
||||||
len(self.images), self.app.verbosity):
|
len(self.images), self.app.verbosity):
|
||||||
dest = self.images[src]
|
dest = self.images[src]
|
||||||
try:
|
try:
|
||||||
img = Image.open(path.join(self.srcdir, src))
|
img = Image.open(path.join(self.srcdir, src))
|
||||||
except IOError:
|
except OSError:
|
||||||
if not self.is_vector_graphics(src):
|
if not self.is_vector_graphics(src):
|
||||||
logger.warning(__('cannot read image file %r: copying it instead'),
|
logger.warning(__('cannot read image file %r: copying it instead'),
|
||||||
path.join(self.srcdir, src))
|
path.join(self.srcdir, src))
|
||||||
try:
|
try:
|
||||||
copyfile(path.join(self.srcdir, src),
|
copyfile(path.join(self.srcdir, src),
|
||||||
path.join(self.outdir, self.imagedir, dest))
|
path.join(self.outdir, self.imagedir, dest))
|
||||||
except (IOError, OSError) as err:
|
except OSError as err:
|
||||||
logger.warning(__('cannot copy image file %r: %s'),
|
logger.warning(__('cannot copy image file %r: %s'),
|
||||||
path.join(self.srcdir, src), err)
|
path.join(self.srcdir, src), err)
|
||||||
continue
|
continue
|
||||||
if self.config.epub_fix_images:
|
if self.config.epub_fix_images:
|
||||||
if img.mode in ('P',):
|
if img.mode in ('P',):
|
||||||
# See PIL documentation for Image.convert()
|
# See the Pillow documentation for Image.convert()
|
||||||
|
# https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.convert
|
||||||
img = img.convert()
|
img = img.convert()
|
||||||
if self.config.epub_max_image_width > 0:
|
if self.config.epub_max_image_width > 0:
|
||||||
(width, height) = img.size
|
(width, height) = img.size
|
||||||
@ -433,24 +440,24 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
img = img.resize((nw, nh), Image.BICUBIC)
|
img = img.resize((nw, nh), Image.BICUBIC)
|
||||||
try:
|
try:
|
||||||
img.save(path.join(self.outdir, self.imagedir, dest))
|
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'),
|
logger.warning(__('cannot write image file %r: %s'),
|
||||||
path.join(self.srcdir, src), err)
|
path.join(self.srcdir, src), err)
|
||||||
|
|
||||||
def copy_image_files(self):
|
def copy_image_files(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
"""Copy image files to destination directory.
|
"""Copy image files to destination directory.
|
||||||
This overwritten method can use the PIL to convert image files.
|
This overwritten method can use Pillow to convert image files.
|
||||||
"""
|
"""
|
||||||
if self.images:
|
if self.images:
|
||||||
if self.config.epub_fix_images or self.config.epub_max_image_width:
|
if self.config.epub_fix_images or self.config.epub_max_image_width:
|
||||||
if not Image:
|
if not Image:
|
||||||
logger.warning(__('PIL not found - copying image files'))
|
logger.warning(__('Pillow not found - copying image files'))
|
||||||
super(EpubBuilder, self).copy_image_files()
|
super().copy_image_files()
|
||||||
else:
|
else:
|
||||||
self.copy_image_files_pil()
|
self.copy_image_files_pil()
|
||||||
else:
|
else:
|
||||||
super(EpubBuilder, self).copy_image_files()
|
super().copy_image_files()
|
||||||
|
|
||||||
def copy_download_files(self):
|
def copy_download_files(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
@ -458,7 +465,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
def handle_page(self, pagename, addctx, templatename='page.html',
|
def handle_page(self, pagename, addctx, templatename='page.html',
|
||||||
outfilename=None, event_arg=None):
|
outfilename=None, event_arg=None):
|
||||||
# type: (unicode, Dict, unicode, unicode, Any) -> None
|
# type: (str, Dict, str, str, Any) -> None
|
||||||
"""Create a rendered page.
|
"""Create a rendered page.
|
||||||
|
|
||||||
This method is overwritten for genindex pages in order to fix href link
|
This method is overwritten for genindex pages in order to fix href link
|
||||||
@ -469,30 +476,41 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
return
|
return
|
||||||
self.fix_genindex(addctx['genindexentries'])
|
self.fix_genindex(addctx['genindexentries'])
|
||||||
addctx['doctype'] = self.doctype
|
addctx['doctype'] = self.doctype
|
||||||
StandaloneHTMLBuilder.handle_page(self, pagename, addctx, templatename,
|
super().handle_page(pagename, addctx, templatename, outfilename, event_arg)
|
||||||
outfilename, event_arg)
|
|
||||||
|
|
||||||
def build_mimetype(self, outdir, outname):
|
def build_mimetype(self, outdir=None, outname='mimetype'):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (str, str) -> None
|
||||||
"""Write the metainfo file mimetype."""
|
"""Write the metainfo file mimetype."""
|
||||||
|
if outdir:
|
||||||
|
warnings.warn('The arguments of EpubBuilder.build_mimetype() is deprecated.',
|
||||||
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
else:
|
||||||
|
outdir = self.outdir
|
||||||
|
|
||||||
logger.info(__('writing %s file...'), outname)
|
logger.info(__('writing %s file...'), outname)
|
||||||
copy_asset_file(path.join(self.template_dir, 'mimetype'),
|
copy_asset_file(path.join(self.template_dir, 'mimetype'),
|
||||||
path.join(outdir, outname))
|
path.join(outdir, outname))
|
||||||
|
|
||||||
def build_container(self, outdir, outname):
|
def build_container(self, outdir=None, outname='META-INF/container.xml'):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (str, str) -> None
|
||||||
"""Write the metainfo file META-INF/container.xml."""
|
"""Write the metainfo file META-INF/container.xml."""
|
||||||
|
if outdir:
|
||||||
|
warnings.warn('The arguments of EpubBuilder.build_container() is deprecated.',
|
||||||
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
else:
|
||||||
|
outdir = self.outdir
|
||||||
|
|
||||||
logger.info(__('writing %s file...'), outname)
|
logger.info(__('writing %s file...'), outname)
|
||||||
filename = path.join(outdir, outname)
|
filename = path.join(outdir, outname)
|
||||||
ensuredir(path.dirname(filename))
|
ensuredir(path.dirname(filename))
|
||||||
copy_asset_file(path.join(self.template_dir, 'container.xml'), filename)
|
copy_asset_file(path.join(self.template_dir, 'container.xml'), filename)
|
||||||
|
|
||||||
def content_metadata(self):
|
def content_metadata(self):
|
||||||
# type: () -> Dict[unicode, Any]
|
# type: () -> Dict[str, Any]
|
||||||
"""Create a dictionary with all metadata for the content.opf
|
"""Create a dictionary with all metadata for the content.opf
|
||||||
file properly escaped.
|
file properly escaped.
|
||||||
"""
|
"""
|
||||||
metadata = {} # type: Dict[unicode, Any]
|
metadata = {} # type: Dict[str, Any]
|
||||||
metadata['title'] = self.esc(self.config.epub_title)
|
metadata['title'] = self.esc(self.config.epub_title)
|
||||||
metadata['author'] = self.esc(self.config.epub_author)
|
metadata['author'] = self.esc(self.config.epub_author)
|
||||||
metadata['uid'] = self.esc(self.config.epub_uid)
|
metadata['uid'] = self.esc(self.config.epub_uid)
|
||||||
@ -507,11 +525,17 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
metadata['guides'] = []
|
metadata['guides'] = []
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def build_content(self, outdir, outname):
|
def build_content(self, outdir=None, outname='content.opf'):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (str, str) -> None
|
||||||
"""Write the metainfo file content.opf It contains bibliographic data,
|
"""Write the metainfo file content.opf It contains bibliographic data,
|
||||||
a file list and the spine (the reading order).
|
a file list and the spine (the reading order).
|
||||||
"""
|
"""
|
||||||
|
if outdir:
|
||||||
|
warnings.warn('The arguments of EpubBuilder.build_content() is deprecated.',
|
||||||
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
else:
|
||||||
|
outdir = self.outdir
|
||||||
|
|
||||||
logger.info(__('writing %s file...'), outname)
|
logger.info(__('writing %s file...'), outname)
|
||||||
metadata = self.content_metadata()
|
metadata = self.content_metadata()
|
||||||
|
|
||||||
@ -519,7 +543,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
if not outdir.endswith(os.sep):
|
if not outdir.endswith(os.sep):
|
||||||
outdir += os.sep
|
outdir += os.sep
|
||||||
olen = len(outdir)
|
olen = len(outdir)
|
||||||
self.files = [] # type: List[unicode]
|
self.files = [] # type: List[str]
|
||||||
self.ignored_files = ['.buildinfo', 'mimetype', 'content.opf',
|
self.ignored_files = ['.buildinfo', 'mimetype', 'content.opf',
|
||||||
'toc.ncx', 'META-INF/container.xml',
|
'toc.ncx', 'META-INF/container.xml',
|
||||||
'Thumbs.db', 'ehthumbs.db', '.DS_Store',
|
'Thumbs.db', 'ehthumbs.db', '.DS_Store',
|
||||||
@ -622,17 +646,17 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
metadata)
|
metadata)
|
||||||
|
|
||||||
def new_navpoint(self, node, level, incr=True):
|
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."""
|
"""Create a new entry in the toc from the node at given level."""
|
||||||
# XXX Modifies the node
|
# XXX Modifies the node
|
||||||
if incr:
|
if incr:
|
||||||
self.playorder += 1
|
self.playorder += 1
|
||||||
self.tocid += 1
|
self.tocid += 1
|
||||||
return NavPoint(self.esc('navPoint%d' % self.tocid), self.playorder,
|
return NavPoint('navPoint%d' % self.tocid, self.playorder,
|
||||||
node['text'], node['refuri'], [])
|
node['text'], node['refuri'], [])
|
||||||
|
|
||||||
def build_navpoints(self, nodes):
|
def build_navpoints(self, nodes):
|
||||||
# type: (nodes.Node) -> List[NavPoint]
|
# type: (List[Dict[str, Any]]) -> List[NavPoint]
|
||||||
"""Create the toc navigation structure.
|
"""Create the toc navigation structure.
|
||||||
|
|
||||||
Subelements of a node are nested inside the navpoint. For nested nodes
|
Subelements of a node are nested inside the navpoint. For nested nodes
|
||||||
@ -677,20 +701,26 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
return navstack[0].children
|
return navstack[0].children
|
||||||
|
|
||||||
def toc_metadata(self, level, navpoints):
|
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
|
"""Create a dictionary with all metadata for the toc.ncx file
|
||||||
properly escaped.
|
properly escaped.
|
||||||
"""
|
"""
|
||||||
metadata = {} # type: Dict[unicode, Any]
|
metadata = {} # type: Dict[str, Any]
|
||||||
metadata['uid'] = self.config.epub_uid
|
metadata['uid'] = self.config.epub_uid
|
||||||
metadata['title'] = self.esc(self.config.epub_title)
|
metadata['title'] = self.esc(self.config.epub_title)
|
||||||
metadata['level'] = level
|
metadata['level'] = level
|
||||||
metadata['navpoints'] = navpoints
|
metadata['navpoints'] = navpoints
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def build_toc(self, outdir, outname):
|
def build_toc(self, outdir=None, outname='toc.ncx'):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (str, str) -> None
|
||||||
"""Write the metainfo file toc.ncx."""
|
"""Write the metainfo file toc.ncx."""
|
||||||
|
if outdir:
|
||||||
|
warnings.warn('The arguments of EpubBuilder.build_toc() is deprecated.',
|
||||||
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
else:
|
||||||
|
outdir = self.outdir
|
||||||
|
|
||||||
logger.info(__('writing %s file...'), outname)
|
logger.info(__('writing %s file...'), outname)
|
||||||
|
|
||||||
if self.config.epub_tocscope == 'default':
|
if self.config.epub_tocscope == 'default':
|
||||||
@ -702,6 +732,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
else:
|
else:
|
||||||
# 'includehidden'
|
# 'includehidden'
|
||||||
refnodes = self.refnodes
|
refnodes = self.refnodes
|
||||||
|
self.check_refnodes(refnodes)
|
||||||
navpoints = self.build_navpoints(refnodes)
|
navpoints = self.build_navpoints(refnodes)
|
||||||
level = max(item['level'] for item in self.refnodes)
|
level = max(item['level'] for item in self.refnodes)
|
||||||
level = min(level, self.config.epub_tocdepth)
|
level = min(level, self.config.epub_tocdepth)
|
||||||
@ -709,18 +740,25 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
path.join(outdir, outname),
|
path.join(outdir, outname),
|
||||||
self.toc_metadata(level, navpoints))
|
self.toc_metadata(level, navpoints))
|
||||||
|
|
||||||
def build_epub(self, outdir, outname):
|
def build_epub(self, outdir=None, outname=None):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (str, str) -> None
|
||||||
"""Write the epub file.
|
"""Write the epub file.
|
||||||
|
|
||||||
It is a zip file with the mimetype file stored uncompressed as the first
|
It is a zip file with the mimetype file stored uncompressed as the first
|
||||||
entry.
|
entry.
|
||||||
"""
|
"""
|
||||||
|
if outdir:
|
||||||
|
warnings.warn('The arguments of EpubBuilder.build_epub() is deprecated.',
|
||||||
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
else:
|
||||||
|
outdir = self.outdir
|
||||||
|
outname = self.config.epub_basename + '.epub'
|
||||||
|
|
||||||
logger.info(__('writing %s file...'), outname)
|
logger.info(__('writing %s file...'), outname)
|
||||||
epub_filename = path.join(outdir, outname)
|
epub_filename = path.join(outdir, outname)
|
||||||
with ZipFile(epub_filename, 'w', ZIP_DEFLATED) as epub:
|
with ZipFile(epub_filename, 'w', ZIP_DEFLATED) as epub:
|
||||||
epub.write(path.join(outdir, 'mimetype'), 'mimetype', ZIP_STORED)
|
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)
|
epub.write(path.join(outdir, filename), filename, ZIP_DEFLATED)
|
||||||
for filename in self.files:
|
for filename in self.files:
|
||||||
epub.write(path.join(outdir, filename), filename, ZIP_DEFLATED)
|
epub.write(path.join(outdir, filename), filename, ZIP_DEFLATED)
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
sphinx.builders.applehelp
|
sphinx.builders.applehelp
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -8,25 +7,16 @@
|
|||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import codecs
|
import warnings
|
||||||
import pipes
|
|
||||||
import plistlib
|
|
||||||
import shlex
|
|
||||||
import subprocess
|
|
||||||
from os import path, environ
|
|
||||||
|
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinxcontrib.applehelp import (
|
||||||
from sphinx.config import string_classes
|
AppleHelpCodeSigningFailed,
|
||||||
from sphinx.errors import SphinxError
|
AppleHelpIndexerFailed,
|
||||||
from sphinx.locale import __
|
AppleHelpBuilder,
|
||||||
from sphinx.util import logging
|
)
|
||||||
from sphinx.util.console import bold # type: ignore
|
|
||||||
from sphinx.util.fileutil import copy_asset
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
from sphinx.util.matching import Matcher
|
|
||||||
from sphinx.util.osutil import copyfile, ensuredir, make_filename
|
|
||||||
from sphinx.util.pycompat import htmlescape
|
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
@ -34,279 +24,20 @@ if False:
|
|||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
deprecated_alias('sphinx.builders.applehelp',
|
||||||
|
{
|
||||||
# Use plistlib.dump in 3.4 and above
|
'AppleHelpCodeSigningFailed': AppleHelpCodeSigningFailed,
|
||||||
try:
|
'AppleHelpIndexerFailed': AppleHelpIndexerFailed,
|
||||||
write_plist = plistlib.dump # type: ignore
|
'AppleHelpBuilder': AppleHelpBuilder,
|
||||||
except AttributeError:
|
},
|
||||||
write_plist = plistlib.writePlist
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
|
||||||
# False access page (used because helpd expects strict XHTML)
|
|
||||||
access_page_template = '''\
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\
|
|
||||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
<title>%(title)s</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<meta name="robots" content="noindex" />
|
|
||||||
<meta http-equiv="refresh" content="0;url=%(toc)s" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
class AppleHelpIndexerFailed(SphinxError):
|
|
||||||
category = __('Help indexer failed')
|
|
||||||
|
|
||||||
|
|
||||||
class AppleHelpCodeSigningFailed(SphinxError):
|
|
||||||
category = __('Code signing failed')
|
|
||||||
|
|
||||||
|
|
||||||
class AppleHelpBuilder(StandaloneHTMLBuilder):
|
|
||||||
"""
|
|
||||||
Builder that outputs an Apple help book. Requires Mac OS X as it relies
|
|
||||||
on the ``hiutil`` command line tool.
|
|
||||||
"""
|
|
||||||
name = 'applehelp'
|
|
||||||
epilog = __('The help book is in %(outdir)s.\n'
|
|
||||||
'Note that won\'t be able to view it unless you put it in '
|
|
||||||
'~/Library/Documentation/Help or install it in your application '
|
|
||||||
'bundle.')
|
|
||||||
|
|
||||||
# don't copy the reST source
|
|
||||||
copysource = False
|
|
||||||
supported_image_types = ['image/png', 'image/gif', 'image/jpeg',
|
|
||||||
'image/tiff', 'image/jp2', 'image/svg+xml']
|
|
||||||
|
|
||||||
# don't add links
|
|
||||||
add_permalinks = False
|
|
||||||
|
|
||||||
# this is an embedded HTML format
|
|
||||||
embedded = True
|
|
||||||
|
|
||||||
# don't generate the search index or include the search page
|
|
||||||
search = False
|
|
||||||
|
|
||||||
def init(self):
|
|
||||||
# type: () -> None
|
|
||||||
super(AppleHelpBuilder, self).init()
|
|
||||||
# the output files for HTML help must be .html only
|
|
||||||
self.out_suffix = '.html'
|
|
||||||
self.link_suffix = '.html'
|
|
||||||
|
|
||||||
if self.config.applehelp_bundle_id is None:
|
|
||||||
raise SphinxError(__('You must set applehelp_bundle_id before '
|
|
||||||
'building Apple Help output'))
|
|
||||||
|
|
||||||
self.bundle_path = path.join(self.outdir,
|
|
||||||
self.config.applehelp_bundle_name +
|
|
||||||
'.help')
|
|
||||||
self.outdir = path.join(self.bundle_path,
|
|
||||||
'Contents',
|
|
||||||
'Resources',
|
|
||||||
self.config.applehelp_locale + '.lproj')
|
|
||||||
|
|
||||||
def handle_finish(self):
|
|
||||||
# type: () -> None
|
|
||||||
super(AppleHelpBuilder, self).handle_finish()
|
|
||||||
|
|
||||||
self.finish_tasks.add_task(self.copy_localized_files)
|
|
||||||
self.finish_tasks.add_task(self.build_helpbook)
|
|
||||||
|
|
||||||
def copy_localized_files(self):
|
|
||||||
# type: () -> None
|
|
||||||
source_dir = path.join(self.confdir, self.config.applehelp_locale + '.lproj')
|
|
||||||
target_dir = self.outdir
|
|
||||||
|
|
||||||
if path.isdir(source_dir):
|
|
||||||
logger.info(bold(__('copying localized files... ')), nonl=True)
|
|
||||||
|
|
||||||
excluded = Matcher(self.config.exclude_patterns + ['**/.*'])
|
|
||||||
copy_asset(source_dir, target_dir, excluded,
|
|
||||||
context=self.globalcontext, renderer=self.templates)
|
|
||||||
|
|
||||||
logger.info(__('done'))
|
|
||||||
|
|
||||||
def build_helpbook(self):
|
|
||||||
# type: () -> None
|
|
||||||
contents_dir = path.join(self.bundle_path, 'Contents')
|
|
||||||
resources_dir = path.join(contents_dir, 'Resources')
|
|
||||||
language_dir = path.join(resources_dir,
|
|
||||||
self.config.applehelp_locale + '.lproj')
|
|
||||||
|
|
||||||
for d in [contents_dir, resources_dir, language_dir]:
|
|
||||||
ensuredir(d)
|
|
||||||
|
|
||||||
# Construct the Info.plist file
|
|
||||||
toc = self.config.master_doc + self.out_suffix
|
|
||||||
|
|
||||||
info_plist = {
|
|
||||||
'CFBundleDevelopmentRegion': self.config.applehelp_dev_region,
|
|
||||||
'CFBundleIdentifier': self.config.applehelp_bundle_id,
|
|
||||||
'CFBundleInfoDictionaryVersion': '6.0',
|
|
||||||
'CFBundlePackageType': 'BNDL',
|
|
||||||
'CFBundleShortVersionString': self.config.release,
|
|
||||||
'CFBundleSignature': 'hbwr',
|
|
||||||
'CFBundleVersion': self.config.applehelp_bundle_version,
|
|
||||||
'HPDBookAccessPath': '_access.html',
|
|
||||||
'HPDBookIndexPath': 'search.helpindex',
|
|
||||||
'HPDBookTitle': self.config.applehelp_title,
|
|
||||||
'HPDBookType': '3',
|
|
||||||
'HPDBookUsesExternalViewer': False,
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.config.applehelp_icon is not None:
|
|
||||||
info_plist['HPDBookIconPath'] \
|
|
||||||
= path.basename(self.config.applehelp_icon)
|
|
||||||
|
|
||||||
if self.config.applehelp_kb_url is not None:
|
|
||||||
info_plist['HPDBookKBProduct'] = self.config.applehelp_kb_product
|
|
||||||
info_plist['HPDBookKBURL'] = self.config.applehelp_kb_url
|
|
||||||
|
|
||||||
if self.config.applehelp_remote_url is not None:
|
|
||||||
info_plist['HPDBookRemoteURL'] = self.config.applehelp_remote_url
|
|
||||||
|
|
||||||
logger.info(bold(__('writing Info.plist... ')), nonl=True)
|
|
||||||
with open(path.join(contents_dir, 'Info.plist'), 'wb') as f:
|
|
||||||
write_plist(info_plist, f)
|
|
||||||
logger.info(__('done'))
|
|
||||||
|
|
||||||
# Copy the icon, if one is supplied
|
|
||||||
if self.config.applehelp_icon:
|
|
||||||
logger.info(bold(__('copying icon... ')), nonl=True)
|
|
||||||
|
|
||||||
try:
|
|
||||||
copyfile(path.join(self.srcdir, self.config.applehelp_icon),
|
|
||||||
path.join(resources_dir, info_plist['HPDBookIconPath']))
|
|
||||||
|
|
||||||
logger.info(__('done'))
|
|
||||||
except Exception as err:
|
|
||||||
logger.warning(__('cannot copy icon file %r: %s'),
|
|
||||||
path.join(self.srcdir, self.config.applehelp_icon), err)
|
|
||||||
del info_plist['HPDBookIconPath']
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
})
|
|
||||||
logger.info(__('done'))
|
|
||||||
|
|
||||||
# Generate the help index
|
|
||||||
logger.info(bold(__('generating help index... ')), nonl=True)
|
|
||||||
|
|
||||||
args = [
|
|
||||||
self.config.applehelp_indexer_path,
|
|
||||||
'-Cf',
|
|
||||||
path.join(language_dir, 'search.helpindex'),
|
|
||||||
language_dir
|
|
||||||
]
|
|
||||||
|
|
||||||
if self.config.applehelp_index_anchors is not None:
|
|
||||||
args.append('-a')
|
|
||||||
|
|
||||||
if self.config.applehelp_min_term_length is not None:
|
|
||||||
args += ['-m', '%s' % self.config.applehelp_min_term_length]
|
|
||||||
|
|
||||||
if self.config.applehelp_stopwords is not None:
|
|
||||||
args += ['-s', self.config.applehelp_stopwords]
|
|
||||||
|
|
||||||
if self.config.applehelp_locale is not None:
|
|
||||||
args += ['-l', self.config.applehelp_locale]
|
|
||||||
|
|
||||||
if self.config.applehelp_disable_external_tools:
|
|
||||||
logger.info(__('skipping'))
|
|
||||||
|
|
||||||
logger.warning(__('you will need to index this help book with:\n %s'),
|
|
||||||
' '.join([pipes.quote(arg) for arg in args]))
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
p = subprocess.Popen(args,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.STDOUT)
|
|
||||||
|
|
||||||
output = p.communicate()[0]
|
|
||||||
|
|
||||||
if p.returncode != 0:
|
|
||||||
raise AppleHelpIndexerFailed(output)
|
|
||||||
else:
|
|
||||||
logger.info(__('done'))
|
|
||||||
except OSError:
|
|
||||||
raise AppleHelpIndexerFailed(__('Command not found: %s') % args[0])
|
|
||||||
|
|
||||||
# If we've been asked to, sign the bundle
|
|
||||||
if self.config.applehelp_codesign_identity:
|
|
||||||
logger.info(bold(__('signing help book... ')), nonl=True)
|
|
||||||
|
|
||||||
args = [
|
|
||||||
self.config.applehelp_codesign_path,
|
|
||||||
'-s', self.config.applehelp_codesign_identity,
|
|
||||||
'-f'
|
|
||||||
]
|
|
||||||
|
|
||||||
args += self.config.applehelp_codesign_flags
|
|
||||||
|
|
||||||
args.append(self.bundle_path)
|
|
||||||
|
|
||||||
if self.config.applehelp_disable_external_tools:
|
|
||||||
logger.info(__('skipping'))
|
|
||||||
logger.warning(__('you will need to sign this help book with:\n %s'),
|
|
||||||
' '.join([pipes.quote(arg) for arg in args]))
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
p = subprocess.Popen(args,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.STDOUT)
|
|
||||||
|
|
||||||
output = p.communicate()[0]
|
|
||||||
|
|
||||||
if p.returncode != 0:
|
|
||||||
raise AppleHelpCodeSigningFailed(output)
|
|
||||||
else:
|
|
||||||
logger.info(__('done'))
|
|
||||||
except OSError:
|
|
||||||
raise AppleHelpCodeSigningFailed(__('Command not found: %s') % args[0])
|
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
# type: (Sphinx) -> Dict[unicode, Any]
|
# type: (Sphinx) -> Dict[str, Any]
|
||||||
app.setup_extension('sphinx.builders.html')
|
warnings.warn('sphinx.builders.applehelp has been moved to sphinxcontrib-applehelp.',
|
||||||
app.add_builder(AppleHelpBuilder)
|
RemovedInSphinx40Warning)
|
||||||
|
app.setup_extension('sphinxcontrib.applehelp')
|
||||||
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_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_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_stopwords',
|
|
||||||
lambda self: self.language or 'en', 'applehelp')
|
|
||||||
app.add_config_value('applehelp_locale', lambda self: self.language or 'en', 'applehelp')
|
|
||||||
app.add_config_value('applehelp_title', lambda self: self.project + ' Help', 'applehelp')
|
|
||||||
app.add_config_value('applehelp_codesign_identity',
|
|
||||||
lambda self: environ.get('CODE_SIGN_IDENTITY', None),
|
|
||||||
'applehelp')
|
|
||||||
app.add_config_value('applehelp_codesign_flags',
|
|
||||||
lambda self: shlex.split(environ.get('OTHER_CODE_SIGN_FLAGS', '')),
|
|
||||||
'applehelp')
|
|
||||||
app.add_config_value('applehelp_indexer_path', '/usr/bin/hiutil', 'applehelp')
|
|
||||||
app.add_config_value('applehelp_codesign_path', '/usr/bin/codesign', 'applehelp')
|
|
||||||
app.add_config_value('applehelp_disable_external_tools', False, None)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
sphinx.builders.changes
|
sphinx.builders.changes
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -9,12 +8,10 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import codecs
|
import html
|
||||||
from os import path
|
from os import path
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
from six import iteritems
|
|
||||||
|
|
||||||
from sphinx import package_dir
|
from sphinx import package_dir
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.domains.changeset import ChangeSetDomain
|
from sphinx.domains.changeset import ChangeSetDomain
|
||||||
@ -24,7 +21,6 @@ from sphinx.util import logging
|
|||||||
from sphinx.util.console import bold # type: ignore
|
from sphinx.util.console import bold # type: ignore
|
||||||
from sphinx.util.fileutil import copy_asset_file
|
from sphinx.util.fileutil import copy_asset_file
|
||||||
from sphinx.util.osutil import ensuredir, os_path
|
from sphinx.util.osutil import ensuredir, os_path
|
||||||
from sphinx.util.pycompat import htmlescape
|
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
@ -50,27 +46,29 @@ class ChangesBuilder(Builder):
|
|||||||
self.templates.init(self, self.theme)
|
self.templates.init(self, self.theme)
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self):
|
||||||
# type: () -> unicode
|
# type: () -> str
|
||||||
return self.outdir
|
return self.outdir
|
||||||
|
|
||||||
typemap = {
|
typemap = {
|
||||||
'versionadded': 'added',
|
'versionadded': 'added',
|
||||||
'versionchanged': 'changed',
|
'versionchanged': 'changed',
|
||||||
'deprecated': 'deprecated',
|
'deprecated': 'deprecated',
|
||||||
} # type: Dict[unicode, unicode]
|
}
|
||||||
|
|
||||||
def write(self, *ignored):
|
def write(self, *ignored):
|
||||||
# type: (Any) -> None
|
# type: (Any) -> None
|
||||||
version = self.config.version
|
version = self.config.version
|
||||||
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
|
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
|
||||||
libchanges = {} # type: Dict[unicode, List[Tuple[unicode, unicode, int]]]
|
libchanges = {} # type: Dict[str, List[Tuple[str, str, int]]]
|
||||||
apichanges = [] # type: List[Tuple[unicode, unicode, int]]
|
apichanges = [] # type: List[Tuple[str, str, int]]
|
||||||
otherchanges = {} # type: Dict[Tuple[unicode, unicode], List[Tuple[unicode, unicode, int]]] # NOQA
|
otherchanges = {} # type: Dict[Tuple[str, str], List[Tuple[str, str, int]]]
|
||||||
if version not in self.env.versionchanges:
|
|
||||||
|
changesets = domain.get_changesets_for(version)
|
||||||
|
if not changesets:
|
||||||
logger.info(bold(__('no changes in version %s.') % version))
|
logger.info(bold(__('no changes in version %s.') % version))
|
||||||
return
|
return
|
||||||
logger.info(bold('writing summary file...'))
|
logger.info(bold(__('writing summary file...')))
|
||||||
for changeset in domain.get_changesets_for(version):
|
for changeset in changesets:
|
||||||
if isinstance(changeset.descname, tuple):
|
if isinstance(changeset.descname, tuple):
|
||||||
descname = changeset.descname[0]
|
descname = changeset.descname[0]
|
||||||
else:
|
else:
|
||||||
@ -109,15 +107,15 @@ class ChangesBuilder(Builder):
|
|||||||
'version': version,
|
'version': version,
|
||||||
'docstitle': self.config.html_title,
|
'docstitle': self.config.html_title,
|
||||||
'shorttitle': self.config.html_short_title,
|
'shorttitle': self.config.html_short_title,
|
||||||
'libchanges': sorted(iteritems(libchanges)),
|
'libchanges': sorted(libchanges.items()),
|
||||||
'apichanges': sorted(apichanges),
|
'apichanges': sorted(apichanges),
|
||||||
'otherchanges': sorted(iteritems(otherchanges)),
|
'otherchanges': sorted(otherchanges.items()),
|
||||||
'show_copyright': self.config.html_show_copyright,
|
'show_copyright': self.config.html_show_copyright,
|
||||||
'show_sphinx': self.config.html_show_sphinx,
|
'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))
|
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))
|
f.write(self.templates.render('changes/versionchanges.html', ctx))
|
||||||
|
|
||||||
hltext = ['.. versionadded:: %s' % version,
|
hltext = ['.. versionadded:: %s' % version,
|
||||||
@ -125,8 +123,8 @@ class ChangesBuilder(Builder):
|
|||||||
'.. deprecated:: %s' % version]
|
'.. deprecated:: %s' % version]
|
||||||
|
|
||||||
def hl(no, line):
|
def hl(no, line):
|
||||||
# type: (int, unicode) -> unicode
|
# type: (int, str) -> str
|
||||||
line = '<a name="L%s"> </a>' % no + htmlescape(line)
|
line = '<a name="L%s"> </a>' % no + html.escape(line)
|
||||||
for x in hltext:
|
for x in hltext:
|
||||||
if x in line:
|
if x in line:
|
||||||
line = '<span class="hl">%s</span>' % line
|
line = '<span class="hl">%s</span>' % line
|
||||||
@ -135,8 +133,8 @@ class ChangesBuilder(Builder):
|
|||||||
|
|
||||||
logger.info(bold(__('copying source files...')))
|
logger.info(bold(__('copying source files...')))
|
||||||
for docname in self.env.all_docs:
|
for docname in self.env.all_docs:
|
||||||
with codecs.open(self.env.doc2path(docname), 'r', # type: ignore
|
with open(self.env.doc2path(docname),
|
||||||
self.env.config.source_encoding) as f:
|
encoding=self.env.config.source_encoding) as f:
|
||||||
try:
|
try:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
@ -144,7 +142,7 @@ class ChangesBuilder(Builder):
|
|||||||
continue
|
continue
|
||||||
targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html'
|
targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html'
|
||||||
ensuredir(path.dirname(targetfn))
|
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))
|
text = ''.join(hl(i + 1, line) for (i, line) in enumerate(lines))
|
||||||
ctx = {
|
ctx = {
|
||||||
'filename': self.env.doc2path(docname, None),
|
'filename': self.env.doc2path(docname, None),
|
||||||
@ -152,15 +150,15 @@ class ChangesBuilder(Builder):
|
|||||||
}
|
}
|
||||||
f.write(self.templates.render('changes/rstsource.html', ctx))
|
f.write(self.templates.render('changes/rstsource.html', ctx))
|
||||||
themectx = dict(('theme_' + key, val) for (key, val) in
|
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'),
|
copy_asset_file(path.join(package_dir, 'themes', 'default', 'static', 'default.css_t'),
|
||||||
self.outdir, context=themectx, renderer=self.templates)
|
self.outdir, context=themectx, renderer=self.templates)
|
||||||
copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'),
|
copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'),
|
||||||
self.outdir)
|
self.outdir)
|
||||||
|
|
||||||
def hl(self, text, version):
|
def hl(self, text, version):
|
||||||
# type: (unicode, unicode) -> unicode
|
# type: (str, str) -> str
|
||||||
text = htmlescape(text)
|
text = html.escape(text)
|
||||||
for directive in ['versionchanged', 'versionadded', 'deprecated']:
|
for directive in ['versionchanged', 'versionadded', 'deprecated']:
|
||||||
text = text.replace('.. %s:: %s' % (directive, version),
|
text = text.replace('.. %s:: %s' % (directive, version),
|
||||||
'<b>.. %s:: %s</b>' % (directive, version))
|
'<b>.. %s:: %s</b>' % (directive, version))
|
||||||
@ -172,7 +170,7 @@ class ChangesBuilder(Builder):
|
|||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
# type: (Sphinx) -> Dict[unicode, Any]
|
# type: (Sphinx) -> Dict[str, Any]
|
||||||
app.add_builder(ChangesBuilder)
|
app.add_builder(ChangesBuilder)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
sphinx.builders.devhelp
|
sphinx.builders.devhelp
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -10,143 +9,32 @@
|
|||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
|
||||||
|
|
||||||
import gzip
|
import warnings
|
||||||
import re
|
|
||||||
from os import path
|
|
||||||
|
|
||||||
from docutils import nodes
|
from sphinxcontrib.devhelp import DevhelpBuilder
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
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
|
|
||||||
|
|
||||||
try:
|
|
||||||
import xml.etree.ElementTree as etree
|
|
||||||
except ImportError:
|
|
||||||
import lxml.etree as etree # type: ignore
|
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, List # NOQA
|
from typing import Any, Dict # NOQA
|
||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
deprecated_alias('sphinx.builders.devhelp',
|
||||||
|
{
|
||||||
|
'DevhelpBuilder': DevhelpBuilder,
|
||||||
class DevhelpBuilder(StandaloneHTMLBuilder):
|
},
|
||||||
"""
|
RemovedInSphinx40Warning)
|
||||||
Builder that also outputs GNOME Devhelp file.
|
|
||||||
"""
|
|
||||||
name = 'devhelp'
|
|
||||||
epilog = __('To view the help file:\n'
|
|
||||||
'$ mkdir -p $HOME/.local/share/devhelp/books\n'
|
|
||||||
'$ ln -s $PWD/%(outdir)s $HOME/.local/share/devhelp/books/%(project)s\n'
|
|
||||||
'$ devhelp')
|
|
||||||
|
|
||||||
# don't copy the reST source
|
|
||||||
copysource = False
|
|
||||||
supported_image_types = ['image/png', 'image/gif', 'image/jpeg']
|
|
||||||
|
|
||||||
# don't add links
|
|
||||||
add_permalinks = False
|
|
||||||
# don't add sidebar etc.
|
|
||||||
embedded = True
|
|
||||||
|
|
||||||
def init(self):
|
|
||||||
# type: () -> None
|
|
||||||
StandaloneHTMLBuilder.init(self)
|
|
||||||
self.out_suffix = '.html'
|
|
||||||
self.link_suffix = '.html'
|
|
||||||
|
|
||||||
def handle_finish(self):
|
|
||||||
# type: () -> None
|
|
||||||
self.build_devhelp(self.outdir, self.config.devhelp_basename)
|
|
||||||
|
|
||||||
def build_devhelp(self, outdir, outname):
|
|
||||||
# type: (unicode, unicode) -> None
|
|
||||||
logger.info(__('dumping devhelp index...'))
|
|
||||||
|
|
||||||
# Basic info
|
|
||||||
root = etree.Element('book',
|
|
||||||
title=self.config.html_title,
|
|
||||||
name=self.config.project,
|
|
||||||
link="index.html",
|
|
||||||
version=self.config.version)
|
|
||||||
tree = etree.ElementTree(root)
|
|
||||||
|
|
||||||
# TOC
|
|
||||||
chapters = etree.SubElement(root, 'chapters')
|
|
||||||
|
|
||||||
tocdoc = self.env.get_and_resolve_doctree(
|
|
||||||
self.config.master_doc, self, prune_toctrees=False)
|
|
||||||
|
|
||||||
def write_toc(node, parent):
|
|
||||||
# type: (nodes.Node, nodes.Node) -> None
|
|
||||||
if isinstance(node, addnodes.compact_paragraph) or \
|
|
||||||
isinstance(node, nodes.bullet_list):
|
|
||||||
for subnode in node:
|
|
||||||
write_toc(subnode, parent)
|
|
||||||
elif isinstance(node, nodes.list_item):
|
|
||||||
item = etree.SubElement(parent, 'sub')
|
|
||||||
for subnode in node:
|
|
||||||
write_toc(subnode, item)
|
|
||||||
elif isinstance(node, nodes.reference):
|
|
||||||
parent.attrib['link'] = node['refuri']
|
|
||||||
parent.attrib['name'] = node.astext()
|
|
||||||
|
|
||||||
def istoctree(node):
|
|
||||||
# type: (nodes.Node) -> bool
|
|
||||||
return isinstance(node, addnodes.compact_paragraph) and \
|
|
||||||
'toctree' in node
|
|
||||||
|
|
||||||
for node in tocdoc.traverse(istoctree):
|
|
||||||
write_toc(node, chapters)
|
|
||||||
|
|
||||||
# Index
|
|
||||||
functions = etree.SubElement(root, 'functions')
|
|
||||||
index = IndexEntries(self.env).create_index(self)
|
|
||||||
|
|
||||||
def write_index(title, refs, subitems):
|
|
||||||
# type: (unicode, List[Any], Any) -> None
|
|
||||||
if len(refs) == 0:
|
|
||||||
pass
|
|
||||||
elif len(refs) == 1:
|
|
||||||
etree.SubElement(functions, 'function',
|
|
||||||
name=title, link=refs[0][1])
|
|
||||||
else:
|
|
||||||
for i, ref in enumerate(refs):
|
|
||||||
etree.SubElement(functions, 'function',
|
|
||||||
name="[%d] %s" % (i, title),
|
|
||||||
link=ref[1])
|
|
||||||
|
|
||||||
if subitems:
|
|
||||||
parent_title = re.sub(r'\s*\(.*\)\s*$', '', title)
|
|
||||||
for subitem in subitems:
|
|
||||||
write_index("%s %s" % (parent_title, subitem[0]),
|
|
||||||
subitem[1], [])
|
|
||||||
|
|
||||||
for (key, group) in index:
|
|
||||||
for title, (refs, subitems, key) in group:
|
|
||||||
write_index(title, refs, subitems)
|
|
||||||
|
|
||||||
# Dump the XML file
|
|
||||||
xmlfile = path.join(outdir, outname + '.devhelp.gz')
|
|
||||||
with gzip.open(xmlfile, 'w') as f: # type: ignore
|
|
||||||
tree.write(f, 'utf-8')
|
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
# type: (Sphinx) -> Dict[unicode, Any]
|
# type: (Sphinx) -> Dict[str, Any]
|
||||||
app.setup_extension('sphinx.builders.html')
|
warnings.warn('sphinx.builders.devhelp has been moved to sphinxcontrib-devhelp.',
|
||||||
app.add_builder(DevhelpBuilder)
|
RemovedInSphinx40Warning)
|
||||||
|
app.setup_extension('sphinxcontrib.devhelp')
|
||||||
app.add_config_value('devhelp_basename', lambda self: make_filename(self.project), None)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
|
68
sphinx/builders/dirhtml.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
"""
|
||||||
|
sphinx.builders.dirhtml
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Directory HTML builders.
|
||||||
|
|
||||||
|
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
||||||
|
:license: BSD, see LICENSE for details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from os import path
|
||||||
|
|
||||||
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
|
from sphinx.util import logging
|
||||||
|
from sphinx.util.osutil import SEP, os_path
|
||||||
|
|
||||||
|
if False:
|
||||||
|
# For type annotation
|
||||||
|
from typing import Any, Dict, Set # NOQA
|
||||||
|
from sphinx.application import Sphinx # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class DirectoryHTMLBuilder(StandaloneHTMLBuilder):
|
||||||
|
"""
|
||||||
|
A StandaloneHTMLBuilder that creates all HTML pages as "index.html" in
|
||||||
|
a directory given by their pagename, so that generated URLs don't have
|
||||||
|
``.html`` in them.
|
||||||
|
"""
|
||||||
|
name = 'dirhtml'
|
||||||
|
|
||||||
|
def get_target_uri(self, docname, typ=None):
|
||||||
|
# type: (str, str) -> str
|
||||||
|
if docname == 'index':
|
||||||
|
return ''
|
||||||
|
if docname.endswith(SEP + 'index'):
|
||||||
|
return docname[:-5] # up to sep
|
||||||
|
return docname + SEP
|
||||||
|
|
||||||
|
def get_outfilename(self, pagename):
|
||||||
|
# type: (str) -> str
|
||||||
|
if pagename == 'index' or pagename.endswith(SEP + 'index'):
|
||||||
|
outfilename = path.join(self.outdir, os_path(pagename) +
|
||||||
|
self.out_suffix)
|
||||||
|
else:
|
||||||
|
outfilename = path.join(self.outdir, os_path(pagename),
|
||||||
|
'index' + self.out_suffix)
|
||||||
|
|
||||||
|
return outfilename
|
||||||
|
|
||||||
|
def prepare_writing(self, docnames):
|
||||||
|
# type: (Set[str]) -> None
|
||||||
|
super().prepare_writing(docnames)
|
||||||
|
self.globalcontext['no_search_suffix'] = True
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
# type: (Sphinx) -> Dict[str, Any]
|
||||||
|
app.setup_extension('sphinx.builders.html')
|
||||||
|
|
||||||
|
app.add_builder(DirectoryHTMLBuilder)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'version': 'builtin',
|
||||||
|
'parallel_read_safe': True,
|
||||||
|
'parallel_write_safe': True,
|
||||||
|
}
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
sphinx.builders.dummy
|
sphinx.builders.dummy
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -31,19 +30,19 @@ class DummyBuilder(Builder):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self):
|
||||||
# type: () -> Set[unicode]
|
# type: () -> Set[str]
|
||||||
return self.env.found_docs
|
return self.env.found_docs
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname, typ=None):
|
||||||
# type: (unicode, unicode) -> unicode
|
# type: (str, str) -> str
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames):
|
||||||
# type: (Set[unicode]) -> None
|
# type: (Set[str]) -> None
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname, doctree):
|
||||||
# type: (unicode, nodes.Node) -> None
|
# type: (str, nodes.Node) -> None
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
@ -52,7 +51,7 @@ class DummyBuilder(Builder):
|
|||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
# type: (Sphinx) -> Dict[unicode, Any]
|
# type: (Sphinx) -> Dict[str, Any]
|
||||||
app.add_builder(DummyBuilder)
|
app.add_builder(DummyBuilder)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
sphinx.builders.epub3
|
sphinx.builders.epub3
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -10,14 +9,14 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import warnings
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
from six import string_types
|
|
||||||
|
|
||||||
from sphinx import package_dir
|
from sphinx import package_dir
|
||||||
from sphinx.builders import _epub_base
|
from sphinx.builders import _epub_base
|
||||||
from sphinx.config import string_classes, ENUM
|
from sphinx.config import ENUM
|
||||||
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging, xmlname_checker
|
from sphinx.util import logging, xmlname_checker
|
||||||
from sphinx.util.fileutil import copy_asset_file
|
from sphinx.util.fileutil import copy_asset_file
|
||||||
@ -26,8 +25,7 @@ from sphinx.util.osutil import make_filename
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, Iterable, List, Tuple # NOQA
|
from typing import Any, Dict, List, Set, Tuple # NOQA
|
||||||
from docutils import nodes # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
from sphinx.config import Config # NOQA
|
from sphinx.config import Config # NOQA
|
||||||
|
|
||||||
@ -53,8 +51,8 @@ THEME_WRITING_MODES = {
|
|||||||
DOCTYPE = '''<!DOCTYPE html>'''
|
DOCTYPE = '''<!DOCTYPE html>'''
|
||||||
|
|
||||||
HTML_TAG = (
|
HTML_TAG = (
|
||||||
u'<html xmlns="http://www.w3.org/1999/xhtml" '
|
'<html xmlns="http://www.w3.org/1999/xhtml" '
|
||||||
u'xmlns:epub="http://www.idpf.org/2007/ops">'
|
'xmlns:epub="http://www.idpf.org/2007/ops">'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -79,50 +77,18 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
def handle_finish(self):
|
def handle_finish(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
"""Create the metainfo files and finally the epub."""
|
"""Create the metainfo files and finally the epub."""
|
||||||
self.validate_config_value()
|
|
||||||
self.get_toc()
|
self.get_toc()
|
||||||
self.build_mimetype(self.outdir, 'mimetype')
|
self.build_mimetype()
|
||||||
self.build_container(self.outdir, 'META-INF/container.xml')
|
self.build_container()
|
||||||
self.build_content(self.outdir, 'content.opf')
|
self.build_content()
|
||||||
self.build_navigation_doc(self.outdir, 'nav.xhtml')
|
self.build_navigation_doc()
|
||||||
self.build_toc(self.outdir, 'toc.ncx')
|
self.build_toc()
|
||||||
self.build_epub(self.outdir, self.config.epub_basename + '.epub')
|
self.build_epub()
|
||||||
|
|
||||||
def validate_config_value(self):
|
def validate_config_value(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
# <package> lang attribute, dc:language
|
warnings.warn('Epub3Builder.validate_config_value() is deprecated.',
|
||||||
if not self.app.config.epub_language:
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
logger.warning(__('conf value "epub_language" (or "language") '
|
|
||||||
'should not be empty for EPUB3'))
|
|
||||||
# <package> unique-identifier attribute
|
|
||||||
if not xmlname_checker().match(self.app.config.epub_uid):
|
|
||||||
logger.warning(__('conf value "epub_uid" should be XML NAME for EPUB3'))
|
|
||||||
# dc:title
|
|
||||||
if not self.app.config.epub_title:
|
|
||||||
logger.warning(__('conf value "epub_title" (or "html_title") '
|
|
||||||
'should not be empty for EPUB3'))
|
|
||||||
# dc:creator
|
|
||||||
if not self.app.config.epub_author:
|
|
||||||
logger.warning(__('conf value "epub_author" should not be empty for EPUB3'))
|
|
||||||
# dc:contributor
|
|
||||||
if not self.app.config.epub_contributor:
|
|
||||||
logger.warning(__('conf value "epub_contributor" should not be empty for EPUB3'))
|
|
||||||
# dc:description
|
|
||||||
if not self.app.config.epub_description:
|
|
||||||
logger.warning(__('conf value "epub_description" should not be empty for EPUB3'))
|
|
||||||
# dc:publisher
|
|
||||||
if not self.app.config.epub_publisher:
|
|
||||||
logger.warning(__('conf value "epub_publisher" should not be empty for EPUB3'))
|
|
||||||
# dc:rights
|
|
||||||
if not self.app.config.epub_copyright:
|
|
||||||
logger.warning(__('conf value "epub_copyright" (or "copyright")'
|
|
||||||
'should not be empty for EPUB3'))
|
|
||||||
# dc:identifier
|
|
||||||
if not self.app.config.epub_identifier:
|
|
||||||
logger.warning(__('conf value "epub_identifier" should not be empty for EPUB3'))
|
|
||||||
# meta ibooks:version
|
|
||||||
if not self.app.config.version:
|
|
||||||
logger.warning(__('conf value "version" should not be empty for EPUB3'))
|
|
||||||
|
|
||||||
def content_metadata(self):
|
def content_metadata(self):
|
||||||
# type: () -> Dict
|
# type: () -> Dict
|
||||||
@ -131,7 +97,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
"""
|
"""
|
||||||
writing_mode = self.config.epub_writing_mode
|
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['description'] = self.esc(self.config.epub_description)
|
||||||
metadata['contributor'] = self.esc(self.config.epub_contributor)
|
metadata['contributor'] = self.esc(self.config.epub_contributor)
|
||||||
metadata['page_progression_direction'] = PAGE_PROGRESSION_DIRECTIONS.get(writing_mode)
|
metadata['page_progression_direction'] = PAGE_PROGRESSION_DIRECTIONS.get(writing_mode)
|
||||||
@ -142,8 +108,8 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames):
|
||||||
# type: (Iterable[unicode]) -> None
|
# type: (Set[str]) -> None
|
||||||
super(Epub3Builder, self).prepare_writing(docnames)
|
super().prepare_writing(docnames)
|
||||||
|
|
||||||
writing_mode = self.config.epub_writing_mode
|
writing_mode = self.config.epub_writing_mode
|
||||||
self.globalcontext['theme_writing_mode'] = THEME_WRITING_MODES.get(writing_mode)
|
self.globalcontext['theme_writing_mode'] = THEME_WRITING_MODES.get(writing_mode)
|
||||||
@ -152,7 +118,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
self.globalcontext['skip_ua_compatible'] = True
|
self.globalcontext['skip_ua_compatible'] = True
|
||||||
|
|
||||||
def build_navlist(self, navnodes):
|
def build_navlist(self, navnodes):
|
||||||
# type: (List[nodes.Node]) -> List[NavPoint]
|
# type: (List[Dict[str, Any]]) -> List[NavPoint]
|
||||||
"""Create the toc navigation structure.
|
"""Create the toc navigation structure.
|
||||||
|
|
||||||
This method is almost same as build_navpoints method in epub.py.
|
This method is almost same as build_navpoints method in epub.py.
|
||||||
@ -205,9 +171,15 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
metadata['navlist'] = navlist
|
metadata['navlist'] = navlist
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def build_navigation_doc(self, outdir, outname):
|
def build_navigation_doc(self, outdir=None, outname='nav.xhtml'):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (str, str) -> None
|
||||||
"""Write the metainfo file nav.xhtml."""
|
"""Write the metainfo file nav.xhtml."""
|
||||||
|
if outdir:
|
||||||
|
warnings.warn('The arguments of Epub3Builder.build_navigation_doc() '
|
||||||
|
'is deprecated.', RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
else:
|
||||||
|
outdir = self.outdir
|
||||||
|
|
||||||
logger.info(__('writing %s file...'), outname)
|
logger.info(__('writing %s file...'), outname)
|
||||||
|
|
||||||
if self.config.epub_tocscope == 'default':
|
if self.config.epub_tocscope == 'default':
|
||||||
@ -229,12 +201,52 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
self.files.append(outname)
|
self.files.append(outname)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_config_values(app):
|
||||||
|
# type: (Sphinx) -> None
|
||||||
|
if app.builder.name != 'epub':
|
||||||
|
return
|
||||||
|
|
||||||
|
# <package> lang attribute, dc:language
|
||||||
|
if not app.config.epub_language:
|
||||||
|
logger.warning(__('conf value "epub_language" (or "language") '
|
||||||
|
'should not be empty for EPUB3'))
|
||||||
|
# <package> unique-identifier attribute
|
||||||
|
if not xmlname_checker().match(app.config.epub_uid):
|
||||||
|
logger.warning(__('conf value "epub_uid" should be XML NAME for EPUB3'))
|
||||||
|
# dc:title
|
||||||
|
if not app.config.epub_title:
|
||||||
|
logger.warning(__('conf value "epub_title" (or "html_title") '
|
||||||
|
'should not be empty for EPUB3'))
|
||||||
|
# dc:creator
|
||||||
|
if not app.config.epub_author:
|
||||||
|
logger.warning(__('conf value "epub_author" should not be empty for EPUB3'))
|
||||||
|
# dc:contributor
|
||||||
|
if not app.config.epub_contributor:
|
||||||
|
logger.warning(__('conf value "epub_contributor" should not be empty for EPUB3'))
|
||||||
|
# dc:description
|
||||||
|
if not app.config.epub_description:
|
||||||
|
logger.warning(__('conf value "epub_description" should not be empty for EPUB3'))
|
||||||
|
# dc:publisher
|
||||||
|
if not app.config.epub_publisher:
|
||||||
|
logger.warning(__('conf value "epub_publisher" should not be empty for EPUB3'))
|
||||||
|
# dc:rights
|
||||||
|
if not app.config.epub_copyright:
|
||||||
|
logger.warning(__('conf value "epub_copyright" (or "copyright")'
|
||||||
|
'should not be empty for EPUB3'))
|
||||||
|
# dc:identifier
|
||||||
|
if not app.config.epub_identifier:
|
||||||
|
logger.warning(__('conf value "epub_identifier" should not be empty for EPUB3'))
|
||||||
|
# meta ibooks:version
|
||||||
|
if not app.config.version:
|
||||||
|
logger.warning(__('conf value "version" should not be empty for EPUB3'))
|
||||||
|
|
||||||
|
|
||||||
def convert_epub_css_files(app, config):
|
def convert_epub_css_files(app, config):
|
||||||
# type: (Sphinx, Config) -> None
|
# type: (Sphinx, Config) -> None
|
||||||
"""This converts string styled epub_css_files to tuple styled one."""
|
"""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:
|
for entry in config.epub_css_files:
|
||||||
if isinstance(entry, string_types):
|
if isinstance(entry, str):
|
||||||
epub_css_files.append((entry, {}))
|
epub_css_files.append((entry, {}))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@ -248,7 +260,7 @@ def convert_epub_css_files(app, config):
|
|||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
# type: (Sphinx) -> Dict[unicode, Any]
|
# type: (Sphinx) -> Dict[str, Any]
|
||||||
app.add_builder(Epub3Builder)
|
app.add_builder(Epub3Builder)
|
||||||
|
|
||||||
# config values
|
# config values
|
||||||
@ -256,7 +268,7 @@ def setup(app):
|
|||||||
app.add_config_value('epub_version', 3.0, 'epub') # experimental
|
app.add_config_value('epub_version', 3.0, 'epub') # experimental
|
||||||
app.add_config_value('epub_theme', 'epub', 'epub')
|
app.add_config_value('epub_theme', 'epub', 'epub')
|
||||||
app.add_config_value('epub_theme_options', {}, 'epub')
|
app.add_config_value('epub_theme_options', {}, 'epub')
|
||||||
app.add_config_value('epub_title', lambda self: self.html_title, 'epub')
|
app.add_config_value('epub_title', lambda self: self.project, 'epub')
|
||||||
app.add_config_value('epub_author', lambda self: self.author, 'epub')
|
app.add_config_value('epub_author', lambda self: self.author, 'epub')
|
||||||
app.add_config_value('epub_language', lambda self: self.language or 'en', 'epub')
|
app.add_config_value('epub_language', lambda self: self.language or 'en', 'epub')
|
||||||
app.add_config_value('epub_publisher', lambda self: self.author, 'epub')
|
app.add_config_value('epub_publisher', lambda self: self.author, 'epub')
|
||||||
@ -277,13 +289,14 @@ def setup(app):
|
|||||||
app.add_config_value('epub_max_image_width', 0, 'env')
|
app.add_config_value('epub_max_image_width', 0, 'env')
|
||||||
app.add_config_value('epub_show_urls', 'inline', 'epub')
|
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_use_index', lambda self: self.html_use_index, 'epub')
|
||||||
app.add_config_value('epub_description', 'unknown', 'epub', string_classes)
|
app.add_config_value('epub_description', 'unknown', 'epub')
|
||||||
app.add_config_value('epub_contributor', 'unknown', 'epub', string_classes)
|
app.add_config_value('epub_contributor', 'unknown', 'epub')
|
||||||
app.add_config_value('epub_writing_mode', 'horizontal', 'epub',
|
app.add_config_value('epub_writing_mode', 'horizontal', 'epub',
|
||||||
ENUM('horizontal', 'vertical'))
|
ENUM('horizontal', 'vertical'))
|
||||||
|
|
||||||
# event handlers
|
# event handlers
|
||||||
app.connect('config-inited', convert_epub_css_files)
|
app.connect('config-inited', convert_epub_css_files)
|
||||||
|
app.connect('builder-inited', validate_config_values)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
sphinx.builders.gettext
|
sphinx.builders.gettext
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -9,17 +8,14 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from codecs import open
|
from codecs import open
|
||||||
from collections import defaultdict, OrderedDict
|
from collections import defaultdict, OrderedDict
|
||||||
from datetime import datetime, tzinfo, timedelta
|
from datetime import datetime, tzinfo, timedelta
|
||||||
|
from io import StringIO
|
||||||
from os import path, walk, getenv
|
from os import path, walk, getenv
|
||||||
from time import time
|
from time import time
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from six import iteritems, StringIO
|
|
||||||
|
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.domains.python import pairindextypes
|
from sphinx.domains.python import pairindextypes
|
||||||
from sphinx.errors import ThemeError
|
from sphinx.errors import ThemeError
|
||||||
@ -33,10 +29,10 @@ from sphinx.util.tags import Tags
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# 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 docutils import nodes # NOQA
|
||||||
from sphinx.util.i18n import CatalogInfo # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
|
from sphinx.util.i18n import CatalogInfo # NOQA
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -63,18 +59,18 @@ msgstr ""
|
|||||||
"""[1:]
|
"""[1:]
|
||||||
|
|
||||||
|
|
||||||
class Catalog(object):
|
class Catalog:
|
||||||
"""Catalog of translatable messages."""
|
"""Catalog of translatable messages."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
self.messages = [] # type: List[unicode]
|
self.messages = [] # type: List[str]
|
||||||
# retain insertion order, a la OrderedDict
|
# 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
|
# msgid -> file, line, uid
|
||||||
|
|
||||||
def add(self, msg, origin):
|
def add(self, msg, origin):
|
||||||
# type: (unicode, MsgOrigin) -> None
|
# type: (str, Union[nodes.Element, MsgOrigin]) -> None
|
||||||
if not hasattr(origin, 'uid'):
|
if not hasattr(origin, 'uid'):
|
||||||
# Nodes that are replicated like todo don't have a uid,
|
# Nodes that are replicated like todo don't have a uid,
|
||||||
# however i18n is also unnecessary.
|
# however i18n is also unnecessary.
|
||||||
@ -82,16 +78,16 @@ class Catalog(object):
|
|||||||
if msg not in self.metadata: # faster lookup in hash
|
if msg not in self.metadata: # faster lookup in hash
|
||||||
self.messages.append(msg)
|
self.messages.append(msg)
|
||||||
self.metadata[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.
|
Origin holder for Catalog message origin.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, source, line):
|
def __init__(self, source, line):
|
||||||
# type: (unicode, int) -> None
|
# type: (str, int) -> None
|
||||||
self.source = source
|
self.source = source
|
||||||
self.line = line
|
self.line = line
|
||||||
self.uid = uuid4().hex
|
self.uid = uuid4().hex
|
||||||
@ -120,32 +116,31 @@ class I18nBuilder(Builder):
|
|||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
Builder.init(self)
|
super().init()
|
||||||
self.env.set_versioning_method(self.versioning_method,
|
self.env.set_versioning_method(self.versioning_method,
|
||||||
self.env.config.gettext_uuid)
|
self.env.config.gettext_uuid)
|
||||||
self.tags = I18nTags()
|
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):
|
def get_target_uri(self, docname, typ=None):
|
||||||
# type: (unicode, unicode) -> unicode
|
# type: (str, str) -> str
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self):
|
||||||
# type: () -> Set[unicode]
|
# type: () -> Set[str]
|
||||||
return self.env.found_docs
|
return self.env.found_docs
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames):
|
||||||
# type: (Set[unicode]) -> None
|
# type: (Set[str]) -> None
|
||||||
return
|
return
|
||||||
|
|
||||||
def compile_catalogs(self, catalogs, message):
|
def compile_catalogs(self, catalogs, message):
|
||||||
# type: (Set[CatalogInfo], unicode) -> None
|
# type: (Set[CatalogInfo], str) -> None
|
||||||
return
|
return
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname, doctree):
|
||||||
# type: (unicode, nodes.Node) -> None
|
# type: (str, nodes.document) -> None
|
||||||
catalog = self.catalogs[find_catalog(docname,
|
catalog = self.catalogs[find_catalog(docname, self.config.gettext_compact)]
|
||||||
self.config.gettext_compact)]
|
|
||||||
|
|
||||||
for node, msg in extract_messages(doctree):
|
for node, msg in extract_messages(doctree):
|
||||||
catalog.add(msg, node)
|
catalog.add(msg, node)
|
||||||
@ -178,7 +173,7 @@ class LocalTimeZone(tzinfo):
|
|||||||
|
|
||||||
def __init__(self, *args, **kw):
|
def __init__(self, *args, **kw):
|
||||||
# type: (Any, Any) -> None
|
# type: (Any, Any) -> None
|
||||||
super(LocalTimeZone, self).__init__(*args, **kw) # type: ignore
|
super().__init__(*args, **kw) # type: ignore
|
||||||
self.tzdelta = tzdelta
|
self.tzdelta = tzdelta
|
||||||
|
|
||||||
def utcoffset(self, dt):
|
def utcoffset(self, dt):
|
||||||
@ -194,11 +189,11 @@ ltz = LocalTimeZone()
|
|||||||
|
|
||||||
|
|
||||||
def should_write(filepath, new_content):
|
def should_write(filepath, new_content):
|
||||||
# type: (unicode, unicode) -> bool
|
# type: (str, str) -> bool
|
||||||
if not path.exists(filepath):
|
if not path.exists(filepath):
|
||||||
return True
|
return True
|
||||||
try:
|
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_content = oldpot.read()
|
||||||
old_header_index = old_content.index('"POT-Creation-Date:')
|
old_header_index = old_content.index('"POT-Creation-Date:')
|
||||||
new_header_index = new_content.index('"POT-Creation-Date:')
|
new_header_index = new_content.index('"POT-Creation-Date:')
|
||||||
@ -221,12 +216,12 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
I18nBuilder.init(self)
|
super().init()
|
||||||
self.create_template_bridge()
|
self.create_template_bridge()
|
||||||
self.templates.init(self)
|
self.templates.init(self)
|
||||||
|
|
||||||
def _collect_templates(self):
|
def _collect_templates(self):
|
||||||
# type: () -> Set[unicode]
|
# type: () -> Set[str]
|
||||||
template_files = set()
|
template_files = set()
|
||||||
for template_path in self.config.templates_path:
|
for template_path in self.config.templates_path:
|
||||||
tmpl_abs_path = path.join(self.app.srcdir, template_path)
|
tmpl_abs_path = path.join(self.app.srcdir, template_path)
|
||||||
@ -241,15 +236,15 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
# type: () -> None
|
# type: () -> None
|
||||||
files = list(self._collect_templates())
|
files = list(self._collect_templates())
|
||||||
files.sort()
|
files.sort()
|
||||||
logger.info(bold(__('building [%s]: ') % self.name), nonl=1)
|
logger.info(bold(__('building [%s]: ') % self.name), nonl=True)
|
||||||
logger.info(__('targets for %d template files'), len(files))
|
logger.info(__('targets for %d template files'), len(files))
|
||||||
|
|
||||||
extract_translations = self.templates.environment.extract_translations
|
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):
|
len(files), self.app.verbosity):
|
||||||
try:
|
try:
|
||||||
with open(template, 'r', encoding='utf-8') as f: # type: ignore
|
with open(template, encoding='utf-8') as f:
|
||||||
context = f.read()
|
context = f.read()
|
||||||
for line, meth, msg in extract_translations(context):
|
for line, meth, msg in extract_translations(context):
|
||||||
origin = MsgOrigin(template, line)
|
origin = MsgOrigin(template, line)
|
||||||
@ -258,21 +253,21 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
raise ThemeError('%s: %r' % (template, exc))
|
raise ThemeError('%s: %r' % (template, exc))
|
||||||
|
|
||||||
def build(self, docnames, summary=None, method='update'):
|
def build(self, docnames, summary=None, method='update'):
|
||||||
# type: (Iterable[unicode], unicode, unicode) -> None
|
# type: (Iterable[str], str, str) -> None
|
||||||
self._extract_from_template()
|
self._extract_from_template()
|
||||||
I18nBuilder.build(self, docnames, summary, method)
|
super().build(docnames, summary, method)
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
I18nBuilder.finish(self)
|
super().finish()
|
||||||
data = dict(
|
data = {
|
||||||
version = self.config.version,
|
'version': self.config.version,
|
||||||
copyright = self.config.copyright,
|
'copyright': self.config.copyright,
|
||||||
project = self.config.project,
|
'project': self.config.project,
|
||||||
ctime = datetime.fromtimestamp(
|
'ctime': datetime.fromtimestamp(
|
||||||
timestamp, ltz).strftime('%Y-%m-%d %H:%M%z'),
|
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... "),
|
__("writing message catalogs... "),
|
||||||
"darkgreen", len(self.catalogs),
|
"darkgreen", len(self.catalogs),
|
||||||
self.app.verbosity,
|
self.app.verbosity,
|
||||||
@ -282,36 +277,35 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
|
|
||||||
pofn = path.join(self.outdir, textdomain + '.pot')
|
pofn = path.join(self.outdir, textdomain + '.pot')
|
||||||
output = StringIO()
|
output = StringIO()
|
||||||
output.write(POHEADER % data) # type: ignore
|
output.write(POHEADER % data)
|
||||||
|
|
||||||
for message in catalog.messages:
|
for message in catalog.messages:
|
||||||
positions = catalog.metadata[message]
|
positions = catalog.metadata[message]
|
||||||
|
|
||||||
if self.config.gettext_location:
|
if self.config.gettext_location:
|
||||||
# generate "#: file1:line1\n#: file2:line2 ..."
|
# 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)
|
"%s:%s" % (canon_path(relpath(source, self.outdir)), line)
|
||||||
for source, line, _ in positions))
|
for source, line, _ in positions))
|
||||||
if self.config.gettext_uuid:
|
if self.config.gettext_uuid:
|
||||||
# generate "# uuid1\n# uuid2\n ..."
|
# generate "# uuid1\n# uuid2\n ..."
|
||||||
output.write("# %s\n" % "\n# ".join( # type: ignore
|
output.write("# %s\n" % "\n# ".join(uid for _, _, uid in positions))
|
||||||
uid for _, _, uid in positions))
|
|
||||||
|
|
||||||
# message contains *one* line of text ready for translation
|
# message contains *one* line of text ready for translation
|
||||||
message = message.replace('\\', r'\\'). \
|
message = message.replace('\\', r'\\'). \
|
||||||
replace('"', r'\"'). \
|
replace('"', r'\"'). \
|
||||||
replace('\n', '\\n"\n"')
|
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()
|
content = output.getvalue()
|
||||||
|
|
||||||
if should_write(pofn, content):
|
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)
|
pofile.write(content)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
# type: (Sphinx) -> Dict[unicode, Any]
|
# type: (Sphinx) -> Dict[str, Any]
|
||||||
app.add_builder(MessageCatalogBuilder)
|
app.add_builder(MessageCatalogBuilder)
|
||||||
|
|
||||||
app.add_config_value('gettext_compact', True, 'gettext')
|
app.add_config_value('gettext_compact', True, 'gettext')
|
||||||
|