mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '3.x' into 7774_remove_develop.rst
This commit is contained in:
commit
51d500833e
@ -3,12 +3,14 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
docker:
|
docker:
|
||||||
- image: sphinxdoc/docker-ci
|
- image: sphinxdoc/docker-ci
|
||||||
|
environment:
|
||||||
|
DO_EPUBCHECK: 1
|
||||||
working_directory: /sphinx
|
working_directory: /sphinx
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run: /python3.6/bin/pip install -U pip setuptools
|
- run: /python3.6/bin/pip install -U pip setuptools
|
||||||
- run: /python3.6/bin/pip install -U .[test]
|
- run: /python3.6/bin/pip install -U .[test]
|
||||||
- run: mkdir -p test-reports/pytest
|
- run: mkdir -p test-reports/pytest
|
||||||
- run: make test PYTHON=/python3.6/bin/python TEST=--junitxml=test-reports/pytest/results.xml
|
- run: make test PYTHON=/python3.6/bin/python TEST="--junitxml=test-reports/pytest/results.xml -vv"
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: test-reports
|
path: test-reports
|
||||||
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -2,5 +2,8 @@
|
|||||||
blank_issues_enabled: false # default: true
|
blank_issues_enabled: false # default: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Question
|
- name: Question
|
||||||
|
url: https://stackoverflow.com/questions/tagged/python-sphinx
|
||||||
|
about: For Q&A purpose, please use Stackoverflow with the tag python-sphinx
|
||||||
|
- name: Discussion
|
||||||
url: https://groups.google.com/forum/#!forum/sphinx-users
|
url: https://groups.google.com/forum/#!forum/sphinx-users
|
||||||
about: For Q&A purpose, please use sphinx-users mailing list.
|
about: For general discussion, please use sphinx-users mailing list.
|
||||||
|
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -7,7 +7,7 @@ Subject: <short purpose of this pull request>
|
|||||||
- Critical or severe bugs: X.Y.Z
|
- Critical or severe bugs: X.Y.Z
|
||||||
- Others: X.Y
|
- Others: X.Y
|
||||||
|
|
||||||
For more details, see https://www.sphinx-doc.org/en/master/devguide.html#branch-model
|
For more details, see https://www.sphinx-doc.org/en/master/internals/release-process.html#branch-model
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Feature or Bugfix
|
### Feature or Bugfix
|
||||||
|
21
.github/workflows/builddoc.yml
vendored
Normal file
21
.github/workflows/builddoc.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
name: Build document
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v1
|
||||||
|
with:
|
||||||
|
python-version: 3.6
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y graphviz
|
||||||
|
pip install -U tox
|
||||||
|
- name: Run Tox
|
||||||
|
run: tox -e docs
|
22
.github/workflows/lint.yml
vendored
Normal file
22
.github/workflows/lint.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
name: Lint source code
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
tool: [docslint, flake8, isort, mypy, twine]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v1
|
||||||
|
with:
|
||||||
|
python-version: 3.6
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pip install -U tox
|
||||||
|
- name: Run Tox
|
||||||
|
run: tox -e ${{ matrix.tool }}
|
61
.github/workflows/main.yml
vendored
61
.github/workflows/main.yml
vendored
@ -1,9 +1,64 @@
|
|||||||
name: CI on Windows
|
name: CI
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
ubuntu:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
name: [py35, py36, py37, py38, py39]
|
||||||
|
os: [ubuntu-16.04]
|
||||||
|
include:
|
||||||
|
- name: py35
|
||||||
|
python: 3.5
|
||||||
|
docutils: du12
|
||||||
|
- name: py36
|
||||||
|
python: 3.6
|
||||||
|
docutils: du13
|
||||||
|
- name: py37
|
||||||
|
python: 3.7
|
||||||
|
docutils: du14
|
||||||
|
- name: py38
|
||||||
|
python: 3.8
|
||||||
|
docutils: du15
|
||||||
|
- name: py39
|
||||||
|
python: 3.9
|
||||||
|
docutils: du16
|
||||||
|
coverage: "--cov ./ --cov-append --cov-config setup.cfg"
|
||||||
|
- name: py310-dev
|
||||||
|
python: 3.10-dev
|
||||||
|
docutils: du16
|
||||||
|
os: ubuntu-latest # required
|
||||||
|
env:
|
||||||
|
PYTEST_ADDOPTS: ${{ matrix.coverage }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up Python ${{ matrix.python }}
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
if: "!endsWith(matrix.python, '-dev')"
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python }}
|
||||||
|
- name: Set up Python ${{ matrix.python }} (deadsnakes)
|
||||||
|
uses: deadsnakes/action@v2.0.1
|
||||||
|
if: endsWith(matrix.python, '-dev')
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python }}
|
||||||
|
- name: Check Python version
|
||||||
|
run: python --version
|
||||||
|
- name: Install graphviz
|
||||||
|
run: sudo apt-get install graphviz
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pip install -U tox codecov
|
||||||
|
- name: Run Tox
|
||||||
|
run: tox -e ${{ matrix.docutils }} -- -vv
|
||||||
|
- name: codecov
|
||||||
|
uses: codecov/codecov-action@v1
|
||||||
|
if: matrix.coverage
|
||||||
|
|
||||||
|
windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@ -18,4 +73,4 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pip install -U tox
|
run: pip install -U tox
|
||||||
- name: Run Tox
|
- name: Run Tox
|
||||||
run: tox -e py
|
run: tox -e py -- -vv
|
||||||
|
21
.github/workflows/nodejs.yml
vendored
Normal file
21
.github/workflows/nodejs.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
name: CI (node.js)
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
node-version: 10.7
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js ${{ env.node-version }}
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.node-version }}
|
||||||
|
- run: npm install
|
||||||
|
- name: Run headless test
|
||||||
|
uses: GabrielBB/xvfb-action@v1
|
||||||
|
with:
|
||||||
|
run: npm test
|
8
.readthedocs.yml
Normal file
8
.readthedocs.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
version: 2
|
||||||
|
python:
|
||||||
|
version: 3
|
||||||
|
install:
|
||||||
|
- method: pip
|
||||||
|
path: .
|
||||||
|
extra_requirements:
|
||||||
|
- docs
|
54
.travis.yml
54
.travis.yml
@ -1,54 +0,0 @@
|
|||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
language: python
|
|
||||||
cache: pip
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- PYTHONFAULTHANDLER=x
|
|
||||||
- SKIP_LATEX_BUILD=1
|
|
||||||
- IS_PYTHON=true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
include:
|
|
||||||
- python: '3.5'
|
|
||||||
env:
|
|
||||||
- TOXENV=du12
|
|
||||||
- python: '3.6'
|
|
||||||
env:
|
|
||||||
- TOXENV=du13
|
|
||||||
- python: '3.7'
|
|
||||||
env:
|
|
||||||
- TOXENV=du14
|
|
||||||
- python: '3.8'
|
|
||||||
env:
|
|
||||||
- TOXENV=du15
|
|
||||||
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
|
|
||||||
- python: 'nightly'
|
|
||||||
env:
|
|
||||||
- TOXENV=du16
|
|
||||||
- python: '3.6'
|
|
||||||
env: TOXENV=docs
|
|
||||||
- python: '3.6'
|
|
||||||
env: TOXENV=docslint
|
|
||||||
- python: '3.6'
|
|
||||||
env: TOXENV=mypy
|
|
||||||
- python: '3.6'
|
|
||||||
env: TOXENV=flake8
|
|
||||||
|
|
||||||
- language: node_js
|
|
||||||
node_js: '10.7'
|
|
||||||
env: IS_PYTHON=false
|
|
||||||
services: xvfb
|
|
||||||
|
|
||||||
install:
|
|
||||||
- "sudo apt-get install graphviz"
|
|
||||||
- if [ $IS_PYTHON = true ]; then pip install -U tox codecov; fi
|
|
||||||
- if [ $IS_PYTHON = false ]; then npm install; fi
|
|
||||||
|
|
||||||
script:
|
|
||||||
- if [ $IS_PYTHON = true ]; then tox -- -v; fi
|
|
||||||
- if [ $IS_PYTHON = false ]; then npm test; fi
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
- if [[ -e .coverage ]]; then codecov -e $TOXENV; fi
|
|
596
CHANGES
596
CHANGES
@ -1,9 +1,555 @@
|
|||||||
Release 3.1.0 (in development)
|
Release 3.5.0 (in development)
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* Update Underscore.js to 1.12.0
|
||||||
|
* #6550: html: The config variable ``html_add_permalinks`` is replaced by
|
||||||
|
:confval:`html_permalinks` and :confval:`html_permalinks_icon`
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
* pending_xref node for viewcode extension
|
||||||
|
* ``sphinx.builders.linkcheck.CheckExternalLinksBuilder.broken``
|
||||||
|
* ``sphinx.builders.linkcheck.CheckExternalLinksBuilder.good``
|
||||||
|
* ``sphinx.builders.linkcheck.CheckExternalLinksBuilder.redirected``
|
||||||
|
* ``sphinx.builders.linkcheck.node_line_or_0()``
|
||||||
|
* ``sphinx.ext.autodoc.AttributeDocumenter.isinstanceattribute()``
|
||||||
|
* ``sphinx.ext.autodoc.directive.DocumenterBridge.reporter``
|
||||||
|
* ``sphinx.ext.autodoc.importer.get_module_members()``
|
||||||
|
* ``sphinx.ext.autosummary.generate._simple_info()``
|
||||||
|
* ``sphinx.ext.autosummary.generate._simple_warn()``
|
||||||
|
* ``sphinx.writers.html.HTMLTranslator.permalink_text``
|
||||||
|
* ``sphinx.writers.html5.HTML5Translator.permalink_text``
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* #8022: autodoc: autodata and autoattribute directives does not show right-hand
|
||||||
|
value of the variable if docstring contains ``:meta hide-value:`` in
|
||||||
|
info-field-list
|
||||||
|
* #8514: autodoc: Default values of overloaded functions are taken from actual
|
||||||
|
implementation if they're ellipsis
|
||||||
|
* #8619: html: kbd role generates customizable HTML tags for compound keys
|
||||||
|
* #8634: html: Allow to change the order of JS/CSS via ``priority`` parameter
|
||||||
|
for :meth:`Sphinx.add_js_file()` and :meth:`Sphinx.add_css_file()`
|
||||||
|
* #6241: html: Allow to add JS/CSS files to the specific page when an extension
|
||||||
|
calls ``app.add_js_file()`` or ``app.add_css_file()`` on
|
||||||
|
:event:`html-page-context` event
|
||||||
|
* #6550: html: Allow to use HTML permalink texts via
|
||||||
|
:confval:`html_permalinks_icon`
|
||||||
|
* #8649: imgconverter: Skip availability check if builder supports the image
|
||||||
|
type
|
||||||
|
* #8573: napoleon: Allow to change the style of custom sections using
|
||||||
|
:confval:`napoleon_custom_styles`
|
||||||
|
* #8004: napoleon: Type definitions in Google style docstrings are rendered as
|
||||||
|
references when :confval:`napoleon_preprocess_types` enabled
|
||||||
|
* #6241: mathjax: Include mathjax.js only on the document using equations
|
||||||
|
* #8651: std domain: cross-reference for a rubric having inline item is broken
|
||||||
|
* #8681: viewcode: Support incremental build
|
||||||
|
* #8132: Add :confval:`project_copyright` as an alias of :confval:`copyright`
|
||||||
|
* #207: Now :confval:`highlight_language` supports multiple languages
|
||||||
|
* #2030: :rst:dir:`code-block` and :rst:dir:`literalinclude` supports automatic
|
||||||
|
dedent via no-argument ``:dedent:`` option
|
||||||
|
* C++, also hyperlink operator overloads in expressions and alias declarations.
|
||||||
|
* #8247: Allow production lists to refer to tokens from other production groups
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #8727: apidoc: namespace module file is not generated if no submodules there
|
||||||
|
* #741: autodoc: inherited-members doesn't work for instance attributes on super
|
||||||
|
class
|
||||||
|
* #8592: autodoc: ``:meta public:`` does not effect to variables
|
||||||
|
* #8594: autodoc: empty __all__ attribute is ignored
|
||||||
|
* #8315: autodoc: Failed to resolve struct.Struct type annotation
|
||||||
|
* #8652: autodoc: All variable comments in the module are ignored if the module
|
||||||
|
contains invalid type comments
|
||||||
|
* #8693: autodoc: Default values for overloaded functions are rendered as string
|
||||||
|
* #8306: autosummary: mocked modules are documented as empty page when using
|
||||||
|
:recursive: option
|
||||||
|
* #8618: html: kbd role produces incorrect HTML when compound-key separators (-,
|
||||||
|
+ or ^) are used as keystrokes
|
||||||
|
* #8629: html: A type warning for html_use_opensearch is shown twice
|
||||||
|
* #8714: html: kbd role with "Caps Lock" rendered incorrectly
|
||||||
|
* #8665: html theme: Could not override globaltoc_maxdepth in theme.conf
|
||||||
|
* #4304: linkcheck: Fix race condition that could lead to checking the
|
||||||
|
availability of the same URL twice
|
||||||
|
* #8094: texinfo: image files on the different directory with document are not
|
||||||
|
copied
|
||||||
|
* #8720: viewcode: module pages are generated for epub on incremental build
|
||||||
|
* #8704: viewcode: anchors are generated in incremental build after singlehtml
|
||||||
|
* #8671: :confval:`highlight_options` is not working
|
||||||
|
* #8341: C, fix intersphinx lookup types for names in declarations.
|
||||||
|
* C, C++: in general fix intersphinx and role lookup types.
|
||||||
|
* #8683: :confval:`html_last_updated_fmt` does not support UTC offset (%z)
|
||||||
|
* #8683: :confval:`html_last_updated_fmt` generates wrong time zone for %Z
|
||||||
|
* #1112: ``download`` role creates duplicated copies when relative path is
|
||||||
|
specified
|
||||||
|
* #8735: LaTeX: wrong internal links in pdf to captioned code-blocks when
|
||||||
|
:confval:`numfig` is not True
|
||||||
|
|
||||||
|
Testing
|
||||||
|
--------
|
||||||
|
|
||||||
|
Release 3.4.4 (in development)
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #8655: autodoc: Failed to generate document if target module contains an
|
||||||
|
object that raises an exception on ``hasattr()``
|
||||||
|
* C, ``expr`` role should start symbol lookup in the current scope.
|
||||||
|
|
||||||
|
Testing
|
||||||
|
--------
|
||||||
|
|
||||||
|
Release 3.4.3 (released Jan 08, 2021)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #8655: autodoc: Failed to generate document if target module contains an
|
||||||
|
object that raises an exception on ``hasattr()``
|
||||||
|
|
||||||
|
Release 3.4.2 (released Jan 04, 2021)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #8164: autodoc: Classes that inherit mocked class are not documented
|
||||||
|
* #8602: autodoc: The ``autodoc-process-docstring`` event is emitted to the
|
||||||
|
non-datadescriptors unexpectedly
|
||||||
|
* #8616: autodoc: AttributeError is raised on non-class object is passed to
|
||||||
|
autoclass directive
|
||||||
|
|
||||||
|
Release 3.4.1 (released Dec 25, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #8559: autodoc: AttributeError is raised when using forward-reference type
|
||||||
|
annotations
|
||||||
|
* #8568: autodoc: TypeError is raised on checking slots attribute
|
||||||
|
* #8567: autodoc: Instance attributes are incorrectly added to Parent class
|
||||||
|
* #8566: autodoc: The ``autodoc-process-docstring`` event is emitted to the
|
||||||
|
alias classes unexpectedly
|
||||||
|
* #8583: autodoc: Unnecessary object comparision via ``__eq__`` method
|
||||||
|
* #8565: linkcheck: Fix PriorityQueue crash when link tuples are not
|
||||||
|
comparable
|
||||||
|
|
||||||
|
Release 3.4.0 (released Dec 20, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* #8105: autodoc: the signature of class constructor will be shown for decorated
|
||||||
|
classes, not a signature of decorator
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
* The ``follow_wrapped`` argument of ``sphinx.util.inspect.signature()``
|
||||||
|
* The ``no_docstring`` argument of
|
||||||
|
``sphinx.ext.autodoc.Documenter.add_content()``
|
||||||
|
* ``sphinx.ext.autodoc.Documenter.get_object_members()``
|
||||||
|
* ``sphinx.ext.autodoc.DataDeclarationDocumenter``
|
||||||
|
* ``sphinx.ext.autodoc.GenericAliasDocumenter``
|
||||||
|
* ``sphinx.ext.autodoc.InstanceAttributeDocumenter``
|
||||||
|
* ``sphinx.ext.autodoc.SlotsAttributeDocumenter``
|
||||||
|
* ``sphinx.ext.autodoc.TypeVarDocumenter``
|
||||||
|
* ``sphinx.ext.autodoc.importer._getannotations()``
|
||||||
|
* ``sphinx.ext.autodoc.importer._getmro()``
|
||||||
|
* ``sphinx.pycode.ModuleAnalyzer.parse()``
|
||||||
|
* ``sphinx.util.osutil.movefile()``
|
||||||
|
* ``sphinx.util.requests.is_ssl_error()``
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* #8119: autodoc: Allow to determine whether a member not included in
|
||||||
|
``__all__`` attribute of the module should be documented or not via
|
||||||
|
:event:`autodoc-skip-member` event
|
||||||
|
* #8219: autodoc: Parameters for generic class are not shown when super class is
|
||||||
|
a generic class and show-inheritance option is given (in Python 3.7 or above)
|
||||||
|
* autodoc: Add ``Documenter.config`` as a shortcut to access the config object
|
||||||
|
* autodoc: Add Optional[t] to annotation of function and method if a default
|
||||||
|
value equal to None is set.
|
||||||
|
* #8209: autodoc: Add ``:no-value:`` option to :rst:dir:`autoattribute` and
|
||||||
|
:rst:dir:`autodata` directive to suppress the default value of the variable
|
||||||
|
* #8460: autodoc: Support custom types defined by typing.NewType
|
||||||
|
* #8285: napoleon: Add :confval:`napoleon_attr_annotations` to merge type hints
|
||||||
|
on source code automatically if any type is specified in docstring
|
||||||
|
* #8236: napoleon: Support numpydoc's "Receives" section
|
||||||
|
* #6914: Add a new event :event:`warn-missing-reference` to custom warning
|
||||||
|
messages when failed to resolve a cross-reference
|
||||||
|
* #6914: Emit a detailed warning when failed to resolve a ``:ref:`` reference
|
||||||
|
* #6629: linkcheck: The builder now handles rate limits. See
|
||||||
|
:confval:`linkcheck_retry_on_rate_limit` for details.
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #7613: autodoc: autodoc does not respect __signature__ of the class
|
||||||
|
* #4606: autodoc: the location of the warning is incorrect for inherited method
|
||||||
|
* #8105: autodoc: the signature of class constructor is incorrect if the class
|
||||||
|
is decorated
|
||||||
|
* #8434: autodoc: :confval:`autodoc_type_aliases` does not effect to variables
|
||||||
|
and attributes
|
||||||
|
* #8443: autodoc: autodata directive can't create document for PEP-526 based
|
||||||
|
type annotated variables
|
||||||
|
* #8443: autodoc: autoattribute directive can't create document for PEP-526
|
||||||
|
based uninitalized variables
|
||||||
|
* #8480: autodoc: autoattribute could not create document for __slots__
|
||||||
|
attributes
|
||||||
|
* #8503: autodoc: autoattribute could not create document for a GenericAlias as
|
||||||
|
class attributes correctly
|
||||||
|
* #8534: autodoc: autoattribute could not create document for a commented
|
||||||
|
attribute in alias class
|
||||||
|
* #8452: autodoc: autodoc_type_aliases doesn't work when autodoc_typehints is
|
||||||
|
set to "description"
|
||||||
|
* #8541: autodoc: autodoc_type_aliases doesn't work for the type annotation to
|
||||||
|
instance attributes
|
||||||
|
* #8460: autodoc: autodata and autoattribute directives do not display type
|
||||||
|
information of TypeVars
|
||||||
|
* #8493: autodoc: references to builtins not working in class aliases
|
||||||
|
* #8522: autodoc: ``__bool__`` method could be called
|
||||||
|
* #8067: autodoc: A typehint for the instance variable having type_comment on
|
||||||
|
super class is not displayed
|
||||||
|
* #8545: autodoc: a __slots__ attribute is not documented even having docstring
|
||||||
|
* #741: autodoc: inherited-members doesn't work for instance attributes on super
|
||||||
|
class
|
||||||
|
* #8477: autosummary: non utf-8 reST files are generated when template contains
|
||||||
|
multibyte characters
|
||||||
|
* #8501: autosummary: summary extraction splits text after "el at." unexpectedly
|
||||||
|
* #8524: html: Wrong url_root has been generated on a document named "index"
|
||||||
|
* #8419: html search: Do not load ``language_data.js`` in non-search pages
|
||||||
|
* #8549: i18n: ``-D gettext_compact=0`` is no longer working
|
||||||
|
* #8454: graphviz: The layout option for graph and digraph directives don't work
|
||||||
|
* #8131: linkcheck: Use GET when HEAD requests cause Too Many Redirects, to
|
||||||
|
accommodate infinite redirect loops on HEAD
|
||||||
|
* #8437: Makefile: ``make clean`` with empty BUILDDIR is dangerous
|
||||||
|
* #8365: py domain: ``:type:`` and ``:rtype:`` gives false ambiguous class
|
||||||
|
lookup warnings
|
||||||
|
* #8352: std domain: Failed to parse an option that starts with bracket
|
||||||
|
* #8519: LaTeX: Prevent page brake in the middle of a seealso
|
||||||
|
* #8520: C, fix copying of AliasNode.
|
||||||
|
|
||||||
|
Release 3.3.1 (released Nov 12, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #8372: autodoc: autoclass directive became slower than Sphinx-3.2
|
||||||
|
* #7727: autosummary: raise PycodeError when documenting python package
|
||||||
|
without __init__.py
|
||||||
|
* #8350: autosummary: autosummary_mock_imports causes slow down builds
|
||||||
|
* #8364: C, properly initialize attributes in empty symbols.
|
||||||
|
* #8399: i18n: Put system locale path after the paths specified by configuration
|
||||||
|
|
||||||
|
Release 3.3.0 (released Nov 02, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
* ``sphinx.builders.latex.LaTeXBuilder.usepackages``
|
||||||
|
* ``sphinx.builders.latex.LaTeXBuilder.usepackages_afger_hyperref``
|
||||||
|
* ``sphinx.ext.autodoc.SingledispatchFunctionDocumenter``
|
||||||
|
* ``sphinx.ext.autodoc.SingledispatchMethodDocumenter``
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* #8100: html: Show a better error message for failures on copying
|
||||||
|
html_static_files
|
||||||
|
* #8141: C: added a ``maxdepth`` option to :rst:dir:`c:alias` to insert
|
||||||
|
nested declarations.
|
||||||
|
* #8081: LaTeX: Allow to add LaTeX package via ``app.add_latex_package()`` until
|
||||||
|
just before writing .tex file
|
||||||
|
* #7996: manpage: Add :confval:`man_make_section_directory` to make a section
|
||||||
|
directory on build man page
|
||||||
|
* #8289: epub: Allow to suppress "duplicated ToC entry found" warnings from epub
|
||||||
|
builder using :confval:`suppress_warnings`.
|
||||||
|
* #8298: sphinx-quickstart: Add :option:`sphinx-quickstart --no-sep` option
|
||||||
|
* #8304: sphinx.testing: Register public markers in sphinx.testing.fixtures
|
||||||
|
* #8051: napoleon: use the obj role for all See Also items
|
||||||
|
* #8050: napoleon: Apply :confval:`napoleon_preprocess_types` to every field
|
||||||
|
* C and C++, show line numbers for previous declarations when duplicates are
|
||||||
|
detected.
|
||||||
|
* #8183: Remove substitution_reference nodes from doctree only on LaTeX builds
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #8085: i18n: Add support for having single text domain
|
||||||
|
* #6640: i18n: Failed to override system message translation
|
||||||
|
* #8143: autodoc: AttributeError is raised when False value is passed to
|
||||||
|
autodoc_default_options
|
||||||
|
* #8103: autodoc: functools.cached_property is not considered as a property
|
||||||
|
* #8190: autodoc: parsing error is raised if some extension replaces docstring
|
||||||
|
by string not ending with blank lines
|
||||||
|
* #8142: autodoc: Wrong constructor signature for the class derived from
|
||||||
|
typing.Generic
|
||||||
|
* #8157: autodoc: TypeError is raised when annotation has invalid __args__
|
||||||
|
* #7964: autodoc: Tuple in default value is wrongly rendered
|
||||||
|
* #8200: autodoc: type aliases break type formatting of autoattribute
|
||||||
|
* #7786: autodoc: can't detect overloaded methods defined in other file
|
||||||
|
* #8294: autodoc: single-string __slots__ is not handled correctly
|
||||||
|
* #7785: autodoc: autodoc_typehints='none' does not effect to overloaded functions
|
||||||
|
* #8192: napoleon: description is disappeared when it contains inline literals
|
||||||
|
* #8142: napoleon: Potential of regex denial of service in google style docs
|
||||||
|
* #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex
|
||||||
|
* #8215: LaTeX: 'oneside' classoption causes build warning
|
||||||
|
* #8175: intersphinx: Potential of regex denial of service by broken inventory
|
||||||
|
* #8277: sphinx-build: missing and redundant spacing (and etc) for console
|
||||||
|
output on building
|
||||||
|
* #7973: imgconverter: Check availability of imagemagick many times
|
||||||
|
* #8255: py domain: number in default argument value is changed from hexadecimal
|
||||||
|
to decimal
|
||||||
|
* #8316: html: Prevent arrow keys changing page when button elements are focused
|
||||||
|
* #8343: html search: Fix unnecessary load of images when parsing the document
|
||||||
|
* #8254: html theme: Line numbers misalign with code lines
|
||||||
|
* #8093: The highlight warning has wrong location in some builders (LaTeX,
|
||||||
|
singlehtml and so on)
|
||||||
|
* #8215: Eliminate Fancyhdr build warnings for oneside documents
|
||||||
|
* #8239: Failed to refer a token in productionlist if it is indented
|
||||||
|
* #8268: linkcheck: Report HTTP errors when ``linkcheck_anchors`` is ``True``
|
||||||
|
* #8245: linkcheck: take source directory into account for local files
|
||||||
|
* #8321: linkcheck: ``tel:`` schema hyperlinks are detected as errors
|
||||||
|
* #8323: linkcheck: An exit status is incorrect when links having unsupported
|
||||||
|
schema found
|
||||||
|
* #8188: C, add missing items to internal object types dictionary,
|
||||||
|
e.g., preventing intersphinx from resolving them.
|
||||||
|
* C, fix anon objects in intersphinx.
|
||||||
|
* #8270, C++, properly reject functions as duplicate declarations if a
|
||||||
|
non-function declaration of the same name already exists.
|
||||||
|
* C, fix references to function parameters.
|
||||||
|
Link to the function instead of a non-existing anchor.
|
||||||
|
* #6914: figure numbers are unexpectedly assigned to uncaptioned items
|
||||||
|
* #8320: make "inline" line numbers un-selectable
|
||||||
|
|
||||||
|
Testing
|
||||||
|
--------
|
||||||
|
|
||||||
|
* #8257: Support parallel build in sphinx.testing
|
||||||
|
|
||||||
|
Release 3.2.1 (released Aug 14, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* #8095: napoleon: Add :confval:`napoleon_preprocess_types` to enable the type
|
||||||
|
preprocessor for numpy style docstrings
|
||||||
|
* #8114: C and C++, parse function attributes after parameters and qualifiers.
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #8074: napoleon: Crashes during processing C-ext module
|
||||||
|
* #8088: napoleon: "Inline literal start-string without end-string" warning in
|
||||||
|
Numpy style Parameters section
|
||||||
|
* #8084: autodoc: KeyError is raised on documenting an attribute of the broken
|
||||||
|
class
|
||||||
|
* #8091: autodoc: AttributeError is raised on documenting an attribute on Python
|
||||||
|
3.5.2
|
||||||
|
* #8099: autodoc: NameError is raised when target code uses ``TYPE_CHECKING``
|
||||||
|
* C++, fix parsing of template template paramters, broken by the fix of #7944
|
||||||
|
|
||||||
|
Release 3.2.0 (released Aug 08, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
* ``sphinx.ext.autodoc.members_set_option()``
|
||||||
|
* ``sphinx.ext.autodoc.merge_special_members_option()``
|
||||||
|
* ``sphinx.writers.texinfo.TexinfoWriter.desc``
|
||||||
|
* C, parsing of pre-v3 style type directives and roles, along with the options
|
||||||
|
:confval:`c_allow_pre_v3` and :confval:`c_warn_on_allowed_pre_v3`.
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* #2076: autodoc: Allow overriding of exclude-members in skip-member function
|
||||||
|
* #8034: autodoc: ``:private-member:`` can take an explicit list of member names
|
||||||
|
to be documented
|
||||||
|
* #2024: autosummary: Add :confval:`autosummary_filename_map` to avoid conflict
|
||||||
|
of filenames between two object with different case
|
||||||
|
* #8011: autosummary: Support instance attributes as a target of autosummary
|
||||||
|
directive
|
||||||
|
* #7849: html: Add :confval:`html_codeblock_linenos_style` to change the style
|
||||||
|
of line numbers for code-blocks
|
||||||
|
* #7853: C and C++, support parameterized GNU style attributes.
|
||||||
|
* #7888: napoleon: Add aliases Warn and Raise.
|
||||||
|
* #7690: napoleon: parse type strings and make them hyperlinks as possible. The
|
||||||
|
conversion rule can be updated via :confval:`napoleon_type_aliases`
|
||||||
|
* #8049: napoleon: Create a hyperlink for each the type of parameter when
|
||||||
|
:confval:`napoleon_use_params` is False
|
||||||
|
* C, added :rst:dir:`c:alias` directive for inserting copies
|
||||||
|
of existing declarations.
|
||||||
|
* #7745: html: inventory is broken if the docname contains a space
|
||||||
|
* #7991: html search: Allow searching for numbers
|
||||||
|
* #7902: html theme: Add a new option :confval:`globaltoc_maxdepth` to control
|
||||||
|
the behavior of globaltoc in sidebar
|
||||||
|
* #7840: i18n: Optimize the dependencies check on bootstrap
|
||||||
|
* #7768: i18n: :confval:`figure_language_filename` supports ``docpath`` token
|
||||||
|
* #5208: linkcheck: Support checks for local links
|
||||||
|
* #5090: setuptools: Link verbosity to distutils' -v and -q option
|
||||||
|
* #6698: doctest: Add ``:trim-doctest-flags:`` and ``:no-trim-doctest-flags:``
|
||||||
|
options to doctest, testcode and testoutput directives
|
||||||
|
* #7052: add ``:noindexentry:`` to the Python, C, C++, and Javascript domains.
|
||||||
|
Update the documentation to better reflect the relationship between this option
|
||||||
|
and the ``:noindex:`` option.
|
||||||
|
* #7899: C, add possibility of parsing of some pre-v3 style type directives and
|
||||||
|
roles and try to convert them to equivalent v3 directives/roles.
|
||||||
|
Set the new option :confval:`c_allow_pre_v3` to ``True`` to enable this.
|
||||||
|
The warnings printed from this functionality can be suppressed by setting
|
||||||
|
:confval:`c_warn_on_allowed_pre_v3`` to ``True``.
|
||||||
|
The functionality is immediately deprecated.
|
||||||
|
* #7999: C, add support for named variadic macro arguments.
|
||||||
|
* #8071: Allow to suppress "self referenced toctrees" warning
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #7886: autodoc: TypeError is raised on mocking generic-typed classes
|
||||||
|
* #7935: autodoc: function signature is not shown when the function has a
|
||||||
|
parameter having ``inspect._empty`` as its default value
|
||||||
|
* #7901: autodoc: type annotations for overloaded functions are not resolved
|
||||||
|
* #904: autodoc: An instance attribute cause a crash of autofunction directive
|
||||||
|
* #1362: autodoc: ``private-members`` option does not work for class attributes
|
||||||
|
* #7983: autodoc: Generator type annotation is wrongly rendered in py36
|
||||||
|
* #8030: autodoc: An uninitialized annotated instance variable is not documented
|
||||||
|
when ``:inherited-members:`` option given
|
||||||
|
* #8032: autodoc: A type hint for the instance variable defined at parent class
|
||||||
|
is not shown in the document of the derived class
|
||||||
|
* #8041: autodoc: An annotated instance variable on super class is not
|
||||||
|
documented when derived class has other annotated instance variables
|
||||||
|
* #7839: autosummary: cannot handle umlauts in function names
|
||||||
|
* #7865: autosummary: Failed to extract summary line when abbreviations found
|
||||||
|
* #7866: autosummary: Failed to extract correct summary line when docstring
|
||||||
|
contains a hyperlink target
|
||||||
|
* #7469: autosummary: "Module attributes" header is not translatable
|
||||||
|
* #7940: apidoc: An extra newline is generated at the end of the rst file if a
|
||||||
|
module has submodules
|
||||||
|
* #4258: napoleon: decorated special methods are not shown
|
||||||
|
* #7799: napoleon: parameters are not escaped for combined params in numpydoc
|
||||||
|
* #7780: napoleon: multiple paramaters declaration in numpydoc was wrongly
|
||||||
|
recognized when napoleon_use_params=True
|
||||||
|
* #7715: LaTeX: ``numfig_secnum_depth > 1`` leads to wrong figure links
|
||||||
|
* #7846: html theme: XML-invalid files were generated
|
||||||
|
* #7894: gettext: Wrong source info is shown when using rst_epilog
|
||||||
|
* #7691: linkcheck: HEAD requests are not used for checking
|
||||||
|
* #4888: i18n: Failed to add an explicit title to ``:ref:`` role on translation
|
||||||
|
* #7928: py domain: failed to resolve a type annotation for the attribute
|
||||||
|
* #8008: py domain: failed to parse a type annotation containing ellipsis
|
||||||
|
* #7994: std domain: option directive does not generate old node_id compatible
|
||||||
|
with 2.x or older
|
||||||
|
* #7968: i18n: The content of ``math`` directive is interpreted as reST on
|
||||||
|
translation
|
||||||
|
* #7768: i18n: The ``root`` element for :confval:`figure_language_filename` is
|
||||||
|
not a path that user specifies in the document
|
||||||
|
* #7993: texinfo: TypeError is raised for nested object descriptions
|
||||||
|
* #7993: texinfo: a warning not supporting desc_signature_line node is shown
|
||||||
|
* #7869: :rst:role:`abbr` role without an explanation will show the explanation
|
||||||
|
from the previous abbr role
|
||||||
|
* #8048: graphviz: graphviz.css was copied on building non-HTML document
|
||||||
|
* C and C++, removed ``noindex`` directive option as it did
|
||||||
|
nothing.
|
||||||
|
* #7619: Duplicated node IDs are generated if node has multiple IDs
|
||||||
|
* #2050: Symbols sections are appeared twice in the index page
|
||||||
|
* #8017: Fix circular import in sphinx.addnodes
|
||||||
|
* #7986: CSS: make "highlight" selector more robust
|
||||||
|
* #7944: C++, parse non-type template parameters starting with
|
||||||
|
a dependent qualified name.
|
||||||
|
* C, don't deepcopy the entire symbol table and make a mess every time an
|
||||||
|
enumerator is handled.
|
||||||
|
|
||||||
|
Release 3.1.2 (released Jul 05, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* #7650: autodoc: the signature of base function will be shown for decorated
|
||||||
|
functions, not a signature of decorator
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #7844: autodoc: Failed to detect module when relative module name given
|
||||||
|
* #7856: autodoc: AttributeError is raised when non-class object is given to
|
||||||
|
the autoclass directive
|
||||||
|
* #7850: autodoc: KeyError is raised for invalid mark up when autodoc_typehints
|
||||||
|
is 'description'
|
||||||
|
* #7812: autodoc: crashed if the target name matches to both an attribute and
|
||||||
|
module that are same name
|
||||||
|
* #7650: autodoc: function signature becomes ``(*args, **kwargs)`` if the
|
||||||
|
function is decorated by generic decorator
|
||||||
|
* #7812: autosummary: generates broken stub files if the target code contains
|
||||||
|
an attribute and module that are same name
|
||||||
|
* #7806: viewcode: Failed to resolve viewcode references on 3rd party builders
|
||||||
|
* #7838: html theme: List items have extra vertical space
|
||||||
|
* #7878: html theme: Undesired interaction between "overflow" and "float"
|
||||||
|
|
||||||
|
Release 3.1.1 (released Jun 14, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* #7808: napoleon: a type for attribute are represented as typed field
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* #7807: autodoc: Show detailed warning when type_comment is mismatched with its
|
||||||
|
signature
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #7808: autodoc: Warnings raised on variable and attribute type annotations
|
||||||
|
* #7802: autodoc: EOFError is raised on parallel build
|
||||||
|
* #7821: autodoc: TypeError is raised for overloaded C-ext function
|
||||||
|
* #7805: autodoc: an object which descriptors returns is unexpectedly documented
|
||||||
|
* #7807: autodoc: wrong signature is shown for the function using contextmanager
|
||||||
|
* #7812: autosummary: generates broken stub files if the target code contains
|
||||||
|
an attribute and module that are same name
|
||||||
|
* #7808: napoleon: Warnings raised on variable and attribute type annotations
|
||||||
|
* #7811: sphinx.util.inspect causes circular import problem
|
||||||
|
|
||||||
|
Release 3.1.0 (released Jun 08, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
* #7746: mathjax: Update to 2.7.5
|
* #7746: mathjax: Update to 2.7.5
|
||||||
|
|
||||||
Incompatible changes
|
Incompatible changes
|
||||||
@ -51,6 +597,8 @@ Features added
|
|||||||
builtin base classes
|
builtin base classes
|
||||||
* #2106: autodoc: Support multiple signatures on docstring
|
* #2106: autodoc: Support multiple signatures on docstring
|
||||||
* #4422: autodoc: Support GenericAlias in Python 3.7 or above
|
* #4422: autodoc: Support GenericAlias in Python 3.7 or above
|
||||||
|
* #3610: autodoc: Support overloaded functions
|
||||||
|
* #7722: autodoc: Support TypeVar
|
||||||
* #7466: autosummary: headings in generated documents are not translated
|
* #7466: autosummary: headings in generated documents are not translated
|
||||||
* #7490: autosummary: Add ``:caption:`` option to autosummary directive to set a
|
* #7490: autosummary: Add ``:caption:`` option to autosummary directive to set a
|
||||||
caption to the toctree
|
caption to the toctree
|
||||||
@ -61,7 +609,8 @@ Features added
|
|||||||
variables for custom templates
|
variables for custom templates
|
||||||
* #7530: html: Support nested <kbd> elements
|
* #7530: html: Support nested <kbd> elements
|
||||||
* #7481: html theme: Add right margin to footnote/citation labels
|
* #7481: html theme: Add right margin to footnote/citation labels
|
||||||
* #7482: html theme: CSS spacing for code blocks with captions and line numbers
|
* #7482, #7717: html theme: CSS spacing for code blocks with captions and line
|
||||||
|
numbers
|
||||||
* #7443: html theme: Add new options :confval:`globaltoc_collapse` and
|
* #7443: html theme: Add new options :confval:`globaltoc_collapse` and
|
||||||
:confval:`globaltoc_includehidden` to control the behavior of globaltoc in
|
:confval:`globaltoc_includehidden` to control the behavior of globaltoc in
|
||||||
sidebar
|
sidebar
|
||||||
@ -73,6 +622,8 @@ Features added
|
|||||||
* #7542: html theme: Make admonition/topic/sidebar scrollable
|
* #7542: html theme: Make admonition/topic/sidebar scrollable
|
||||||
* #7543: html theme: Add top and bottom margins to tables
|
* #7543: html theme: Add top and bottom margins to tables
|
||||||
* #7695: html theme: Add viewport meta tag for basic theme
|
* #7695: html theme: Add viewport meta tag for basic theme
|
||||||
|
* #7721: html theme: classic: default codetextcolor/codebgcolor doesn't override
|
||||||
|
Pygments
|
||||||
* C and C++: allow semicolon in the end of declarations.
|
* C and C++: allow semicolon in the end of declarations.
|
||||||
* C++, parse parameterized noexcept specifiers.
|
* C++, parse parameterized noexcept specifiers.
|
||||||
* #7294: C++, parse expressions with user-defined literals.
|
* #7294: C++, parse expressions with user-defined literals.
|
||||||
@ -80,8 +631,13 @@ Features added
|
|||||||
* #7143: py domain: Add ``:final:`` option to :rst:dir:`py:class:`,
|
* #7143: py domain: Add ``:final:`` option to :rst:dir:`py:class:`,
|
||||||
:rst:dir:`py:exception:` and :rst:dir:`py:method:` directives
|
:rst:dir:`py:exception:` and :rst:dir:`py:method:` directives
|
||||||
* #7596: py domain: Change a type annotation for variables to a hyperlink
|
* #7596: py domain: Change a type annotation for variables to a hyperlink
|
||||||
|
* #7770: std domain: :rst:dir:`option` directive support arguments in the form
|
||||||
|
of ``foo[=bar]``
|
||||||
* #7582: napoleon: a type for attribute are represented like type annotation
|
* #7582: napoleon: a type for attribute are represented like type annotation
|
||||||
* #7734: napoleon: overescaped trailing underscore on attribute
|
* #7734: napoleon: overescaped trailing underscore on attribute
|
||||||
|
* #7247: linkcheck: Add :confval:`linkcheck_request_headers` to send custom HTTP
|
||||||
|
headers for specific host
|
||||||
|
* #7792: setuptools: Support ``--verbosity`` option
|
||||||
* #7683: Add ``allowed_exceptions`` parameter to ``Sphinx.emit()`` to allow
|
* #7683: Add ``allowed_exceptions`` parameter to ``Sphinx.emit()`` to allow
|
||||||
handlers to raise specified exceptions
|
handlers to raise specified exceptions
|
||||||
* #7295: C++, parse (trailing) requires clauses.
|
* #7295: C++, parse (trailing) requires clauses.
|
||||||
@ -113,6 +669,7 @@ Bugs fixed
|
|||||||
* #7668: autodoc: wrong retann value is passed to a handler of
|
* #7668: autodoc: wrong retann value is passed to a handler of
|
||||||
autodoc-proccess-signature
|
autodoc-proccess-signature
|
||||||
* #7711: autodoc: fails with ValueError when processing numpy objects
|
* #7711: autodoc: fails with ValueError when processing numpy objects
|
||||||
|
* #7791: autodoc: TypeError is raised on documenting singledispatch function
|
||||||
* #7551: autosummary: a nested class is indexed as non-nested class
|
* #7551: autosummary: a nested class is indexed as non-nested class
|
||||||
* #7661: autosummary: autosummary directive emits warnings twices if failed to
|
* #7661: autosummary: autosummary directive emits warnings twices if failed to
|
||||||
import the target module
|
import the target module
|
||||||
@ -121,8 +678,12 @@ Bugs fixed
|
|||||||
* #7671: autosummary: The location of import failure warning is missing
|
* #7671: autosummary: The location of import failure warning is missing
|
||||||
* #7535: sphinx-autogen: crashes when custom template uses inheritance
|
* #7535: sphinx-autogen: crashes when custom template uses inheritance
|
||||||
* #7536: sphinx-autogen: crashes when template uses i18n feature
|
* #7536: sphinx-autogen: crashes when template uses i18n feature
|
||||||
|
* #7781: sphinx-build: Wrong error message when outdir is not directory
|
||||||
* #7653: sphinx-quickstart: Fix multiple directory creation for nested relpath
|
* #7653: sphinx-quickstart: Fix multiple directory creation for nested relpath
|
||||||
* #2785: html: Bad alignment of equation links
|
* #2785: html: Bad alignment of equation links
|
||||||
|
* #7718: html theme: some themes does not respect background color of Pygments
|
||||||
|
style (agogo, haiku, nature, pyramid, scrolls, sphinxdoc and traditional)
|
||||||
|
* #7544: html theme: inconsistent padding in admonitions
|
||||||
* #7581: napoleon: bad parsing of inline code in attribute docstrings
|
* #7581: napoleon: bad parsing of inline code in attribute docstrings
|
||||||
* #7628: imgconverter: runs imagemagick once unnecessary for builders not
|
* #7628: imgconverter: runs imagemagick once unnecessary for builders not
|
||||||
supporting images
|
supporting images
|
||||||
@ -130,7 +691,10 @@ Bugs fixed
|
|||||||
* #7646: handle errors on event handlers
|
* #7646: handle errors on event handlers
|
||||||
* #4187: LaTeX: EN DASH disappears from PDF bookmarks in Japanese documents
|
* #4187: LaTeX: EN DASH disappears from PDF bookmarks in Japanese documents
|
||||||
* #7701: LaTeX: Anonymous indirect hyperlink target causes duplicated labels
|
* #7701: LaTeX: Anonymous indirect hyperlink target causes duplicated labels
|
||||||
|
* #7723: LaTeX: pdflatex crashed when URL contains a single quote
|
||||||
* #7756: py domain: The default value for positional only argument is not shown
|
* #7756: py domain: The default value for positional only argument is not shown
|
||||||
|
* #7760: coverage: Add :confval:`coverage_show_missing_items` to show coverage
|
||||||
|
result to console
|
||||||
* C++, fix rendering and xrefs in nested names explicitly starting
|
* C++, fix rendering and xrefs in nested names explicitly starting
|
||||||
in global scope, e.g., ``::A::B``.
|
in global scope, e.g., ``::A::B``.
|
||||||
* C, fix rendering and xrefs in nested names explicitly starting
|
* C, fix rendering and xrefs in nested names explicitly starting
|
||||||
@ -138,30 +702,6 @@ Bugs fixed
|
|||||||
* #7763: C and C++, don't crash during display stringification of unary
|
* #7763: C and C++, don't crash during display stringification of unary
|
||||||
expressions and fold expressions.
|
expressions and fold expressions.
|
||||||
|
|
||||||
Testing
|
|
||||||
--------
|
|
||||||
|
|
||||||
Release 3.0.5 (in development)
|
|
||||||
==============================
|
|
||||||
|
|
||||||
Dependencies
|
|
||||||
------------
|
|
||||||
|
|
||||||
Incompatible changes
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Deprecated
|
|
||||||
----------
|
|
||||||
|
|
||||||
Features added
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Bugs fixed
|
|
||||||
----------
|
|
||||||
|
|
||||||
Testing
|
|
||||||
--------
|
|
||||||
|
|
||||||
Release 3.0.4 (released May 27, 2020)
|
Release 3.0.4 (released May 27, 2020)
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
@ -470,7 +1010,7 @@ Release 2.4.1 (released Feb 11, 2020)
|
|||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
|
|
||||||
* #7120: html: crashed when on scaling SVG images which have float dimentions
|
* #7120: html: crashed when on scaling SVG images which have float dimensions
|
||||||
* #7126: autodoc: TypeError: 'getset_descriptor' object is not iterable
|
* #7126: autodoc: TypeError: 'getset_descriptor' object is not iterable
|
||||||
|
|
||||||
Release 2.4.0 (released Feb 09, 2020)
|
Release 2.4.0 (released Feb 09, 2020)
|
||||||
@ -616,7 +1156,7 @@ Features added
|
|||||||
* #6548: html: Use favicon for OpenSearch if available
|
* #6548: html: Use favicon for OpenSearch if available
|
||||||
* #6729: html theme: agogo theme now supports ``rightsidebar`` option
|
* #6729: html theme: agogo theme now supports ``rightsidebar`` option
|
||||||
* #6780: Add PEP-561 Support
|
* #6780: Add PEP-561 Support
|
||||||
* #6762: latex: Allow to load additonal LaTeX packages via ``extrapackages`` key
|
* #6762: latex: Allow to load additional LaTeX packages via ``extrapackages`` key
|
||||||
of :confval:`latex_elements`
|
of :confval:`latex_elements`
|
||||||
* #1331: Add new config variable: :confval:`user_agent`
|
* #1331: Add new config variable: :confval:`user_agent`
|
||||||
* #6000: LaTeX: have backslash also be an inline literal word wrap break
|
* #6000: LaTeX: have backslash also be an inline literal word wrap break
|
||||||
|
@ -8,10 +8,11 @@ reports/feature requests.
|
|||||||
|
|
||||||
Our contributing guide can be found online at:
|
Our contributing guide can be found online at:
|
||||||
|
|
||||||
https://www.sphinx-doc.org/en/master/internals/contributing/
|
https://www.sphinx-doc.org/en/master/internals/contributing.html
|
||||||
|
|
||||||
You can also browse it from this repository from
|
You can also browse it from this repository from
|
||||||
``doc/internals/contributing/``
|
``doc/internals/contributing.rst``
|
||||||
|
|
||||||
Sphinx uses GitHub to host source code, track patches and bugs, and more.
|
Sphinx uses GitHub to host source code, track patches and bugs, and more.
|
||||||
Please make an effort to provide as much possible when filing bugs.
|
Please make an effort to provide as much detail as possible when filing
|
||||||
|
bugs.
|
||||||
|
6
EXAMPLES
6
EXAMPLES
@ -230,6 +230,7 @@ Documentation using sphinx_rtd_theme
|
|||||||
* `MyHDL <http://docs.myhdl.org/>`__
|
* `MyHDL <http://docs.myhdl.org/>`__
|
||||||
* `Nextflow <https://www.nextflow.io/docs/latest/index.html>`__
|
* `Nextflow <https://www.nextflow.io/docs/latest/index.html>`__
|
||||||
* `NICOS <https://forge.frm2.tum.de/nicos/doc/nicos-master/>`__ (customized)
|
* `NICOS <https://forge.frm2.tum.de/nicos/doc/nicos-master/>`__ (customized)
|
||||||
|
* `OpenFAST <https://openfast.readthedocs.io/>`__
|
||||||
* `Pelican <http://docs.getpelican.com/>`__
|
* `Pelican <http://docs.getpelican.com/>`__
|
||||||
* `picamera <https://picamera.readthedocs.io/>`__
|
* `picamera <https://picamera.readthedocs.io/>`__
|
||||||
* `Pillow <https://pillow.readthedocs.io/>`__
|
* `Pillow <https://pillow.readthedocs.io/>`__
|
||||||
@ -317,6 +318,7 @@ Documentation using a custom theme or integrated in a website
|
|||||||
* `Django <https://docs.djangoproject.com/>`__
|
* `Django <https://docs.djangoproject.com/>`__
|
||||||
* `Doctrine <https://www.doctrine-project.org/>`__
|
* `Doctrine <https://www.doctrine-project.org/>`__
|
||||||
* `Enterprise Toolkit for Acrobat products <https://www.adobe.com/devnet-docs/acrobatetk/>`__
|
* `Enterprise Toolkit for Acrobat products <https://www.adobe.com/devnet-docs/acrobatetk/>`__
|
||||||
|
* `FreeFEM <https://doc.freefem.org/introduction/>`__
|
||||||
* `Gameduino <http://excamera.com/sphinx/gameduino/>`__
|
* `Gameduino <http://excamera.com/sphinx/gameduino/>`__
|
||||||
* `gensim <https://radimrehurek.com/gensim/>`__
|
* `gensim <https://radimrehurek.com/gensim/>`__
|
||||||
* `GeoServer <http://docs.geoserver.org/>`__
|
* `GeoServer <http://docs.geoserver.org/>`__
|
||||||
@ -330,6 +332,7 @@ Documentation using a custom theme or integrated in a website
|
|||||||
* `Lasso <http://lassoguide.com/>`__
|
* `Lasso <http://lassoguide.com/>`__
|
||||||
* `Mako <http://docs.makotemplates.org/>`__
|
* `Mako <http://docs.makotemplates.org/>`__
|
||||||
* `MirrorBrain <http://mirrorbrain.org/docs/>`__
|
* `MirrorBrain <http://mirrorbrain.org/docs/>`__
|
||||||
|
* `Mitiq <https://mitiq.readthedocs.io/>`__
|
||||||
* `MongoDB <https://docs.mongodb.com/>`__
|
* `MongoDB <https://docs.mongodb.com/>`__
|
||||||
* `Music21 <https://web.mit.edu/music21/doc/>`__
|
* `Music21 <https://web.mit.edu/music21/doc/>`__
|
||||||
* `MyHDL <http://docs.myhdl.org/>`__
|
* `MyHDL <http://docs.myhdl.org/>`__
|
||||||
@ -355,7 +358,7 @@ Documentation using a custom theme or integrated in a website
|
|||||||
* `Roundup <http://www.roundup-tracker.org/>`__
|
* `Roundup <http://www.roundup-tracker.org/>`__
|
||||||
* `SaltStack <https://docs.saltstack.com/>`__
|
* `SaltStack <https://docs.saltstack.com/>`__
|
||||||
* `scikit-learn <http://scikit-learn.org/stable/>`__
|
* `scikit-learn <http://scikit-learn.org/stable/>`__
|
||||||
* `SciPy <https://docs.scipy.org/doc/scipy/refrence/>`__
|
* `SciPy <https://docs.scipy.org/doc/scipy/reference/>`__
|
||||||
* `Scrapy <https://doc.scrapy.org/>`__
|
* `Scrapy <https://doc.scrapy.org/>`__
|
||||||
* `Seaborn <https://seaborn.pydata.org/>`__
|
* `Seaborn <https://seaborn.pydata.org/>`__
|
||||||
* `Selenium <https://docs.seleniumhq.org/docs/>`__
|
* `Selenium <https://docs.seleniumhq.org/docs/>`__
|
||||||
@ -382,6 +385,7 @@ Homepages and other non-documentation sites
|
|||||||
* `Pylearn2 <http://www.deeplearning.net/software/pylearn2/>`__ (sphinxdoc, customized)
|
* `Pylearn2 <http://www.deeplearning.net/software/pylearn2/>`__ (sphinxdoc, customized)
|
||||||
* `PyXLL <https://www.pyxll.com/>`__ (sphinx_bootstrap_theme, customized)
|
* `PyXLL <https://www.pyxll.com/>`__ (sphinx_bootstrap_theme, customized)
|
||||||
* `SciPy Cookbook <https://scipy-cookbook.readthedocs.io/>`__ (sphinx_rtd_theme)
|
* `SciPy Cookbook <https://scipy-cookbook.readthedocs.io/>`__ (sphinx_rtd_theme)
|
||||||
|
* `Tech writer at work blog <https://blog.documatt.com/>`__ (custom theme)
|
||||||
* `The Wine Cellar Book <https://www.thewinecellarbook.com/doc/en/>`__ (sphinxdoc)
|
* `The Wine Cellar Book <https://www.thewinecellarbook.com/doc/en/>`__ (sphinxdoc)
|
||||||
* `Thomas Cokelaer's Python, Sphinx and reStructuredText tutorials <https://thomas-cokelaer.info/tutorials/>`__ (standard)
|
* `Thomas Cokelaer's Python, Sphinx and reStructuredText tutorials <https://thomas-cokelaer.info/tutorials/>`__ (standard)
|
||||||
* `UC Berkeley ME233 Advanced Control Systems II course <https://berkeley-me233.github.io/>`__ (sphinxdoc)
|
* `UC Berkeley ME233 Advanced Control Systems II course <https://berkeley-me233.github.io/>`__ (sphinxdoc)
|
||||||
|
2
LICENSE
2
LICENSE
@ -1,7 +1,7 @@
|
|||||||
License for Sphinx
|
License for Sphinx
|
||||||
==================
|
==================
|
||||||
|
|
||||||
Copyright (c) 2007-2019 by the Sphinx team (see AUTHORS file).
|
Copyright (c) 2007-2021 by the Sphinx team (see AUTHORS file).
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
10
Makefile
10
Makefile
@ -64,17 +64,13 @@ type-check:
|
|||||||
doclinter:
|
doclinter:
|
||||||
python utils/doclinter.py CHANGES *.rst doc/
|
python utils/doclinter.py CHANGES *.rst doc/
|
||||||
|
|
||||||
.PHONY: pylint
|
|
||||||
pylint:
|
|
||||||
@pylint --rcfile utils/pylintrc sphinx
|
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
@$(PYTHON) -m pytest -v $(TEST)
|
@$(PYTHON) -X dev -m pytest -v $(TEST)
|
||||||
|
|
||||||
.PHONY: covertest
|
.PHONY: covertest
|
||||||
covertest:
|
covertest:
|
||||||
@$(PYTHON) -m pytest -v --cov=sphinx --junitxml=.junit.xml $(TEST)
|
@$(PYTHON) -X dev -m pytest -v --cov=sphinx --junitxml=.junit.xml $(TEST)
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build:
|
build:
|
||||||
@ -83,6 +79,6 @@ build:
|
|||||||
.PHONY: docs
|
.PHONY: docs
|
||||||
docs:
|
docs:
|
||||||
ifndef target
|
ifndef target
|
||||||
$(info You need to give a provide a target variable, e.g. `make docs target=html`.)
|
$(info You need to provide a target variable, e.g. `make docs target=html`.)
|
||||||
endif
|
endif
|
||||||
$(MAKE) -C doc $(target)
|
$(MAKE) -C doc $(target)
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
:target: https://opensource.org/licenses/BSD-3-Clause
|
:target: https://opensource.org/licenses/BSD-3-Clause
|
||||||
:alt: BSD 3 Clause
|
:alt: BSD 3 Clause
|
||||||
|
|
||||||
|
.. image:: https://codetriage.com/sphinx-doc/sphinx/badges/users.svg
|
||||||
|
:target: https://codetriage.com/sphinx-doc/sphinx
|
||||||
|
:alt: Open Source Helpers badge
|
||||||
|
|
||||||
Sphinx is a tool that makes it easy to create intelligent and beautiful
|
Sphinx is a tool that makes it easy to create intelligent and beautiful
|
||||||
documentation for Python projects (or other documents consisting of multiple
|
documentation for Python projects (or other documents consisting of multiple
|
||||||
reStructuredText sources), written by Georg Brandl. It was originally created
|
reStructuredText sources), written by Georg Brandl. It was originally created
|
||||||
|
@ -13,3 +13,9 @@ texlive-anyfontsize [platform:rpm]
|
|||||||
texlive-ctablestack [platform:rpm]
|
texlive-ctablestack [platform:rpm]
|
||||||
texlive-gnu-freefont [platform:rpm]
|
texlive-gnu-freefont [platform:rpm]
|
||||||
latexmk [platform:rpm]
|
latexmk [platform:rpm]
|
||||||
|
|
||||||
|
texlive-latex-recommended [platform:dpkg]
|
||||||
|
texlive-fonts-recommended [platform:dpkg]
|
||||||
|
texlive-latex-extra [platform:dpkg]
|
||||||
|
texlive-luatex [platform:dpkg]
|
||||||
|
latexmk [platform:dpkg]
|
||||||
|
4
doc/_static/Makefile
vendored
4
doc/_static/Makefile
vendored
@ -1,4 +1,6 @@
|
|||||||
|
translation.png: translation.puml
|
||||||
|
plantuml -tpng $<
|
||||||
translation.svg: translation.puml
|
translation.svg: translation.puml
|
||||||
plantuml -tsvg $<
|
plantuml -tsvg $<
|
||||||
clean:
|
clean:
|
||||||
rm translation.svg
|
rm -f translation.png translation.svg
|
||||||
|
8
doc/_static/favicon.svg
vendored
Normal file
8
doc/_static/favicon.svg
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||||
|
<style>
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
svg { fill: white; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<path d="m 67.780707,71.526216 c 0,-2.720856 0.735772,-7.633735 1.635035,-10.917507 2.076574,-7.582764 3.222746,-16.97568 2.071477,-16.97568 -0.485619,0 -3.994408,3.173002 -7.797313,7.051115 -14.448869,14.734603 -29.952812,23.068339 -42.915946,23.068339 -7.400211,0 -12.4298817,-1.871115 -17.2867007,-6.430912 -2.94436186,-2.764297 -3.47532146,-4.129685 -3.47532146,-8.936928 0,-4.94488 0.4862322,-6.108589 3.78321146,-9.054437 2.987989,-2.669773 4.875111,-3.380296 8.9779137,-3.380296 3.163221,0.711278 5.032659,0.664017 6.063532,1.917191 1.045041,1.231842 1.406892,5.262673 0.143323,7.623675 -0.674746,1.260763 -2.435471,2.043539 -4.5966,2.043539 -2.040303,0 -3.203991,-0.483702 -2.786976,-1.15844 1.31395,-2.126021 -0.560952,-3.566616 -2.9664067,-2.279256 -2.907025,1.555792 -2.957418,7.069066 -0.08839,9.665535 4.0345357,3.651203 15.1912207,5.023925 21.9019857,2.694828 7.250749,-2.516503 16.739014,-8.578986 24.30831,-15.531674 l 6.657407,-6.115083 -8.688303,-0.05007 C 43.622519,44.707714 37.702703,43.621524 18.54695,38.489741 12.175528,36.782852 6.0502733,35.306342 4.9352743,35.208608 3.6710803,35.097791 2.841723,34.067882 2.9080043,32.476074 3.0199286,29.788108 4.4800823,27.78768 6.2067673,27.033038 7.2437505,26.579828 14.43583,25.894406 22.0605,23.866486 c 29.699148,-7.899023 31.502043,-6.781254 51.28707,-1.772167 6.461504,1.635896 13.942408,3.414988 17.256961,3.474566 5.106245,0.09178 6.211825,0.514653 7.240255,2.76932 0.66758,1.46355 1.21378,2.858905 1.21378,3.10079 0,0.241884 -2.89333,1.764397 -6.429613,3.383363 -12.984983,5.944723 -17.083271,9.093943 -12.855172,15.130399 1.753219,2.503069 1.718037,2.768923 -0.57922,4.37799 -1.345193,0.942203 -2.457238,2.856456 -2.471232,4.253898 -0.03777,3.776976 -2.424786,11.884847 -5.893734,15.080164 l -3.048923,2.808424 z m 6.632814,-34.658372 c 5.169656,-1.440693 8.302047,-3.07045 14.72913,-6.500861 -5.292267,-1.548658 -18.570782,-3.724097 -18.570782,-3.724097 -9.796513,-1.964547 -8.76916,-1.865132 -9.21348,0.29669 -0.176673,0.859598 -0.702644,2.763948 -1.872329,4.596663 -2.251474,3.527711 -10.489307,4.271075 -15.214327,2.009703 -1.482367,-0.709454 -2.971272,-3.416276 -2.950606,-5.336922 0.02911,-2.705486 -1.505386,-3.336055 -2.486689,-2.975309 -0.796428,0.292781 -3.384665,0.330004 -9.071284,1.864262 -18.784765,5.068157 -21.3552119,4.487473 -9.110967,6.223299 1.472409,0.208739 9.252992,2.381926 13.052028,3.39412 9.318588,2.482796 11.064717,2.665087 23.125496,2.414247 8.385835,-0.174409 11.891174,-0.675356 17.58381,-2.261795 z M 3.0589449,14.916483 C 3.2921927,12.514245 3.424378,11.992797 10.100599,10.647894 13.924923,9.8774962 23.355266,7.3808108 31.056903,5.0997052 c 17.703937,-5.2436279 22.73392,-5.2565016 41.092202,-0.105175 7.923233,2.2232606 16.798382,4.047803 19.72254,4.054541 4.567242,0.01054 6.941892,2.0284768 6.941892,2.0284768 2.101843,4.825342 1.718463,5.158474 -6.484103,5.158474 -5.714193,0 -10.641875,-0.963081 -18.245438,-3.565943 C 68.300078,10.69012 60.060462,8.8316882 55.557963,8.4915615 47.342337,7.8709375 47.353713,7.8687835 21.963188,14.855617 17.503192,16.082896 11.34213,17.454164 8.2719268,17.902883 l -5.5821654,0.81585 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
BIN
doc/_static/translation.png
vendored
Normal file
BIN
doc/_static/translation.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
2
doc/_static/translation.puml
vendored
2
doc/_static/translation.puml
vendored
@ -12,5 +12,5 @@ SphinxProject -r-> .rst
|
|||||||
.pot -r-> .po : Pootle
|
.pot -r-> .po : Pootle
|
||||||
.po -d-> .mo : msgfmt
|
.po -d-> .mo : msgfmt
|
||||||
.mo -l-> TranslatedBuild
|
.mo -l-> TranslatedBuild
|
||||||
.rst -d-> TranslatedBuild : "sphinx-buid -Dlanguage="
|
.rst -d-> TranslatedBuild : "sphinx-build -Dlanguage="
|
||||||
@enduml
|
@enduml
|
||||||
|
25
doc/_static/translation.svg
vendored
25
doc/_static/translation.svg
vendored
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 8.0 KiB |
2
doc/_themes/sphinx13/static/sphinx13.css
vendored
2
doc/_themes/sphinx13/static/sphinx13.css
vendored
@ -239,7 +239,7 @@ div.footer a {
|
|||||||
|
|
||||||
/* -- body styles ----------------------------------------------------------- */
|
/* -- body styles ----------------------------------------------------------- */
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0.8em 0 0.5em 0;
|
margin: 0.8em 0 0.5em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
doc/conf.py
11
doc/conf.py
@ -4,7 +4,6 @@ import re
|
|||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
|
|
||||||
|
|
||||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo',
|
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo',
|
||||||
'sphinx.ext.autosummary', 'sphinx.ext.extlinks',
|
'sphinx.ext.autosummary', 'sphinx.ext.extlinks',
|
||||||
'sphinx.ext.intersphinx',
|
'sphinx.ext.intersphinx',
|
||||||
@ -15,7 +14,7 @@ templates_path = ['_templates']
|
|||||||
exclude_patterns = ['_build']
|
exclude_patterns = ['_build']
|
||||||
|
|
||||||
project = 'Sphinx'
|
project = 'Sphinx'
|
||||||
copyright = '2007-2020, Georg Brandl and the Sphinx team'
|
copyright = '2007-2021, Georg Brandl and the Sphinx team'
|
||||||
version = sphinx.__display_version__
|
version = sphinx.__display_version__
|
||||||
release = version
|
release = version
|
||||||
show_authors = True
|
show_authors = True
|
||||||
@ -28,6 +27,7 @@ html_sidebars = {'index': ['indexsidebar.html', 'searchbox.html']}
|
|||||||
html_additional_pages = {'index': 'index.html'}
|
html_additional_pages = {'index': 'index.html'}
|
||||||
html_use_opensearch = 'https://www.sphinx-doc.org/en/master'
|
html_use_opensearch = 'https://www.sphinx-doc.org/en/master'
|
||||||
html_baseurl = 'https://www.sphinx-doc.org/en/master/'
|
html_baseurl = 'https://www.sphinx-doc.org/en/master/'
|
||||||
|
html_favicon = '_static/favicon.svg'
|
||||||
|
|
||||||
htmlhelp_basename = 'Sphinxdoc'
|
htmlhelp_basename = 'Sphinxdoc'
|
||||||
|
|
||||||
@ -110,9 +110,10 @@ texinfo_documents = [
|
|||||||
1),
|
1),
|
||||||
]
|
]
|
||||||
|
|
||||||
# We're not using intersphinx right now, but if we did, this would be part of
|
intersphinx_mapping = {
|
||||||
# the mapping:
|
'python': ('https://docs.python.org/3/', None),
|
||||||
intersphinx_mapping = {'python': ('https://docs.python.org/3/', None)}
|
'requests': ('https://requests.readthedocs.io/en/master', None),
|
||||||
|
}
|
||||||
|
|
||||||
# Sphinx document translation with sphinx gettext feature uses these settings:
|
# Sphinx document translation with sphinx gettext feature uses these settings:
|
||||||
locale_dirs = ['locale/']
|
locale_dirs = ['locale/']
|
||||||
|
@ -10,7 +10,6 @@ Sphinx documentation contents
|
|||||||
development/index
|
development/index
|
||||||
man/index
|
man/index
|
||||||
|
|
||||||
theming
|
|
||||||
templating
|
templating
|
||||||
latex
|
latex
|
||||||
extdev/index
|
extdev/index
|
||||||
|
34
doc/development/builders.rst
Normal file
34
doc/development/builders.rst
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
Configuring builders
|
||||||
|
====================
|
||||||
|
|
||||||
|
Discover builders by entry point
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
|
:term:`builder` extensions can be discovered by means of `entry points`_ so
|
||||||
|
that they do not have to be listed in the :confval:`extensions` configuration
|
||||||
|
value.
|
||||||
|
|
||||||
|
Builder extensions should define an entry point in the ``sphinx.builders``
|
||||||
|
group. The name of the entry point needs to match your builder's
|
||||||
|
:attr:`~.Builder.name` attribute, which is the name passed to the
|
||||||
|
:option:`sphinx-build -b` option. The entry point value should equal the
|
||||||
|
dotted name of the extension module. Here is an example of how an entry point
|
||||||
|
for 'mybuilder' can be defined in the extension's ``setup.py``
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
setup(
|
||||||
|
# ...
|
||||||
|
entry_points={
|
||||||
|
'sphinx.builders': [
|
||||||
|
'mybuilder = my.extension.module',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Note that it is still necessary to register the builder using
|
||||||
|
:meth:`~.Sphinx.add_builder` in the extension's :func:`setup` function.
|
||||||
|
|
||||||
|
.. _entry points: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
|
@ -2,12 +2,22 @@
|
|||||||
Extending Sphinx
|
Extending Sphinx
|
||||||
================
|
================
|
||||||
|
|
||||||
This guide is aimed at those wishing to develop their own extensions for
|
This guide is aimed at giving a quick introduction for those wishing to
|
||||||
Sphinx. Sphinx possesses significant extensibility capabilities including the
|
develop their own extensions for Sphinx. Sphinx possesses significant
|
||||||
ability to hook into almost every point of the build process. If you simply
|
extensibility capabilities including the ability to hook into almost every
|
||||||
wish to use Sphinx with existing extensions, refer to :doc:`/usage/index`.
|
point of the build process. If you simply wish to use Sphinx with existing
|
||||||
|
extensions, refer to :doc:`/usage/index`. For a more detailed discussion of
|
||||||
|
the extension interface see :doc:`/extdev/index`.
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
overview
|
||||||
tutorials/index
|
tutorials/index
|
||||||
|
builders
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Theming
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
theming
|
||||||
|
32
doc/development/overview.rst
Normal file
32
doc/development/overview.rst
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
Developing extensions overview
|
||||||
|
==============================
|
||||||
|
|
||||||
|
This page contains general information about developing Sphinx extensions.
|
||||||
|
|
||||||
|
Make an extension depend on another extension
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
Sometimes your extension depends on the functionality of another
|
||||||
|
Sphinx extension. Most Sphinx extensions are activated in a
|
||||||
|
project's :file:`conf.py` file, but this is not available to you as an
|
||||||
|
extension developer.
|
||||||
|
|
||||||
|
.. module:: sphinx.application
|
||||||
|
:noindex:
|
||||||
|
|
||||||
|
To ensure that another extension is activated as a part of your own extension,
|
||||||
|
use the :meth:`Sphinx.setup_extension` method. This will
|
||||||
|
activate another extension at run-time, ensuring that you have access to its
|
||||||
|
functionality.
|
||||||
|
|
||||||
|
For example, the following code activates the ``recommonmark`` extension:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.setup_extension("recommonmark")
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Since your extension will depend on another, make sure to include
|
||||||
|
it as a part of your extension's installation requirements.
|
336
doc/development/theming.rst
Normal file
336
doc/development/theming.rst
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
HTML theme development
|
||||||
|
======================
|
||||||
|
|
||||||
|
.. versionadded:: 0.6
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This document provides information about creating your own theme. If you
|
||||||
|
simply wish to use a pre-existing HTML themes, refer to
|
||||||
|
:doc:`/usage/theming`.
|
||||||
|
|
||||||
|
Sphinx supports changing the appearance of its HTML output via *themes*. A
|
||||||
|
theme is a collection of HTML templates, stylesheet(s) and other static files.
|
||||||
|
Additionally, it has a configuration file which specifies from which theme to
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
See :ref:`dev-extensions` for more information that may
|
||||||
|
be helpful in developing themes.
|
||||||
|
|
||||||
|
|
||||||
|
Creating themes
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Themes take the form of either a directory or a zipfile (whose name is the
|
||||||
|
theme name), containing the following:
|
||||||
|
|
||||||
|
* A :file:`theme.conf` file.
|
||||||
|
* HTML templates, if needed.
|
||||||
|
* A ``static/`` directory containing any static files that will be copied to the
|
||||||
|
output static directory on build. These can be images, styles, script files.
|
||||||
|
|
||||||
|
The :file:`theme.conf` file is in INI format [1]_ (readable by the standard
|
||||||
|
Python :mod:`ConfigParser` module) and has the following structure:
|
||||||
|
|
||||||
|
.. sourcecode:: ini
|
||||||
|
|
||||||
|
[theme]
|
||||||
|
inherit = base theme
|
||||||
|
stylesheet = main CSS name
|
||||||
|
pygments_style = stylename
|
||||||
|
sidebars = localtoc.html, relations.html, sourcelink.html, searchbox.html
|
||||||
|
|
||||||
|
[options]
|
||||||
|
variable = default value
|
||||||
|
|
||||||
|
* The **inherit** setting gives the name of a "base theme", or ``none``. The
|
||||||
|
base theme will be used to locate missing templates (most themes will not have
|
||||||
|
to supply most templates if they use ``basic`` as the base theme), its options
|
||||||
|
will be inherited, and all of its static files will be used as well. If you
|
||||||
|
want to also inherit the stylesheet, include it via CSS' ``@import`` in your
|
||||||
|
own.
|
||||||
|
|
||||||
|
* The **stylesheet** setting gives the name of a CSS file which will be
|
||||||
|
referenced in the HTML header. If you need more than one CSS file, either
|
||||||
|
include one from the other via CSS' ``@import``, or use a custom HTML template
|
||||||
|
that adds ``<link rel="stylesheet">`` tags as necessary. Setting the
|
||||||
|
:confval:`html_style` config value will override this setting.
|
||||||
|
|
||||||
|
* The **pygments_style** setting gives the name of a Pygments style to use for
|
||||||
|
highlighting. This can be overridden by the user in the
|
||||||
|
:confval:`pygments_style` config value.
|
||||||
|
|
||||||
|
* The **pygments_dark_style** setting gives the name of a Pygments style to use
|
||||||
|
for highlighting when the CSS media query ``(prefers-color-scheme: dark)``
|
||||||
|
evaluates to true. It is injected into the page using
|
||||||
|
:meth:`~Sphinx.add_css_file()`.
|
||||||
|
|
||||||
|
* The **sidebars** setting gives the comma separated list of sidebar templates
|
||||||
|
for constructing sidebars. This can be overridden by the user in the
|
||||||
|
:confval:`html_sidebars` config value.
|
||||||
|
|
||||||
|
* The **options** section contains pairs of variable names and default values.
|
||||||
|
These options can be overridden by the user in :confval:`html_theme_options`
|
||||||
|
and are accessible from all templates as ``theme_<name>``.
|
||||||
|
|
||||||
|
.. versionadded:: 1.7
|
||||||
|
sidebar settings
|
||||||
|
|
||||||
|
|
||||||
|
.. _distribute-your-theme:
|
||||||
|
|
||||||
|
Distribute your theme as a Python package
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
As a way to distribute your theme, you can use Python package. Python package
|
||||||
|
brings to users easy setting up ways.
|
||||||
|
|
||||||
|
To distribute your theme as a Python package, please define an entry point
|
||||||
|
called ``sphinx.html_themes`` in your ``setup.py`` file, and write a ``setup()``
|
||||||
|
function to register your themes using ``add_html_theme()`` API in it::
|
||||||
|
|
||||||
|
# 'setup.py'
|
||||||
|
setup(
|
||||||
|
...
|
||||||
|
entry_points = {
|
||||||
|
'sphinx.html_themes': [
|
||||||
|
'name_of_theme = your_package',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
# 'your_package.py'
|
||||||
|
from os import path
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_html_theme('name_of_theme', path.abspath(path.dirname(__file__)))
|
||||||
|
|
||||||
|
If your theme package contains two or more themes, please call
|
||||||
|
``add_html_theme()`` twice or more.
|
||||||
|
|
||||||
|
.. versionadded:: 1.2
|
||||||
|
'sphinx_themes' entry_points feature.
|
||||||
|
|
||||||
|
.. deprecated:: 1.6
|
||||||
|
``sphinx_themes`` entry_points has been deprecated.
|
||||||
|
|
||||||
|
.. versionadded:: 1.6
|
||||||
|
``sphinx.html_themes`` entry_points feature.
|
||||||
|
|
||||||
|
|
||||||
|
Templating
|
||||||
|
----------
|
||||||
|
|
||||||
|
The :doc:`guide to templating </templating>` is helpful if you want to write your
|
||||||
|
own templates. What is important to keep in mind is the order in which Sphinx
|
||||||
|
searches for templates:
|
||||||
|
|
||||||
|
* First, in the user's ``templates_path`` directories.
|
||||||
|
* Then, in the selected theme.
|
||||||
|
* Then, in its base theme, its base's base theme, etc.
|
||||||
|
|
||||||
|
When extending a template in the base theme with the same name, use the theme
|
||||||
|
name as an explicit directory: ``{% extends "basic/layout.html" %}``. From a
|
||||||
|
user ``templates_path`` template, you can still use the "exclamation mark"
|
||||||
|
syntax as described in the templating document.
|
||||||
|
|
||||||
|
|
||||||
|
.. _theming-static-templates:
|
||||||
|
|
||||||
|
Static templates
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Since theme options are meant for the user to configure a theme more easily,
|
||||||
|
without having to write a custom stylesheet, it is necessary to be able to
|
||||||
|
template static files as well as HTML files. Therefore, Sphinx supports
|
||||||
|
so-called "static templates", like this:
|
||||||
|
|
||||||
|
If the name of a file in the ``static/`` directory of a theme (or in the user's
|
||||||
|
static path, for that matter) ends with ``_t``, it will be processed by the
|
||||||
|
template engine. The ``_t`` will be left from the final file name. For
|
||||||
|
example, the *classic* theme has a file ``static/classic.css_t`` which uses
|
||||||
|
templating to put the color options into the stylesheet. When a documentation
|
||||||
|
is built with the classic theme, the output directory will contain a
|
||||||
|
``_static/classic.css`` file where all template tags have been processed.
|
||||||
|
|
||||||
|
|
||||||
|
Use custom page metadata in HTML templates
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Any key / value pairs in :doc:`field lists </usage/restructuredtext/field-lists>`
|
||||||
|
that are placed *before* the page's title will be available to the Jinja
|
||||||
|
template when building the page within the :data:`meta` attribute. For example,
|
||||||
|
if a page had the following text before its first title:
|
||||||
|
|
||||||
|
.. code-block:: rst
|
||||||
|
|
||||||
|
:mykey: My value
|
||||||
|
|
||||||
|
My first title
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Then it could be accessed within a Jinja template like so:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{%- if meta is mapping %}
|
||||||
|
{{ meta.get("mykey") }}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
Note the check that ``meta`` is a dictionary ("mapping" in Jinja
|
||||||
|
terminology) to ensure that using it in this way is valid.
|
||||||
|
|
||||||
|
|
||||||
|
Defining custom template functions
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Sometimes it is useful to define your own function in Python that you wish to
|
||||||
|
then use in a template. For example, if you'd like to insert a template value
|
||||||
|
with logic that depends on the user's configuration in the project, or if you'd
|
||||||
|
like to include non-trivial checks and provide friendly error messages for
|
||||||
|
incorrect configuration in the template.
|
||||||
|
|
||||||
|
To define your own template function, you'll need to define two functions
|
||||||
|
inside your module:
|
||||||
|
|
||||||
|
* A **page context event handler** (or **registration**) function. This is
|
||||||
|
connected to the :class:`.Sphinx` application via an event callback.
|
||||||
|
* A **template function** that you will use in your Jinja template.
|
||||||
|
|
||||||
|
First, define the registration function, which accepts the arguments for
|
||||||
|
:event:`html-page-context`.
|
||||||
|
|
||||||
|
Within the registration function, define the template function that you'd like to use
|
||||||
|
within Jinja. The template function should return a string or Python objects (lists,
|
||||||
|
dictionaries) with strings inside that Jinja uses in the templating process
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The template function will have access to all of the variables that
|
||||||
|
are passed to the registration function.
|
||||||
|
|
||||||
|
At the end of the registration function, add the template function to the
|
||||||
|
Sphinx application's context with ``context['template_func'] = template_func``.
|
||||||
|
|
||||||
|
Finally, in your extension's ``setup()`` function, add your registration
|
||||||
|
function as a callback for :event:`html-page-context`.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
# The registration function
|
||||||
|
def setup_my_func(app, pagename, templatename, context, doctree):
|
||||||
|
# The template function
|
||||||
|
def my_func(mystring):
|
||||||
|
return "Your string is %s" % mystring
|
||||||
|
# Add it to the page's context
|
||||||
|
context['my_func'] = my_func
|
||||||
|
|
||||||
|
# Your extension's setup function
|
||||||
|
def setup(app):
|
||||||
|
app.connect("html-page-context", setup_my_func)
|
||||||
|
|
||||||
|
Now, you will have access to this function in jinja like so:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{ my_func("some string") }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
Add your own static files to the build assets
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If you are packaging your own build assets with an extension
|
||||||
|
(e.g., a CSS or JavaScript file), you need to ensure that they are placed
|
||||||
|
in the ``_static/`` folder of HTML outputs. To do so, you may copy them directly
|
||||||
|
into a build's ``_static/`` folder at build time, generally via an event hook.
|
||||||
|
Here is some sample code to accomplish this:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def copy_custom_files(app, exc):
|
||||||
|
if app.builder.format == 'html' and not exc:
|
||||||
|
staticdir = path.join(app.builder.outdir, '_static')
|
||||||
|
copy_asset_file('path/to/myextension/_static/myjsfile.js', staticdir)
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.connect('builder-inited', copy_custom_files)
|
||||||
|
|
||||||
|
|
||||||
|
Inject JavaScript based on user configuration
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If your extension makes use of JavaScript, it can be useful to allow users
|
||||||
|
to control its behavior using their Sphinx configuration. However, this can
|
||||||
|
be difficult to do if your JavaScript comes in the form of a static library
|
||||||
|
(which will not be built with Jinja).
|
||||||
|
|
||||||
|
There are two ways to inject variables into the JavaScript space based on user
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
First, you may append ``_t`` to the end of any static files included with your
|
||||||
|
extension. This will cause Sphinx to process these files with the templating
|
||||||
|
engine, allowing you to embed variables and control behavior.
|
||||||
|
|
||||||
|
For example, the following JavaScript structure:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
mymodule/
|
||||||
|
├── _static
|
||||||
|
│ └── myjsfile.js_t
|
||||||
|
└── mymodule.py
|
||||||
|
|
||||||
|
Will result in the following static file placed in your HTML's build output:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
_build/
|
||||||
|
└── html
|
||||||
|
└── _static
|
||||||
|
└── myjsfile.js
|
||||||
|
|
||||||
|
See :ref:`theming-static-templates` for more information.
|
||||||
|
|
||||||
|
Second, you may use the :meth:`Sphinx.add_js_file` method without pointing it
|
||||||
|
to a file. Normally, this method is used to insert a new JavaScript file
|
||||||
|
into your site. However, if you do *not* pass a file path, but instead pass
|
||||||
|
a string to the "body" argument, then this text will be inserted as JavaScript
|
||||||
|
into your site's head. This allows you to insert variables into your project's
|
||||||
|
JavaScript from Python.
|
||||||
|
|
||||||
|
For example, the following code will read in a user-configured value and then
|
||||||
|
insert this value as a JavaScript variable, which your extension's JavaScript
|
||||||
|
code may use:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
# This function reads in a variable and inserts it into JavaScript
|
||||||
|
def add_js_variable(app):
|
||||||
|
# This is a configuration that you've specified for users in `conf.py`
|
||||||
|
js_variable = app.config['my_javascript_variable']
|
||||||
|
js_text = "var my_variable = '%s';" % js_variable
|
||||||
|
app.add_js_file(None, body=js_text)
|
||||||
|
# We connect this function to the step after the builder is initialized
|
||||||
|
def setup(app):
|
||||||
|
# Tell Sphinx about this configuration variable
|
||||||
|
app.add_config_value('my_javascript_variable')
|
||||||
|
# Run the function after the builder is initialized
|
||||||
|
app.connect('builder-inited', add_js_variable)
|
||||||
|
|
||||||
|
As a result, in your theme you can use code that depends on the presence of
|
||||||
|
this variable. Users can control the variable's value by defining it in their
|
||||||
|
:file:`conf.py` file.
|
||||||
|
|
||||||
|
|
||||||
|
.. [1] It is not an executable Python file, as opposed to :file:`conf.py`,
|
||||||
|
because that would pose an unnecessary security risk if themes are
|
||||||
|
shared.
|
@ -4,8 +4,7 @@ from docutils.parsers.rst import directives
|
|||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.directives import ObjectDescription
|
from sphinx.directives import ObjectDescription
|
||||||
from sphinx.domains import Domain
|
from sphinx.domains import Domain, Index
|
||||||
from sphinx.domains import Index
|
|
||||||
from sphinx.roles import XRefRole
|
from sphinx.roles import XRefRole
|
||||||
from sphinx.util.nodes import make_refnode
|
from sphinx.util.nodes import make_refnode
|
||||||
|
|
||||||
|
@ -61,6 +61,13 @@ def purge_todos(app, env, docname):
|
|||||||
if todo['docname'] != docname]
|
if todo['docname'] != docname]
|
||||||
|
|
||||||
|
|
||||||
|
def merge_todos(app, env, docnames, other):
|
||||||
|
if not hasattr(env, 'todo_all_todos'):
|
||||||
|
env.todo_all_todos = []
|
||||||
|
if hasattr(other, 'todo_all_todos'):
|
||||||
|
env.todo_all_todos.extend(other.todo_all_todos)
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
for node in doctree.traverse(todo):
|
for node in doctree.traverse(todo):
|
||||||
@ -119,6 +126,7 @@ def setup(app):
|
|||||||
app.add_directive('todolist', TodolistDirective)
|
app.add_directive('todolist', TodolistDirective)
|
||||||
app.connect('doctree-resolved', process_todo_nodes)
|
app.connect('doctree-resolved', process_todo_nodes)
|
||||||
app.connect('env-purge-doc', purge_todos)
|
app.connect('env-purge-doc', purge_todos)
|
||||||
|
app.connect('env-merge-info', merge_todos)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': '0.1',
|
'version': '0.1',
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
.. _extension-tutorials-index:
|
||||||
|
|
||||||
Extension tutorials
|
Extension tutorials
|
||||||
===================
|
===================
|
||||||
|
|
||||||
Refer to the following tutorials to get started with extension development.
|
Refer to the following tutorials to get started with extension development.
|
||||||
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:caption: Directive tutorials
|
:caption: Directive tutorials
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
@ -38,9 +38,10 @@ For that, we will need to add the following elements to Sphinx:
|
|||||||
with the extension name, in order to stay unique) that controls whether todo
|
with the extension name, in order to stay unique) that controls whether todo
|
||||||
entries make it into the output.
|
entries make it into the output.
|
||||||
|
|
||||||
* New event handlers: one for the :event:`doctree-resolved` event, to replace
|
* New event handlers: one for the :event:`doctree-resolved` event, to
|
||||||
the todo and todolist nodes, and one for :event:`env-purge-doc` (the reason
|
replace the todo and todolist nodes, one for :event:`env-merge-info`
|
||||||
for that will be covered later).
|
to merge intermediate results from parallel builds, and one for
|
||||||
|
:event:`env-purge-doc` (the reason for that will be covered later).
|
||||||
|
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
@ -212,12 +213,23 @@ Here we clear out all todos whose docname matches the given one from the
|
|||||||
``todo_all_todos`` list. If there are todos left in the document, they will be
|
``todo_all_todos`` list. If there are todos left in the document, they will be
|
||||||
added again during parsing.
|
added again during parsing.
|
||||||
|
|
||||||
|
The next handler, for the :event:`env-merge-info` event, is used
|
||||||
|
during parallel builds. As during parallel builds all threads have
|
||||||
|
their own ``env``, there's multiple ``todo_all_todos`` lists that need
|
||||||
|
to be merged:
|
||||||
|
|
||||||
|
.. literalinclude:: examples/todo.py
|
||||||
|
:language: python
|
||||||
|
:linenos:
|
||||||
|
:lines: 64-68
|
||||||
|
|
||||||
|
|
||||||
The other handler belongs to the :event:`doctree-resolved` event:
|
The other handler belongs to the :event:`doctree-resolved` event:
|
||||||
|
|
||||||
.. literalinclude:: examples/todo.py
|
.. literalinclude:: examples/todo.py
|
||||||
:language: python
|
:language: python
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 64-103
|
:lines: 71-113
|
||||||
|
|
||||||
The :event:`doctree-resolved` event is emitted at the end of :ref:`phase 3
|
The :event:`doctree-resolved` event is emitted at the end of :ref:`phase 3
|
||||||
(resolving) <build-phases>` and allows custom resolving to be done. The handler
|
(resolving) <build-phases>` and allows custom resolving to be done. The handler
|
||||||
@ -230,7 +242,7 @@ where they come from. The list items are composed of the nodes from the
|
|||||||
``todo`` entry and docutils nodes created on the fly: a paragraph for each
|
``todo`` entry and docutils nodes created on the fly: a paragraph for each
|
||||||
entry, containing text that gives the location, and a link (reference node
|
entry, containing text that gives the location, and a link (reference node
|
||||||
containing an italic node) with the backreference. The reference URI is built
|
containing an italic node) with the backreference. The reference URI is built
|
||||||
by :meth:`sphinx.builders.Builder.get_relative_uri`` which creates a suitable
|
by :meth:`sphinx.builders.Builder.get_relative_uri` which creates a suitable
|
||||||
URI depending on the used builder, and appending the todo node's (the target's)
|
URI depending on the used builder, and appending the todo node's (the target's)
|
||||||
ID as the anchor name.
|
ID as the anchor name.
|
||||||
|
|
||||||
@ -245,7 +257,7 @@ the other parts of our extension. Let's look at our ``setup`` function:
|
|||||||
.. literalinclude:: examples/todo.py
|
.. literalinclude:: examples/todo.py
|
||||||
:language: python
|
:language: python
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 106-
|
:lines: 116-
|
||||||
|
|
||||||
The calls in this function refer to the classes and functions we added earlier.
|
The calls in this function refer to the classes and functions we added earlier.
|
||||||
What the individual calls do is the following:
|
What the individual calls do is the following:
|
||||||
|
@ -25,75 +25,75 @@ package.
|
|||||||
|
|
||||||
.. currentmodule:: sphinx.application
|
.. currentmodule:: sphinx.application
|
||||||
|
|
||||||
.. automethod:: Sphinx.setup_extension(name)
|
.. automethod:: Sphinx.setup_extension
|
||||||
|
|
||||||
.. automethod:: Sphinx.require_sphinx(version)
|
.. automethod:: Sphinx.require_sphinx
|
||||||
|
|
||||||
.. automethod:: Sphinx.connect(event, callback)
|
.. automethod:: Sphinx.connect
|
||||||
|
|
||||||
.. automethod:: Sphinx.disconnect(listener_id)
|
.. automethod:: Sphinx.disconnect
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_builder(builder)
|
.. automethod:: Sphinx.add_builder
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_config_value(name, default, rebuild)
|
.. automethod:: Sphinx.add_config_value
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_event(name)
|
.. automethod:: Sphinx.add_event
|
||||||
|
|
||||||
.. automethod:: Sphinx.set_translator(name, translator_class)
|
.. automethod:: Sphinx.set_translator
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_node(node, \*\*kwds)
|
.. automethod:: Sphinx.add_node
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_enumerable_node(node, figtype, title_getter=None, \*\*kwds)
|
.. automethod:: Sphinx.add_enumerable_node
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_directive(name, directiveclass)
|
.. automethod:: Sphinx.add_directive
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_role(name, role)
|
.. automethod:: Sphinx.add_role
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_generic_role(name, nodeclass)
|
.. automethod:: Sphinx.add_generic_role
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_domain(domain)
|
.. automethod:: Sphinx.add_domain
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_directive_to_domain(domain, name, directiveclass)
|
.. automethod:: Sphinx.add_directive_to_domain
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_role_to_domain(domain, name, role)
|
.. automethod:: Sphinx.add_role_to_domain
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_index_to_domain(domain, index)
|
.. automethod:: Sphinx.add_index_to_domain
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_object_type(directivename, rolename, indextemplate='', parse_node=None, ref_nodeclass=None, objname='', doc_field_types=[])
|
.. automethod:: Sphinx.add_object_type
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_crossref_type(directivename, rolename, indextemplate='', ref_nodeclass=None, objname='')
|
.. automethod:: Sphinx.add_crossref_type
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_transform(transform)
|
.. automethod:: Sphinx.add_transform
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_post_transform(transform)
|
.. automethod:: Sphinx.add_post_transform
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_js_file(filename, **kwargs)
|
.. automethod:: Sphinx.add_js_file
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_css_file(filename, **kwargs)
|
.. automethod:: Sphinx.add_css_file
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_latex_package(packagename, options=None)
|
.. automethod:: Sphinx.add_latex_package
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_lexer(alias, lexer)
|
.. automethod:: Sphinx.add_lexer
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_autodocumenter(cls)
|
.. automethod:: Sphinx.add_autodocumenter
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_autodoc_attrgetter(type, getter)
|
.. automethod:: Sphinx.add_autodoc_attrgetter
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_search_language(cls)
|
.. automethod:: Sphinx.add_search_language
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_source_suffix(suffix, filetype)
|
.. automethod:: Sphinx.add_source_suffix
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_source_parser(parser)
|
.. automethod:: Sphinx.add_source_parser
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_env_collector(collector)
|
.. automethod:: Sphinx.add_env_collector
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_html_theme(name, theme_path)
|
.. automethod:: Sphinx.add_html_theme
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_html_math_renderer(name, inline_renderers, block_renderers)
|
.. automethod:: Sphinx.add_html_math_renderer
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_message_catalog(catalog, locale_dir)
|
.. automethod:: Sphinx.add_message_catalog
|
||||||
|
|
||||||
.. automethod:: Sphinx.is_parallel_allowed(typ)
|
.. automethod:: Sphinx.is_parallel_allowed
|
||||||
|
|
||||||
.. exception:: ExtensionError
|
.. exception:: ExtensionError
|
||||||
|
|
||||||
@ -107,9 +107,9 @@ Emitting events
|
|||||||
.. class:: Sphinx
|
.. class:: Sphinx
|
||||||
:noindex:
|
:noindex:
|
||||||
|
|
||||||
.. automethod:: emit(event, \*arguments)
|
.. automethod:: emit
|
||||||
|
|
||||||
.. automethod:: emit_firstresult(event, \*arguments)
|
.. automethod:: emit_firstresult
|
||||||
|
|
||||||
|
|
||||||
Sphinx runtime information
|
Sphinx runtime information
|
||||||
@ -157,6 +157,42 @@ connect handlers to the events. Example:
|
|||||||
app.connect('source-read', source_read_handler)
|
app.connect('source-read', source_read_handler)
|
||||||
|
|
||||||
|
|
||||||
|
Below is an overview of each event that happens during a build. In the list
|
||||||
|
below, we include the event name, its callback parameters, and the input and output
|
||||||
|
type for that event::
|
||||||
|
|
||||||
|
1. event.config-inited(app,config)
|
||||||
|
2. event.builder-inited(app)
|
||||||
|
3. event.env-get-outdated(app, env, added, changed, removed)
|
||||||
|
4. event.env-before-read-docs(app, env, docnames)
|
||||||
|
|
||||||
|
for docname in docnames:
|
||||||
|
5. event.env-purge-doc(app, env, docname)
|
||||||
|
if doc changed and not removed:
|
||||||
|
6. source-read(app, docname, source)
|
||||||
|
7. run source parsers: text -> docutils.document (parsers can be added with the app.add_source_parser() API)
|
||||||
|
8. apply transforms (by priority): docutils.document -> docutils.document
|
||||||
|
- event.doctree-read(app, doctree) is called in the middly of transforms,
|
||||||
|
transforms come before/after this event depending on their priority.
|
||||||
|
9. (if running in parallel mode, for each process) event.env-merged-info(app, env, docnames, other)
|
||||||
|
10. event.env-updated(app, env)
|
||||||
|
11. event.env-get-updated(app, env)
|
||||||
|
12. event.env-check-consistency(app, env)
|
||||||
|
|
||||||
|
# The updated-docs list can be builder dependent, but generally includes all new/changed documents,
|
||||||
|
# plus any output from `env-get-updated`, and then all "parent" documents in the ToC tree
|
||||||
|
# For builders that output a single page, they are first joined into a single doctree before post-transforms/doctree-resolved
|
||||||
|
for docname in updated-docs:
|
||||||
|
13. apply post-transforms (by priority): docutils.document -> docutils.document
|
||||||
|
14. event.doctree-resolved(app, doctree, docname)
|
||||||
|
- (for any reference node that fails to resolve) event.missing-reference(env, node, contnode)
|
||||||
|
- (for any reference node that fails to resolve) event.warn-missing-reference(domain, node)
|
||||||
|
|
||||||
|
15. Generate output files
|
||||||
|
16. event.build-finished(app, exception)
|
||||||
|
|
||||||
|
Here is a more detailed list of these events.
|
||||||
|
|
||||||
.. event:: builder-inited (app)
|
.. event:: builder-inited (app)
|
||||||
|
|
||||||
Emitted when the builder object has been created. It is available as
|
Emitted when the builder object has been created. It is available as
|
||||||
@ -249,6 +285,14 @@ connect handlers to the events. Example:
|
|||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
|
|
||||||
|
.. event:: warn-missing-reference (app, domain, node)
|
||||||
|
|
||||||
|
Emitted when a cross-reference to an object cannot be resolved even after
|
||||||
|
:event:`missing-reference`. If the event handler can emit warnings for
|
||||||
|
the missing reference, it should return ``True``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
.. event:: doctree-resolved (app, doctree, docname)
|
.. event:: doctree-resolved (app, doctree, docname)
|
||||||
|
|
||||||
Emitted when a doctree has been "resolved" by the environment, that is, all
|
Emitted when a doctree has been "resolved" by the environment, that is, all
|
||||||
@ -325,6 +369,9 @@ connect handlers to the events. Example:
|
|||||||
You can return a string from the handler, it will then replace
|
You can return a string from the handler, it will then replace
|
||||||
``'page.html'`` as the HTML template for this page.
|
``'page.html'`` as the HTML template for this page.
|
||||||
|
|
||||||
|
.. note:: You can install JS/CSS files for the specific page via
|
||||||
|
:meth:`Sphinx.add_js_file` and :meth:`Sphinx.add_css_file` since v3.5.0.
|
||||||
|
|
||||||
.. versionadded:: 0.4
|
.. versionadded:: 0.4
|
||||||
|
|
||||||
.. versionchanged:: 1.3
|
.. versionchanged:: 1.3
|
||||||
|
@ -26,6 +26,167 @@ The following is a list of deprecated interfaces.
|
|||||||
- (will be) Removed
|
- (will be) Removed
|
||||||
- Alternatives
|
- Alternatives
|
||||||
|
|
||||||
|
* - pending_xref node for viewcode extension
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.viewcode.viewcode_anchor``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.linkcheck.CheckExternalLinksBuilder.broken``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.builders.linkcheck.CheckExternalLinksBuilder.good``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.builders.linkcheck.CheckExternalLinksBuilder.redirected``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.builders.linkcheck.node_line_or_0()``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.util.nodes.get_node_line()``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.AttributeDocumenter.isinstanceattribute()``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.importer.get_module_members()``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.ModuleDocumenter.get_module_members()``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autosummary.generate._simple_info()``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- :ref:`logging-api`
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autosummary.generate._simple_warn()``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- :ref:`logging-api`
|
||||||
|
|
||||||
|
* - ``sphinx.writers.html.HTMLTranslator.permalink_text``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- :confval:`html_permalinks_icon`
|
||||||
|
|
||||||
|
* - ``sphinx.writers.html5.HTML5Translator.permalink_text``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- :confval:`html_permalinks_icon`
|
||||||
|
|
||||||
|
* - The ``follow_wrapped`` argument of ``sphinx.util.inspect.signature()``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - The ``no_docstring`` argument of
|
||||||
|
``sphinx.ext.autodoc.Documenter.add_content()``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.Documenter.get_doc()``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.Documenter.get_object_members()``
|
||||||
|
- 3.4
|
||||||
|
- 6.0
|
||||||
|
- ``sphinx.ext.autodoc.ClassDocumenter.get_object_members()``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.DataDeclarationDocumenter``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.DataDocumenter``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.GenericAliasDocumenter``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.DataDocumenter``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.InstanceAttributeDocumenter``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.AttributeDocumenter``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.SlotsAttributeDocumenter``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.AttributeDocumenter``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.TypeVarDocumenter``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.DataDocumenter``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.directive.DocumenterBridge.reporter``
|
||||||
|
- 3.5
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.util.logging``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.importer._getannotations()``
|
||||||
|
- 3.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.util.inspect.getannotations()``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.importer._getmro()``
|
||||||
|
- 3.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.util.inspect.getmro()``
|
||||||
|
|
||||||
|
* - ``sphinx.pycode.ModuleAnalyzer.parse()``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.pycode.ModuleAnalyzer.analyze()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.osutil.movefile()``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- ``os.replace()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.requests.is_ssl_error()``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.builders.latex.LaTeXBuilder.usepackages``
|
||||||
|
- 3.3
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.builders.latex.LaTeXBuilder.usepackages_afger_hyperref``
|
||||||
|
- 3.3
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.SingledispatchFunctionDocumenter``
|
||||||
|
- 3.3
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.FunctionDocumenter``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.SingledispatchMethodDocumenter``
|
||||||
|
- 3.3
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.MethodDocumenter``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.members_set_option()``
|
||||||
|
- 3.2
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.merge_special_members_option()``
|
||||||
|
- 3.2
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.merge_members_option()``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.texinfo.TexinfoWriter.desc``
|
||||||
|
- 3.2
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.writers.texinfo.TexinfoWriter.descs``
|
||||||
|
|
||||||
* - The first argument for
|
* - The first argument for
|
||||||
``sphinx.ext.autosummary.generate.AutosummaryRenderer`` has been changed
|
``sphinx.ext.autosummary.generate.AutosummaryRenderer`` has been changed
|
||||||
to Sphinx object
|
to Sphinx object
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.. _domain-api:
|
.. _domain-api:
|
||||||
|
|
||||||
Domain API
|
Domain API
|
||||||
----------
|
==========
|
||||||
|
|
||||||
.. module:: sphinx.domains
|
.. module:: sphinx.domains
|
||||||
|
|
||||||
@ -12,3 +12,16 @@ Domain API
|
|||||||
|
|
||||||
.. autoclass:: Index
|
.. autoclass:: Index
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
|
||||||
|
Python Domain
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. module:: sphinx.domains.python
|
||||||
|
|
||||||
|
.. autoclass:: PythonDomain
|
||||||
|
|
||||||
|
.. autoattribute:: objects
|
||||||
|
.. autoattribute:: modules
|
||||||
|
.. automethod:: note_object
|
||||||
|
.. automethod:: note_module
|
||||||
|
@ -3,54 +3,41 @@
|
|||||||
Developing extensions for Sphinx
|
Developing extensions for Sphinx
|
||||||
================================
|
================================
|
||||||
|
|
||||||
Since many projects will need special features in their documentation, Sphinx is
|
Since many projects will need special features in their documentation, Sphinx
|
||||||
designed to be extensible on several levels.
|
is designed to be extensible on several levels.
|
||||||
|
|
||||||
This is what you can do in an extension: First, you can add new
|
Here are a few things you can do in an extension:
|
||||||
:term:`builder`\s to support new output formats or actions on the parsed
|
|
||||||
documents. Then, it is possible to register custom reStructuredText roles and
|
|
||||||
directives, extending the markup. And finally, there are so-called "hook
|
|
||||||
points" at strategic places throughout the build process, where an extension can
|
|
||||||
register a hook and run specialized code.
|
|
||||||
|
|
||||||
An extension is simply a Python module. When an extension is loaded, Sphinx
|
* Add new :term:`builder`\s to support new output formats or actions on the
|
||||||
imports this module and executes its ``setup()`` function, which in turn
|
parsed documents.
|
||||||
notifies Sphinx of everything the extension offers -- see the extension tutorial
|
* Register custom reStructuredText roles and directives, extending the markup
|
||||||
for examples.
|
using the :doc:`markupapi`.
|
||||||
|
* Add custom code to so-called "hook points" at strategic places throughout the
|
||||||
|
build process, allowing you to register a hook and run specialized code.
|
||||||
|
For example, see the :ref:`events`.
|
||||||
|
|
||||||
The configuration file itself can be treated as an extension if it contains a
|
An extension is simply a Python module with a ``setup()`` function. A user
|
||||||
``setup()`` function. All other extensions to load must be listed in the
|
activates the extension by placing the extension's module name
|
||||||
:confval:`extensions` configuration value.
|
(or a sub-module) in their :confval:`extensions` configuration value.
|
||||||
|
|
||||||
Discovery of builders by entry point
|
When :program:`sphinx-build` is executed, Sphinx will attempt to import each
|
||||||
------------------------------------
|
module that is listed, and execute ``yourmodule.setup(app)``. This
|
||||||
|
function is used to prepare the extension (e.g., by executing Python code),
|
||||||
|
linking resources that Sphinx uses in the build process (like CSS or HTML
|
||||||
|
files), and notifying Sphinx of everything the extension offers (such
|
||||||
|
as directive or role definitions). The ``app`` argument is an instance of
|
||||||
|
:class:`.Sphinx` and gives you control over most aspects of the Sphinx build.
|
||||||
|
|
||||||
.. versionadded:: 1.6
|
.. note::
|
||||||
|
|
||||||
:term:`builder` extensions can be discovered by means of `entry points`_ so
|
The configuration file itself can be treated as an extension if it
|
||||||
that they do not have to be listed in the :confval:`extensions` configuration
|
contains a ``setup()`` function. All other extensions to load must be
|
||||||
value.
|
listed in the :confval:`extensions` configuration value.
|
||||||
|
|
||||||
Builder extensions should define an entry point in the ``sphinx.builders``
|
The rest of this page describes some high-level aspects of developing
|
||||||
group. The name of the entry point needs to match your builder's
|
extensions and various parts of Sphinx's behavior that you can control.
|
||||||
:attr:`~.Builder.name` attribute, which is the name passed to the
|
For some examples of how extensions can be built and used to control different
|
||||||
:option:`sphinx-build -b` option. The entry point value should equal the
|
parts of Sphinx, see the :ref:`extension-tutorials-index`.
|
||||||
dotted name of the extension module. Here is an example of how an entry point
|
|
||||||
for 'mybuilder' can be defined in the extension's ``setup.py``::
|
|
||||||
|
|
||||||
setup(
|
|
||||||
# ...
|
|
||||||
entry_points={
|
|
||||||
'sphinx.builders': [
|
|
||||||
'mybuilder = my.extension.module',
|
|
||||||
],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
Note that it is still necessary to register the builder using
|
|
||||||
:meth:`~.Sphinx.add_builder` in the extension's :func:`setup` function.
|
|
||||||
|
|
||||||
.. _entry points: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
|
|
||||||
|
|
||||||
.. _important-objects:
|
.. _important-objects:
|
||||||
|
|
||||||
@ -192,6 +179,11 @@ as metadata of the extension. Metadata keys currently recognized are:
|
|||||||
APIs used for writing extensions
|
APIs used for writing extensions
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
|
These sections provide a more complete description of the tools at your
|
||||||
|
disposal when developing Sphinx extensions. Some are core to Sphinx
|
||||||
|
(such as the :doc:`appapi`) while others trigger specific behavior
|
||||||
|
(such as the :doc:`i18n`)
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ Glossary
|
|||||||
A class (inheriting from :class:`~sphinx.builders.Builder`) that takes
|
A class (inheriting from :class:`~sphinx.builders.Builder`) that takes
|
||||||
parsed documents and performs an action on them. Normally, builders
|
parsed documents and performs an action on them. Normally, builders
|
||||||
translate the documents to an output format, but it is also possible to
|
translate the documents to an output format, but it is also possible to
|
||||||
use the builder builders that e.g. check for broken links in the
|
use builders that e.g. check for broken links in the documentation, or
|
||||||
documentation, or build coverage information.
|
build coverage information.
|
||||||
|
|
||||||
See :doc:`/usage/builders/index` for an overview over Sphinx's built-in
|
See :doc:`/usage/builders/index` for an overview over Sphinx's built-in
|
||||||
builders.
|
builders.
|
||||||
|
@ -12,6 +12,9 @@ Getting help
|
|||||||
|
|
||||||
The Sphinx community maintains a number of mailing lists and IRC channels.
|
The Sphinx community maintains a number of mailing lists and IRC channels.
|
||||||
|
|
||||||
|
Stack Overflow with tag `python-sphinx`_
|
||||||
|
Questions and answers about use and development.
|
||||||
|
|
||||||
sphinx-users <sphinx-users@googlegroups.com>
|
sphinx-users <sphinx-users@googlegroups.com>
|
||||||
Mailing list for user support.
|
Mailing list for user support.
|
||||||
|
|
||||||
@ -21,6 +24,7 @@ sphinx-dev <sphinx-dev@googlegroups.com>
|
|||||||
#sphinx-doc on irc.freenode.net
|
#sphinx-doc on irc.freenode.net
|
||||||
IRC channel for development questions and user support.
|
IRC channel for development questions and user support.
|
||||||
|
|
||||||
|
.. _python-sphinx: https://stackoverflow.com/questions/tagged/python-sphinx
|
||||||
|
|
||||||
Bug Reports and Feature Requests
|
Bug Reports and Feature Requests
|
||||||
--------------------------------
|
--------------------------------
|
||||||
@ -134,10 +138,7 @@ Coding style
|
|||||||
|
|
||||||
Please follow these guidelines when writing code for Sphinx:
|
Please follow these guidelines when writing code for Sphinx:
|
||||||
|
|
||||||
* Try to use the same code style as used in the rest of the project. See the
|
* Try to use the same code style as used in the rest of the project.
|
||||||
`Pocoo Styleguide`__ for more information.
|
|
||||||
|
|
||||||
__ http://flask.pocoo.org/docs/styleguide/
|
|
||||||
|
|
||||||
* For non-trivial changes, please update the :file:`CHANGES` file. If your
|
* For non-trivial changes, please update the :file:`CHANGES` file. If your
|
||||||
changes alter existing behavior, please document this.
|
changes alter existing behavior, please document this.
|
||||||
@ -268,9 +269,9 @@ identifier and put ``sphinx.po`` in there. Don't forget to update the possible
|
|||||||
values for :confval:`language` in ``doc/usage/configuration.rst``.
|
values for :confval:`language` in ``doc/usage/configuration.rst``.
|
||||||
|
|
||||||
The Sphinx core messages can also be translated on `Transifex
|
The Sphinx core messages can also be translated on `Transifex
|
||||||
<https://www.transifex.com/sphinx-doc/>`_. There ``tx`` client tool, which is
|
<https://www.transifex.com/sphinx-doc/sphinx-1/>`_. There ``tx`` client tool,
|
||||||
provided by the ``transifex_client`` Python package, can be used to pull
|
which is provided by the ``transifex_client`` Python package, can be used to
|
||||||
translations in ``.po`` format from Transifex. To do this, go to
|
pull translations in ``.po`` format from Transifex. To do this, go to
|
||||||
``sphinx/locale`` and then run ``tx pull -f -l LANG`` where ``LANG`` is an
|
``sphinx/locale`` and then run ``tx pull -f -l LANG`` where ``LANG`` is an
|
||||||
existing language identifier. It is good practice to run ``python setup.py
|
existing language identifier. It is good practice to run ``python setup.py
|
||||||
update_catalog`` afterwards to make sure the ``.po`` file has the canonical
|
update_catalog`` afterwards to make sure the ``.po`` file has the canonical
|
||||||
|
@ -95,6 +95,12 @@ Keys that you may want to override include:
|
|||||||
A string which will be positioned early in the preamble, designed to
|
A string which will be positioned early in the preamble, designed to
|
||||||
contain ``\\PassOptionsToPackage{options}{foo}`` commands.
|
contain ``\\PassOptionsToPackage{options}{foo}`` commands.
|
||||||
|
|
||||||
|
.. hint::
|
||||||
|
|
||||||
|
It may be also used for loading LaTeX packages very early in the
|
||||||
|
preamble. For example package ``fancybox`` is incompatible with
|
||||||
|
being loaded via the ``'preamble'`` key, it must be loaded earlier.
|
||||||
|
|
||||||
Default: ``''``
|
Default: ``''``
|
||||||
|
|
||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
@ -195,8 +201,8 @@ Keys that you may want to override include:
|
|||||||
"Bjornstrup". You can also set this to ``''`` to disable fncychap.
|
"Bjornstrup". You can also set this to ``''`` to disable fncychap.
|
||||||
|
|
||||||
Default: ``'\\usepackage[Bjarne]{fncychap}'`` for English documents,
|
Default: ``'\\usepackage[Bjarne]{fncychap}'`` for English documents,
|
||||||
``'\\usepackage[Sonny]{fncychap}'`` for internationalized documents, and
|
``'\\usepackage[Sonny]{fncychap}'`` for internationalized documents, and
|
||||||
``''`` for Japanese documents.
|
``''`` for Japanese documents.
|
||||||
|
|
||||||
``'preamble'``
|
``'preamble'``
|
||||||
Additional preamble content. One may move all needed macros into some file
|
Additional preamble content. One may move all needed macros into some file
|
||||||
@ -300,7 +306,7 @@ Keys that don't need to be overridden unless in special cases are:
|
|||||||
"inputenc" package inclusion.
|
"inputenc" package inclusion.
|
||||||
|
|
||||||
Default: ``'\\usepackage[utf8]{inputenc}'`` when using pdflatex, else
|
Default: ``'\\usepackage[utf8]{inputenc}'`` when using pdflatex, else
|
||||||
``''``
|
``''``
|
||||||
|
|
||||||
.. versionchanged:: 1.4.3
|
.. versionchanged:: 1.4.3
|
||||||
Previously ``'\\usepackage[utf8]{inputenc}'`` was used for all
|
Previously ``'\\usepackage[utf8]{inputenc}'`` was used for all
|
||||||
@ -389,7 +395,7 @@ Keys that don't need to be overridden unless in special cases are:
|
|||||||
key is ignored.
|
key is ignored.
|
||||||
|
|
||||||
Default: ``'\\usepackage{textalpha}'`` or ``''`` if ``fontenc`` does not
|
Default: ``'\\usepackage{textalpha}'`` or ``''`` if ``fontenc`` does not
|
||||||
include the ``LGR`` option.
|
include the ``LGR`` option.
|
||||||
|
|
||||||
.. versionadded:: 2.0
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
@ -407,7 +413,7 @@ Keys that don't need to be overridden unless in special cases are:
|
|||||||
<latexsphinxsetup>`.
|
<latexsphinxsetup>`.
|
||||||
|
|
||||||
Default: ``'\\usepackage{geometry}'`` (or
|
Default: ``'\\usepackage{geometry}'`` (or
|
||||||
``'\\usepackage[dvipdfm]{geometry}'`` for Japanese documents)
|
``'\\usepackage[dvipdfm]{geometry}'`` for Japanese documents)
|
||||||
|
|
||||||
.. versionadded:: 1.5
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
@ -784,14 +790,14 @@ macros may be significant.
|
|||||||
|warningbdcolors|
|
|warningbdcolors|
|
||||||
The colour for the admonition frame.
|
The colour for the admonition frame.
|
||||||
|
|
||||||
Default: ``{rgb}{0,0,0}`` (black)
|
Default: ``{rgb}{0,0,0}`` (black)
|
||||||
|
|
||||||
.. only:: latex
|
.. only:: latex
|
||||||
|
|
||||||
|wgbdcolorslatex|
|
|wgbdcolorslatex|
|
||||||
The colour for the admonition frame.
|
The colour for the admonition frame.
|
||||||
|
|
||||||
Default: ``{rgb}{0,0,0}`` (black)
|
Default: ``{rgb}{0,0,0}`` (black)
|
||||||
|
|
||||||
|warningbgcolors|
|
|warningbgcolors|
|
||||||
The background colours for the respective admonitions.
|
The background colours for the respective admonitions.
|
||||||
|
@ -20,7 +20,7 @@ Options
|
|||||||
|
|
||||||
.. option:: -q, --quiet
|
.. option:: -q, --quiet
|
||||||
|
|
||||||
Quiet mode that will skip interactive wizard to specify options.
|
Quiet mode that skips the interactive wizard for specifying options.
|
||||||
This option requires `-p`, `-a` and `-v` options.
|
This option requires `-p`, `-a` and `-v` options.
|
||||||
|
|
||||||
.. option:: -h, --help, --version
|
.. option:: -h, --help, --version
|
||||||
@ -33,6 +33,10 @@ Options
|
|||||||
|
|
||||||
If specified, separate source and build directories.
|
If specified, separate source and build directories.
|
||||||
|
|
||||||
|
.. option:: --no-sep
|
||||||
|
|
||||||
|
If specified, create build directroy under source directroy.
|
||||||
|
|
||||||
.. option:: --dot=DOT
|
.. option:: --dot=DOT
|
||||||
|
|
||||||
Inside the root directory, two more directories will be created;
|
Inside the root directory, two more directories will be created;
|
||||||
|
@ -7,7 +7,7 @@ Templating
|
|||||||
==========
|
==========
|
||||||
|
|
||||||
Sphinx uses the `Jinja <http://jinja.pocoo.org>`_ templating engine for its HTML
|
Sphinx uses the `Jinja <http://jinja.pocoo.org>`_ templating engine for its HTML
|
||||||
templates. Jinja is a text-based engine, and inspired by Django templates, so
|
templates. Jinja is a text-based engine, inspired by Django templates, so
|
||||||
anyone having used Django will already be familiar with it. It also has
|
anyone having used Django will already be familiar with it. It also has
|
||||||
excellent documentation for those who need to make themselves familiar with it.
|
excellent documentation for those who need to make themselves familiar with it.
|
||||||
|
|
||||||
|
159
doc/theming.rst
159
doc/theming.rst
@ -1,159 +0,0 @@
|
|||||||
.. highlight:: python
|
|
||||||
|
|
||||||
HTML theming support
|
|
||||||
====================
|
|
||||||
|
|
||||||
.. versionadded:: 0.6
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
This document provides information about creating your own theme. If you
|
|
||||||
simply wish to use a pre-existing HTML themes, refer to
|
|
||||||
:doc:`/usage/theming`.
|
|
||||||
|
|
||||||
Sphinx supports changing the appearance of its HTML output via *themes*. A
|
|
||||||
theme is a collection of HTML templates, stylesheet(s) and other static files.
|
|
||||||
Additionally, it has a configuration file which specifies from which theme to
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
Creating themes
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Themes take the form of either a directory or a zipfile (whose name is the
|
|
||||||
theme name), containing the following:
|
|
||||||
|
|
||||||
* A :file:`theme.conf` file.
|
|
||||||
* HTML templates, if needed.
|
|
||||||
* A ``static/`` directory containing any static files that will be copied to the
|
|
||||||
output static directory on build. These can be images, styles, script files.
|
|
||||||
|
|
||||||
The :file:`theme.conf` file is in INI format [1]_ (readable by the standard
|
|
||||||
Python :mod:`ConfigParser` module) and has the following structure:
|
|
||||||
|
|
||||||
.. sourcecode:: ini
|
|
||||||
|
|
||||||
[theme]
|
|
||||||
inherit = base theme
|
|
||||||
stylesheet = main CSS name
|
|
||||||
pygments_style = stylename
|
|
||||||
sidebars = localtoc.html, relations.html, sourcelink.html, searchbox.html
|
|
||||||
|
|
||||||
[options]
|
|
||||||
variable = default value
|
|
||||||
|
|
||||||
* The **inherit** setting gives the name of a "base theme", or ``none``. The
|
|
||||||
base theme will be used to locate missing templates (most themes will not have
|
|
||||||
to supply most templates if they use ``basic`` as the base theme), its options
|
|
||||||
will be inherited, and all of its static files will be used as well. If you
|
|
||||||
want to also inherit the stylesheet, include it via CSS' ``@import`` in your
|
|
||||||
own.
|
|
||||||
|
|
||||||
* The **stylesheet** setting gives the name of a CSS file which will be
|
|
||||||
referenced in the HTML header. If you need more than one CSS file, either
|
|
||||||
include one from the other via CSS' ``@import``, or use a custom HTML template
|
|
||||||
that adds ``<link rel="stylesheet">`` tags as necessary. Setting the
|
|
||||||
:confval:`html_style` config value will override this setting.
|
|
||||||
|
|
||||||
* The **pygments_style** setting gives the name of a Pygments style to use for
|
|
||||||
highlighting. This can be overridden by the user in the
|
|
||||||
:confval:`pygments_style` config value.
|
|
||||||
|
|
||||||
* The **pygments_dark_style** setting gives the name of a Pygments style to use
|
|
||||||
for highlighting when the CSS media query ``(prefers-color-scheme: dark)``
|
|
||||||
evaluates to true. It is injected into the page using
|
|
||||||
:meth:`~Sphinx.add_css_file()`.
|
|
||||||
|
|
||||||
* The **sidebars** setting gives the comma separated list of sidebar templates
|
|
||||||
for constructing sidebars. This can be overridden by the user in the
|
|
||||||
:confval:`html_sidebars` config value.
|
|
||||||
|
|
||||||
* The **options** section contains pairs of variable names and default values.
|
|
||||||
These options can be overridden by the user in :confval:`html_theme_options`
|
|
||||||
and are accessible from all templates as ``theme_<name>``.
|
|
||||||
|
|
||||||
.. versionadded:: 1.7
|
|
||||||
sidebar settings
|
|
||||||
|
|
||||||
|
|
||||||
.. _distribute-your-theme:
|
|
||||||
|
|
||||||
Distribute your theme as a Python package
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
As a way to distribute your theme, you can use Python package. Python package
|
|
||||||
brings to users easy setting up ways.
|
|
||||||
|
|
||||||
To distribute your theme as a Python package, please define an entry point
|
|
||||||
called ``sphinx.html_themes`` in your ``setup.py`` file, and write a ``setup()``
|
|
||||||
function to register your themes using ``add_html_theme()`` API in it::
|
|
||||||
|
|
||||||
# 'setup.py'
|
|
||||||
setup(
|
|
||||||
...
|
|
||||||
entry_points = {
|
|
||||||
'sphinx.html_themes': [
|
|
||||||
'name_of_theme = your_package',
|
|
||||||
]
|
|
||||||
},
|
|
||||||
...
|
|
||||||
)
|
|
||||||
|
|
||||||
# 'your_package.py'
|
|
||||||
from os import path
|
|
||||||
|
|
||||||
def setup(app):
|
|
||||||
app.add_html_theme('name_of_theme', path.abspath(path.dirname(__file__)))
|
|
||||||
|
|
||||||
If your theme package contains two or more themes, please call
|
|
||||||
``add_html_theme()`` twice or more.
|
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
|
||||||
'sphinx_themes' entry_points feature.
|
|
||||||
|
|
||||||
.. deprecated:: 1.6
|
|
||||||
``sphinx_themes`` entry_points has been deprecated.
|
|
||||||
|
|
||||||
.. versionadded:: 1.6
|
|
||||||
``sphinx.html_themes`` entry_points feature.
|
|
||||||
|
|
||||||
|
|
||||||
Templating
|
|
||||||
----------
|
|
||||||
|
|
||||||
The :doc:`guide to templating <templating>` is helpful if you want to write your
|
|
||||||
own templates. What is important to keep in mind is the order in which Sphinx
|
|
||||||
searches for templates:
|
|
||||||
|
|
||||||
* First, in the user's ``templates_path`` directories.
|
|
||||||
* Then, in the selected theme.
|
|
||||||
* Then, in its base theme, its base's base theme, etc.
|
|
||||||
|
|
||||||
When extending a template in the base theme with the same name, use the theme
|
|
||||||
name as an explicit directory: ``{% extends "basic/layout.html" %}``. From a
|
|
||||||
user ``templates_path`` template, you can still use the "exclamation mark"
|
|
||||||
syntax as described in the templating document.
|
|
||||||
|
|
||||||
Static templates
|
|
||||||
~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Since theme options are meant for the user to configure a theme more easily,
|
|
||||||
without having to write a custom stylesheet, it is necessary to be able to
|
|
||||||
template static files as well as HTML files. Therefore, Sphinx supports
|
|
||||||
so-called "static templates", like this:
|
|
||||||
|
|
||||||
If the name of a file in the ``static/`` directory of a theme (or in the user's
|
|
||||||
static path, for that matter) ends with ``_t``, it will be processed by the
|
|
||||||
template engine. The ``_t`` will be left from the final file name. For
|
|
||||||
example, the *classic* theme has a file ``static/classic.css_t`` which uses
|
|
||||||
templating to put the color options into the stylesheet. When a documentation
|
|
||||||
is built with the classic theme, the output directory will contain a
|
|
||||||
``_static/classic.css`` file where all template tags have been processed.
|
|
||||||
|
|
||||||
.. [1] It is not an executable Python file, as opposed to :file:`conf.py`,
|
|
||||||
because that would pose an unnecessary security risk if themes are
|
|
||||||
shared.
|
|
@ -6,10 +6,10 @@ Internationalization
|
|||||||
.. versionadded:: 1.1
|
.. versionadded:: 1.1
|
||||||
|
|
||||||
Complementary to translations provided for Sphinx-generated messages such as
|
Complementary to translations provided for Sphinx-generated messages such as
|
||||||
navigation bars, Sphinx provides mechanisms facilitating *document* translations
|
navigation bars, Sphinx provides mechanisms facilitating the translation of
|
||||||
in itself. See the :ref:`intl-options` for details on configuration.
|
*documents*. See the :ref:`intl-options` for details on configuration.
|
||||||
|
|
||||||
.. figure:: /_static/translation.svg
|
.. figure:: /_static/translation.*
|
||||||
:width: 100%
|
:width: 100%
|
||||||
|
|
||||||
Workflow visualization of translations in Sphinx. (The figure is created by
|
Workflow visualization of translations in Sphinx. (The figure is created by
|
||||||
|
@ -442,6 +442,10 @@ name is ``rinoh``. Refer to the `rinohtype manual`_ for details.
|
|||||||
|
|
||||||
Since Sphinx-1.5, the linkcheck builder comes to use requests module.
|
Since Sphinx-1.5, the linkcheck builder comes to use requests module.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4
|
||||||
|
|
||||||
|
The linkcheck builder retries links when servers apply rate limits.
|
||||||
|
|
||||||
.. module:: sphinx.builders.xml
|
.. module:: sphinx.builders.xml
|
||||||
.. class:: XMLBuilder
|
.. class:: XMLBuilder
|
||||||
|
|
||||||
|
@ -70,9 +70,14 @@ Project information
|
|||||||
The author name(s) of the document. The default value is ``'unknown'``.
|
The author name(s) of the document. The default value is ``'unknown'``.
|
||||||
|
|
||||||
.. confval:: copyright
|
.. confval:: copyright
|
||||||
|
.. confval:: project_copyright
|
||||||
|
|
||||||
A copyright statement in the style ``'2008, Author Name'``.
|
A copyright statement in the style ``'2008, Author Name'``.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.5
|
||||||
|
|
||||||
|
As an alias, ``project_copyright`` is also allowed.
|
||||||
|
|
||||||
.. confval:: version
|
.. confval:: version
|
||||||
|
|
||||||
The major project version, used as the replacement for ``|version|``. For
|
The major project version, used as the replacement for ``|version|``. For
|
||||||
@ -316,6 +321,7 @@ General configuration
|
|||||||
* ``toc.circular``
|
* ``toc.circular``
|
||||||
* ``toc.secnum``
|
* ``toc.secnum``
|
||||||
* ``epub.unknown_project_files``
|
* ``epub.unknown_project_files``
|
||||||
|
* ``epub.duplicated_toc_entry``
|
||||||
* ``autosectionlabel.*``
|
* ``autosectionlabel.*``
|
||||||
|
|
||||||
You can choose from these types.
|
You can choose from these types.
|
||||||
@ -340,6 +346,10 @@ General configuration
|
|||||||
|
|
||||||
Added ``autosectionlabel.*``
|
Added ``autosectionlabel.*``
|
||||||
|
|
||||||
|
.. versionchanged:: 3.3.0
|
||||||
|
|
||||||
|
Added ``epub.duplicated_toc_entry``
|
||||||
|
|
||||||
.. confval:: needs_sphinx
|
.. confval:: needs_sphinx
|
||||||
|
|
||||||
If set to a ``major.minor`` version string like ``'1.1'``, Sphinx will
|
If set to a ``major.minor`` version string like ``'1.1'``, Sphinx will
|
||||||
@ -551,7 +561,7 @@ General configuration
|
|||||||
* Otherwise, the current time is formatted using :func:`time.strftime` and
|
* Otherwise, the current time is formatted using :func:`time.strftime` and
|
||||||
the format given in :confval:`today_fmt`.
|
the format given in :confval:`today_fmt`.
|
||||||
|
|
||||||
The default is now :confval:`today` and a :confval:`today_fmt` of ``'%B %d,
|
The default is now :confval:`today` and a :confval:`today_fmt` of ``'%b %d,
|
||||||
%Y'`` (or, if translation is enabled with :confval:`language`, an equivalent
|
%Y'`` (or, if translation is enabled with :confval:`language`, an equivalent
|
||||||
format for the selected locale).
|
format for the selected locale).
|
||||||
|
|
||||||
@ -572,12 +582,27 @@ General configuration
|
|||||||
|
|
||||||
.. confval:: highlight_options
|
.. confval:: highlight_options
|
||||||
|
|
||||||
A dictionary of options that modify how the lexer specified by
|
A dictionary that maps language names to options for the lexer modules of
|
||||||
:confval:`highlight_language` generates highlighted source code. These are
|
Pygments. These are lexer-specific; for the options understood by each,
|
||||||
lexer-specific; for the options understood by each, see the
|
see the `Pygments documentation <https://pygments.org/docs/lexers>`_.
|
||||||
`Pygments documentation <https://pygments.org/docs/lexers>`_.
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
highlight_options = {
|
||||||
|
'default': {'stripall': True},
|
||||||
|
'php': {'startinline': True},
|
||||||
|
}
|
||||||
|
|
||||||
|
A single dictionary of options are also allowed. Then it is recognized
|
||||||
|
as options to the lexer specified by :confval:`highlight_language`::
|
||||||
|
|
||||||
|
# configuration for the ``highlight_language``
|
||||||
|
highlight_options = {'stripall': True}
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
.. versionchanged:: 3.5
|
||||||
|
|
||||||
|
Allow to configure highlight options for multiple languages
|
||||||
|
|
||||||
.. confval:: pygments_style
|
.. confval:: pygments_style
|
||||||
|
|
||||||
@ -660,10 +685,11 @@ documentation on :ref:`intl` for details.
|
|||||||
generated by Sphinx will be in that language. Also, Sphinx will try to
|
generated by Sphinx will be in that language. Also, Sphinx will try to
|
||||||
substitute individual paragraphs from your documents with the translation
|
substitute individual paragraphs from your documents with the translation
|
||||||
sets obtained from :confval:`locale_dirs`. Sphinx will search
|
sets obtained from :confval:`locale_dirs`. Sphinx will search
|
||||||
language-specific figures named by `figure_language_filename` and substitute
|
language-specific figures named by :confval:`figure_language_filename`
|
||||||
them for original figures. In the LaTeX builder, a suitable language will
|
(e.g. the German version of ``myfigure.png`` will be ``myfigure.de.png``
|
||||||
be selected as an option for the *Babel* package. Default is ``None``,
|
by default setting) and substitute them for original figures. In the LaTeX
|
||||||
which means that no translation will be done.
|
builder, a suitable language will be selected as an option for the *Babel*
|
||||||
|
package. Default is ``None``, which means that no translation will be done.
|
||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
|
|
||||||
@ -755,9 +781,15 @@ documentation on :ref:`intl` for details.
|
|||||||
If true, a document's text domain is its docname if it is a top-level
|
If true, a document's text domain is its docname if it is a top-level
|
||||||
project file and its very base directory otherwise.
|
project file and its very base directory otherwise.
|
||||||
|
|
||||||
|
If set to string, all document's text domain is this string, making all
|
||||||
|
documents use single text domain.
|
||||||
|
|
||||||
By default, the document ``markup/code.rst`` ends up in the ``markup`` text
|
By default, the document ``markup/code.rst`` ends up in the ``markup`` text
|
||||||
domain. With this option set to ``False``, it is ``markup/code``.
|
domain. With this option set to ``False``, it is ``markup/code``.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.3
|
||||||
|
The string value is now accepted.
|
||||||
|
|
||||||
.. confval:: gettext_uuid
|
.. confval:: gettext_uuid
|
||||||
|
|
||||||
If true, Sphinx generates uuid information for version tracking in message
|
If true, Sphinx generates uuid information for version tracking in message
|
||||||
@ -820,6 +852,8 @@ documentation on :ref:`intl` for details.
|
|||||||
extension, e.g. ``dirname/filename``
|
extension, e.g. ``dirname/filename``
|
||||||
* ``{path}`` - the directory path component of the filename, with a trailing
|
* ``{path}`` - the directory path component of the filename, with a trailing
|
||||||
slash if non-empty, e.g. ``dirname/``
|
slash if non-empty, e.g. ``dirname/``
|
||||||
|
* ``{docpath}`` - the directory path component for the current document, with
|
||||||
|
a trailing slash if non-empty.
|
||||||
* ``{basename}`` - the filename without the directory path or file extension
|
* ``{basename}`` - the filename without the directory path or file extension
|
||||||
components, e.g. ``filename``
|
components, e.g. ``filename``
|
||||||
* ``{ext}`` - the file extension, e.g. ``.png``
|
* ``{ext}`` - the file extension, e.g. ``.png``
|
||||||
@ -833,6 +867,9 @@ documentation on :ref:`intl` for details.
|
|||||||
.. versionchanged:: 1.5
|
.. versionchanged:: 1.5
|
||||||
Added ``{path}`` and ``{basename}`` tokens.
|
Added ``{path}`` and ``{basename}`` tokens.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.2
|
||||||
|
Added ``{docpath}`` token.
|
||||||
|
|
||||||
|
|
||||||
.. _math-options:
|
.. _math-options:
|
||||||
|
|
||||||
@ -912,7 +949,7 @@ that use Sphinx's HTMLWriter class.
|
|||||||
|
|
||||||
.. confval:: html_short_title
|
.. confval:: html_short_title
|
||||||
|
|
||||||
A shorter "title" for the HTML docs. This is used in for links in the
|
A shorter "title" for the HTML docs. This is used for links in the
|
||||||
header and in the HTML Help docs. If not given, it defaults to the value of
|
header and in the HTML Help docs. If not given, it defaults to the value of
|
||||||
:confval:`html_title`.
|
:confval:`html_title`.
|
||||||
|
|
||||||
@ -920,11 +957,23 @@ that use Sphinx's HTMLWriter class.
|
|||||||
|
|
||||||
.. confval:: html_baseurl
|
.. confval:: html_baseurl
|
||||||
|
|
||||||
The URL which points to the root of the HTML documentation. It is used to
|
The base URL which points to the root of the HTML documentation. It is used
|
||||||
indicate the location of document like ``canonical_url``.
|
to indicate the location of document using `The Canonical Link Relation`_.
|
||||||
|
Default: ``''``.
|
||||||
|
|
||||||
|
.. _The Canonical Link Relation: https://tools.ietf.org/html/rfc6596
|
||||||
|
|
||||||
.. versionadded:: 1.8
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
|
.. confval:: html_codeblock_linenos_style
|
||||||
|
|
||||||
|
The style of line numbers for code-blocks.
|
||||||
|
|
||||||
|
* ``'table'`` -- display line numbers using ``<table>`` tag (default)
|
||||||
|
* ``'inline'`` -- display line numbers using ``<span>`` tag
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
.. 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
|
||||||
@ -970,7 +1019,14 @@ that use Sphinx's HTMLWriter class.
|
|||||||
'https://example.com/css/custom.css',
|
'https://example.com/css/custom.css',
|
||||||
('print.css', {'media': 'print'})]
|
('print.css', {'media': 'print'})]
|
||||||
|
|
||||||
|
As a special attribute, *priority* can be set as an integer to load the CSS
|
||||||
|
file earlier or lazier step. For more information, refer
|
||||||
|
:meth:`Sphinx.add_css_files()`.
|
||||||
|
|
||||||
.. versionadded:: 1.8
|
.. versionadded:: 1.8
|
||||||
|
.. versionchanged:: 3.5
|
||||||
|
|
||||||
|
Support priority attribute
|
||||||
|
|
||||||
.. confval:: html_js_files
|
.. confval:: html_js_files
|
||||||
|
|
||||||
@ -986,7 +1042,14 @@ that use Sphinx's HTMLWriter class.
|
|||||||
'https://example.com/scripts/custom.js',
|
'https://example.com/scripts/custom.js',
|
||||||
('custom.js', {'async': 'async'})]
|
('custom.js', {'async': 'async'})]
|
||||||
|
|
||||||
|
As a special attribute, *priority* can be set as an integer to load the CSS
|
||||||
|
file earlier or lazier step. For more information, refer
|
||||||
|
:meth:`Sphinx.add_css_files()`.
|
||||||
|
|
||||||
.. versionadded:: 1.8
|
.. versionadded:: 1.8
|
||||||
|
.. versionchanged:: 3.5
|
||||||
|
|
||||||
|
Support priority attribute
|
||||||
|
|
||||||
.. confval:: html_static_path
|
.. confval:: html_static_path
|
||||||
|
|
||||||
@ -1070,6 +1133,23 @@ that use Sphinx's HTMLWriter class.
|
|||||||
This can now be a string to select the actual text of the link.
|
This can now be a string to select the actual text of the link.
|
||||||
Previously, only boolean values were accepted.
|
Previously, only boolean values were accepted.
|
||||||
|
|
||||||
|
.. deprecated:: 3.5
|
||||||
|
This has been replaced by :confval:`html_permalinks`
|
||||||
|
|
||||||
|
.. confval:: html_permalinks
|
||||||
|
|
||||||
|
If true, Sphinx will add "permalinks" for each heading and description
|
||||||
|
environment. Default: ``True``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
|
.. confval:: html_permalinks_icon
|
||||||
|
|
||||||
|
A text for permalinks for each heading and description environment. HTML
|
||||||
|
tags are allowed. Default: a paragraph sign; ``¶``
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
.. confval:: html_sidebars
|
.. confval:: html_sidebars
|
||||||
|
|
||||||
Custom sidebar templates, must be a dictionary that maps document names to
|
Custom sidebar templates, must be a dictionary that maps document names to
|
||||||
@ -2224,6 +2304,12 @@ These options influence manual page output.
|
|||||||
|
|
||||||
.. versionadded:: 1.1
|
.. versionadded:: 1.1
|
||||||
|
|
||||||
|
.. confval:: man_make_section_directory
|
||||||
|
|
||||||
|
If true, make a section directory on build man page. Default is False.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. _texinfo-options:
|
.. _texinfo-options:
|
||||||
|
|
||||||
@ -2390,6 +2476,32 @@ Options for the linkcheck builder
|
|||||||
|
|
||||||
.. versionadded:: 1.1
|
.. versionadded:: 1.1
|
||||||
|
|
||||||
|
.. confval:: linkcheck_request_headers
|
||||||
|
|
||||||
|
A dictionary that maps baseurls to HTTP request headers.
|
||||||
|
|
||||||
|
The key is a URL base string like ``"https://sphinx-doc.org/"``. To specify
|
||||||
|
headers for other hosts, ``"*"`` can be used. It matches all hosts only when
|
||||||
|
the URL does not match other settings.
|
||||||
|
|
||||||
|
The value is a dictionary that maps header name to its value.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
linkcheck_request_headers = {
|
||||||
|
"https://sphinx-doc.org/": {
|
||||||
|
"Accept": "text/html",
|
||||||
|
"Accept-Encoding": "utf-8",
|
||||||
|
},
|
||||||
|
"*": {
|
||||||
|
"Accept": "text/html,application/xhtml+xml",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
.. confval:: linkcheck_retries
|
.. confval:: linkcheck_retries
|
||||||
|
|
||||||
The number of times the linkcheck builder will attempt to check a URL before
|
The number of times the linkcheck builder will attempt to check a URL before
|
||||||
@ -2467,6 +2579,23 @@ Options for the linkcheck builder
|
|||||||
|
|
||||||
.. versionadded:: 2.3
|
.. versionadded:: 2.3
|
||||||
|
|
||||||
|
.. confval:: linkcheck_rate_limit_timeout
|
||||||
|
|
||||||
|
The ``linkcheck`` builder may issue a large number of requests to the same
|
||||||
|
site over a short period of time. This setting controls the builder behavior
|
||||||
|
when servers indicate that requests are rate-limited.
|
||||||
|
|
||||||
|
If a server indicates when to retry (using the `Retry-After`_ header),
|
||||||
|
``linkcheck`` always follows the server indication.
|
||||||
|
|
||||||
|
Otherwise, ``linkcheck`` waits for a minute before to retry and keeps
|
||||||
|
doubling the wait time between attempts until it succeeds or exceeds the
|
||||||
|
``linkcheck_rate_limit_timeout``. By default, the timeout is 5 minutes.
|
||||||
|
|
||||||
|
.. _Retry-After: https://tools.ietf.org/html/rfc7231#section-7.1.3
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
|
||||||
Options for the XML builder
|
Options for the XML builder
|
||||||
---------------------------
|
---------------------------
|
||||||
@ -2509,6 +2638,23 @@ Options for the C domain
|
|||||||
|
|
||||||
.. versionadded:: 3.0
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
.. confval:: c_allow_pre_v3
|
||||||
|
|
||||||
|
A boolean (default ``False``) controlling whether to parse and try to
|
||||||
|
convert pre-v3 style type directives and type roles.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
.. deprecated:: 3.2
|
||||||
|
Use the directives and roles added in v3.
|
||||||
|
|
||||||
|
.. confval:: c_warn_on_allowed_pre_v3
|
||||||
|
|
||||||
|
A boolean (default ``True``) controlling whether to warn when a pre-v3
|
||||||
|
style type directive/role is parsed and converted.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
.. deprecated:: 3.2
|
||||||
|
Use the directives and roles added in v3.
|
||||||
|
|
||||||
.. _cpp-config:
|
.. _cpp-config:
|
||||||
|
|
||||||
|
@ -136,15 +136,28 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
:undoc-members:
|
:undoc-members:
|
||||||
|
|
||||||
* "Private" members (that is, those named like ``_private`` or ``__private``)
|
* "Private" members (that is, those named like ``_private`` or ``__private``)
|
||||||
will be included if the ``private-members`` flag option is given.
|
will be included if the ``private-members`` flag option is given::
|
||||||
|
|
||||||
|
.. automodule:: noodle
|
||||||
|
:members:
|
||||||
|
:private-members:
|
||||||
|
|
||||||
|
It can also take an explicit list of member names to be documented as
|
||||||
|
arguments::
|
||||||
|
|
||||||
|
.. automodule:: noodle
|
||||||
|
:members:
|
||||||
|
:private-members: _spicy, _garlickly
|
||||||
|
|
||||||
.. versionadded:: 1.1
|
.. versionadded:: 1.1
|
||||||
|
.. versionchanged:: 3.2
|
||||||
|
The option can now take arguments.
|
||||||
|
|
||||||
* autodoc considers a member private if its docstring contains
|
* autodoc considers a member private if its docstring contains
|
||||||
``:meta private:`` in its :ref:`info-field-lists`.
|
``:meta private:`` in its :ref:`info-field-lists`.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code-block:: rst
|
.. code-block:: python
|
||||||
|
|
||||||
def my_function(my_arg, my_other_arg):
|
def my_function(my_arg, my_other_arg):
|
||||||
"""blah blah blah
|
"""blah blah blah
|
||||||
@ -159,7 +172,7 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
an underscore.
|
an underscore.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code-block:: rst
|
.. code-block:: python
|
||||||
|
|
||||||
def _my_function(my_arg, my_other_arg):
|
def _my_function(my_arg, my_other_arg):
|
||||||
"""blah blah blah
|
"""blah blah blah
|
||||||
@ -169,6 +182,16 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
|
|
||||||
.. versionadded:: 3.1
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
* autodoc considers a variable member does not have any default value if its
|
||||||
|
docstring contains ``:meta hide-value:`` in its :ref:`info-field-lists`.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
var1 = None #: :meta hide-value:
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
* Python "special" members (that is, those named like ``__special__``) will
|
* Python "special" members (that is, those named like ``__special__``) will
|
||||||
be included if the ``special-members`` flag option is given::
|
be included if the ``special-members`` flag option is given::
|
||||||
|
|
||||||
@ -216,7 +239,7 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
|
|
||||||
.. versionchanged:: 3.0
|
.. versionchanged:: 3.0
|
||||||
|
|
||||||
It takes an anchestor class name as an argument.
|
It takes an ancestor class name as an argument.
|
||||||
|
|
||||||
* It's possible to override the signature for explicitly documented callable
|
* It's possible to override the signature for explicitly documented callable
|
||||||
objects (functions, methods, classes) with the regular syntax that will
|
objects (functions, methods, classes) with the regular syntax that will
|
||||||
@ -280,6 +303,12 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
* As a hint to autodoc extension, you can put a ``::`` separator in between
|
||||||
|
module name and object name to let autodoc know the correct module name if
|
||||||
|
it is ambiguous. ::
|
||||||
|
|
||||||
|
.. autoclass:: module.name::Noodle
|
||||||
|
|
||||||
|
|
||||||
.. rst:directive:: autofunction
|
.. rst:directive:: autofunction
|
||||||
autodecorator
|
autodecorator
|
||||||
@ -307,6 +336,15 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
By default, without ``annotation`` option, Sphinx tries to obtain the value of
|
By default, without ``annotation`` option, Sphinx tries to obtain the value of
|
||||||
the variable and print it after the name.
|
the variable and print it after the name.
|
||||||
|
|
||||||
|
The ``no-value`` option can be used instead of a blank ``annotation`` to show the
|
||||||
|
type hint but not the value::
|
||||||
|
|
||||||
|
.. autodata:: CD_DRIVE
|
||||||
|
:no-value:
|
||||||
|
|
||||||
|
If both the ``annotation`` and ``no-value`` options are used, ``no-value`` has no
|
||||||
|
effect.
|
||||||
|
|
||||||
For module data members and class attributes, documentation can either be put
|
For module data members and class attributes, documentation can either be put
|
||||||
into a comment with special formatting (using a ``#:`` to start the comment
|
into a comment with special formatting (using a ``#:`` to start the comment
|
||||||
instead of just ``#``), or in a docstring *after* the definition. Comments
|
instead of just ``#``), or in a docstring *after* the definition. Comments
|
||||||
@ -346,6 +384,9 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
option.
|
option.
|
||||||
.. versionchanged:: 2.0
|
.. versionchanged:: 2.0
|
||||||
:rst:dir:`autodecorator` added.
|
:rst:dir:`autodecorator` added.
|
||||||
|
.. versionchanged:: 3.4
|
||||||
|
:rst:dir:`autodata` and :rst:dir:`autoattribute` now have a ``no-value``
|
||||||
|
option.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -496,6 +537,44 @@ There are also config values that you can set:
|
|||||||
|
|
||||||
New option ``'description'`` is added.
|
New option ``'description'`` is added.
|
||||||
|
|
||||||
|
.. confval:: autodoc_type_aliases
|
||||||
|
|
||||||
|
A dictionary for users defined `type aliases`__ that maps a type name to the
|
||||||
|
full-qualified object name. It is used to keep type aliases not evaluated in
|
||||||
|
the document. Defaults to empty (``{}``).
|
||||||
|
|
||||||
|
The type aliases are only available if your program enables `Postponed
|
||||||
|
Evaluation of Annotations (PEP 563)`__ feature via ``from __future__ import
|
||||||
|
annotations``.
|
||||||
|
|
||||||
|
For example, there is code using a type alias::
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
AliasType = Union[List[Dict[Tuple[int, str], Set[int]]], Tuple[str, List[str]]]
|
||||||
|
|
||||||
|
def f() -> AliasType:
|
||||||
|
...
|
||||||
|
|
||||||
|
If ``autodoc_type_aliases`` is not set, autodoc will generate internal mark-up
|
||||||
|
from this code as following::
|
||||||
|
|
||||||
|
.. py:function:: f() -> Union[List[Dict[Tuple[int, str], Set[int]]], Tuple[str, List[str]]]
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
If you set ``autodoc_type_aliases`` as
|
||||||
|
``{'AliasType': 'your.module.AliasType'}``, it generates the following document
|
||||||
|
internally::
|
||||||
|
|
||||||
|
.. py:function:: f() -> your.module.AliasType:
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
.. __: https://www.python.org/dev/peps/pep-0563/
|
||||||
|
.. __: https://mypy.readthedocs.io/en/latest/kinds_of_types.html#type-aliases
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
.. confval:: autodoc_warningiserror
|
.. confval:: autodoc_warningiserror
|
||||||
|
|
||||||
This value controls the behavior of :option:`sphinx-build -W` during
|
This value controls the behavior of :option:`sphinx-build -W` during
|
||||||
|
@ -175,7 +175,7 @@ also use these config values:
|
|||||||
|
|
||||||
.. confval:: autosummary_generate_overwrite
|
.. confval:: autosummary_generate_overwrite
|
||||||
|
|
||||||
If true, autosummary already overwrites stub files by generated contents.
|
If true, autosummary overwrites existing files by generated stub pages.
|
||||||
Defaults to true (enabled).
|
Defaults to true (enabled).
|
||||||
|
|
||||||
.. versionadded:: 3.0
|
.. versionadded:: 3.0
|
||||||
@ -195,6 +195,15 @@ also use these config values:
|
|||||||
|
|
||||||
.. versionadded:: 2.1
|
.. versionadded:: 2.1
|
||||||
|
|
||||||
|
.. confval:: autosummary_filename_map
|
||||||
|
|
||||||
|
A dict mapping object names to filenames. This is necessary to avoid
|
||||||
|
filename conflicts where multiple objects have names that are
|
||||||
|
indistinguishable when case is ignored, on file systems where filenames
|
||||||
|
are case-insensitive.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
||||||
Customizing templates
|
Customizing templates
|
||||||
---------------------
|
---------------------
|
||||||
@ -295,7 +304,7 @@ The following variables available in the templates:
|
|||||||
.. data:: modules
|
.. data:: modules
|
||||||
|
|
||||||
List containing names of "public" modules in the package. Only available for
|
List containing names of "public" modules in the package. Only available for
|
||||||
modules that are packages.
|
modules that are packages and the ``recursive`` option is on.
|
||||||
|
|
||||||
.. versionadded:: 3.1
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
@ -51,4 +51,11 @@ should check:
|
|||||||
|
|
||||||
.. versionadded:: 1.1
|
.. versionadded:: 1.1
|
||||||
|
|
||||||
.. _Python regular expressions: https://docs.python.org/library/re
|
.. confval:: coverage_show_missing_items
|
||||||
|
|
||||||
|
Print objects that are missing to standard output also.
|
||||||
|
``False`` by default.
|
||||||
|
|
||||||
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
.. _Python regular expressions: https://docs.python.org/library/re
|
||||||
|
@ -67,7 +67,7 @@ a comma-separated list of group names.
|
|||||||
default set of flags is specified by the :confval:`doctest_default_flags`
|
default set of flags is specified by the :confval:`doctest_default_flags`
|
||||||
configuration variable.
|
configuration variable.
|
||||||
|
|
||||||
This directive supports three options:
|
This directive supports five options:
|
||||||
|
|
||||||
* ``hide``, a flag option, hides the doctest block in other builders. By
|
* ``hide``, a flag option, hides the doctest block in other builders. By
|
||||||
default it is shown as a highlighted doctest block.
|
default it is shown as a highlighted doctest block.
|
||||||
@ -102,6 +102,11 @@ a comma-separated list of group names.
|
|||||||
|
|
||||||
Supported PEP-440 operands and notations
|
Supported PEP-440 operands and notations
|
||||||
|
|
||||||
|
* ``trim-doctest-flags`` and ``no-trim-doctest-flags``, a flag option,
|
||||||
|
doctest flags (comments looking like ``# doctest: FLAG, ...``) at the
|
||||||
|
ends of lines and ``<BLANKLINE>`` markers are removed (or not removed)
|
||||||
|
individually. Default is ``trim-doctest-flags``.
|
||||||
|
|
||||||
Note that like with standard doctests, you have to use ``<BLANKLINE>`` to
|
Note that like with standard doctests, you have to use ``<BLANKLINE>`` to
|
||||||
signal a blank line in the expected output. The ``<BLANKLINE>`` is removed
|
signal a blank line in the expected output. The ``<BLANKLINE>`` is removed
|
||||||
when building presentation output (HTML, LaTeX etc.).
|
when building presentation output (HTML, LaTeX etc.).
|
||||||
@ -119,11 +124,16 @@ a comma-separated list of group names.
|
|||||||
|
|
||||||
A code block for a code-output-style test.
|
A code block for a code-output-style test.
|
||||||
|
|
||||||
This directive supports one option:
|
This directive supports three options:
|
||||||
|
|
||||||
* ``hide``, a flag option, hides the code block in other builders. By
|
* ``hide``, a flag option, hides the code block in other builders. By
|
||||||
default it is shown as a highlighted code block.
|
default it is shown as a highlighted code block.
|
||||||
|
|
||||||
|
* ``trim-doctest-flags`` and ``no-trim-doctest-flags``, a flag option,
|
||||||
|
doctest flags (comments looking like ``# doctest: FLAG, ...``) at the
|
||||||
|
ends of lines and ``<BLANKLINE>`` markers are removed (or not removed)
|
||||||
|
individually. Default is ``trim-doctest-flags``.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Code in a ``testcode`` block is always executed all at once, no matter how
|
Code in a ``testcode`` block is always executed all at once, no matter how
|
||||||
@ -149,7 +159,7 @@ a comma-separated list of group names.
|
|||||||
The corresponding output, or the exception message, for the last
|
The corresponding output, or the exception message, for the last
|
||||||
:rst:dir:`testcode` block.
|
:rst:dir:`testcode` block.
|
||||||
|
|
||||||
This directive supports two options:
|
This directive supports four options:
|
||||||
|
|
||||||
* ``hide``, a flag option, hides the output block in other builders. By
|
* ``hide``, a flag option, hides the output block in other builders. By
|
||||||
default it is shown as a literal block without highlighting.
|
default it is shown as a literal block without highlighting.
|
||||||
@ -157,6 +167,11 @@ a comma-separated list of group names.
|
|||||||
* ``options``, a string option, can be used to give doctest flags
|
* ``options``, a string option, can be used to give doctest flags
|
||||||
(comma-separated) just like in normal doctest blocks.
|
(comma-separated) just like in normal doctest blocks.
|
||||||
|
|
||||||
|
* ``trim-doctest-flags`` and ``no-trim-doctest-flags``, a flag option,
|
||||||
|
doctest flags (comments looking like ``# doctest: FLAG, ...``) at the
|
||||||
|
ends of lines and ``<BLANKLINE>`` markers are removed (or not removed)
|
||||||
|
individually. Default is ``trim-doctest-flags``.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
.. testcode::
|
.. testcode::
|
||||||
|
@ -294,3 +294,21 @@ class ExampleClass:
|
|||||||
|
|
||||||
def _private_without_docstring(self):
|
def _private_without_docstring(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class ExamplePEP526Class:
|
||||||
|
"""The summary line for a class docstring should fit on one line.
|
||||||
|
|
||||||
|
If the class has public attributes, they may be documented here
|
||||||
|
in an ``Attributes`` section and follow the same formatting as a
|
||||||
|
function's ``Args`` section. If ``napoleon_attr_annotations``
|
||||||
|
is True, types can be specified in the class body using ``PEP 526``
|
||||||
|
annotations.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
attr1: Description of `attr1`.
|
||||||
|
attr2: Description of `attr2`.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
attr1: str
|
||||||
|
attr2: int
|
@ -75,8 +75,9 @@ linking:
|
|||||||
A dictionary mapping unique identifiers to a tuple ``(target, inventory)``.
|
A dictionary mapping unique identifiers to a tuple ``(target, inventory)``.
|
||||||
Each ``target`` is the base URI of a foreign Sphinx documentation set and can
|
Each ``target`` is the base URI of a foreign Sphinx documentation set and can
|
||||||
be a local path or an HTTP URI. The ``inventory`` indicates where the
|
be a local path or an HTTP URI. The ``inventory`` indicates where the
|
||||||
inventory file can be found: it can be ``None`` (at the same location as
|
inventory file can be found: it can be ``None`` (an :file:`objects.inv` file
|
||||||
the base URI) or another local or HTTP URI.
|
at the same location as the base URI) or another local file path or a full
|
||||||
|
HTTP URI to an inventory file.
|
||||||
|
|
||||||
The unique identifier can be used to prefix cross-reference targets, so that
|
The unique identifier can be used to prefix cross-reference targets, so that
|
||||||
it is clear which intersphinx set the target belongs to. A link like
|
it is clear which intersphinx set the target belongs to. A link like
|
||||||
@ -106,7 +107,7 @@ linking:
|
|||||||
``https://docs.python.org/3``. It is up to you to update the inventory file
|
``https://docs.python.org/3``. It is up to you to update the inventory file
|
||||||
as new objects are added to the Python documentation.
|
as new objects are added to the Python documentation.
|
||||||
|
|
||||||
**Multiple target for the inventory**
|
**Multiple targets for the inventory**
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
@ -120,6 +121,16 @@ linking:
|
|||||||
intersphinx_mapping = {'python': ('https://docs.python.org/3',
|
intersphinx_mapping = {'python': ('https://docs.python.org/3',
|
||||||
(None, 'python-inv.txt'))}
|
(None, 'python-inv.txt'))}
|
||||||
|
|
||||||
|
For a set of books edited and tested locally and then published
|
||||||
|
together, it could be helpful to try a local inventory file first,
|
||||||
|
to check references before publication::
|
||||||
|
|
||||||
|
intersphinx_mapping = {
|
||||||
|
'otherbook':
|
||||||
|
('https://myproj.readthedocs.io/projects/otherbook/en/latest',
|
||||||
|
('../../otherbook/build/html/objects.inv', None)),
|
||||||
|
}
|
||||||
|
|
||||||
.. confval:: intersphinx_cache_limit
|
.. confval:: intersphinx_cache_limit
|
||||||
|
|
||||||
The maximum number of days to cache remote inventories. The default is
|
The maximum number of days to cache remote inventories. The default is
|
||||||
|
@ -115,6 +115,7 @@ All of the following section headers are supported:
|
|||||||
* ``Parameters``
|
* ``Parameters``
|
||||||
* ``Return`` *(alias of Returns)*
|
* ``Return`` *(alias of Returns)*
|
||||||
* ``Returns``
|
* ``Returns``
|
||||||
|
* ``Raise`` *(alias of Raises)*
|
||||||
* ``Raises``
|
* ``Raises``
|
||||||
* ``References``
|
* ``References``
|
||||||
* ``See Also``
|
* ``See Also``
|
||||||
@ -122,6 +123,7 @@ All of the following section headers are supported:
|
|||||||
* ``Todo``
|
* ``Todo``
|
||||||
* ``Warning``
|
* ``Warning``
|
||||||
* ``Warnings`` *(alias of Warning)*
|
* ``Warnings`` *(alias of Warning)*
|
||||||
|
* ``Warn`` *(alias of Warns)*
|
||||||
* ``Warns``
|
* ``Warns``
|
||||||
* ``Yield`` *(alias of Yields)*
|
* ``Yield`` *(alias of Yields)*
|
||||||
* ``Yields``
|
* ``Yields``
|
||||||
@ -201,7 +203,8 @@ Type Annotations
|
|||||||
This is an alternative to expressing types directly in docstrings.
|
This is an alternative to expressing types directly in docstrings.
|
||||||
One benefit of expressing types according to `PEP 484`_ is that
|
One benefit of expressing types according to `PEP 484`_ is that
|
||||||
type checkers and IDEs can take advantage of them for static code
|
type checkers and IDEs can take advantage of them for static code
|
||||||
analysis.
|
analysis. `PEP 484`_ was then extended by `PEP 526`_ which introduced
|
||||||
|
a similar way to annotate variables (and attributes).
|
||||||
|
|
||||||
Google style with Python 3 type annotations::
|
Google style with Python 3 type annotations::
|
||||||
|
|
||||||
@ -219,6 +222,19 @@ Google style with Python 3 type annotations::
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
class Class:
|
||||||
|
"""Summary line.
|
||||||
|
|
||||||
|
Extended description of class
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
attr1: Description of attr1
|
||||||
|
attr2: Description of attr2
|
||||||
|
"""
|
||||||
|
|
||||||
|
attr1: int
|
||||||
|
attr2: str
|
||||||
|
|
||||||
Google style with types in docstrings::
|
Google style with types in docstrings::
|
||||||
|
|
||||||
@ -236,6 +252,16 @@ Google style with types in docstrings::
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
class Class:
|
||||||
|
"""Summary line.
|
||||||
|
|
||||||
|
Extended description of class
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
attr1 (int): Description of attr1
|
||||||
|
attr2 (str): Description of attr2
|
||||||
|
"""
|
||||||
|
|
||||||
.. Note::
|
.. Note::
|
||||||
`Python 2/3 compatible annotations`_ aren't currently
|
`Python 2/3 compatible annotations`_ aren't currently
|
||||||
@ -244,6 +270,9 @@ Google style with types in docstrings::
|
|||||||
.. _PEP 484:
|
.. _PEP 484:
|
||||||
https://www.python.org/dev/peps/pep-0484/
|
https://www.python.org/dev/peps/pep-0484/
|
||||||
|
|
||||||
|
.. _PEP 526:
|
||||||
|
https://www.python.org/dev/peps/pep-0526/
|
||||||
|
|
||||||
.. _Python 2/3 compatible annotations:
|
.. _Python 2/3 compatible annotations:
|
||||||
https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
|
https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
|
||||||
|
|
||||||
@ -272,11 +301,13 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
|
|||||||
napoleon_use_ivar = False
|
napoleon_use_ivar = False
|
||||||
napoleon_use_param = True
|
napoleon_use_param = True
|
||||||
napoleon_use_rtype = True
|
napoleon_use_rtype = True
|
||||||
|
napoleon_type_aliases = None
|
||||||
|
napoleon_attr_annotations = True
|
||||||
|
|
||||||
.. _Google style:
|
.. _Google style:
|
||||||
https://google.github.io/styleguide/pyguide.html
|
https://google.github.io/styleguide/pyguide.html
|
||||||
.. _NumPy style:
|
.. _NumPy style:
|
||||||
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
|
https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard
|
||||||
|
|
||||||
.. confval:: napoleon_google_docstring
|
.. confval:: napoleon_google_docstring
|
||||||
|
|
||||||
@ -433,7 +464,7 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
|
|||||||
:param arg1: Description of `arg1`
|
:param arg1: Description of `arg1`
|
||||||
:type arg1: str
|
:type arg1: str
|
||||||
:param arg2: Description of `arg2`, defaults to 0
|
:param arg2: Description of `arg2`, defaults to 0
|
||||||
:type arg2: int, optional
|
:type arg2: :class:`int`, *optional*
|
||||||
|
|
||||||
**If False**::
|
**If False**::
|
||||||
|
|
||||||
@ -478,3 +509,65 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
|
|||||||
**If False**::
|
**If False**::
|
||||||
|
|
||||||
:returns: *bool* -- True if successful, False otherwise
|
:returns: *bool* -- True if successful, False otherwise
|
||||||
|
|
||||||
|
.. confval:: napoleon_type_aliases
|
||||||
|
|
||||||
|
A mapping to translate type names to other names or references. Works
|
||||||
|
only when ``napoleon_use_param = True``. *Defaults to None.*
|
||||||
|
|
||||||
|
With::
|
||||||
|
|
||||||
|
napoleon_type_aliases = {
|
||||||
|
"CustomType": "mypackage.CustomType",
|
||||||
|
"dict-like": ":term:`dict-like <mapping>`",
|
||||||
|
}
|
||||||
|
|
||||||
|
This `NumPy style`_ snippet::
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
arg1 : CustomType
|
||||||
|
Description of `arg1`
|
||||||
|
arg2 : dict-like
|
||||||
|
Description of `arg2`
|
||||||
|
|
||||||
|
becomes::
|
||||||
|
|
||||||
|
:param arg1: Description of `arg1`
|
||||||
|
:type arg1: mypackage.CustomType
|
||||||
|
:param arg2: Description of `arg2`
|
||||||
|
:type arg2: :term:`dict-like <mapping>`
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
.. confval:: napoleon_attr_annotations
|
||||||
|
|
||||||
|
True to allow using `PEP 526`_ attributes annotations in classes.
|
||||||
|
If an attribute is documented in the docstring without a type and
|
||||||
|
has an annotation in the class body, that type is used.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
.. confval:: napoleon_custom_sections
|
||||||
|
|
||||||
|
Add a list of custom sections to include, expanding the list of parsed sections.
|
||||||
|
*Defaults to None.*
|
||||||
|
|
||||||
|
The entries can either be strings or tuples, depending on the intention:
|
||||||
|
|
||||||
|
* To create a custom "generic" section, just pass a string.
|
||||||
|
* To create an alias for an existing section, pass a tuple containing the
|
||||||
|
alias name and the original, in that order.
|
||||||
|
* To create a custom section that displays like the parameters or returns
|
||||||
|
section, pass a tuple containing the custom section name and a string
|
||||||
|
value, "params_style" or "returns_style".
|
||||||
|
|
||||||
|
If an entry is just a string, it is interpreted as a header for a generic
|
||||||
|
section. If the entry is a tuple/list/indexed container, the first entry
|
||||||
|
is the name of the section, the second is the section key to emulate. If the
|
||||||
|
second entry value is "params_style" or "returns_style", the custom section
|
||||||
|
will be displayed like the parameters section or returns section.
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
.. versionchanged:: 3.5
|
||||||
|
Support ``params_style`` and ``returns_style``
|
@ -171,7 +171,7 @@ Docker images for Sphinx are published on the `Docker Hub <https://hub.docker.co
|
|||||||
- `sphinxdoc/sphinx <https://hub.docker.com/repository/docker/sphinxdoc/sphinx>`_
|
- `sphinxdoc/sphinx <https://hub.docker.com/repository/docker/sphinxdoc/sphinx>`_
|
||||||
- `sphinxdoc/sphinx-latexpdf <https://hub.docker.com/repository/docker/sphinxdoc/sphinx-latexpdf>`_
|
- `sphinxdoc/sphinx-latexpdf <https://hub.docker.com/repository/docker/sphinxdoc/sphinx-latexpdf>`_
|
||||||
|
|
||||||
Former one is used for standard usage of Sphinx, and latter one is mainly used for PDF builds using LaTeX.
|
Former one is used for standard usage of Sphinx, and latter one is mainly used for PDF builds using LaTeX.
|
||||||
Please choose one for your purpose.
|
Please choose one for your purpose.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
@ -15,7 +15,7 @@ Much of Sphinx's power comes from the richness of its default plain-text markup
|
|||||||
format, :doc:`reStructuredText </usage/restructuredtext/index>`, along with
|
format, :doc:`reStructuredText </usage/restructuredtext/index>`, along with
|
||||||
it's :doc:`significant extensibility capabilities </development/index>`.
|
it's :doc:`significant extensibility capabilities </development/index>`.
|
||||||
|
|
||||||
The goal of this document is to give you a quick taste of what Sphinx it is and
|
The goal of this document is to give you a quick taste of what Sphinx is and
|
||||||
how you might use it. When you're done here, you can check out the
|
how you might use it. When you're done here, you can check out the
|
||||||
:doc:`installation guide </usage/installation>` followed by the intro to the
|
:doc:`installation guide </usage/installation>` followed by the intro to the
|
||||||
default markup format used by Sphinx, :doc:`reStucturedText
|
default markup format used by Sphinx, :doc:`reStucturedText
|
||||||
|
@ -114,9 +114,9 @@ tables of contents. The ``toctree`` directive is the central element.
|
|||||||
|
|
||||||
**Additional options**
|
**Additional options**
|
||||||
|
|
||||||
You can use ``caption`` option to provide a toctree caption and you can use
|
You can use the ``caption`` option to provide a toctree caption and you can
|
||||||
``name`` option to provide implicit target name that can be referenced by
|
use the ``name`` option to provide an implicit target name that can be
|
||||||
using :rst:role:`ref`::
|
referenced by using :rst:role:`ref`::
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:caption: Table of Contents
|
:caption: Table of Contents
|
||||||
@ -246,7 +246,7 @@ The special document names (and pages generated for them) are:
|
|||||||
|
|
||||||
* every name beginning with ``_``
|
* every name beginning with ``_``
|
||||||
|
|
||||||
Though only few such names are currently used by Sphinx, you should not
|
Though few such names are currently used by Sphinx, you should not
|
||||||
create documents or document-containing directories with such names. (Using
|
create documents or document-containing directories with such names. (Using
|
||||||
``_`` as a prefix for a custom template directory is fine.)
|
``_`` as a prefix for a custom template directory is fine.)
|
||||||
|
|
||||||
@ -569,12 +569,28 @@ __ http://pygments.org/docs/lexers
|
|||||||
|
|
||||||
print 'Explicit is better than implicit.'
|
print 'Explicit is better than implicit.'
|
||||||
|
|
||||||
|
In order to cross-reference a code-block using either the
|
||||||
|
:rst:role:`ref` or the :rst:role:`numref` role, it is necessary
|
||||||
|
that both :strong:`name` and :strong:`caption` be defined. The
|
||||||
|
argument of :strong:`name` can then be given to :rst:role:`numref`
|
||||||
|
to generate the cross-reference. Example::
|
||||||
|
|
||||||
|
See :numref:`this-py` for an example.
|
||||||
|
|
||||||
|
When using :rst:role:`ref`, it is possible to generate a cross-reference
|
||||||
|
with only :strong:`name` defined, provided an explicit title is
|
||||||
|
given. Example::
|
||||||
|
|
||||||
|
See :ref:`this code snippet <this-py>` for an example.
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
.. rst:directive:option:: dedent: number
|
.. rst:directive:option:: dedent: number
|
||||||
:type: number
|
:type: number or no value
|
||||||
|
|
||||||
Strip indentation characters from the code block. For example::
|
Strip indentation characters from the code block. When number given,
|
||||||
|
leading N characters are removed. When no argument given, leading spaces
|
||||||
|
are removed via :func:`textwrap.dedent()`. For example::
|
||||||
|
|
||||||
.. code-block:: ruby
|
.. code-block:: ruby
|
||||||
:dedent: 4
|
:dedent: 4
|
||||||
@ -582,6 +598,8 @@ __ http://pygments.org/docs/lexers
|
|||||||
some ruby code
|
some ruby code
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
.. versionchanged:: 3.5
|
||||||
|
Support automatic dedent.
|
||||||
|
|
||||||
.. rst:directive:option:: force
|
.. rst:directive:option:: force
|
||||||
:type: no value
|
:type: no value
|
||||||
@ -656,9 +674,43 @@ __ http://pygments.org/docs/lexers
|
|||||||
string are included. The ``start-at`` and ``end-at`` options behave in a
|
string are included. The ``start-at`` and ``end-at`` options behave in a
|
||||||
similar way, but the lines containing the matched string are included.
|
similar way, but the lines containing the matched string are included.
|
||||||
|
|
||||||
With lines selected using ``start-after`` it is still possible to use
|
``start-after``/``start-at`` and ``end-before``/``end-at`` can have same string.
|
||||||
``lines``, the first allowed line having by convention the line number
|
``start-after``/``start-at`` filter lines before the line that contains
|
||||||
``1``.
|
option string (``start-at`` will keep the line). Then ``end-before``/``end-at``
|
||||||
|
filter lines after the line that contains option string (``end-at`` will keep
|
||||||
|
the line and ``end-before`` skip the first line).
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If you want to select only ``[second-section]`` of ini file like the
|
||||||
|
following, you can use ``:start-at: [second-section]`` and
|
||||||
|
``:end-before: [third-section]``:
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[first-section]
|
||||||
|
|
||||||
|
var_in_first=true
|
||||||
|
|
||||||
|
[second-section]
|
||||||
|
|
||||||
|
var_in_second=true
|
||||||
|
|
||||||
|
[third-section]
|
||||||
|
|
||||||
|
var_in_third=true
|
||||||
|
|
||||||
|
Useful cases of these option is working with tag comments.
|
||||||
|
``:start-after: [initialized]`` and ``:end-before: [initialized]`` options
|
||||||
|
keep lines between comments:
|
||||||
|
|
||||||
|
.. code-block:: py
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# [initialize]
|
||||||
|
app.start(":8000")
|
||||||
|
# [initialize]
|
||||||
|
|
||||||
|
|
||||||
When lines have been selected in any of the ways described above, the line
|
When lines have been selected in any of the ways described above, the line
|
||||||
numbers in ``emphasize-lines`` refer to those selected lines, counted
|
numbers in ``emphasize-lines`` refer to those selected lines, counted
|
||||||
@ -708,6 +760,9 @@ __ http://pygments.org/docs/lexers
|
|||||||
.. versionchanged:: 2.1
|
.. versionchanged:: 2.1
|
||||||
Added the ``force`` option.
|
Added the ``force`` option.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.5
|
||||||
|
Support automatic dedent.
|
||||||
|
|
||||||
.. _glossary-directive:
|
.. _glossary-directive:
|
||||||
|
|
||||||
Glossary
|
Glossary
|
||||||
@ -1165,20 +1220,29 @@ the definition of the symbol. There is this directive:
|
|||||||
the following definition. If the definition spans multiple lines, each
|
the following definition. If the definition spans multiple lines, each
|
||||||
continuation line must begin with a colon placed at the same column as in
|
continuation line must begin with a colon placed at the same column as in
|
||||||
the first line.
|
the first line.
|
||||||
|
Blank lines are not allowed within ``productionlist`` directive arguments.
|
||||||
|
|
||||||
|
The definition can contain token names which are marked as interpreted text
|
||||||
|
(e.g., "``sum ::= `integer` "+" `integer```") -- this generates
|
||||||
|
cross-references to the productions of these tokens. Outside of the
|
||||||
|
production list, you can reference to token productions using
|
||||||
|
:rst:role:`token`.
|
||||||
|
|
||||||
The *productionGroup* argument to :rst:dir:`productionlist` serves to
|
The *productionGroup* argument to :rst:dir:`productionlist` serves to
|
||||||
distinguish different sets of production lists that belong to different
|
distinguish different sets of production lists that belong to different
|
||||||
grammars. Multiple production lists with the same *productionGroup* thus
|
grammars. Multiple production lists with the same *productionGroup* thus
|
||||||
define rules in the same scope.
|
define rules in the same scope.
|
||||||
|
|
||||||
Blank lines are not allowed within ``productionlist`` directive arguments.
|
Inside of the production list, tokens implicitly refer to productions
|
||||||
|
from the current group. You can refer to the production of another
|
||||||
|
grammar by prefixing the token with its group name and a colon, e.g,
|
||||||
|
"``otherGroup:sum``". If the group of the token should not be shown in
|
||||||
|
the production, it can be prefixed by a tilde, e.g.,
|
||||||
|
"``~otherGroup:sum``". To refer to a production from an unnamed
|
||||||
|
grammar, the token should be prefixed by a colon, e.g., "``:sum``".
|
||||||
|
|
||||||
The definition can contain token names which are marked as interpreted text
|
Outside of the production list,
|
||||||
(e.g. "``sum ::= `integer` "+" `integer```") -- this generates
|
if you have given a *productionGroup* argument you must prefix the
|
||||||
cross-references to the productions of these tokens. Outside of the
|
|
||||||
production list, you can reference to token productions using
|
|
||||||
:rst:role:`token`.
|
|
||||||
However, if you have given a *productionGroup* argument you must prefix the
|
|
||||||
token name in the cross-reference with the group name and a colon,
|
token name in the cross-reference with the group name and a colon,
|
||||||
e.g., "``myGroup:sum``" instead of just "``sum``".
|
e.g., "``myGroup:sum``" instead of just "``sum``".
|
||||||
If the group should not be shown in the title of the link either
|
If the group should not be shown in the title of the link either
|
||||||
|
@ -42,9 +42,22 @@ Basic Markup
|
|||||||
Most domains provide a number of :dfn:`object description directives`, used to
|
Most domains provide a number of :dfn:`object description directives`, used to
|
||||||
describe specific objects provided by modules. Each directive requires one or
|
describe specific objects provided by modules. Each directive requires one or
|
||||||
more signatures to provide basic information about what is being described, and
|
more signatures to provide basic information about what is being described, and
|
||||||
the content should be the description. The basic version makes entries in the
|
the content should be the description. A domain will typically keep an
|
||||||
general index; if no index entry is desired, you can give the directive option
|
internal index of all entites to aid cross-referencing. Typically it will
|
||||||
flag ``:noindex:``. An example using a Python domain directive::
|
also add entries in the shown general index.
|
||||||
|
If you want to suppress the addition of an entry in the shown index, you can
|
||||||
|
give the directive option flag ``:noindexentry:``.
|
||||||
|
If you want to typeset an object description, without even making it available
|
||||||
|
for cross-referencing, you can give the directive option flag ``:noindex:``
|
||||||
|
(which implies ``:noindexentry:``).
|
||||||
|
Though, note that not every directive en every domain may support these
|
||||||
|
options.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
The directive option ``noindexentry`` in the Python, C, C++, and Javascript
|
||||||
|
domains.
|
||||||
|
|
||||||
|
An example using a Python domain directive::
|
||||||
|
|
||||||
.. py:function:: spam(eggs)
|
.. py:function:: spam(eggs)
|
||||||
ham(eggs)
|
ham(eggs)
|
||||||
@ -699,6 +712,53 @@ Explicit ref: :c:var:`Data.@data.a`. Short-hand ref: :c:var:`Data.a`.
|
|||||||
.. versionadded:: 3.0
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
|
||||||
|
Aliasing Declarations
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. c:namespace-push:: @alias
|
||||||
|
|
||||||
|
Sometimes it may be helpful list declarations elsewhere than their main
|
||||||
|
documentation, e.g., when creating a synopsis of an interface.
|
||||||
|
The following directive can be used for this purpose.
|
||||||
|
|
||||||
|
.. rst:directive:: .. c:alias:: name
|
||||||
|
|
||||||
|
Insert one or more alias declarations. Each entity can be specified
|
||||||
|
as they can in the :rst:role:`c:any` role.
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
.. c:var:: int data
|
||||||
|
.. c:function:: int f(double k)
|
||||||
|
|
||||||
|
.. c:alias:: data
|
||||||
|
f
|
||||||
|
|
||||||
|
becomes
|
||||||
|
|
||||||
|
.. c:var:: int data
|
||||||
|
.. c:function:: int f(double k)
|
||||||
|
|
||||||
|
.. c:alias:: data
|
||||||
|
f
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
||||||
|
.. rubric:: Options
|
||||||
|
|
||||||
|
.. rst:directive:option:: maxdepth: int
|
||||||
|
|
||||||
|
Insert nested declarations as well, up to the total depth given.
|
||||||
|
Use 0 for infinite depth and 1 for just the mentioned declaration.
|
||||||
|
Defaults to 1.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. c:namespace-pop::
|
||||||
|
|
||||||
|
|
||||||
Inline Expressions and Types
|
Inline Expressions and Types
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -1038,7 +1098,7 @@ Options
|
|||||||
|
|
||||||
Some directives support options:
|
Some directives support options:
|
||||||
|
|
||||||
- ``:noindex:``, see :ref:`basic-domain-markup`.
|
- ``:noindexentry:``, see :ref:`basic-domain-markup`.
|
||||||
- ``: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.
|
||||||
|
|
||||||
|
@ -9,7 +9,14 @@ fields marked up like this::
|
|||||||
|
|
||||||
:fieldname: Field content
|
:fieldname: Field content
|
||||||
|
|
||||||
Sphinx provides custom behavior for bibliographic fields compared to docutils.
|
Sphinx extends standard docutils behavior for field lists and adds some extra
|
||||||
|
functionality that is covered in this section.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The values of field lists will be parsed as
|
||||||
|
strings. You cannot use Python collections such as lists or dictionaries.
|
||||||
|
|
||||||
|
|
||||||
.. _metadata:
|
.. _metadata:
|
||||||
|
|
||||||
@ -17,11 +24,20 @@ File-wide metadata
|
|||||||
------------------
|
------------------
|
||||||
|
|
||||||
A field list near the top of a file is normally parsed by docutils as the
|
A field list near the top of a file is normally parsed by docutils as the
|
||||||
*docinfo* which is generally used to record the author, date of publication and
|
*docinfo* and shown on the page. However, in Sphinx, a field list preceding
|
||||||
other metadata. However, in Sphinx, a field list preceding any other markup is
|
any other markup is moved from the *docinfo* to the Sphinx environment as
|
||||||
moved from the *docinfo* to the Sphinx environment as document metadata and is
|
document metadata, and is not displayed in the output.
|
||||||
not displayed in the output; a field list appearing after the document title
|
|
||||||
will be part of the *docinfo* as normal and will be displayed in the output.
|
.. note::
|
||||||
|
|
||||||
|
A field list appearing after the document title *will* be part of the
|
||||||
|
*docinfo* as normal and will be displayed in the output.
|
||||||
|
|
||||||
|
|
||||||
|
Special metadata fields
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Sphinx provides custom behavior for bibliographic fields compared to docutils.
|
||||||
|
|
||||||
At the moment, these metadata fields are recognized:
|
At the moment, these metadata fields are recognized:
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
.. _html-themes:
|
.. _html-themes:
|
||||||
|
|
||||||
HTML
|
HTML Theming
|
||||||
====
|
============
|
||||||
|
|
||||||
Sphinx provides a number of builders for HTML and HTML-based formats.
|
Sphinx provides a number of builders for HTML and HTML-based formats.
|
||||||
|
|
||||||
@ -21,7 +21,8 @@ Themes
|
|||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
This section provides information about using pre-existing HTML themes. If
|
This section provides information about using pre-existing HTML themes. If
|
||||||
you wish to create your own theme, refer to :doc:`/theming`.
|
you wish to create your own theme, refer to
|
||||||
|
:doc:`/development/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.
|
||||||
@ -80,7 +81,7 @@ zipfile-based theme::
|
|||||||
html_theme = "dotted"
|
html_theme = "dotted"
|
||||||
|
|
||||||
For more information on the design of themes, including information about
|
For more information on the design of themes, including information about
|
||||||
writing your own themes, refer to :doc:`/theming`.
|
writing your own themes, refer to :doc:`/development/theming`.
|
||||||
|
|
||||||
.. _builtin-themes:
|
.. _builtin-themes:
|
||||||
|
|
||||||
@ -172,6 +173,12 @@ These themes are:
|
|||||||
|
|
||||||
.. versionadded:: 3.1
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
- **globaltoc_maxdepth** (int): The maximum depth of the toctree in
|
||||||
|
``globaltoc.html`` (see :confval:`html_sidebars`). Set it to -1 to allow
|
||||||
|
unlimited depth. Defaults to the max depth selected in the toctree directive.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
**alabaster**
|
**alabaster**
|
||||||
`Alabaster theme`_ is a modified "Kr" Sphinx theme from @kennethreitz
|
`Alabaster theme`_ is a modified "Kr" Sphinx theme from @kennethreitz
|
||||||
(especially as used in his Requests project), which was itself originally
|
(especially as used in his Requests project), which was itself originally
|
||||||
@ -341,7 +348,7 @@ Third Party Themes
|
|||||||
|
|
||||||
There are many third-party themes available. Some of these are general use,
|
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
|
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
|
themes is listed below. Many more can be found on PyPI__, GitHub__, GitLab__ and
|
||||||
sphinx-themes.org__.
|
sphinx-themes.org__.
|
||||||
|
|
||||||
.. cssclass:: clear
|
.. cssclass:: clear
|
||||||
@ -357,6 +364,8 @@ sphinx-themes.org__.
|
|||||||
.. versionchanged:: 1.4
|
.. versionchanged:: 1.4
|
||||||
**sphinx_rtd_theme** has become optional.
|
**sphinx_rtd_theme** has become optional.
|
||||||
|
|
||||||
|
|
||||||
.. __: https://pypi.org/search/?q=&o=&c=Framework+%3A%3A+Sphinx+%3A%3A+Theme
|
.. __: 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://github.com/search?utf8=%E2%9C%93&q=sphinx+theme&type=
|
||||||
|
.. __: https://gitlab.com/explore?name=sphinx+theme
|
||||||
.. __: https://sphinx-themes.org/
|
.. __: https://sphinx-themes.org/
|
||||||
|
28
package-lock.json
generated
28
package-lock.json
generated
@ -385,12 +385,6 @@
|
|||||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
|
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"eventemitter3": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"extend": {
|
"extend": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
@ -535,14 +529,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"http-proxy": {
|
"http-proxy": {
|
||||||
"version": "1.17.0",
|
"version": "1.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
|
||||||
"integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
|
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"eventemitter3": "^3.0.0",
|
"eventemitter3": "^4.0.0",
|
||||||
"follow-redirects": "^1.0.0",
|
"follow-redirects": "^1.0.0",
|
||||||
"requires-port": "^1.0.0"
|
"requires-port": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"eventemitter3": {
|
||||||
|
"version": "4.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
||||||
|
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
@ -702,9 +704,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.14",
|
"version": "4.17.19",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||||
"integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==",
|
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"log4js": {
|
"log4js": {
|
||||||
|
10
setup.cfg
10
setup.cfg
@ -29,9 +29,11 @@ directory = sphinx/locale/
|
|||||||
[flake8]
|
[flake8]
|
||||||
max-line-length = 95
|
max-line-length = 95
|
||||||
ignore = E116,E241,E251,E741,W504,I101
|
ignore = E116,E241,E251,E741,W504,I101
|
||||||
exclude = .git,.tox,.venv,tests/*,build/*,doc/_build/*,sphinx/search/*,doc/usage/extensions/example*.py
|
exclude = .git,.tox,.venv,tests/roots/*,build/*,doc/_build/*,sphinx/search/*,doc/usage/extensions/example*.py
|
||||||
application-import-names = sphinx
|
application-import-names = sphinx
|
||||||
import-order-style = smarkets
|
import-order-style = smarkets
|
||||||
|
per-file-ignores =
|
||||||
|
tests/*: E501
|
||||||
|
|
||||||
[flake8:local-plugins]
|
[flake8:local-plugins]
|
||||||
extension =
|
extension =
|
||||||
@ -39,6 +41,9 @@ extension =
|
|||||||
paths =
|
paths =
|
||||||
.
|
.
|
||||||
|
|
||||||
|
[isort]
|
||||||
|
line_length = 95
|
||||||
|
|
||||||
[mypy]
|
[mypy]
|
||||||
python_version = 3.5
|
python_version = 3.5
|
||||||
disallow_incomplete_defs = True
|
disallow_incomplete_defs = True
|
||||||
@ -55,12 +60,11 @@ filterwarnings =
|
|||||||
all
|
all
|
||||||
ignore::DeprecationWarning:docutils.io
|
ignore::DeprecationWarning:docutils.io
|
||||||
ignore::DeprecationWarning:pyximport.pyximport
|
ignore::DeprecationWarning:pyximport.pyximport
|
||||||
|
ignore::ImportWarning:importlib._bootstrap
|
||||||
ignore::PendingDeprecationWarning:sphinx.util.pycompat
|
ignore::PendingDeprecationWarning:sphinx.util.pycompat
|
||||||
markers =
|
markers =
|
||||||
sphinx
|
|
||||||
apidoc
|
apidoc
|
||||||
setup_command
|
setup_command
|
||||||
test_params
|
|
||||||
testpaths = tests
|
testpaths = tests
|
||||||
|
|
||||||
[coverage:run]
|
[coverage:run]
|
||||||
|
18
setup.py
18
setup.py
@ -43,15 +43,15 @@ extras_require = {
|
|||||||
],
|
],
|
||||||
'lint': [
|
'lint': [
|
||||||
'flake8>=3.5.0',
|
'flake8>=3.5.0',
|
||||||
'flake8-import-order',
|
'isort',
|
||||||
'mypy>=0.770',
|
'mypy>=0.800',
|
||||||
'docutils-stubs',
|
'docutils-stubs',
|
||||||
],
|
],
|
||||||
'test': [
|
'test': [
|
||||||
'pytest',
|
'pytest',
|
||||||
'pytest-cov',
|
'pytest-cov',
|
||||||
'html5lib',
|
'html5lib',
|
||||||
'typed_ast', # for py35-37
|
"typed_ast; python_version < '3.8'",
|
||||||
'cython',
|
'cython',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -76,9 +76,10 @@ class Tee:
|
|||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from babel.messages.pofile import read_po
|
|
||||||
from babel.messages.frontend import compile_catalog
|
|
||||||
from json import dump
|
from json import dump
|
||||||
|
|
||||||
|
from babel.messages.frontend import compile_catalog
|
||||||
|
from babel.messages.pofile import read_po
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@ -139,7 +140,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) as infile:
|
with open(po_file, encoding='utf8') 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:
|
||||||
@ -157,13 +158,13 @@ else:
|
|||||||
msgid = msgid[0]
|
msgid = msgid[0]
|
||||||
jscatalog[msgid] = message.string
|
jscatalog[msgid] = message.string
|
||||||
|
|
||||||
with open(js_file, 'wt') as outfile:
|
with open(js_file, 'wt', encoding='utf8') as outfile:
|
||||||
outfile.write('Documentation.addTranslations(')
|
outfile.write('Documentation.addTranslations(')
|
||||||
dump({
|
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, indent=4)
|
||||||
outfile.write(');')
|
outfile.write(');')
|
||||||
|
|
||||||
cmdclass['compile_catalog'] = compile_catalog_plusjs
|
cmdclass['compile_catalog'] = compile_catalog_plusjs
|
||||||
@ -203,6 +204,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
'Programming Language :: Python :: 3.7',
|
'Programming Language :: Python :: 3.7',
|
||||||
'Programming Language :: Python :: 3.8',
|
'Programming Language :: Python :: 3.8',
|
||||||
|
'Programming Language :: Python :: 3.9',
|
||||||
'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',
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
The Sphinx documentation toolchain.
|
The Sphinx documentation toolchain.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -32,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__ = '3.1.0+'
|
__version__ = '3.5.0+'
|
||||||
__released__ = '3.1.0' # used when Sphinx builds its own docs
|
__released__ = '3.5.0' # used when Sphinx builds its own docs
|
||||||
|
|
||||||
#: Version info for better programmatic use.
|
#: Version info for better programmatic use.
|
||||||
#:
|
#:
|
||||||
@ -43,7 +43,7 @@ __released__ = '3.1.0' # 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 = (3, 1, 0, 'beta', 0)
|
version_info = (3, 5, 0, 'beta', 0)
|
||||||
|
|
||||||
package_dir = path.abspath(path.dirname(__file__))
|
package_dir = path.abspath(path.dirname(__file__))
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
The Sphinx documentation toolchain.
|
The Sphinx documentation toolchain.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Additional docutils nodes.
|
Additional docutils nodes.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -21,6 +21,33 @@ if False:
|
|||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
|
|
||||||
|
|
||||||
|
class document(nodes.document):
|
||||||
|
"""The document root element patched by Sphinx.
|
||||||
|
|
||||||
|
This fixes that document.set_id() does not support a node having multiple node Ids.
|
||||||
|
see https://sourceforge.net/p/docutils/patches/167/
|
||||||
|
|
||||||
|
.. important:: This is only for Sphinx internal use. Please don't use this
|
||||||
|
in your extensions. It will be removed without deprecation period.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def set_id(self, node: Element, msgnode: Element = None,
|
||||||
|
suggested_prefix: str = '') -> str:
|
||||||
|
from sphinx.util import docutils
|
||||||
|
if docutils.__version_info__ >= (0, 16):
|
||||||
|
ret = super().set_id(node, msgnode, suggested_prefix) # type: ignore
|
||||||
|
else:
|
||||||
|
ret = super().set_id(node, msgnode)
|
||||||
|
|
||||||
|
if docutils.__version_info__ < (0, 17):
|
||||||
|
# register other node IDs forcedly
|
||||||
|
for node_id in node['ids']:
|
||||||
|
if node_id not in self.ids:
|
||||||
|
self.ids[node_id] = node
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class translatable(nodes.Node):
|
class translatable(nodes.Node):
|
||||||
"""Node which supports translation.
|
"""Node which supports translation.
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Gracefully adapted from the TextPress system by Armin.
|
Gracefully adapted from the TextPress system by Armin.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -18,16 +18,17 @@ import warnings
|
|||||||
from collections import deque
|
from collections import deque
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Callable, Dict, IO, List, Tuple, Union
|
from typing import IO, Any, Callable, Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Element, TextElement
|
from docutils.nodes import Element, TextElement
|
||||||
|
from docutils.parsers import Parser
|
||||||
from docutils.parsers.rst import Directive, roles
|
from docutils.parsers.rst import Directive, roles
|
||||||
from docutils.transforms import Transform
|
from docutils.transforms import Transform
|
||||||
from pygments.lexer import Lexer
|
from pygments.lexer import Lexer
|
||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
from sphinx import package_dir, locale
|
from sphinx import locale, package_dir
|
||||||
from sphinx.config import Config
|
from sphinx.config import Config
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.domains import Domain, Index
|
from sphinx.domains import Domain, Index
|
||||||
@ -42,9 +43,7 @@ from sphinx.project import Project
|
|||||||
from sphinx.registry import SphinxComponentRegistry
|
from sphinx.registry import SphinxComponentRegistry
|
||||||
from sphinx.roles import XRefRole
|
from sphinx.roles import XRefRole
|
||||||
from sphinx.theming import Theme
|
from sphinx.theming import Theme
|
||||||
from sphinx.util import docutils
|
from sphinx.util import docutils, logging, progress_message
|
||||||
from sphinx.util import logging
|
|
||||||
from sphinx.util import progress_message
|
|
||||||
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.i18n import CatalogRepository
|
from sphinx.util.i18n import CatalogRepository
|
||||||
@ -55,8 +54,10 @@ from sphinx.util.typing import RoleFunction, TitleGetter
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from docutils.nodes import Node # NOQA
|
|
||||||
from typing import Type # for python3.5.1
|
from typing import Type # for python3.5.1
|
||||||
|
|
||||||
|
from docutils.nodes import Node # NOQA
|
||||||
|
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
|
|
||||||
|
|
||||||
@ -134,7 +135,7 @@ class Sphinx:
|
|||||||
:ivar outdir: Directory for storing build documents.
|
:ivar outdir: Directory for storing build documents.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, srcdir: str, confdir: str, outdir: str, doctreedir: str,
|
def __init__(self, srcdir: str, confdir: Optional[str], outdir: str, doctreedir: str,
|
||||||
buildername: str, confoverrides: Dict = None,
|
buildername: str, confoverrides: Dict = None,
|
||||||
status: IO = sys.stdout, warning: IO = sys.stderr,
|
status: IO = sys.stdout, warning: IO = sys.stderr,
|
||||||
freshenv: bool = False, warningiserror: bool = False, tags: List[str] = None,
|
freshenv: bool = False, warningiserror: bool = False, tags: List[str] = None,
|
||||||
@ -165,7 +166,7 @@ class Sphinx:
|
|||||||
|
|
||||||
if path.exists(self.outdir) and not path.isdir(self.outdir):
|
if path.exists(self.outdir) and not path.isdir(self.outdir):
|
||||||
raise ApplicationError(__('Output directory (%s) is not a directory') %
|
raise ApplicationError(__('Output directory (%s) is not a directory') %
|
||||||
self.srcdir)
|
self.outdir)
|
||||||
|
|
||||||
if self.srcdir == self.outdir:
|
if self.srcdir == self.outdir:
|
||||||
raise ApplicationError(__('Source directory and destination '
|
raise ApplicationError(__('Source directory and destination '
|
||||||
@ -293,7 +294,10 @@ class Sphinx:
|
|||||||
if catalog.domain == 'sphinx' and catalog.is_outdated():
|
if catalog.domain == 'sphinx' and catalog.is_outdated():
|
||||||
catalog.write_mo(self.config.language)
|
catalog.write_mo(self.config.language)
|
||||||
|
|
||||||
locale_dirs = [None, path.join(package_dir, 'locale')] + list(repo.locale_dirs)
|
locale_dirs = list(repo.locale_dirs) # type: List[Optional[str]]
|
||||||
|
locale_dirs += [None]
|
||||||
|
locale_dirs += [path.join(package_dir, 'locale')]
|
||||||
|
|
||||||
self.translator, has_translation = locale.init(locale_dirs, self.config.language)
|
self.translator, has_translation = locale.init(locale_dirs, self.config.language)
|
||||||
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
|
||||||
@ -400,9 +404,10 @@ class Sphinx:
|
|||||||
def require_sphinx(self, version: str) -> None:
|
def require_sphinx(self, version: 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* with the version of the running Sphinx, and abort the
|
||||||
``'1.1'``) with the version of the running Sphinx, and abort the build
|
build when it is too old.
|
||||||
when it is too old.
|
|
||||||
|
:param version: The required version in the form of ``major.minor``.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
"""
|
"""
|
||||||
@ -416,11 +421,11 @@ class Sphinx:
|
|||||||
For details on available core events and the arguments of callback
|
For details on available core events and the arguments of callback
|
||||||
functions, please see :ref:`events`.
|
functions, please see :ref:`events`.
|
||||||
|
|
||||||
Registered callbacks will be invoked on event in the order of *priority* and
|
:param event: The name of target event
|
||||||
registration. The priority is ascending order.
|
:param callback: Callback function for the event
|
||||||
|
:param priority: The priority of the callback. The callbacks will be invoked
|
||||||
The method returns a "listener ID" that can be used as an argument to
|
in the order of *priority* in asending.
|
||||||
:meth:`disconnect`.
|
:return: A listener ID. It can be used for :meth:`disconnect`.
|
||||||
|
|
||||||
.. versionchanged:: 3.0
|
.. versionchanged:: 3.0
|
||||||
|
|
||||||
@ -432,7 +437,10 @@ class Sphinx:
|
|||||||
return listener_id
|
return listener_id
|
||||||
|
|
||||||
def disconnect(self, listener_id: int) -> None:
|
def disconnect(self, listener_id: int) -> None:
|
||||||
"""Unregister callback by *listener_id*."""
|
"""Unregister callback by *listener_id*.
|
||||||
|
|
||||||
|
:param listener_id: A listener_id that :meth:`connect` returns
|
||||||
|
"""
|
||||||
logger.debug('[app] disconnecting event: [id=%s]', listener_id)
|
logger.debug('[app] disconnecting event: [id=%s]', listener_id)
|
||||||
self.events.disconnect(listener_id)
|
self.events.disconnect(listener_id)
|
||||||
|
|
||||||
@ -443,6 +451,10 @@ class Sphinx:
|
|||||||
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
|
||||||
Sphinx events in extensions!
|
Sphinx events in extensions!
|
||||||
|
|
||||||
|
:param event: The name of event that will be emitted
|
||||||
|
:param args: The arguments for the event
|
||||||
|
:param allowed_exceptions: The list of exceptions that are allowed in the callbacks
|
||||||
|
|
||||||
.. versionchanged:: 3.1
|
.. versionchanged:: 3.1
|
||||||
|
|
||||||
Added *allowed_exceptions* to specify path-through exceptions
|
Added *allowed_exceptions* to specify path-through exceptions
|
||||||
@ -455,6 +467,10 @@ class Sphinx:
|
|||||||
|
|
||||||
Return the result of the first callback that doesn't return ``None``.
|
Return the result of the first callback that doesn't return ``None``.
|
||||||
|
|
||||||
|
:param event: The name of event that will be emitted
|
||||||
|
:param args: The arguments for the event
|
||||||
|
:param allowed_exceptions: The list of exceptions that are allowed in the callbacks
|
||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
.. versionchanged:: 3.1
|
.. versionchanged:: 3.1
|
||||||
|
|
||||||
@ -468,8 +484,9 @@ class Sphinx:
|
|||||||
def add_builder(self, builder: "Type[Builder]", override: bool = False) -> None:
|
def add_builder(self, builder: "Type[Builder]", override: bool = False) -> None:
|
||||||
"""Register a new builder.
|
"""Register a new builder.
|
||||||
|
|
||||||
*builder* must be a class that inherits from
|
:param builder: A builder class
|
||||||
:class:`~sphinx.builders.Builder`.
|
:param override: If true, install the builder forcedly even if another builder
|
||||||
|
is already installed as the same name
|
||||||
|
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
@ -493,6 +510,10 @@ class Sphinx:
|
|||||||
documents.
|
documents.
|
||||||
* ``''`` if a change in the setting will not need any special rebuild.
|
* ``''`` if a change in the setting will not need any special rebuild.
|
||||||
|
|
||||||
|
The *types* value takes a list of types that describes the type of
|
||||||
|
configuration value. For example, ``[str]`` is used to describe a
|
||||||
|
configuration that takes string value.
|
||||||
|
|
||||||
.. versionchanged:: 0.6
|
.. versionchanged:: 0.6
|
||||||
Changed *rebuild* from a simple boolean (equivalent to ``''`` or
|
Changed *rebuild* from a simple boolean (equivalent to ``''`` or
|
||||||
``'env'``) to a string. However, booleans are still accepted and
|
``'env'``) to a string. However, booleans are still accepted and
|
||||||
@ -526,6 +547,11 @@ class Sphinx:
|
|||||||
builtin translator. This allows extensions to use custom translator
|
builtin translator. This allows extensions to use custom translator
|
||||||
and define custom nodes for the translator (see :meth:`add_node`).
|
and define custom nodes for the translator (see :meth:`add_node`).
|
||||||
|
|
||||||
|
:param name: The name of builder for the translator
|
||||||
|
:param translator_class: A translator class
|
||||||
|
:param override: If true, install the translator forcedly even if another translator
|
||||||
|
is already installed as the same name
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
@ -560,6 +586,9 @@ class Sphinx:
|
|||||||
Obviously, translators for which you don't specify visitor methods will
|
Obviously, translators for which you don't specify visitor methods will
|
||||||
choke on the node when encountered in a document to translate.
|
choke on the node when encountered in a document to translate.
|
||||||
|
|
||||||
|
If *override* is True, the given *node* is forcedly installed even if
|
||||||
|
a node having the same name is already installed.
|
||||||
|
|
||||||
.. versionchanged:: 0.5
|
.. versionchanged:: 0.5
|
||||||
Added the support for keyword arguments giving visit functions.
|
Added the support for keyword arguments giving visit functions.
|
||||||
"""
|
"""
|
||||||
@ -595,6 +624,9 @@ class Sphinx:
|
|||||||
Other keyword arguments are used for node visitor functions. See the
|
Other keyword arguments are used for node visitor functions. See the
|
||||||
:meth:`.Sphinx.add_node` for details.
|
:meth:`.Sphinx.add_node` for details.
|
||||||
|
|
||||||
|
If *override* is True, the given *node* is forcedly installed even if
|
||||||
|
a node having the same name is already installed.
|
||||||
|
|
||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
"""
|
"""
|
||||||
self.registry.add_enumerable_node(node, figtype, title_getter, override=override)
|
self.registry.add_enumerable_node(node, figtype, title_getter, override=override)
|
||||||
@ -603,19 +635,19 @@ class Sphinx:
|
|||||||
def add_directive(self, name: str, cls: "Type[Directive]", override: bool = False) -> None:
|
def add_directive(self, name: str, cls: "Type[Directive]", override: bool = False) -> None:
|
||||||
"""Register a Docutils directive.
|
"""Register a Docutils directive.
|
||||||
|
|
||||||
*name* must be the prospective directive name. *cls* is a directive
|
:param name: The name of directive
|
||||||
class which inherits ``docutils.parsers.rst.Directive``. For more
|
:param cls: A directive class
|
||||||
details, see `the Docutils docs
|
:param override: If true, install the directive forcedly even if another directive
|
||||||
<http://docutils.sourceforge.net/docs/howto/rst-directives.html>`_ .
|
is already installed as the same name
|
||||||
|
|
||||||
For example, the (already existing) :rst:dir:`literalinclude` directive
|
For example, a custom directive named ``my-directive`` would be added
|
||||||
would be added like this:
|
like this:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from docutils.parsers.rst import Directive, directives
|
from docutils.parsers.rst import Directive, directives
|
||||||
|
|
||||||
class LiteralIncludeDirective(Directive):
|
class MyDirective(Directive):
|
||||||
has_content = True
|
has_content = True
|
||||||
required_arguments = 1
|
required_arguments = 1
|
||||||
optional_arguments = 0
|
optional_arguments = 0
|
||||||
@ -628,7 +660,11 @@ class Sphinx:
|
|||||||
def run(self):
|
def run(self):
|
||||||
...
|
...
|
||||||
|
|
||||||
add_directive('literalinclude', LiteralIncludeDirective)
|
def setup(app):
|
||||||
|
add_directive('my-directive', MyDirective)
|
||||||
|
|
||||||
|
For more details, see `the Docutils docs
|
||||||
|
<http://docutils.sourceforge.net/docs/howto/rst-directives.html>`__ .
|
||||||
|
|
||||||
.. versionchanged:: 0.6
|
.. versionchanged:: 0.6
|
||||||
Docutils 0.5-style directive classes are now supported.
|
Docutils 0.5-style directive classes are now supported.
|
||||||
@ -647,10 +683,13 @@ class Sphinx:
|
|||||||
def add_role(self, name: str, role: Any, override: bool = False) -> None:
|
def add_role(self, name: str, role: Any, override: bool = False) -> None:
|
||||||
"""Register a Docutils role.
|
"""Register a Docutils role.
|
||||||
|
|
||||||
*name* must be the role name that occurs in the source, *role* the role
|
:param name: The name of role
|
||||||
function. Refer to the `Docutils documentation
|
:param cls: A role function
|
||||||
<http://docutils.sourceforge.net/docs/howto/rst-roles.html>`_ for
|
:param override: If true, install the role forcedly even if another role is already
|
||||||
more information.
|
installed as the same name
|
||||||
|
|
||||||
|
For more details about role functions, see `the Docutils docs
|
||||||
|
<http://docutils.sourceforge.net/docs/howto/rst-roles.html>`__ .
|
||||||
|
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
@ -667,6 +706,9 @@ class Sphinx:
|
|||||||
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
|
||||||
node given by *nodeclass*.
|
node given by *nodeclass*.
|
||||||
|
|
||||||
|
If *override* is True, the given *nodeclass* is forcedly installed even if
|
||||||
|
a role named as *name* is already installed.
|
||||||
|
|
||||||
.. versionadded:: 0.6
|
.. versionadded:: 0.6
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
@ -686,6 +728,9 @@ class Sphinx:
|
|||||||
Make the given *domain* (which must be a class; more precisely, a
|
Make the given *domain* (which must be a class; more precisely, a
|
||||||
subclass of :class:`~sphinx.domains.Domain`) known to Sphinx.
|
subclass of :class:`~sphinx.domains.Domain`) known to Sphinx.
|
||||||
|
|
||||||
|
If *override* is True, the given *domain* is forcedly installed even if
|
||||||
|
a domain having the same name is already installed.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
@ -699,6 +744,9 @@ class Sphinx:
|
|||||||
Like :meth:`add_directive`, but the directive is added to the domain
|
Like :meth:`add_directive`, but the directive is added to the domain
|
||||||
named *domain*.
|
named *domain*.
|
||||||
|
|
||||||
|
If *override* is True, the given *directive* is forcedly installed even if
|
||||||
|
a directive named as *name* is already installed.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
@ -712,6 +760,9 @@ class Sphinx:
|
|||||||
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
|
||||||
*domain*.
|
*domain*.
|
||||||
|
|
||||||
|
If *override* is True, the given *role* is forcedly installed even if
|
||||||
|
a role named as *name* is already installed.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
@ -725,6 +776,9 @@ class Sphinx:
|
|||||||
Add a custom *index* class to the domain named *domain*. *index* must
|
Add a custom *index* class to the domain named *domain*. *index* must
|
||||||
be a subclass of :class:`~sphinx.domains.Index`.
|
be a subclass of :class:`~sphinx.domains.Index`.
|
||||||
|
|
||||||
|
If *override* is True, the given *index* is forcedly installed even if
|
||||||
|
an index having the same name is already installed.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
@ -788,6 +842,9 @@ class Sphinx:
|
|||||||
For the role content, you have the same syntactical possibilities as
|
For the role content, you have the same syntactical possibilities as
|
||||||
for standard Sphinx roles (see :ref:`xref-syntax`).
|
for standard Sphinx roles (see :ref:`xref-syntax`).
|
||||||
|
|
||||||
|
If *override* is True, the given object_type is forcedly installed even if
|
||||||
|
an object_type having the same name is already installed.
|
||||||
|
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
"""
|
"""
|
||||||
@ -824,6 +881,9 @@ class Sphinx:
|
|||||||
(Of course, the element following the ``topic`` directive needn't be a
|
(Of course, the element following the ``topic`` directive needn't be a
|
||||||
section.)
|
section.)
|
||||||
|
|
||||||
|
If *override* is True, the given crossref_type is forcedly installed even if
|
||||||
|
a crossref_type having the same name is already installed.
|
||||||
|
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
"""
|
"""
|
||||||
@ -873,22 +933,24 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_post_transform(transform)
|
self.registry.add_post_transform(transform)
|
||||||
|
|
||||||
def add_javascript(self, filename: str, **kwargs: str) -> None:
|
def add_javascript(self, filename: str, **kwargs: Any) -> 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.',
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
self.add_js_file(filename, **kwargs)
|
self.add_js_file(filename, **kwargs)
|
||||||
|
|
||||||
def add_js_file(self, filename: str, **kwargs: str) -> None:
|
def add_js_file(self, filename: str, priority: int = 500, **kwargs: Any) -> 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
|
||||||
template will include. The filename must be relative to the HTML
|
template will include in order of *priority* (ascending). The filename
|
||||||
static path , or a full URI with scheme. If the keyword argument
|
must be relative to the HTML static path , or a full URI with scheme.
|
||||||
``body`` is given, its value will be added between the
|
If the priority of JavaScript file is the same as others, the JavaScript
|
||||||
``<script>`` tags. Extra keyword arguments are included as
|
files will be included in order of the registration. If the keyword
|
||||||
attributes of the ``<script>`` tag.
|
argument ``body`` is given, its value will be added between the
|
||||||
|
``<script>`` tags. Extra keyword arguments are included as attributes of
|
||||||
|
the ``<script>`` tag.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
@ -901,23 +963,43 @@ class Sphinx:
|
|||||||
app.add_js_file(None, body="var myVariable = 'foo';")
|
app.add_js_file(None, body="var myVariable = 'foo';")
|
||||||
# => <script>var myVariable = 'foo';</script>
|
# => <script>var myVariable = 'foo';</script>
|
||||||
|
|
||||||
|
.. list-table:: priority range for JavaScript files
|
||||||
|
:widths: 20,80
|
||||||
|
|
||||||
|
* - Priority
|
||||||
|
- Main purpose in Sphinx
|
||||||
|
* - 200
|
||||||
|
- default priority for built-in JavaScript files
|
||||||
|
* - 500
|
||||||
|
- default priority for extensions
|
||||||
|
* - 800
|
||||||
|
- default priority for :confval:`html_js_files`
|
||||||
|
|
||||||
|
A JavaScript file can be added to the specific HTML page when on extension
|
||||||
|
calls this method on :event:`html-page-context` event.
|
||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
|
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Renamed from ``app.add_javascript()``.
|
Renamed from ``app.add_javascript()``.
|
||||||
And it allows keyword arguments as attributes of script tag.
|
And it allows keyword arguments as attributes of script tag.
|
||||||
"""
|
|
||||||
self.registry.add_js_file(filename, **kwargs)
|
|
||||||
if hasattr(self.builder, 'add_js_file'):
|
|
||||||
self.builder.add_js_file(filename, **kwargs) # type: ignore
|
|
||||||
|
|
||||||
def add_css_file(self, filename: str, **kwargs: str) -> None:
|
.. versionchanged:: 3.5
|
||||||
|
Take priority argument. Allow to add a JavaScript file to the specific page.
|
||||||
|
"""
|
||||||
|
self.registry.add_js_file(filename, priority=priority, **kwargs)
|
||||||
|
if hasattr(self.builder, 'add_js_file'):
|
||||||
|
self.builder.add_js_file(filename, priority=priority, **kwargs) # type: ignore
|
||||||
|
|
||||||
|
def add_css_file(self, filename: str, priority: int = 500, **kwargs: Any) -> 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
|
||||||
will include. The filename must be relative to the HTML static path,
|
will include in order of *priority* (ascending). The filename must be
|
||||||
or a full URI with scheme. The keyword arguments are also accepted for
|
relative to the HTML static path, or a full URI with scheme. If the
|
||||||
attributes of ``<link>`` tag.
|
priority of CSS file is the same as others, the CSS files will be
|
||||||
|
included in order of the registration. The keyword arguments are also
|
||||||
|
accepted for attributes of ``<link>`` tag.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
@ -932,6 +1014,19 @@ class Sphinx:
|
|||||||
# => <link rel="alternate stylesheet" href="_static/fancy.css"
|
# => <link rel="alternate stylesheet" href="_static/fancy.css"
|
||||||
# type="text/css" title="fancy" />
|
# type="text/css" title="fancy" />
|
||||||
|
|
||||||
|
.. list-table:: priority range for CSS files
|
||||||
|
:widths: 20,80
|
||||||
|
|
||||||
|
* - Priority
|
||||||
|
- Main purpose in Sphinx
|
||||||
|
* - 500
|
||||||
|
- default priority for extensions
|
||||||
|
* - 800
|
||||||
|
- default priority for :confval:`html_css_files`
|
||||||
|
|
||||||
|
A CSS file can be added to the specific HTML page when on extension calls
|
||||||
|
this method on :event:`html-page-context` event.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
|
|
||||||
.. versionchanged:: 1.6
|
.. versionchanged:: 1.6
|
||||||
@ -944,11 +1039,14 @@ class Sphinx:
|
|||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Renamed from ``app.add_stylesheet()``.
|
Renamed from ``app.add_stylesheet()``.
|
||||||
And it allows keyword arguments as attributes of link tag.
|
And it allows keyword arguments as attributes of link tag.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.5
|
||||||
|
Take priority argument. Allow to add a CSS file to the specific page.
|
||||||
"""
|
"""
|
||||||
logger.debug('[app] adding stylesheet: %r', filename)
|
logger.debug('[app] adding stylesheet: %r', filename)
|
||||||
self.registry.add_css_files(filename, **kwargs)
|
self.registry.add_css_files(filename, priority=priority, **kwargs)
|
||||||
if hasattr(self.builder, 'add_css_file'):
|
if hasattr(self.builder, 'add_css_file'):
|
||||||
self.builder.add_css_file(filename, **kwargs) # type: ignore
|
self.builder.add_css_file(filename, priority=priority, **kwargs) # type: ignore
|
||||||
|
|
||||||
def add_stylesheet(self, filename: str, alternate: bool = False, title: str = None
|
def add_stylesheet(self, filename: str, alternate: bool = False, title: str = None
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -957,7 +1055,7 @@ class Sphinx:
|
|||||||
'Please use app.add_css_file() instead.',
|
'Please use app.add_css_file() instead.',
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
|
||||||
attributes = {} # type: Dict[str, str]
|
attributes = {} # type: Dict[str, Any]
|
||||||
if alternate:
|
if alternate:
|
||||||
attributes['rel'] = 'alternate stylesheet'
|
attributes['rel'] = 'alternate stylesheet'
|
||||||
else:
|
else:
|
||||||
@ -1004,7 +1102,7 @@ class Sphinx:
|
|||||||
logger.debug('[app] adding lexer: %r', (alias, lexer))
|
logger.debug('[app] adding lexer: %r', (alias, lexer))
|
||||||
if isinstance(lexer, Lexer):
|
if isinstance(lexer, Lexer):
|
||||||
warnings.warn('app.add_lexer() API changed; '
|
warnings.warn('app.add_lexer() API changed; '
|
||||||
'Please give lexer class instead instance',
|
'Please give lexer class instead of instance',
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
lexers[alias] = lexer
|
lexers[alias] = lexer
|
||||||
else:
|
else:
|
||||||
@ -1019,6 +1117,9 @@ class Sphinx:
|
|||||||
new types of objects. See the source of the autodoc module for
|
new types of objects. See the source of the autodoc module for
|
||||||
examples on how to subclass :class:`Documenter`.
|
examples on how to subclass :class:`Documenter`.
|
||||||
|
|
||||||
|
If *override* is True, the given *cls* is forcedly installed even if
|
||||||
|
a documenter having the same name is already installed.
|
||||||
|
|
||||||
.. todo:: Add real docs for Documenter and subclassing
|
.. todo:: Add real docs for Documenter and subclassing
|
||||||
|
|
||||||
.. versionadded:: 0.6
|
.. versionadded:: 0.6
|
||||||
@ -1057,7 +1158,7 @@ class Sphinx:
|
|||||||
.. versionadded:: 1.1
|
.. versionadded:: 1.1
|
||||||
"""
|
"""
|
||||||
logger.debug('[app] adding search language: %r', cls)
|
logger.debug('[app] adding search language: %r', cls)
|
||||||
from sphinx.search import languages, SearchLanguage
|
from sphinx.search import SearchLanguage, languages
|
||||||
assert issubclass(cls, SearchLanguage)
|
assert issubclass(cls, SearchLanguage)
|
||||||
languages[cls.lang] = cls
|
languages[cls.lang] = cls
|
||||||
|
|
||||||
@ -1067,13 +1168,19 @@ class Sphinx:
|
|||||||
Same as :confval:`source_suffix`. The users can override this
|
Same as :confval:`source_suffix`. The users can override this
|
||||||
using the setting.
|
using the setting.
|
||||||
|
|
||||||
|
If *override* is True, the given *suffix* is forcedly installed even if
|
||||||
|
a same suffix is already installed.
|
||||||
|
|
||||||
.. versionadded:: 1.8
|
.. versionadded:: 1.8
|
||||||
"""
|
"""
|
||||||
self.registry.add_source_suffix(suffix, filetype, override=override)
|
self.registry.add_source_suffix(suffix, filetype, override=override)
|
||||||
|
|
||||||
def add_source_parser(self, *args: Any, **kwargs: Any) -> None:
|
def add_source_parser(self, parser: "Type[Parser]", override: bool = False) -> None:
|
||||||
"""Register a parser class.
|
"""Register a parser class.
|
||||||
|
|
||||||
|
If *override* is True, the given *parser* is forcedly installed even if
|
||||||
|
a parser for the same suffix is already installed.
|
||||||
|
|
||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
*suffix* argument is deprecated. It only accepts *parser* argument.
|
*suffix* argument is deprecated. It only accepts *parser* argument.
|
||||||
@ -1081,7 +1188,7 @@ class Sphinx:
|
|||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
Add *override* keyword.
|
Add *override* keyword.
|
||||||
"""
|
"""
|
||||||
self.registry.add_source_parser(*args, **kwargs)
|
self.registry.add_source_parser(parser, override=override)
|
||||||
|
|
||||||
def add_env_collector(self, collector: "Type[EnvironmentCollector]") -> None:
|
def add_env_collector(self, collector: "Type[EnvironmentCollector]") -> None:
|
||||||
"""Register an environment collector class.
|
"""Register an environment collector class.
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Builder superclass for all builders.
|
Builder superclass for all builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -17,26 +17,24 @@ from docutils import nodes
|
|||||||
from docutils.nodes import Node
|
from docutils.nodes import Node
|
||||||
|
|
||||||
from sphinx.config import Config
|
from sphinx.config import Config
|
||||||
from sphinx.environment import BuildEnvironment, CONFIG_OK, CONFIG_CHANGED_REASON
|
from sphinx.environment import CONFIG_CHANGED_REASON, CONFIG_OK, BuildEnvironment
|
||||||
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.events import EventManager
|
from sphinx.events import EventManager
|
||||||
from sphinx.io import read_doc
|
from sphinx.io import read_doc
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import import_object, logging, rst, progress_message, status_iterator
|
from sphinx.util import import_object, logging, progress_message, rst, 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
|
||||||
from sphinx.util.i18n import CatalogInfo, CatalogRepository, docname_to_domain
|
from sphinx.util.i18n import CatalogInfo, CatalogRepository, docname_to_domain
|
||||||
from sphinx.util.osutil import SEP, ensuredir, relative_uri, relpath
|
from sphinx.util.osutil import SEP, ensuredir, relative_uri, relpath
|
||||||
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, \
|
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, parallel_available
|
||||||
parallel_available
|
|
||||||
from sphinx.util.tags import Tags
|
from sphinx.util.tags import Tags
|
||||||
|
|
||||||
# side effect: registers roles and directives
|
# side effect: registers roles and directives
|
||||||
from sphinx import roles # noqa
|
from sphinx import directives # NOQA isort:skip
|
||||||
from sphinx import directives # noqa
|
from sphinx import roles # NOQA isort:skip
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -45,6 +43,7 @@ except ImportError:
|
|||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Type # for python3.5.1
|
from typing import Type # for python3.5.1
|
||||||
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Base class of epub2/epub3 builders.
|
Base class of epub2/epub3 builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -25,11 +25,10 @@ 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.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging, status_iterator
|
||||||
from sphinx.util import status_iterator
|
|
||||||
from sphinx.util.fileutil import copy_asset_file
|
from sphinx.util.fileutil import copy_asset_file
|
||||||
from sphinx.util.i18n import format_date
|
from sphinx.util.i18n import format_date
|
||||||
from sphinx.util.osutil import ensuredir, copyfile
|
from sphinx.util.osutil import copyfile, ensuredir
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
@ -208,7 +207,12 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
appeared = set() # type: Set[str]
|
appeared = set() # type: Set[str]
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
if node['refuri'] in appeared:
|
if node['refuri'] in appeared:
|
||||||
logger.warning(__('duplicated ToC entry found: %s'), node['refuri'])
|
logger.warning(
|
||||||
|
__('duplicated ToC entry found: %s'),
|
||||||
|
node['refuri'],
|
||||||
|
type="epub",
|
||||||
|
subtype="duplicated_toc_entry",
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
appeared.add(node['refuri'])
|
appeared.add(node['refuri'])
|
||||||
|
|
||||||
@ -388,7 +392,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
return ext in VECTOR_GRAPHICS_EXTENSIONS
|
return ext in VECTOR_GRAPHICS_EXTENSIONS
|
||||||
|
|
||||||
def copy_image_files_pil(self) -> None:
|
def copy_image_files_pil(self) -> None:
|
||||||
"""Copy images using Pillow, the Python Imaging Libary.
|
"""Copy images using Pillow, the Python Imaging Library.
|
||||||
The method tries to read and write the files with Pillow, converting
|
The method tries to read and write the files with Pillow, converting
|
||||||
the format and resizing the image if necessary/possible.
|
the format and resizing the image if necessary/possible.
|
||||||
"""
|
"""
|
||||||
|
@ -4,30 +4,33 @@
|
|||||||
|
|
||||||
Build Apple help books.
|
Build Apple help books.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
from sphinxcontrib.applehelp import (
|
from sphinxcontrib.applehelp import (AppleHelpBuilder, AppleHelpCodeSigningFailed,
|
||||||
AppleHelpCodeSigningFailed,
|
AppleHelpIndexerFailed)
|
||||||
AppleHelpIndexerFailed,
|
|
||||||
AppleHelpBuilder,
|
|
||||||
)
|
|
||||||
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
|
|
||||||
|
|
||||||
deprecated_alias('sphinx.builders.applehelp',
|
deprecated_alias('sphinx.builders.applehelp',
|
||||||
{
|
{
|
||||||
'AppleHelpCodeSigningFailed': AppleHelpCodeSigningFailed,
|
'AppleHelpCodeSigningFailed': AppleHelpCodeSigningFailed,
|
||||||
'AppleHelpIndexerFailed': AppleHelpIndexerFailed,
|
'AppleHelpIndexerFailed': AppleHelpIndexerFailed,
|
||||||
'AppleHelpBuilder': AppleHelpBuilder,
|
'AppleHelpBuilder': AppleHelpBuilder,
|
||||||
},
|
},
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning,
|
||||||
|
{
|
||||||
|
'AppleHelpCodeSigningFailed':
|
||||||
|
'sphinxcontrib.applehelp.AppleHelpCodeSigningFailed',
|
||||||
|
'AppleHelpIndexerFailed':
|
||||||
|
'sphinxcontrib.applehelp.AppleHelpIndexerFailed',
|
||||||
|
'AppleHelpBuilder': 'sphinxcontrib.applehelp.AppleHelpBuilder',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
|
@ -4,14 +4,13 @@
|
|||||||
|
|
||||||
Changelog builder.
|
Changelog builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import html
|
import html
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, List, Tuple, cast
|
||||||
from typing import cast
|
|
||||||
|
|
||||||
from sphinx import package_dir
|
from sphinx import package_dir
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
@ -24,7 +23,6 @@ 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
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
.. _Devhelp: https://wiki.gnome.org/Apps/Devhelp
|
.. _Devhelp: https://wiki.gnome.org/Apps/Devhelp
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -18,12 +18,14 @@ from sphinxcontrib.devhelp import DevhelpBuilder
|
|||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
|
|
||||||
|
|
||||||
deprecated_alias('sphinx.builders.devhelp',
|
deprecated_alias('sphinx.builders.devhelp',
|
||||||
{
|
{
|
||||||
'DevhelpBuilder': DevhelpBuilder,
|
'DevhelpBuilder': DevhelpBuilder,
|
||||||
},
|
},
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning,
|
||||||
|
{
|
||||||
|
'DevhelpBuilder': 'sphinxcontrib.devhelp.DevhelpBuilder'
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Directory HTML builders.
|
Directory HTML builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -49,9 +49,12 @@ class DirectoryHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
# for compatibility
|
# for compatibility
|
||||||
deprecated_alias('sphinx.builders.html',
|
deprecated_alias('sphinx.builders.html',
|
||||||
{
|
{
|
||||||
'DirectoryHTMLBuilder': DirectoryHTMLBuilder,
|
'DirectoryHTMLBuilder': DirectoryHTMLBuilder,
|
||||||
},
|
},
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning,
|
||||||
|
{
|
||||||
|
'DirectoryHTMLBuilder': 'sphinx.builders.dirhtml.DirectoryHTMLBuilder',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Do syntax checks, but no writing.
|
Do syntax checks, but no writing.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
Build epub3 files.
|
Build epub3 files.
|
||||||
Originally derived from epub.py.
|
Originally derived from epub.py.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ from typing import Any, Dict, List, Set, Tuple
|
|||||||
from sphinx import package_dir
|
from sphinx import package_dir
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import _epub_base
|
from sphinx.builders import _epub_base
|
||||||
from sphinx.config import Config, ENUM
|
from sphinx.config import ENUM, Config
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
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
|
||||||
|
@ -4,33 +4,32 @@
|
|||||||
|
|
||||||
The MessageCatalogBuilder class.
|
The MessageCatalogBuilder class.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from codecs import open
|
from codecs import open
|
||||||
from collections import defaultdict, OrderedDict
|
from collections import OrderedDict, defaultdict
|
||||||
from datetime import datetime, tzinfo, timedelta
|
from datetime import datetime, timedelta, tzinfo
|
||||||
from os import path, walk, getenv
|
from os import getenv, path, walk
|
||||||
from time import time
|
from time import time
|
||||||
from typing import Any, Dict, Iterable, Generator, List, Set, Tuple, Union
|
from typing import Any, Dict, Generator, Iterable, List, Set, Tuple, Union
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Element
|
from docutils.nodes import Element
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes, package_dir
|
||||||
from sphinx import package_dir
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
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
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import split_index_msg, logging, status_iterator
|
from sphinx.util import logging, split_index_msg, status_iterator
|
||||||
from sphinx.util.console import bold # type: ignore
|
from sphinx.util.console import bold # type: ignore
|
||||||
from sphinx.util.i18n import CatalogInfo, docname_to_domain
|
from sphinx.util.i18n import CatalogInfo, docname_to_domain
|
||||||
from sphinx.util.nodes import extract_messages, traverse_translatable_index
|
from sphinx.util.nodes import extract_messages, traverse_translatable_index
|
||||||
from sphinx.util.osutil import ensuredir, canon_path, relpath
|
from sphinx.util.osutil import canon_path, ensuredir, relpath
|
||||||
from sphinx.util.tags import Tags
|
from sphinx.util.tags import Tags
|
||||||
from sphinx.util.template import SphinxRenderer
|
from sphinx.util.template import SphinxRenderer
|
||||||
|
|
||||||
@ -278,7 +277,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
origin = MsgOrigin(template, line)
|
origin = MsgOrigin(template, line)
|
||||||
self.catalogs['sphinx'].add(msg, origin)
|
self.catalogs['sphinx'].add(msg, origin)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise ThemeError('%s: %r' % (template, exc))
|
raise ThemeError('%s: %r' % (template, exc)) from exc
|
||||||
|
|
||||||
def build(self, docnames: Iterable[str], summary: str = None, method: str = 'update') -> None: # NOQA
|
def build(self, docnames: Iterable[str], summary: str = None, method: str = 'update') -> None: # NOQA
|
||||||
self._extract_from_template()
|
self._extract_from_template()
|
||||||
@ -316,7 +315,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: 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', {bool, str})
|
||||||
app.add_config_value('gettext_location', True, 'gettext')
|
app.add_config_value('gettext_location', True, 'gettext')
|
||||||
app.add_config_value('gettext_uuid', False, 'gettext')
|
app.add_config_value('gettext_uuid', False, 'gettext')
|
||||||
app.add_config_value('gettext_auto_build', True, 'env')
|
app.add_config_value('gettext_auto_build', True, 'env')
|
||||||
|
@ -4,17 +4,19 @@
|
|||||||
|
|
||||||
Several HTML builders.
|
Several HTML builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import html
|
import html
|
||||||
|
import os
|
||||||
import posixpath
|
import posixpath
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, IO, Iterable, Iterator, List, Set, Tuple
|
from typing import IO, Any, Dict, Iterable, Iterator, List, Set, Tuple
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.core import publish_parts
|
from docutils.core import publish_parts
|
||||||
@ -23,10 +25,10 @@ from docutils.io import DocTreeInput, StringOutput
|
|||||||
from docutils.nodes import Node
|
from docutils.nodes import Node
|
||||||
from docutils.utils import relative_path
|
from docutils.utils import relative_path
|
||||||
|
|
||||||
from sphinx import package_dir, __display_version__
|
from sphinx import __display_version__, package_dir
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.config import Config
|
from sphinx.config import ENUM, Config
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.domains import Domain, Index, IndexEntry
|
from sphinx.domains import Domain, Index, IndexEntry
|
||||||
from sphinx.environment.adapters.asset import ImageAdapter
|
from sphinx.environment.adapters.asset import ImageAdapter
|
||||||
@ -37,15 +39,15 @@ from sphinx.highlighting import PygmentsBridge
|
|||||||
from sphinx.locale import _, __
|
from sphinx.locale import _, __
|
||||||
from sphinx.search import js_index
|
from sphinx.search import js_index
|
||||||
from sphinx.theming import HTMLThemeFactory
|
from sphinx.theming import HTMLThemeFactory
|
||||||
from sphinx.util import logging, progress_message, status_iterator, md5
|
from sphinx.util import logging, md5, progress_message, status_iterator
|
||||||
from sphinx.util.docutils import is_html5_writer_available, new_document
|
from sphinx.util.docutils import is_html5_writer_available, new_document
|
||||||
from sphinx.util.fileutil import copy_asset
|
from sphinx.util.fileutil import copy_asset
|
||||||
from sphinx.util.i18n import format_date
|
from sphinx.util.i18n import format_date
|
||||||
from sphinx.util.inventory import InventoryFile
|
from sphinx.util.inventory import InventoryFile
|
||||||
from sphinx.util.matching import patmatch, Matcher, DOTFILES
|
from sphinx.util.matching import DOTFILES, Matcher, patmatch
|
||||||
from sphinx.util.osutil import os_path, relative_uri, ensuredir, movefile, copyfile
|
from sphinx.util.osutil import copyfile, ensuredir, os_path, relative_uri
|
||||||
from sphinx.util.tags import Tags
|
from sphinx.util.tags import Tags
|
||||||
from sphinx.writers.html import HTMLWriter, HTMLTranslator
|
from sphinx.writers.html import HTMLTranslator, HTMLWriter
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
@ -88,10 +90,13 @@ class Stylesheet(str):
|
|||||||
|
|
||||||
attributes = None # type: Dict[str, str]
|
attributes = None # type: Dict[str, str]
|
||||||
filename = None # type: str
|
filename = None # type: str
|
||||||
|
priority = None # type: int
|
||||||
|
|
||||||
def __new__(cls, filename: str, *args: str, **attributes: str) -> "Stylesheet":
|
def __new__(cls, filename: str, *args: str, priority: int = 500, **attributes: Any
|
||||||
self = str.__new__(cls, filename) # type: ignore
|
) -> "Stylesheet":
|
||||||
|
self = str.__new__(cls, filename)
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
self.priority = priority
|
||||||
self.attributes = attributes
|
self.attributes = attributes
|
||||||
self.attributes.setdefault('rel', 'stylesheet')
|
self.attributes.setdefault('rel', 'stylesheet')
|
||||||
self.attributes.setdefault('type', 'text/css')
|
self.attributes.setdefault('type', 'text/css')
|
||||||
@ -111,10 +116,12 @@ class JavaScript(str):
|
|||||||
|
|
||||||
attributes = None # type: Dict[str, str]
|
attributes = None # type: Dict[str, str]
|
||||||
filename = None # type: str
|
filename = None # type: str
|
||||||
|
priority = None # type: int
|
||||||
|
|
||||||
def __new__(cls, filename: str, **attributes: str) -> "JavaScript":
|
def __new__(cls, filename: str, priority: int = 500, **attributes: str) -> "JavaScript":
|
||||||
self = str.__new__(cls, filename) # type: ignore
|
self = str.__new__(cls, filename)
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
self.priority = priority
|
||||||
self.attributes = attributes
|
self.attributes = attributes
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -140,7 +147,7 @@ class BuildInfo:
|
|||||||
build_info.tags_hash = lines[3].split()[1].strip()
|
build_info.tags_hash = lines[3].split()[1].strip()
|
||||||
return build_info
|
return build_info
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise ValueError(__('build info file is broken: %r') % exc)
|
raise ValueError(__('build info file is broken: %r') % exc) from exc
|
||||||
|
|
||||||
def __init__(self, config: Config = None, tags: Tags = None, config_categories: List[str] = []) -> None: # NOQA
|
def __init__(self, config: Config = None, tags: Tags = None, config_categories: List[str] = []) -> None: # NOQA
|
||||||
self.config_hash = ''
|
self.config_hash = ''
|
||||||
@ -288,30 +295,31 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
self.add_css_file(filename, **attrs)
|
self.add_css_file(filename, **attrs)
|
||||||
|
|
||||||
for filename, attrs in self.get_builder_config('css_files', 'html'):
|
for filename, attrs in self.get_builder_config('css_files', 'html'):
|
||||||
|
attrs.setdefault('priority', 800) # User's CSSs are loaded after extensions'
|
||||||
self.add_css_file(filename, **attrs)
|
self.add_css_file(filename, **attrs)
|
||||||
|
|
||||||
def add_css_file(self, filename: str, **kwargs: str) -> None:
|
def add_css_file(self, filename: str, **kwargs: Any) -> None:
|
||||||
if '://' not in filename:
|
if '://' not in filename:
|
||||||
filename = posixpath.join('_static', filename)
|
filename = posixpath.join('_static', filename)
|
||||||
|
|
||||||
self.css_files.append(Stylesheet(filename, **kwargs)) # type: ignore
|
self.css_files.append(Stylesheet(filename, **kwargs)) # type: ignore
|
||||||
|
|
||||||
def init_js_files(self) -> None:
|
def init_js_files(self) -> None:
|
||||||
self.add_js_file('jquery.js')
|
self.add_js_file('jquery.js', priority=200)
|
||||||
self.add_js_file('underscore.js')
|
self.add_js_file('underscore.js', priority=200)
|
||||||
self.add_js_file('doctools.js')
|
self.add_js_file('doctools.js', priority=200)
|
||||||
self.add_js_file('language_data.js')
|
|
||||||
|
|
||||||
for filename, attrs in self.app.registry.js_files:
|
for filename, attrs in self.app.registry.js_files:
|
||||||
self.add_js_file(filename, **attrs)
|
self.add_js_file(filename, **attrs)
|
||||||
|
|
||||||
for filename, attrs in self.get_builder_config('js_files', 'html'):
|
for filename, attrs in self.get_builder_config('js_files', 'html'):
|
||||||
|
attrs.setdefault('priority', 800) # User's JSs are loaded after extensions'
|
||||||
self.add_js_file(filename, **attrs)
|
self.add_js_file(filename, **attrs)
|
||||||
|
|
||||||
if self.config.language and self._get_translations_js():
|
if self.config.language and self._get_translations_js():
|
||||||
self.add_js_file('translations.js')
|
self.add_js_file('translations.js')
|
||||||
|
|
||||||
def add_js_file(self, filename: str, **kwargs: str) -> None:
|
def add_js_file(self, filename: str, **kwargs: Any) -> None:
|
||||||
if filename and '://' not in filename:
|
if filename and '://' not in filename:
|
||||||
filename = posixpath.join('_static', filename)
|
filename = posixpath.join('_static', filename)
|
||||||
|
|
||||||
@ -447,9 +455,6 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
logo = path.basename(self.config.html_logo) if self.config.html_logo else ''
|
logo = path.basename(self.config.html_logo) if self.config.html_logo else ''
|
||||||
favicon = path.basename(self.config.html_favicon) if self.config.html_favicon else ''
|
favicon = path.basename(self.config.html_favicon) if self.config.html_favicon else ''
|
||||||
|
|
||||||
if not isinstance(self.config.html_use_opensearch, str):
|
|
||||||
logger.warning(__('html_use_opensearch config value must now be a string'))
|
|
||||||
|
|
||||||
self.relations = self.env.collect_relations()
|
self.relations = self.env.collect_relations()
|
||||||
|
|
||||||
rellinks = [] # type: List[Tuple[str, str, str, str]]
|
rellinks = [] # type: List[Tuple[str, str, str, str]]
|
||||||
@ -461,6 +466,10 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
rellinks.append((indexname, indexcls.localname,
|
rellinks.append((indexname, indexcls.localname,
|
||||||
'', indexcls.shortname))
|
'', indexcls.shortname))
|
||||||
|
|
||||||
|
# back up script_files and css_files to allow adding JS/CSS files to a specific page.
|
||||||
|
self._script_files = list(self.script_files)
|
||||||
|
self._css_files = list(self.css_files)
|
||||||
|
|
||||||
if self.config.html_style is not None:
|
if self.config.html_style is not None:
|
||||||
stylename = self.config.html_style
|
stylename = self.config.html_style
|
||||||
elif self.theme:
|
elif self.theme:
|
||||||
@ -640,17 +649,17 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
def gen_additional_pages(self) -> None:
|
def gen_additional_pages(self) -> None:
|
||||||
# additional pages from conf.py
|
# additional pages from conf.py
|
||||||
for pagename, template in self.config.html_additional_pages.items():
|
for pagename, template in self.config.html_additional_pages.items():
|
||||||
logger.info(' ' + pagename, nonl=True)
|
logger.info(pagename + ' ', nonl=True)
|
||||||
self.handle_page(pagename, {}, template)
|
self.handle_page(pagename, {}, template)
|
||||||
|
|
||||||
# the search page
|
# the search page
|
||||||
if self.search:
|
if self.search:
|
||||||
logger.info(' search', nonl=True)
|
logger.info('search ', nonl=True)
|
||||||
self.handle_page('search', {}, 'search.html')
|
self.handle_page('search', {}, 'search.html')
|
||||||
|
|
||||||
# the opensearch xml file
|
# the opensearch xml file
|
||||||
if self.config.html_use_opensearch and self.search:
|
if self.config.html_use_opensearch and self.search:
|
||||||
logger.info(' opensearch', nonl=True)
|
logger.info('opensearch ', nonl=True)
|
||||||
fn = path.join(self.outdir, '_static', 'opensearch.xml')
|
fn = path.join(self.outdir, '_static', 'opensearch.xml')
|
||||||
self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn)
|
self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn)
|
||||||
|
|
||||||
@ -668,7 +677,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
'genindexcounts': indexcounts,
|
'genindexcounts': indexcounts,
|
||||||
'split_index': self.config.html_split_index,
|
'split_index': self.config.html_split_index,
|
||||||
}
|
}
|
||||||
logger.info(' genindex', nonl=True)
|
logger.info('genindex ', nonl=True)
|
||||||
|
|
||||||
if self.config.html_split_index:
|
if self.config.html_split_index:
|
||||||
self.handle_page('genindex', genindexcontext,
|
self.handle_page('genindex', genindexcontext,
|
||||||
@ -690,7 +699,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
'content': content,
|
'content': content,
|
||||||
'collapse_index': collapse,
|
'collapse_index': collapse,
|
||||||
}
|
}
|
||||||
logger.info(' ' + indexname, nonl=True)
|
logger.info(indexname + ' ', nonl=True)
|
||||||
self.handle_page(indexname, indexcontext, 'domainindex.html')
|
self.handle_page(indexname, indexcontext, 'domainindex.html')
|
||||||
|
|
||||||
def copy_image_files(self) -> None:
|
def copy_image_files(self) -> None:
|
||||||
@ -750,18 +759,27 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
copyfile(jsfile, path.join(self.outdir, '_static', '_stemmer.js'))
|
copyfile(jsfile, path.join(self.outdir, '_static', '_stemmer.js'))
|
||||||
|
|
||||||
def copy_theme_static_files(self, context: Dict) -> None:
|
def copy_theme_static_files(self, context: Dict) -> None:
|
||||||
|
def onerror(filename: str, error: Exception) -> None:
|
||||||
|
logger.warning(__('Failed to copy a file in html_static_file: %s: %r'),
|
||||||
|
filename, error)
|
||||||
|
|
||||||
if self.theme:
|
if self.theme:
|
||||||
for entry in self.theme.get_theme_dirs()[::-1]:
|
for entry in self.theme.get_theme_dirs()[::-1]:
|
||||||
copy_asset(path.join(entry, 'static'),
|
copy_asset(path.join(entry, 'static'),
|
||||||
path.join(self.outdir, '_static'),
|
path.join(self.outdir, '_static'),
|
||||||
excluded=DOTFILES, context=context, renderer=self.templates)
|
excluded=DOTFILES, context=context,
|
||||||
|
renderer=self.templates, onerror=onerror)
|
||||||
|
|
||||||
def copy_html_static_files(self, context: Dict) -> None:
|
def copy_html_static_files(self, context: Dict) -> None:
|
||||||
|
def onerror(filename: str, error: Exception) -> None:
|
||||||
|
logger.warning(__('Failed to copy a file in html_static_file: %s: %r'),
|
||||||
|
filename, error)
|
||||||
|
|
||||||
excluded = Matcher(self.config.exclude_patterns + ["**/.*"])
|
excluded = Matcher(self.config.exclude_patterns + ["**/.*"])
|
||||||
for entry in self.config.html_static_path:
|
for entry in self.config.html_static_path:
|
||||||
copy_asset(path.join(self.confdir, entry),
|
copy_asset(path.join(self.confdir, entry),
|
||||||
path.join(self.outdir, '_static'),
|
path.join(self.outdir, '_static'),
|
||||||
excluded, context=context, renderer=self.templates)
|
excluded, context=context, renderer=self.templates, onerror=onerror)
|
||||||
|
|
||||||
def copy_html_logo(self) -> None:
|
def copy_html_logo(self) -> None:
|
||||||
if self.config.html_logo:
|
if self.config.html_logo:
|
||||||
@ -775,7 +793,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
|
|
||||||
def copy_static_files(self) -> None:
|
def copy_static_files(self) -> None:
|
||||||
try:
|
try:
|
||||||
with progress_message(__('copying static files... ')):
|
with progress_message(__('copying static files')):
|
||||||
ensuredir(path.join(self.outdir, '_static'))
|
ensuredir(path.join(self.outdir, '_static'))
|
||||||
|
|
||||||
# prepare context for templates
|
# prepare context for templates
|
||||||
@ -886,6 +904,8 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str:
|
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str:
|
||||||
if 'includehidden' not in kwargs:
|
if 'includehidden' not in kwargs:
|
||||||
kwargs['includehidden'] = False
|
kwargs['includehidden'] = False
|
||||||
|
if kwargs.get('maxdepth') == '':
|
||||||
|
kwargs.pop('maxdepth')
|
||||||
return self.render_partial(TocTree(self.env).get_toctree_for(
|
return self.render_partial(TocTree(self.env).get_toctree_for(
|
||||||
docname, self, collapse, **kwargs))['fragment']
|
docname, self, collapse, **kwargs))['fragment']
|
||||||
|
|
||||||
@ -945,7 +965,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
# --------- these are overwritten by the serialization builder
|
# --------- these are overwritten by the serialization builder
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
return docname + self.link_suffix
|
return quote(docname) + self.link_suffix
|
||||||
|
|
||||||
def handle_page(self, pagename: str, addctx: Dict, templatename: str = 'page.html',
|
def handle_page(self, pagename: str, addctx: Dict, templatename: str = 'page.html',
|
||||||
outfilename: str = None, event_arg: Any = None) -> None:
|
outfilename: str = None, event_arg: Any = None) -> None:
|
||||||
@ -1000,12 +1020,20 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
self.add_sidebars(pagename, ctx)
|
self.add_sidebars(pagename, ctx)
|
||||||
ctx.update(addctx)
|
ctx.update(addctx)
|
||||||
|
|
||||||
|
# revert script_files and css_files
|
||||||
|
self.script_files[:] = self._script_files
|
||||||
|
self.css_files[:] = self.css_files
|
||||||
|
|
||||||
self.update_page_context(pagename, templatename, ctx, event_arg)
|
self.update_page_context(pagename, templatename, ctx, event_arg)
|
||||||
newtmpl = self.app.emit_firstresult('html-page-context', pagename,
|
newtmpl = self.app.emit_firstresult('html-page-context', pagename,
|
||||||
templatename, ctx, event_arg)
|
templatename, ctx, event_arg)
|
||||||
if newtmpl:
|
if newtmpl:
|
||||||
templatename = newtmpl
|
templatename = newtmpl
|
||||||
|
|
||||||
|
# sort JS/CSS before rendering HTML
|
||||||
|
ctx['script_files'].sort(key=lambda js: js.priority)
|
||||||
|
ctx['css_files'].sort(key=lambda js: js.priority)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
output = self.templates.render(templatename, ctx)
|
output = self.templates.render(templatename, ctx)
|
||||||
except UnicodeError:
|
except UnicodeError:
|
||||||
@ -1015,7 +1043,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
return
|
return
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise ThemeError(__("An error happened in rendering the page %s.\nReason: %r") %
|
raise ThemeError(__("An error happened in rendering the page %s.\nReason: %r") %
|
||||||
(pagename, exc))
|
(pagename, exc)) from exc
|
||||||
|
|
||||||
if not outfilename:
|
if not outfilename:
|
||||||
outfilename = self.get_outfilename(pagename)
|
outfilename = self.get_outfilename(pagename)
|
||||||
@ -1059,7 +1087,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
else:
|
else:
|
||||||
with open(searchindexfn + '.tmp', 'wb') as fb:
|
with open(searchindexfn + '.tmp', 'wb') as fb:
|
||||||
self.indexer.dump(fb, self.indexer_format)
|
self.indexer.dump(fb, self.indexer_format)
|
||||||
movefile(searchindexfn + '.tmp', searchindexfn)
|
os.replace(searchindexfn + '.tmp', searchindexfn)
|
||||||
|
|
||||||
|
|
||||||
def convert_html_css_files(app: Sphinx, config: Config) -> None:
|
def convert_html_css_files(app: Sphinx, config: Config) -> None:
|
||||||
@ -1177,10 +1205,21 @@ def validate_html_favicon(app: Sphinx, config: Config) -> None:
|
|||||||
config.html_favicon = None # type: ignore
|
config.html_favicon = None # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_html_add_permalinks(app: Sphinx, config: Config) -> None:
|
||||||
|
"""Migrate html_add_permalinks to html_permalinks*."""
|
||||||
|
if config.html_add_permalinks:
|
||||||
|
if (isinstance(config.html_add_permalinks, bool) and
|
||||||
|
config.html_add_permalinks is False):
|
||||||
|
config.html_permalinks = False # type: ignore
|
||||||
|
else:
|
||||||
|
config.html_permalinks_icon = html.escape(config.html_add_permalinks) # type: ignore # NOQA
|
||||||
|
|
||||||
|
|
||||||
# for compatibility
|
# for compatibility
|
||||||
|
import sphinxcontrib.serializinghtml # NOQA
|
||||||
|
|
||||||
import sphinx.builders.dirhtml # NOQA
|
import sphinx.builders.dirhtml # NOQA
|
||||||
import sphinx.builders.singlehtml # NOQA
|
import sphinx.builders.singlehtml # NOQA
|
||||||
import sphinxcontrib.serializinghtml # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
@ -1206,7 +1245,9 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_config_value('html_sidebars', {}, 'html')
|
app.add_config_value('html_sidebars', {}, 'html')
|
||||||
app.add_config_value('html_additional_pages', {}, 'html')
|
app.add_config_value('html_additional_pages', {}, 'html')
|
||||||
app.add_config_value('html_domain_indices', True, 'html', [list])
|
app.add_config_value('html_domain_indices', True, 'html', [list])
|
||||||
app.add_config_value('html_add_permalinks', '¶', 'html')
|
app.add_config_value('html_add_permalinks', None, 'html')
|
||||||
|
app.add_config_value('html_permalinks', True, 'html')
|
||||||
|
app.add_config_value('html_permalinks_icon', '¶', 'html')
|
||||||
app.add_config_value('html_use_index', True, 'html')
|
app.add_config_value('html_use_index', True, 'html')
|
||||||
app.add_config_value('html_split_index', False, 'html')
|
app.add_config_value('html_split_index', False, 'html')
|
||||||
app.add_config_value('html_copy_source', True, 'html')
|
app.add_config_value('html_copy_source', True, 'html')
|
||||||
@ -1226,12 +1267,19 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_config_value('html_search_scorer', '', None)
|
app.add_config_value('html_search_scorer', '', None)
|
||||||
app.add_config_value('html_scaled_image_link', True, 'html')
|
app.add_config_value('html_scaled_image_link', True, 'html')
|
||||||
app.add_config_value('html_baseurl', '', 'html')
|
app.add_config_value('html_baseurl', '', 'html')
|
||||||
|
app.add_config_value('html_codeblock_linenos_style', 'table', 'html',
|
||||||
|
ENUM('table', 'inline'))
|
||||||
app.add_config_value('html_math_renderer', None, 'env')
|
app.add_config_value('html_math_renderer', None, 'env')
|
||||||
app.add_config_value('html4_writer', False, 'html')
|
app.add_config_value('html4_writer', False, 'html')
|
||||||
|
|
||||||
|
# events
|
||||||
|
app.add_event('html-collect-pages')
|
||||||
|
app.add_event('html-page-context')
|
||||||
|
|
||||||
# event handlers
|
# event handlers
|
||||||
app.connect('config-inited', convert_html_css_files, priority=800)
|
app.connect('config-inited', convert_html_css_files, priority=800)
|
||||||
app.connect('config-inited', convert_html_js_files, priority=800)
|
app.connect('config-inited', convert_html_js_files, priority=800)
|
||||||
|
app.connect('config-inited', migrate_html_add_permalinks, priority=800)
|
||||||
app.connect('config-inited', validate_html_extra_path, priority=800)
|
app.connect('config-inited', validate_html_extra_path, priority=800)
|
||||||
app.connect('config-inited', validate_html_static_path, priority=800)
|
app.connect('config-inited', validate_html_static_path, priority=800)
|
||||||
app.connect('config-inited', validate_html_logo, priority=800)
|
app.connect('config-inited', validate_html_logo, priority=800)
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
Transforms for HTML builder.
|
Transforms for HTML builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ class KeyboardTransform(SphinxPostTransform):
|
|||||||
|
|
||||||
After::
|
After::
|
||||||
|
|
||||||
<literal class="kbd">
|
<literal class="kbd compound">
|
||||||
<literal class="kbd">
|
<literal class="kbd">
|
||||||
Control
|
Control
|
||||||
-
|
-
|
||||||
@ -37,18 +37,30 @@ class KeyboardTransform(SphinxPostTransform):
|
|||||||
"""
|
"""
|
||||||
default_priority = 400
|
default_priority = 400
|
||||||
builders = ('html',)
|
builders = ('html',)
|
||||||
pattern = re.compile(r'(-|\+|\^|\s+)')
|
pattern = re.compile(r'(?<=.)(-|\+|\^|\s+)(?=.)')
|
||||||
|
multiwords_keys = (('caps', 'lock'),
|
||||||
|
('page' 'down'),
|
||||||
|
('page', 'up'),
|
||||||
|
('scroll' 'lock'),
|
||||||
|
('num', 'lock'),
|
||||||
|
('sys' 'rq'),
|
||||||
|
('back' 'space'))
|
||||||
|
|
||||||
def run(self, **kwargs: Any) -> None:
|
def run(self, **kwargs: Any) -> None:
|
||||||
matcher = NodeMatcher(nodes.literal, classes=["kbd"])
|
matcher = NodeMatcher(nodes.literal, classes=["kbd"])
|
||||||
for node in self.document.traverse(matcher): # type: nodes.literal
|
for node in self.document.traverse(matcher): # type: nodes.literal
|
||||||
parts = self.pattern.split(node[-1].astext())
|
parts = self.pattern.split(node[-1].astext())
|
||||||
if len(parts) == 1:
|
if len(parts) == 1 or self.is_multiwords_key(parts):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
node['classes'].append('compound')
|
||||||
node.pop()
|
node.pop()
|
||||||
while parts:
|
while parts:
|
||||||
key = parts.pop(0)
|
if self.is_multiwords_key(parts):
|
||||||
|
key = ''.join(parts[:3])
|
||||||
|
parts[:3] = []
|
||||||
|
else:
|
||||||
|
key = parts.pop(0)
|
||||||
node += nodes.literal('', key, classes=["kbd"])
|
node += nodes.literal('', key, classes=["kbd"])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -58,6 +70,16 @@ class KeyboardTransform(SphinxPostTransform):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def is_multiwords_key(self, parts: List[str]) -> bool:
|
||||||
|
if len(parts) >= 3 and parts[1].strip() == '':
|
||||||
|
name = parts[0].lower(), parts[2].lower()
|
||||||
|
if name in self.multiwords_keys:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
app.add_post_transform(KeyboardTransform)
|
app.add_post_transform(KeyboardTransform)
|
||||||
|
@ -5,29 +5,34 @@
|
|||||||
Build HTML help support files.
|
Build HTML help support files.
|
||||||
Parts adapted from Python's Doc/tools/prechm.py.
|
Parts adapted from Python's Doc/tools/prechm.py.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
from sphinxcontrib.htmlhelp import (
|
from sphinxcontrib.htmlhelp import (HTMLHelpBuilder, chm_htmlescape, chm_locales,
|
||||||
chm_locales, chm_htmlescape, HTMLHelpBuilder, default_htmlhelp_basename
|
default_htmlhelp_basename)
|
||||||
)
|
|
||||||
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
|
|
||||||
|
|
||||||
deprecated_alias('sphinx.builders.htmlhelp',
|
deprecated_alias('sphinx.builders.htmlhelp',
|
||||||
{
|
{
|
||||||
'chm_locales': chm_locales,
|
'chm_locales': chm_locales,
|
||||||
'chm_htmlescape': chm_htmlescape,
|
'chm_htmlescape': chm_htmlescape,
|
||||||
'HTMLHelpBuilder': HTMLHelpBuilder,
|
'HTMLHelpBuilder': HTMLHelpBuilder,
|
||||||
'default_htmlhelp_basename': default_htmlhelp_basename,
|
'default_htmlhelp_basename': default_htmlhelp_basename,
|
||||||
},
|
},
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning,
|
||||||
|
{
|
||||||
|
'chm_locales': 'sphinxcontrib.htmlhelp.chm_locales',
|
||||||
|
'chm_htmlescape': 'sphinxcontrib.htmlhelp.chm_htmlescape',
|
||||||
|
'HTMLHelpBuilder': 'sphinxcontrib.htmlhelp.HTMLHelpBuilder',
|
||||||
|
'default_htmlhelp_basename':
|
||||||
|
'sphinxcontrib.htmlhelp.default_htmlhelp_basename',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
LaTeX builder.
|
LaTeX builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -17,18 +17,18 @@ from docutils.frontend import OptionParser
|
|||||||
from docutils.nodes import Node
|
from docutils.nodes import Node
|
||||||
|
|
||||||
import sphinx.builders.latex.nodes # NOQA # Workaround: import this before writer to avoid ImportError
|
import sphinx.builders.latex.nodes # NOQA # Workaround: import this before writer to avoid ImportError
|
||||||
from sphinx import package_dir, addnodes, highlighting
|
from sphinx import addnodes, highlighting, package_dir
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.builders.latex.constants import ADDITIONAL_SETTINGS, DEFAULT_SETTINGS, SHORTHANDOFF
|
from sphinx.builders.latex.constants import ADDITIONAL_SETTINGS, DEFAULT_SETTINGS, SHORTHANDOFF
|
||||||
from sphinx.builders.latex.theming import Theme, ThemeFactory
|
from sphinx.builders.latex.theming import Theme, ThemeFactory
|
||||||
from sphinx.builders.latex.util import ExtBabel
|
from sphinx.builders.latex.util import ExtBabel
|
||||||
from sphinx.config import Config, ENUM
|
from sphinx.config import ENUM, Config
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning
|
||||||
from sphinx.environment.adapters.asset import ImageAdapter
|
from sphinx.environment.adapters.asset import ImageAdapter
|
||||||
from sphinx.errors import NoUri, SphinxError
|
from sphinx.errors import NoUri, SphinxError
|
||||||
from sphinx.locale import _, __
|
from sphinx.locale import _, __
|
||||||
from sphinx.util import texescape, logging, progress_message, status_iterator
|
from sphinx.util import logging, progress_message, status_iterator, texescape
|
||||||
from sphinx.util.console import bold, darkgreen # type: ignore
|
from sphinx.util.console import bold, darkgreen # type: ignore
|
||||||
from sphinx.util.docutils import SphinxFileOutput, new_document
|
from sphinx.util.docutils import SphinxFileOutput, new_document
|
||||||
from sphinx.util.fileutil import copy_asset_file
|
from sphinx.util.fileutil import copy_asset_file
|
||||||
@ -36,11 +36,10 @@ from sphinx.util.i18n import format_date
|
|||||||
from sphinx.util.nodes import inline_all_toctrees
|
from sphinx.util.nodes import inline_all_toctrees
|
||||||
from sphinx.util.osutil import SEP, make_filename_from_project
|
from sphinx.util.osutil import SEP, make_filename_from_project
|
||||||
from sphinx.util.template import LaTeXRenderer
|
from sphinx.util.template import LaTeXRenderer
|
||||||
from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
|
from sphinx.writers.latex import LaTeXTranslator, LaTeXWriter
|
||||||
|
|
||||||
# load docutils.nodes after loading sphinx.builders.latex.nodes
|
# load docutils.nodes after loading sphinx.builders.latex.nodes
|
||||||
from docutils import nodes # NOQA
|
from docutils import nodes # isort:skip
|
||||||
|
|
||||||
|
|
||||||
XINDY_LANG_OPTIONS = {
|
XINDY_LANG_OPTIONS = {
|
||||||
# language codes from docutils.writers.latex2e.Babel
|
# language codes from docutils.writers.latex2e.Babel
|
||||||
@ -128,8 +127,6 @@ class LaTeXBuilder(Builder):
|
|||||||
self.docnames = [] # type: Iterable[str]
|
self.docnames = [] # type: Iterable[str]
|
||||||
self.document_data = [] # type: List[Tuple[str, str, str, str, str, bool]]
|
self.document_data = [] # type: List[Tuple[str, str, str, str, str, bool]]
|
||||||
self.themes = ThemeFactory(self.app)
|
self.themes = ThemeFactory(self.app)
|
||||||
self.usepackages = self.app.registry.latex_packages
|
|
||||||
self.usepackages_after_hyperref = self.app.registry.latex_packages_after_hyperref
|
|
||||||
texescape.init()
|
texescape.init()
|
||||||
|
|
||||||
self.init_context()
|
self.init_context()
|
||||||
@ -179,10 +176,6 @@ class LaTeXBuilder(Builder):
|
|||||||
key = (self.config.latex_engine, self.config.language[:2])
|
key = (self.config.latex_engine, self.config.language[:2])
|
||||||
self.context.update(ADDITIONAL_SETTINGS.get(key, {}))
|
self.context.update(ADDITIONAL_SETTINGS.get(key, {}))
|
||||||
|
|
||||||
# Apply extension settings to context
|
|
||||||
self.context['packages'] = self.usepackages
|
|
||||||
self.context['packages_after_hyperref'] = self.usepackages_after_hyperref
|
|
||||||
|
|
||||||
# Apply user settings to context
|
# Apply user settings to context
|
||||||
self.context.update(self.config.latex_elements)
|
self.context.update(self.config.latex_elements)
|
||||||
self.context['release'] = self.config.release
|
self.context['release'] = self.config.release
|
||||||
@ -203,6 +196,13 @@ class LaTeXBuilder(Builder):
|
|||||||
# Show the release label only if release value exists
|
# Show the release label only if release value exists
|
||||||
self.context.setdefault('releasename', _('Release'))
|
self.context.setdefault('releasename', _('Release'))
|
||||||
|
|
||||||
|
def update_context(self) -> None:
|
||||||
|
"""Update template variables for .tex file just before writing."""
|
||||||
|
# Apply extension settings to context
|
||||||
|
registry = self.app.registry
|
||||||
|
self.context['packages'] = registry.latex_packages
|
||||||
|
self.context['packages_after_hyperref'] = registry.latex_packages_after_hyperref
|
||||||
|
|
||||||
def init_babel(self) -> None:
|
def init_babel(self) -> None:
|
||||||
self.babel = ExtBabel(self.config.language, not self.context['babel'])
|
self.babel = ExtBabel(self.config.language, not self.context['babel'])
|
||||||
if self.config.language and not self.babel.is_supported_language():
|
if self.config.language and not self.babel.is_supported_language():
|
||||||
@ -290,6 +290,7 @@ class LaTeXBuilder(Builder):
|
|||||||
doctree['tocdepth'] = tocdepth
|
doctree['tocdepth'] = tocdepth
|
||||||
self.post_process_images(doctree)
|
self.post_process_images(doctree)
|
||||||
self.update_doc_context(title, author, theme)
|
self.update_doc_context(title, author, theme)
|
||||||
|
self.update_context()
|
||||||
|
|
||||||
with progress_message(__("writing")):
|
with progress_message(__("writing")):
|
||||||
docsettings._author = author
|
docsettings._author = author
|
||||||
@ -448,6 +449,18 @@ class LaTeXBuilder(Builder):
|
|||||||
filename = path.join(package_dir, 'templates', 'latex', 'sphinxmessages.sty_t')
|
filename = path.join(package_dir, 'templates', 'latex', 'sphinxmessages.sty_t')
|
||||||
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())
|
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def usepackages(self) -> List[Tuple[str, str]]:
|
||||||
|
warnings.warn('LaTeXBuilder.usepackages is deprecated.',
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
return self.app.registry.latex_packages
|
||||||
|
|
||||||
|
@property
|
||||||
|
def usepackages_after_hyperref(self) -> List[Tuple[str, str]]:
|
||||||
|
warnings.warn('LaTeXBuilder.usepackages_after_hyperref is deprecated.',
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
return self.app.registry.latex_packages_after_hyperref
|
||||||
|
|
||||||
|
|
||||||
def patch_settings(settings: Any) -> Any:
|
def patch_settings(settings: Any) -> Any:
|
||||||
"""Make settings object to show deprecation messages."""
|
"""Make settings object to show deprecation messages."""
|
||||||
@ -503,9 +516,9 @@ def validate_latex_theme_options(app: Sphinx, config: Config) -> None:
|
|||||||
config.latex_theme_options.pop(key)
|
config.latex_theme_options.pop(key)
|
||||||
|
|
||||||
|
|
||||||
def install_pakcages_for_ja(app: Sphinx) -> None:
|
def install_packages_for_ja(app: Sphinx) -> None:
|
||||||
"""Install packages for Japanese."""
|
"""Install packages for Japanese."""
|
||||||
if app.config.language == 'ja':
|
if app.config.language == 'ja' and app.config.latex_engine in ('platex', 'uplatex'):
|
||||||
app.add_latex_package('pxjahyper', after_hyperref=True)
|
app.add_latex_package('pxjahyper', after_hyperref=True)
|
||||||
|
|
||||||
|
|
||||||
@ -556,7 +569,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_builder(LaTeXBuilder)
|
app.add_builder(LaTeXBuilder)
|
||||||
app.connect('config-inited', validate_config_values, priority=800)
|
app.connect('config-inited', validate_config_values, priority=800)
|
||||||
app.connect('config-inited', validate_latex_theme_options, priority=800)
|
app.connect('config-inited', validate_latex_theme_options, priority=800)
|
||||||
app.connect('builder-inited', install_pakcages_for_ja)
|
app.connect('builder-inited', install_packages_for_ja)
|
||||||
|
|
||||||
app.add_config_value('latex_engine', default_latex_engine, None,
|
app.add_config_value('latex_engine', default_latex_engine, None,
|
||||||
ENUM('pdflatex', 'xelatex', 'lualatex', 'platex', 'uplatex'))
|
ENUM('pdflatex', 'xelatex', 'lualatex', 'platex', 'uplatex'))
|
||||||
|
@ -4,13 +4,12 @@
|
|||||||
|
|
||||||
consntants for LaTeX builder.
|
consntants for LaTeX builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
|
||||||
PDFLATEX_DEFAULT_FONTPKG = r'''
|
PDFLATEX_DEFAULT_FONTPKG = r'''
|
||||||
\usepackage{times}
|
\usepackage{times}
|
||||||
\expandafter\ifx\csname T@LGR\endcsname\relax
|
\expandafter\ifx\csname T@LGR\endcsname\relax
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Additional nodes for LaTeX writer.
|
Additional nodes for LaTeX writer.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Theming support for LaTeX builder.
|
Theming support for LaTeX builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -87,10 +87,12 @@ class UserTheme(Theme):
|
|||||||
try:
|
try:
|
||||||
value = self.config.get('theme', key)
|
value = self.config.get('theme', key)
|
||||||
setattr(self, key, value)
|
setattr(self, key, value)
|
||||||
except configparser.NoSectionError:
|
except configparser.NoSectionError as exc:
|
||||||
raise ThemeError(__('%r doesn\'t have "theme" setting') % filename)
|
raise ThemeError(__('%r doesn\'t have "theme" setting') %
|
||||||
|
filename) from exc
|
||||||
except configparser.NoOptionError as exc:
|
except configparser.NoOptionError as exc:
|
||||||
raise ThemeError(__('%r doesn\'t have "%s" setting') % (filename, exc.args[0]))
|
raise ThemeError(__('%r doesn\'t have "%s" setting') %
|
||||||
|
(filename, exc.args[0])) from exc
|
||||||
|
|
||||||
for key in self.OPTIONAL_CONFIG_KEYS:
|
for key in self.OPTIONAL_CONFIG_KEYS:
|
||||||
try:
|
try:
|
||||||
|
@ -4,21 +4,20 @@
|
|||||||
|
|
||||||
Transforms for LaTeX builder.
|
Transforms for LaTeX builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Any, Dict, List, Set, Tuple
|
from typing import Any, Dict, List, Set, Tuple, cast
|
||||||
from typing import cast
|
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Element, Node
|
from docutils.nodes import Element, Node
|
||||||
|
from docutils.transforms.references import Substitutions
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders.latex.nodes import (
|
from sphinx.builders.latex.nodes import (captioned_literal_block, footnotemark, footnotetext,
|
||||||
captioned_literal_block, footnotemark, footnotetext, math_reference, thebibliography
|
math_reference, thebibliography)
|
||||||
)
|
|
||||||
from sphinx.domains.citation import CitationDomain
|
from sphinx.domains.citation import CitationDomain
|
||||||
from sphinx.transforms import SphinxTransform
|
from sphinx.transforms import SphinxTransform
|
||||||
from sphinx.transforms.post_transforms import SphinxPostTransform
|
from sphinx.transforms.post_transforms import SphinxPostTransform
|
||||||
@ -38,6 +37,18 @@ class FootnoteDocnameUpdater(SphinxTransform):
|
|||||||
node['docname'] = self.env.docname
|
node['docname'] = self.env.docname
|
||||||
|
|
||||||
|
|
||||||
|
class SubstitutionDefinitionsRemover(SphinxPostTransform):
|
||||||
|
"""Remove ``substitution_definition node from doctrees."""
|
||||||
|
|
||||||
|
# should be invoked after Substitutions process
|
||||||
|
default_priority = Substitutions.default_priority + 1
|
||||||
|
builders = ('latex',)
|
||||||
|
|
||||||
|
def apply(self, **kwargs: Any) -> None:
|
||||||
|
for node in self.document.traverse(nodes.substitution_definition):
|
||||||
|
node.parent.remove(node)
|
||||||
|
|
||||||
|
|
||||||
class ShowUrlsTransform(SphinxPostTransform):
|
class ShowUrlsTransform(SphinxPostTransform):
|
||||||
"""Expand references to inline text or footnotes.
|
"""Expand references to inline text or footnotes.
|
||||||
|
|
||||||
@ -602,6 +613,7 @@ class IndexInSectionTitleTransform(SphinxTransform):
|
|||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
app.add_transform(FootnoteDocnameUpdater)
|
app.add_transform(FootnoteDocnameUpdater)
|
||||||
|
app.add_post_transform(SubstitutionDefinitionsRemover)
|
||||||
app.add_post_transform(BibliographyTransform)
|
app.add_post_transform(BibliographyTransform)
|
||||||
app.add_post_transform(CitationReferenceTransform)
|
app.add_post_transform(CitationReferenceTransform)
|
||||||
app.add_post_transform(DocumentTargetTransform)
|
app.add_post_transform(DocumentTargetTransform)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Utilities for LaTeX builder.
|
Utilities for LaTeX builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
The CheckExternalLinksBuilder class.
|
The CheckExternalLinksBuilder class.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -13,28 +13,56 @@ import queue
|
|||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
|
import warnings
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from email.utils import parsedate_to_datetime
|
||||||
from html.parser import HTMLParser
|
from html.parser import HTMLParser
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, List, Set, Tuple
|
from typing import Any, Dict, List, NamedTuple, Optional, Set, Tuple, cast
|
||||||
from urllib.parse import unquote
|
from urllib.parse import unquote, urlparse
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Node
|
from docutils.nodes import Element
|
||||||
from requests.exceptions import HTTPError
|
from requests import Response
|
||||||
|
from requests.exceptions import HTTPError, TooManyRedirects
|
||||||
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders.dummy import DummyBuilder
|
||||||
|
from sphinx.deprecation import RemovedInSphinx50Warning
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import encode_uri, requests, logging
|
from sphinx.transforms.post_transforms import SphinxPostTransform
|
||||||
from sphinx.util.console import ( # type: ignore
|
from sphinx.util import encode_uri, logging, requests
|
||||||
purple, red, darkgreen, darkgray, turquoise
|
from sphinx.util.console import darkgray, darkgreen, purple, red, turquoise # type: ignore
|
||||||
)
|
|
||||||
from sphinx.util.nodes import get_node_line
|
from sphinx.util.nodes import get_node_line
|
||||||
from sphinx.util.requests import is_ssl_error
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
uri_re = re.compile('([a-z]+:)?//') # matches to foo:// and // (a protocol relative URL)
|
||||||
|
|
||||||
|
Hyperlink = NamedTuple('Hyperlink', (('next_check', float),
|
||||||
|
('uri', Optional[str]),
|
||||||
|
('docname', Optional[str]),
|
||||||
|
('lineno', Optional[int])))
|
||||||
|
RateLimit = NamedTuple('RateLimit', (('delay', float), ('next_check', float)))
|
||||||
|
|
||||||
|
DEFAULT_REQUEST_HEADERS = {
|
||||||
|
'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8',
|
||||||
|
}
|
||||||
|
CHECK_IMMEDIATELY = 0
|
||||||
|
QUEUE_POLL_SECS = 1
|
||||||
|
DEFAULT_DELAY = 60.0
|
||||||
|
|
||||||
|
|
||||||
|
def node_line_or_0(node: Element) -> int:
|
||||||
|
"""
|
||||||
|
PriorityQueue items must be comparable. The line number is part of the
|
||||||
|
tuple used by the PriorityQueue, keep an homogeneous type for comparison.
|
||||||
|
"""
|
||||||
|
warnings.warn('node_line_or_0() is deprecated.',
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
return get_node_line(node) or 0
|
||||||
|
|
||||||
|
|
||||||
class AnchorCheckParser(HTMLParser):
|
class AnchorCheckParser(HTMLParser):
|
||||||
"""Specialized HTML parser that looks for a specific anchor."""
|
"""Specialized HTML parser that looks for a specific anchor."""
|
||||||
@ -70,7 +98,7 @@ def check_anchor(response: requests.requests.Response, anchor: str) -> bool:
|
|||||||
return parser.found
|
return parser.found
|
||||||
|
|
||||||
|
|
||||||
class CheckExternalLinksBuilder(Builder):
|
class CheckExternalLinksBuilder(DummyBuilder):
|
||||||
"""
|
"""
|
||||||
Checks for broken external links.
|
Checks for broken external links.
|
||||||
"""
|
"""
|
||||||
@ -79,14 +107,15 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
'%(outdir)s/output.txt')
|
'%(outdir)s/output.txt')
|
||||||
|
|
||||||
def init(self) -> None:
|
def init(self) -> None:
|
||||||
|
self.hyperlinks = {} # type: Dict[str, Hyperlink]
|
||||||
self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
|
self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
|
||||||
self.anchors_ignore = [re.compile(x)
|
self.anchors_ignore = [re.compile(x)
|
||||||
for x in self.app.config.linkcheck_anchors_ignore]
|
for x in self.app.config.linkcheck_anchors_ignore]
|
||||||
self.auth = [(re.compile(pattern), auth_info) for pattern, auth_info
|
self.auth = [(re.compile(pattern), auth_info) for pattern, auth_info
|
||||||
in self.app.config.linkcheck_auth]
|
in self.app.config.linkcheck_auth]
|
||||||
self.good = set() # type: Set[str]
|
self._good = set() # type: Set[str]
|
||||||
self.broken = {} # type: Dict[str, str]
|
self._broken = {} # type: Dict[str, str]
|
||||||
self.redirected = {} # type: Dict[str, Tuple[str, int]]
|
self._redirected = {} # type: Dict[str, Tuple[str, int]]
|
||||||
# set a timeout for non-responding servers
|
# set a timeout for non-responding servers
|
||||||
socket.setdefaulttimeout(5.0)
|
socket.setdefaulttimeout(5.0)
|
||||||
# create output file
|
# create output file
|
||||||
@ -95,25 +124,62 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
open(path.join(self.outdir, 'output.json'), 'w').close()
|
open(path.join(self.outdir, 'output.json'), 'w').close()
|
||||||
|
|
||||||
# create queues and worker threads
|
# create queues and worker threads
|
||||||
self.wqueue = queue.Queue() # type: queue.Queue
|
self.rate_limits = {} # type: Dict[str, RateLimit]
|
||||||
|
self.wqueue = queue.PriorityQueue() # type: queue.PriorityQueue
|
||||||
self.rqueue = queue.Queue() # type: queue.Queue
|
self.rqueue = queue.Queue() # type: queue.Queue
|
||||||
self.workers = [] # type: List[threading.Thread]
|
self.workers = [] # type: List[threading.Thread]
|
||||||
for i in range(self.app.config.linkcheck_workers):
|
for i in range(self.app.config.linkcheck_workers):
|
||||||
thread = threading.Thread(target=self.check_thread)
|
thread = threading.Thread(target=self.check_thread, daemon=True)
|
||||||
thread.setDaemon(True)
|
|
||||||
thread.start()
|
thread.start()
|
||||||
self.workers.append(thread)
|
self.workers.append(thread)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def good(self):
|
||||||
|
warnings.warn(
|
||||||
|
"%s.%s is deprecated." % (self.__class__.__name__, "good"),
|
||||||
|
RemovedInSphinx50Warning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
return self._good
|
||||||
|
|
||||||
|
@property
|
||||||
|
def broken(self):
|
||||||
|
warnings.warn(
|
||||||
|
"%s.%s is deprecated." % (self.__class__.__name__, "broken"),
|
||||||
|
RemovedInSphinx50Warning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
return self._broken
|
||||||
|
|
||||||
|
@property
|
||||||
|
def redirected(self):
|
||||||
|
warnings.warn(
|
||||||
|
"%s.%s is deprecated." % (self.__class__.__name__, "redirected"),
|
||||||
|
RemovedInSphinx50Warning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
return self._redirected
|
||||||
|
|
||||||
def check_thread(self) -> None:
|
def check_thread(self) -> None:
|
||||||
kwargs = {
|
kwargs = {}
|
||||||
'allow_redirects': True,
|
|
||||||
'headers': {
|
|
||||||
'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if self.app.config.linkcheck_timeout:
|
if self.app.config.linkcheck_timeout:
|
||||||
kwargs['timeout'] = self.app.config.linkcheck_timeout
|
kwargs['timeout'] = self.app.config.linkcheck_timeout
|
||||||
|
|
||||||
|
def get_request_headers() -> Dict:
|
||||||
|
url = urlparse(uri)
|
||||||
|
candidates = ["%s://%s" % (url.scheme, url.netloc),
|
||||||
|
"%s://%s/" % (url.scheme, url.netloc),
|
||||||
|
uri,
|
||||||
|
"*"]
|
||||||
|
|
||||||
|
for u in candidates:
|
||||||
|
if u in self.config.linkcheck_request_headers:
|
||||||
|
headers = dict(DEFAULT_REQUEST_HEADERS)
|
||||||
|
headers.update(self.config.linkcheck_request_headers[u])
|
||||||
|
return headers
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
def check_uri() -> Tuple[str, str, int]:
|
def check_uri() -> Tuple[str, str, int]:
|
||||||
# split off anchor
|
# split off anchor
|
||||||
if '#' in uri:
|
if '#' in uri:
|
||||||
@ -139,11 +205,15 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
else:
|
else:
|
||||||
auth_info = None
|
auth_info = None
|
||||||
|
|
||||||
|
# update request headers for the URL
|
||||||
|
kwargs['headers'] = get_request_headers()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if anchor and self.app.config.linkcheck_anchors:
|
if anchor and self.app.config.linkcheck_anchors:
|
||||||
# Read the whole document and see if #anchor exists
|
# Read the whole document and see if #anchor exists
|
||||||
response = requests.get(req_url, stream=True, config=self.app.config,
|
response = requests.get(req_url, stream=True, config=self.app.config,
|
||||||
auth=auth_info, **kwargs)
|
auth=auth_info, **kwargs)
|
||||||
|
response.raise_for_status()
|
||||||
found = check_anchor(response, unquote(anchor))
|
found = check_anchor(response, unquote(anchor))
|
||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
@ -152,29 +222,42 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
try:
|
try:
|
||||||
# try a HEAD request first, which should be easier on
|
# try a HEAD request first, which should be easier on
|
||||||
# the server and the network
|
# the server and the network
|
||||||
response = requests.head(req_url, config=self.app.config,
|
response = requests.head(req_url, allow_redirects=True,
|
||||||
auth=auth_info, **kwargs)
|
config=self.app.config, auth=auth_info,
|
||||||
|
**kwargs)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except HTTPError:
|
except (HTTPError, TooManyRedirects) as err:
|
||||||
|
if isinstance(err, HTTPError) and err.response.status_code == 429:
|
||||||
|
raise
|
||||||
# retry with GET request if that fails, some servers
|
# retry with GET request if that fails, some servers
|
||||||
# don't like HEAD requests.
|
# don't like HEAD requests.
|
||||||
response = requests.get(req_url, stream=True, config=self.app.config,
|
response = requests.get(req_url, stream=True,
|
||||||
|
config=self.app.config,
|
||||||
auth=auth_info, **kwargs)
|
auth=auth_info, **kwargs)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except HTTPError as err:
|
except HTTPError as err:
|
||||||
if err.response.status_code == 401:
|
if err.response.status_code == 401:
|
||||||
# We'll take "Unauthorized" as working.
|
# We'll take "Unauthorized" as working.
|
||||||
return 'working', ' - unauthorized', 0
|
return 'working', ' - unauthorized', 0
|
||||||
|
elif err.response.status_code == 429:
|
||||||
|
next_check = self.limit_rate(err.response)
|
||||||
|
if next_check is not None:
|
||||||
|
self.wqueue.put((next_check, uri, docname, lineno), False)
|
||||||
|
return 'rate-limited', '', 0
|
||||||
|
return 'broken', str(err), 0
|
||||||
elif err.response.status_code == 503:
|
elif err.response.status_code == 503:
|
||||||
# We'll take "Service Unavailable" as ignored.
|
# We'll take "Service Unavailable" as ignored.
|
||||||
return 'ignored', str(err), 0
|
return 'ignored', str(err), 0
|
||||||
else:
|
else:
|
||||||
return 'broken', str(err), 0
|
return 'broken', str(err), 0
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
if is_ssl_error(err):
|
return 'broken', str(err), 0
|
||||||
return 'ignored', str(err), 0
|
else:
|
||||||
else:
|
netloc = urlparse(req_url).netloc
|
||||||
return 'broken', str(err), 0
|
try:
|
||||||
|
del self.rate_limits[netloc]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
if response.url.rstrip('/') == req_url.rstrip('/'):
|
if response.url.rstrip('/') == req_url.rstrip('/'):
|
||||||
return 'working', '', 0
|
return 'working', '', 0
|
||||||
else:
|
else:
|
||||||
@ -188,18 +271,31 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
else:
|
else:
|
||||||
return 'redirected', new_url, 0
|
return 'redirected', new_url, 0
|
||||||
|
|
||||||
def check() -> Tuple[str, str, int]:
|
def check(docname: str) -> Tuple[str, str, int]:
|
||||||
# check for various conditions without bothering the network
|
# check for various conditions without bothering the network
|
||||||
if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'ftp:')):
|
if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'tel:')):
|
||||||
return 'unchecked', '', 0
|
return 'unchecked', '', 0
|
||||||
elif not uri.startswith(('http:', 'https:')):
|
elif not uri.startswith(('http:', 'https:')):
|
||||||
return 'local', '', 0
|
if uri_re.match(uri):
|
||||||
elif uri in self.good:
|
# non supported URI schemes (ex. ftp)
|
||||||
|
return 'unchecked', '', 0
|
||||||
|
else:
|
||||||
|
srcdir = path.dirname(self.env.doc2path(docname))
|
||||||
|
if path.exists(path.join(srcdir, uri)):
|
||||||
|
return 'working', '', 0
|
||||||
|
else:
|
||||||
|
for rex in self.to_ignore:
|
||||||
|
if rex.match(uri):
|
||||||
|
return 'ignored', '', 0
|
||||||
|
else:
|
||||||
|
self._broken[uri] = ''
|
||||||
|
return 'broken', '', 0
|
||||||
|
elif uri in self._good:
|
||||||
return 'working', 'old', 0
|
return 'working', 'old', 0
|
||||||
elif uri in self.broken:
|
elif uri in self._broken:
|
||||||
return 'broken', self.broken[uri], 0
|
return 'broken', self._broken[uri], 0
|
||||||
elif uri in self.redirected:
|
elif uri in self._redirected:
|
||||||
return 'redirected', self.redirected[uri][0], self.redirected[uri][1]
|
return 'redirected', self._redirected[uri][0], self._redirected[uri][1]
|
||||||
for rex in self.to_ignore:
|
for rex in self.to_ignore:
|
||||||
if rex.match(uri):
|
if rex.match(uri):
|
||||||
return 'ignored', '', 0
|
return 'ignored', '', 0
|
||||||
@ -211,20 +307,78 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
break
|
break
|
||||||
|
|
||||||
if status == "working":
|
if status == "working":
|
||||||
self.good.add(uri)
|
self._good.add(uri)
|
||||||
elif status == "broken":
|
elif status == "broken":
|
||||||
self.broken[uri] = info
|
self._broken[uri] = info
|
||||||
elif status == "redirected":
|
elif status == "redirected":
|
||||||
self.redirected[uri] = (info, code)
|
self._redirected[uri] = (info, code)
|
||||||
|
|
||||||
return (status, info, code)
|
return (status, info, code)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
uri, docname, lineno = self.wqueue.get()
|
next_check, uri, docname, lineno = self.wqueue.get()
|
||||||
if uri is None:
|
if uri is None:
|
||||||
break
|
break
|
||||||
status, info, code = check()
|
netloc = urlparse(uri).netloc
|
||||||
self.rqueue.put((uri, docname, lineno, status, info, code))
|
try:
|
||||||
|
# Refresh rate limit.
|
||||||
|
# When there are many links in the queue, workers are all stuck waiting
|
||||||
|
# for responses, but the builder keeps queuing. Links in the queue may
|
||||||
|
# have been queued before rate limits were discovered.
|
||||||
|
next_check = self.rate_limits[netloc].next_check
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
if next_check > time.time():
|
||||||
|
# Sleep before putting message back in the queue to avoid
|
||||||
|
# waking up other threads.
|
||||||
|
time.sleep(QUEUE_POLL_SECS)
|
||||||
|
self.wqueue.put((next_check, uri, docname, lineno), False)
|
||||||
|
self.wqueue.task_done()
|
||||||
|
continue
|
||||||
|
status, info, code = check(docname)
|
||||||
|
if status == 'rate-limited':
|
||||||
|
logger.info(darkgray('-rate limited- ') + uri + darkgray(' | sleeping...'))
|
||||||
|
else:
|
||||||
|
self.rqueue.put((uri, docname, lineno, status, info, code))
|
||||||
|
self.wqueue.task_done()
|
||||||
|
|
||||||
|
def limit_rate(self, response: Response) -> Optional[float]:
|
||||||
|
next_check = None
|
||||||
|
retry_after = response.headers.get("Retry-After")
|
||||||
|
if retry_after:
|
||||||
|
try:
|
||||||
|
# Integer: time to wait before next attempt.
|
||||||
|
delay = float(retry_after)
|
||||||
|
except ValueError:
|
||||||
|
try:
|
||||||
|
# An HTTP-date: time of next attempt.
|
||||||
|
until = parsedate_to_datetime(retry_after)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
# TypeError: Invalid date format.
|
||||||
|
# ValueError: Invalid date, e.g. Oct 52th.
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
next_check = datetime.timestamp(until)
|
||||||
|
delay = (until - datetime.now(timezone.utc)).total_seconds()
|
||||||
|
else:
|
||||||
|
next_check = time.time() + delay
|
||||||
|
netloc = urlparse(response.url).netloc
|
||||||
|
if next_check is None:
|
||||||
|
max_delay = self.app.config.linkcheck_rate_limit_timeout
|
||||||
|
try:
|
||||||
|
rate_limit = self.rate_limits[netloc]
|
||||||
|
except KeyError:
|
||||||
|
delay = DEFAULT_DELAY
|
||||||
|
else:
|
||||||
|
last_wait_time = rate_limit.delay
|
||||||
|
delay = 2.0 * last_wait_time
|
||||||
|
if delay > max_delay and last_wait_time < max_delay:
|
||||||
|
delay = max_delay
|
||||||
|
if delay > max_delay:
|
||||||
|
return None
|
||||||
|
next_check = time.time() + delay
|
||||||
|
self.rate_limits[netloc] = RateLimit(delay, next_check)
|
||||||
|
return next_check
|
||||||
|
|
||||||
def process_result(self, result: Tuple[str, str, int, str, str, int]) -> None:
|
def process_result(self, result: Tuple[str, str, int, str, str, int]) -> None:
|
||||||
uri, docname, lineno, status, info, code = result
|
uri, docname, lineno, status, info, code = result
|
||||||
@ -279,44 +433,6 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
lineno, uri + ' to ' + info)
|
lineno, uri + ' to ' + info)
|
||||||
self.write_linkstat(linkstat)
|
self.write_linkstat(linkstat)
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def get_outdated_docs(self) -> Set[str]:
|
|
||||||
return self.env.found_docs
|
|
||||||
|
|
||||||
def prepare_writing(self, docnames: Set[str]) -> None:
|
|
||||||
return
|
|
||||||
|
|
||||||
def write_doc(self, docname: str, doctree: Node) -> None:
|
|
||||||
logger.info('')
|
|
||||||
n = 0
|
|
||||||
|
|
||||||
# reference nodes
|
|
||||||
for refnode in doctree.traverse(nodes.reference):
|
|
||||||
if 'refuri' not in refnode:
|
|
||||||
continue
|
|
||||||
uri = refnode['refuri']
|
|
||||||
lineno = get_node_line(refnode)
|
|
||||||
self.wqueue.put((uri, docname, lineno), False)
|
|
||||||
n += 1
|
|
||||||
|
|
||||||
# image nodes
|
|
||||||
for imgnode in doctree.traverse(nodes.image):
|
|
||||||
uri = imgnode['candidates'].get('?')
|
|
||||||
if uri and '://' in uri:
|
|
||||||
lineno = get_node_line(imgnode)
|
|
||||||
self.wqueue.put((uri, docname, lineno), False)
|
|
||||||
n += 1
|
|
||||||
|
|
||||||
done = 0
|
|
||||||
while done < n:
|
|
||||||
self.process_result(self.rqueue.get())
|
|
||||||
done += 1
|
|
||||||
|
|
||||||
if self.broken:
|
|
||||||
self.app.statuscode = 1
|
|
||||||
|
|
||||||
def write_entry(self, what: str, docname: str, filename: str, line: int,
|
def write_entry(self, what: str, docname: str, filename: str, line: int,
|
||||||
uri: str) -> None:
|
uri: str) -> None:
|
||||||
with open(path.join(self.outdir, 'output.txt'), 'a') as output:
|
with open(path.join(self.outdir, 'output.txt'), 'a') as output:
|
||||||
@ -328,15 +444,62 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
output.write('\n')
|
output.write('\n')
|
||||||
|
|
||||||
def finish(self) -> None:
|
def finish(self) -> None:
|
||||||
|
logger.info('')
|
||||||
|
n = 0
|
||||||
|
|
||||||
|
for hyperlink in self.hyperlinks.values():
|
||||||
|
self.wqueue.put(hyperlink, False)
|
||||||
|
n += 1
|
||||||
|
|
||||||
|
done = 0
|
||||||
|
while done < n:
|
||||||
|
self.process_result(self.rqueue.get())
|
||||||
|
done += 1
|
||||||
|
|
||||||
|
if self._broken:
|
||||||
|
self.app.statuscode = 1
|
||||||
|
|
||||||
|
self.wqueue.join()
|
||||||
|
# Shutdown threads.
|
||||||
for worker in self.workers:
|
for worker in self.workers:
|
||||||
self.wqueue.put((None, None, None), False)
|
self.wqueue.put((CHECK_IMMEDIATELY, None, None, None), False)
|
||||||
|
|
||||||
|
|
||||||
|
class HyperlinkCollector(SphinxPostTransform):
|
||||||
|
builders = ('linkcheck',)
|
||||||
|
default_priority = 800
|
||||||
|
|
||||||
|
def run(self, **kwargs: Any) -> None:
|
||||||
|
builder = cast(CheckExternalLinksBuilder, self.app.builder)
|
||||||
|
hyperlinks = builder.hyperlinks
|
||||||
|
|
||||||
|
# reference nodes
|
||||||
|
for refnode in self.document.traverse(nodes.reference):
|
||||||
|
if 'refuri' not in refnode:
|
||||||
|
continue
|
||||||
|
uri = refnode['refuri']
|
||||||
|
lineno = get_node_line(refnode)
|
||||||
|
uri_info = Hyperlink(CHECK_IMMEDIATELY, uri, self.env.docname, lineno)
|
||||||
|
if uri not in hyperlinks:
|
||||||
|
hyperlinks[uri] = uri_info
|
||||||
|
|
||||||
|
# image nodes
|
||||||
|
for imgnode in self.document.traverse(nodes.image):
|
||||||
|
uri = imgnode['candidates'].get('?')
|
||||||
|
if uri and '://' in uri:
|
||||||
|
lineno = get_node_line(imgnode)
|
||||||
|
uri_info = Hyperlink(CHECK_IMMEDIATELY, uri, self.env.docname, lineno)
|
||||||
|
if uri not in hyperlinks:
|
||||||
|
hyperlinks[uri] = uri_info
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
app.add_builder(CheckExternalLinksBuilder)
|
app.add_builder(CheckExternalLinksBuilder)
|
||||||
|
app.add_post_transform(HyperlinkCollector)
|
||||||
|
|
||||||
app.add_config_value('linkcheck_ignore', [], None)
|
app.add_config_value('linkcheck_ignore', [], None)
|
||||||
app.add_config_value('linkcheck_auth', [], None)
|
app.add_config_value('linkcheck_auth', [], None)
|
||||||
|
app.add_config_value('linkcheck_request_headers', {}, None)
|
||||||
app.add_config_value('linkcheck_retries', 1, None)
|
app.add_config_value('linkcheck_retries', 1, None)
|
||||||
app.add_config_value('linkcheck_timeout', None, None, [int])
|
app.add_config_value('linkcheck_timeout', None, None, [int])
|
||||||
app.add_config_value('linkcheck_workers', 5, None)
|
app.add_config_value('linkcheck_workers', 5, None)
|
||||||
@ -344,6 +507,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
# Anchors starting with ! are ignored since they are
|
# Anchors starting with ! are ignored since they are
|
||||||
# commonly used for dynamic pages
|
# commonly used for dynamic pages
|
||||||
app.add_config_value('linkcheck_anchors_ignore', ["^!"], None)
|
app.add_config_value('linkcheck_anchors_ignore', ["^!"], None)
|
||||||
|
app.add_config_value('linkcheck_rate_limit_timeout', 300.0, None)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Manual pages builder.
|
Manual pages builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -20,13 +20,11 @@ from sphinx.builders import Builder
|
|||||||
from sphinx.config import Config
|
from sphinx.config import Config
|
||||||
from sphinx.errors import NoUri
|
from sphinx.errors import NoUri
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging, progress_message
|
||||||
from sphinx.util import progress_message
|
|
||||||
from sphinx.util.console import darkgreen # type: ignore
|
from sphinx.util.console import darkgreen # type: ignore
|
||||||
from sphinx.util.nodes import inline_all_toctrees
|
from sphinx.util.nodes import inline_all_toctrees
|
||||||
from sphinx.util.osutil import make_filename_from_project
|
from sphinx.util.osutil import ensuredir, make_filename_from_project
|
||||||
from sphinx.writers.manpage import ManualPageWriter, ManualPageTranslator
|
from sphinx.writers.manpage import ManualPageTranslator, ManualPageWriter
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -80,7 +78,12 @@ class ManualPageBuilder(Builder):
|
|||||||
docsettings.authors = authors
|
docsettings.authors = authors
|
||||||
docsettings.section = section
|
docsettings.section = section
|
||||||
|
|
||||||
targetname = '%s.%s' % (name, section)
|
if self.config.man_make_section_directory:
|
||||||
|
ensuredir(path.join(self.outdir, str(section)))
|
||||||
|
targetname = '%s/%s.%s' % (section, name, section)
|
||||||
|
else:
|
||||||
|
targetname = '%s.%s' % (name, section)
|
||||||
|
|
||||||
logger.info(darkgreen(targetname) + ' { ', nonl=True)
|
logger.info(darkgreen(targetname) + ' { ', nonl=True)
|
||||||
destination = FileOutput(
|
destination = FileOutput(
|
||||||
destination_path=path.join(self.outdir, targetname),
|
destination_path=path.join(self.outdir, targetname),
|
||||||
@ -115,6 +118,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
|
|
||||||
app.add_config_value('man_pages', default_man_pages, None)
|
app.add_config_value('man_pages', default_man_pages, None)
|
||||||
app.add_config_value('man_show_urls', False, None)
|
app.add_config_value('man_show_urls', False, None)
|
||||||
|
app.add_config_value('man_make_section_directory', False, None)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Build input files for the Qt collection generator.
|
Build input files for the Qt collection generator.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -17,13 +17,16 @@ import sphinx
|
|||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
|
|
||||||
|
|
||||||
deprecated_alias('sphinx.builders.qthelp',
|
deprecated_alias('sphinx.builders.qthelp',
|
||||||
{
|
{
|
||||||
'render_file': render_file,
|
'render_file': render_file,
|
||||||
'QtHelpBuilder': QtHelpBuilder,
|
'QtHelpBuilder': QtHelpBuilder,
|
||||||
},
|
},
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning,
|
||||||
|
{
|
||||||
|
'render_file': 'sphinxcontrib.qthelp.render_file',
|
||||||
|
'QtHelpBuilder': 'sphinxcontrib.qthelp.QtHelpBuilder',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Single HTML builders.
|
Single HTML builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -19,8 +19,7 @@ from sphinx.builders.html import StandaloneHTMLBuilder
|
|||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
from sphinx.environment.adapters.toctree import TocTree
|
from sphinx.environment.adapters.toctree import TocTree
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging, progress_message
|
||||||
from sphinx.util import progress_message
|
|
||||||
from sphinx.util.console import darkgreen # type: ignore
|
from sphinx.util.console import darkgreen # type: ignore
|
||||||
from sphinx.util.nodes import inline_all_toctrees
|
from sphinx.util.nodes import inline_all_toctrees
|
||||||
|
|
||||||
@ -193,7 +192,11 @@ deprecated_alias('sphinx.builders.html',
|
|||||||
{
|
{
|
||||||
'SingleFileHTMLBuilder': SingleFileHTMLBuilder,
|
'SingleFileHTMLBuilder': SingleFileHTMLBuilder,
|
||||||
},
|
},
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning,
|
||||||
|
{
|
||||||
|
'SingleFileHTMLBuilder':
|
||||||
|
'sphinx.builders.singlehtml.SingleFileHTMLBuilder',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Texinfo builder.
|
Texinfo builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -16,23 +16,20 @@ from docutils import nodes
|
|||||||
from docutils.frontend import OptionParser
|
from docutils.frontend import OptionParser
|
||||||
from docutils.io import FileOutput
|
from docutils.io import FileOutput
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes, package_dir
|
||||||
from sphinx import package_dir
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.config import Config
|
from sphinx.config import Config
|
||||||
from sphinx.environment.adapters.asset import ImageAdapter
|
from sphinx.environment.adapters.asset import ImageAdapter
|
||||||
from sphinx.errors import NoUri
|
from sphinx.errors import NoUri
|
||||||
from sphinx.locale import _, __
|
from sphinx.locale import _, __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging, progress_message, status_iterator
|
||||||
from sphinx.util import progress_message, status_iterator
|
|
||||||
from sphinx.util.console import darkgreen # type: ignore
|
from sphinx.util.console import darkgreen # type: ignore
|
||||||
from sphinx.util.docutils import new_document
|
from sphinx.util.docutils import new_document
|
||||||
from sphinx.util.fileutil import copy_asset_file
|
from sphinx.util.fileutil import copy_asset_file
|
||||||
from sphinx.util.nodes import inline_all_toctrees
|
from sphinx.util.nodes import inline_all_toctrees
|
||||||
from sphinx.util.osutil import SEP, ensuredir, make_filename_from_project
|
from sphinx.util.osutil import SEP, ensuredir, make_filename_from_project
|
||||||
from sphinx.writers.texinfo import TexinfoWriter, TexinfoTranslator
|
from sphinx.writers.texinfo import TexinfoTranslator, TexinfoWriter
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
template_dir = os.path.join(package_dir, 'templates', 'texinfo')
|
template_dir = os.path.join(package_dir, 'templates', 'texinfo')
|
||||||
@ -182,7 +179,8 @@ class TexinfoBuilder(Builder):
|
|||||||
try:
|
try:
|
||||||
imagedir = path.join(self.outdir, targetname + '-figures')
|
imagedir = path.join(self.outdir, targetname + '-figures')
|
||||||
ensuredir(imagedir)
|
ensuredir(imagedir)
|
||||||
copy_asset_file(path.join(self.srcdir, dest), imagedir)
|
copy_asset_file(path.join(self.srcdir, src),
|
||||||
|
path.join(imagedir, dest))
|
||||||
except Exception as err:
|
except Exception 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)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Plain-text Sphinx builder.
|
Plain-text Sphinx builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ from sphinx.builders import Builder
|
|||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util.osutil import ensuredir, os_path
|
from sphinx.util.osutil import ensuredir, os_path
|
||||||
from sphinx.writers.text import TextWriter, TextTranslator
|
from sphinx.writers.text import TextTranslator, TextWriter
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Docutils-native XML and pseudo-XML builders.
|
Docutils-native XML and pseudo-XML builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ from sphinx.builders import Builder
|
|||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util.osutil import ensuredir, os_path
|
from sphinx.util.osutil import ensuredir, os_path
|
||||||
from sphinx.writers.xml import XMLWriter, PseudoXMLWriter
|
from sphinx.writers.xml import PseudoXMLWriter, XMLWriter
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
Modules for command line executables.
|
Modules for command line executables.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Build documentation from a provided source.
|
Build documentation from a provided source.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ import os
|
|||||||
import pdb
|
import pdb
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
from typing import Any, IO, List
|
from typing import IO, Any, List
|
||||||
|
|
||||||
from docutils.utils import SystemMessage
|
from docutils.utils import SystemMessage
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ from sphinx.application import Sphinx
|
|||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import Tee, format_exception_cut_frames, save_traceback
|
from sphinx.util import Tee, format_exception_cut_frames, save_traceback
|
||||||
from sphinx.util.console import red, nocolor, color_terminal, terminal_safe # type: ignore
|
from sphinx.util.console import color_terminal, nocolor, red, terminal_safe # type: ignore
|
||||||
from sphinx.util.docutils import docutils_namespace, patch_docutils
|
from sphinx.util.docutils import docutils_namespace, patch_docutils
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
This is in its own module so that importing it is fast. It should not
|
This is in its own module so that importing it is fast. It should not
|
||||||
import the main Sphinx modules (like sphinx.applications, sphinx.builders).
|
import the main Sphinx modules (like sphinx.applications, sphinx.builders).
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -22,10 +22,9 @@ from typing import List
|
|||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
from sphinx.cmd.build import build_main
|
from sphinx.cmd.build import build_main
|
||||||
from sphinx.util.console import color_terminal, nocolor, bold, blue # type: ignore
|
from sphinx.util.console import blue, bold, color_terminal, nocolor # type: ignore
|
||||||
from sphinx.util.osutil import cd, rmtree
|
from sphinx.util.osutil import cd, rmtree
|
||||||
|
|
||||||
|
|
||||||
BUILDERS = [
|
BUILDERS = [
|
||||||
("", "html", "to make standalone HTML files"),
|
("", "html", "to make standalone HTML files"),
|
||||||
("", "dirhtml", "to make HTML files named index.html in directories"),
|
("", "dirhtml", "to make HTML files named index.html in directories"),
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Quickly setup documentation source to work with Sphinx.
|
Quickly setup documentation source to work with Sphinx.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -37,9 +37,8 @@ import sphinx.locale
|
|||||||
from sphinx import __display_version__, package_dir
|
from sphinx import __display_version__, package_dir
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util.console import ( # type: ignore
|
from sphinx.util.console import (bold, color_terminal, colorize, nocolor, red, # type: ignore
|
||||||
colorize, bold, red, turquoise, nocolor, color_terminal
|
turquoise)
|
||||||
)
|
|
||||||
from sphinx.util.osutil import ensuredir
|
from sphinx.util.osutil import ensuredir
|
||||||
from sphinx.util.template import SphinxRenderer
|
from sphinx.util.template import SphinxRenderer
|
||||||
|
|
||||||
@ -489,8 +488,10 @@ def get_parser() -> argparse.ArgumentParser:
|
|||||||
help=__('project root'))
|
help=__('project root'))
|
||||||
|
|
||||||
group = parser.add_argument_group(__('Structure options'))
|
group = parser.add_argument_group(__('Structure options'))
|
||||||
group.add_argument('--sep', action='store_true', default=None,
|
group.add_argument('--sep', action='store_true', dest='sep', default=None,
|
||||||
help=__('if specified, separate source and build dirs'))
|
help=__('if specified, separate source and build dirs'))
|
||||||
|
group.add_argument('--no-sep', action='store_false', dest='sep',
|
||||||
|
help=__('if specified, create build dir under source dir'))
|
||||||
group.add_argument('--dot', metavar='DOT', default='_',
|
group.add_argument('--dot', metavar='DOT', default='_',
|
||||||
help=__('replacement for dot in _templates etc.'))
|
help=__('replacement for dot in _templates etc.'))
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Build configuration file handling.
|
Build configuration file handling.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -13,10 +13,9 @@ import traceback
|
|||||||
import types
|
import types
|
||||||
import warnings
|
import warnings
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from os import path, getenv
|
from os import getenv, path
|
||||||
from typing import (
|
from typing import (Any, Callable, Dict, Generator, Iterator, List, NamedTuple, Set, Tuple,
|
||||||
Any, Callable, Dict, Generator, Iterator, List, NamedTuple, Set, Tuple, Union
|
Union)
|
||||||
)
|
|
||||||
|
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.errors import ConfigError, ExtensionError
|
from sphinx.errors import ConfigError, ExtensionError
|
||||||
@ -99,7 +98,8 @@ class Config:
|
|||||||
# general options
|
# general options
|
||||||
'project': ('Python', 'env', []),
|
'project': ('Python', 'env', []),
|
||||||
'author': ('unknown', 'env', []),
|
'author': ('unknown', 'env', []),
|
||||||
'copyright': ('', 'html', []),
|
'project_copyright': ('', 'html', [str]),
|
||||||
|
'copyright': (lambda c: c.project_copyright, 'html', [str]),
|
||||||
'version': ('', 'env', []),
|
'version': ('', 'env', []),
|
||||||
'release': ('', 'env', []),
|
'release': ('', 'env', []),
|
||||||
'today': ('', 'env', []),
|
'today': ('', 'env', []),
|
||||||
@ -131,7 +131,7 @@ class Config:
|
|||||||
'rst_epilog': (None, 'env', [str]),
|
'rst_epilog': (None, 'env', [str]),
|
||||||
'rst_prolog': (None, 'env', [str]),
|
'rst_prolog': (None, 'env', [str]),
|
||||||
'trim_doctest_flags': (True, 'env', []),
|
'trim_doctest_flags': (True, 'env', []),
|
||||||
'primary_domain': ('py', 'env', [NoneType]), # type: ignore
|
'primary_domain': ('py', 'env', [NoneType]),
|
||||||
'needs_sphinx': (None, None, [str]),
|
'needs_sphinx': (None, None, [str]),
|
||||||
'needs_extensions': ({}, None, []),
|
'needs_extensions': ({}, None, []),
|
||||||
'manpages_url': (None, 'env', []),
|
'manpages_url': (None, 'env', []),
|
||||||
@ -181,6 +181,14 @@ class Config:
|
|||||||
defvalue = self.values[name][0]
|
defvalue = self.values[name][0]
|
||||||
if self.values[name][2] == Any:
|
if self.values[name][2] == Any:
|
||||||
return value
|
return value
|
||||||
|
elif self.values[name][2] == {bool, str}:
|
||||||
|
if value == '0':
|
||||||
|
# given falsy string from command line option
|
||||||
|
return False
|
||||||
|
elif value == '1':
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return value
|
||||||
elif type(defvalue) is bool or self.values[name][2] == [bool]:
|
elif type(defvalue) is bool or self.values[name][2] == [bool]:
|
||||||
if value == '0':
|
if value == '0':
|
||||||
# given falsy string from command line option
|
# given falsy string from command line option
|
||||||
@ -196,9 +204,9 @@ class Config:
|
|||||||
elif isinstance(defvalue, int):
|
elif isinstance(defvalue, int):
|
||||||
try:
|
try:
|
||||||
return int(value)
|
return int(value)
|
||||||
except ValueError:
|
except ValueError as exc:
|
||||||
raise ValueError(__('invalid number %r for config value %r, ignoring') %
|
raise ValueError(__('invalid number %r for config value %r, ignoring') %
|
||||||
(value, name))
|
(value, name)) from exc
|
||||||
elif hasattr(defvalue, '__call__'):
|
elif hasattr(defvalue, '__call__'):
|
||||||
return value
|
return value
|
||||||
elif defvalue is not None and not isinstance(defvalue, str):
|
elif defvalue is not None and not isinstance(defvalue, str):
|
||||||
@ -319,17 +327,17 @@ def eval_config_file(filename: str, tags: Tags) -> Dict[str, Any]:
|
|||||||
execfile_(filename, namespace)
|
execfile_(filename, namespace)
|
||||||
except SyntaxError as err:
|
except SyntaxError as err:
|
||||||
msg = __("There is a syntax error in your configuration file: %s\n")
|
msg = __("There is a syntax error in your configuration file: %s\n")
|
||||||
raise ConfigError(msg % err)
|
raise ConfigError(msg % err) from err
|
||||||
except SystemExit:
|
except SystemExit as exc:
|
||||||
msg = __("The configuration file (or one of the modules it imports) "
|
msg = __("The configuration file (or one of the modules it imports) "
|
||||||
"called sys.exit()")
|
"called sys.exit()")
|
||||||
raise ConfigError(msg)
|
raise ConfigError(msg) from exc
|
||||||
except ConfigError:
|
except ConfigError:
|
||||||
# pass through ConfigError from conf.py as is. It will be shown in console.
|
# pass through ConfigError from conf.py as is. It will be shown in console.
|
||||||
raise
|
raise
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
msg = __("There is a programmable error in your configuration file:\n\n%s")
|
msg = __("There is a programmable error in your configuration file:\n\n%s")
|
||||||
raise ConfigError(msg % traceback.format_exc())
|
raise ConfigError(msg % traceback.format_exc()) from exc
|
||||||
|
|
||||||
return namespace
|
return namespace
|
||||||
|
|
||||||
@ -359,6 +367,18 @@ def convert_source_suffix(app: "Sphinx", config: Config) -> None:
|
|||||||
"But `%r' is given." % source_suffix))
|
"But `%r' is given." % source_suffix))
|
||||||
|
|
||||||
|
|
||||||
|
def convert_highlight_options(app: "Sphinx", config: Config) -> None:
|
||||||
|
"""Convert old styled highlight_options to new styled one.
|
||||||
|
|
||||||
|
* old style: options
|
||||||
|
* new style: dict that maps language names to options
|
||||||
|
"""
|
||||||
|
options = config.highlight_options
|
||||||
|
if options and not all(isinstance(v, dict) for v in options.values()):
|
||||||
|
# old styled option detected because all values are not dictionary.
|
||||||
|
config.highlight_options = {config.highlight_language: options} # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def init_numfig_format(app: "Sphinx", config: Config) -> None:
|
def init_numfig_format(app: "Sphinx", config: Config) -> None:
|
||||||
"""Initialize :confval:`numfig_format`."""
|
"""Initialize :confval:`numfig_format`."""
|
||||||
numfig_format = {'section': _('Section %s'),
|
numfig_format = {'section': _('Section %s'),
|
||||||
@ -479,6 +499,7 @@ def check_master_doc(app: "Sphinx", env: "BuildEnvironment", added: Set[str],
|
|||||||
|
|
||||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
app.connect('config-inited', convert_source_suffix, priority=800)
|
app.connect('config-inited', convert_source_suffix, priority=800)
|
||||||
|
app.connect('config-inited', convert_highlight_options, priority=800)
|
||||||
app.connect('config-inited', init_numfig_format, priority=800)
|
app.connect('config-inited', init_numfig_format, priority=800)
|
||||||
app.connect('config-inited', correct_copyright_year, priority=800)
|
app.connect('config-inited', correct_copyright_year, priority=800)
|
||||||
app.connect('config-inited', check_confval_types, priority=800)
|
app.connect('config-inited', check_confval_types, priority=800)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Sphinx deprecation classes and utilities.
|
Sphinx deprecation classes and utilities.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -26,30 +26,46 @@ class RemovedInSphinx50Warning(PendingDeprecationWarning):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class RemovedInSphinx60Warning(PendingDeprecationWarning):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
RemovedInNextVersionWarning = RemovedInSphinx40Warning
|
RemovedInNextVersionWarning = RemovedInSphinx40Warning
|
||||||
|
|
||||||
|
|
||||||
def deprecated_alias(modname: str, objects: Dict, warning: "Type[Warning]") -> None:
|
def deprecated_alias(modname: str, objects: Dict[str, object],
|
||||||
|
warning: "Type[Warning]", names: Dict[str, str] = None) -> None:
|
||||||
module = import_module(modname)
|
module = import_module(modname)
|
||||||
sys.modules[modname] = _ModuleWrapper(module, modname, objects, warning) # type: ignore
|
sys.modules[modname] = _ModuleWrapper( # type: ignore
|
||||||
|
module, modname, objects, warning, names)
|
||||||
|
|
||||||
|
|
||||||
class _ModuleWrapper:
|
class _ModuleWrapper:
|
||||||
def __init__(self, module: Any, modname: str, objects: Dict, warning: "Type[Warning]"
|
def __init__(self, module: Any, modname: str,
|
||||||
) -> None:
|
objects: Dict[str, object],
|
||||||
|
warning: "Type[Warning]",
|
||||||
|
names: Dict[str, str]) -> None:
|
||||||
self._module = module
|
self._module = module
|
||||||
self._modname = modname
|
self._modname = modname
|
||||||
self._objects = objects
|
self._objects = objects
|
||||||
self._warning = warning
|
self._warning = warning
|
||||||
|
self._names = names
|
||||||
|
|
||||||
def __getattr__(self, name: str) -> Any:
|
def __getattr__(self, name: str) -> Any:
|
||||||
if name in self._objects:
|
if name not in self._objects:
|
||||||
warnings.warn("%s.%s is deprecated. Check CHANGES for Sphinx "
|
return getattr(self._module, name)
|
||||||
"API modifications." % (self._modname, name),
|
|
||||||
self._warning, stacklevel=3)
|
|
||||||
return self._objects[name]
|
|
||||||
|
|
||||||
return getattr(self._module, name)
|
canonical_name = self._names.get(name, None)
|
||||||
|
if canonical_name is not None:
|
||||||
|
warnings.warn(
|
||||||
|
"The alias '{}.{}' is deprecated, use '{}' instead. Check CHANGES for "
|
||||||
|
"Sphinx API modifications.".format(self._modname, name, canonical_name),
|
||||||
|
self._warning, stacklevel=3)
|
||||||
|
else:
|
||||||
|
warnings.warn("{}.{} is deprecated. Check CHANGES for Sphinx "
|
||||||
|
"API modifications.".format(self._modname, name),
|
||||||
|
self._warning, stacklevel=3)
|
||||||
|
return self._objects[name]
|
||||||
|
|
||||||
|
|
||||||
class DeprecatedDict(dict):
|
class DeprecatedDict(dict):
|
||||||
|
@ -4,13 +4,12 @@
|
|||||||
|
|
||||||
Handlers for additional ReST directives.
|
Handlers for additional ReST directives.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, Generic, List, Tuple, TypeVar, cast
|
||||||
from typing import cast
|
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Node
|
from docutils.nodes import Node
|
||||||
@ -18,9 +17,8 @@ from docutils.parsers.rst import directives, roles
|
|||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.addnodes import desc_signature
|
from sphinx.addnodes import desc_signature
|
||||||
from sphinx.deprecation import (
|
from sphinx.deprecation import (RemovedInSphinx40Warning, RemovedInSphinx50Warning,
|
||||||
RemovedInSphinx40Warning, RemovedInSphinx50Warning, deprecated_alias
|
deprecated_alias)
|
||||||
)
|
|
||||||
from sphinx.util import docutils
|
from sphinx.util import docutils
|
||||||
from sphinx.util.docfields import DocFieldTransformer, Field, TypedField
|
from sphinx.util.docfields import DocFieldTransformer, Field, TypedField
|
||||||
from sphinx.util.docutils import SphinxDirective
|
from sphinx.util.docutils import SphinxDirective
|
||||||
@ -35,6 +33,8 @@ if False:
|
|||||||
nl_escape_re = re.compile(r'\\\n')
|
nl_escape_re = re.compile(r'\\\n')
|
||||||
strip_backslash_re = re.compile(r'\\(.)')
|
strip_backslash_re = re.compile(r'\\(.)')
|
||||||
|
|
||||||
|
T = TypeVar('T')
|
||||||
|
|
||||||
|
|
||||||
def optional_int(argument: str) -> int:
|
def optional_int(argument: str) -> int:
|
||||||
"""
|
"""
|
||||||
@ -49,7 +49,7 @@ def optional_int(argument: str) -> int:
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
class ObjectDescription(SphinxDirective):
|
class ObjectDescription(SphinxDirective, Generic[T]):
|
||||||
"""
|
"""
|
||||||
Directive to describe a class, function or similar object. Not used
|
Directive to describe a class, function or similar object. Not used
|
||||||
directly, but subclassed (in domain-specific directives) to add custom
|
directly, but subclassed (in domain-specific directives) to add custom
|
||||||
@ -99,7 +99,7 @@ class ObjectDescription(SphinxDirective):
|
|||||||
else:
|
else:
|
||||||
return [line.strip() for line in lines]
|
return [line.strip() for line in lines]
|
||||||
|
|
||||||
def handle_signature(self, sig: str, signode: desc_signature) -> Any:
|
def handle_signature(self, sig: str, signode: desc_signature) -> T:
|
||||||
"""
|
"""
|
||||||
Parse the signature *sig* into individual nodes and append them to
|
Parse the signature *sig* into individual nodes and append them to
|
||||||
*signode*. If ValueError is raised, parsing is aborted and the whole
|
*signode*. If ValueError is raised, parsing is aborted and the whole
|
||||||
@ -111,7 +111,7 @@ class ObjectDescription(SphinxDirective):
|
|||||||
"""
|
"""
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
def add_target_and_index(self, name: Any, sig: str, signode: desc_signature) -> None:
|
def add_target_and_index(self, name: T, sig: str, signode: desc_signature) -> None:
|
||||||
"""
|
"""
|
||||||
Add cross-reference IDs and entries to self.indexnode, if applicable.
|
Add cross-reference IDs and entries to self.indexnode, if applicable.
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ class ObjectDescription(SphinxDirective):
|
|||||||
if self.domain:
|
if self.domain:
|
||||||
node['classes'].append(self.domain)
|
node['classes'].append(self.domain)
|
||||||
|
|
||||||
self.names = [] # type: List[Any]
|
self.names = [] # type: List[T]
|
||||||
signatures = self.get_signatures()
|
signatures = self.get_signatures()
|
||||||
for i, sig in enumerate(signatures):
|
for i, sig in enumerate(signatures):
|
||||||
# add a signature node for each signature in the current unit
|
# add a signature node for each signature in the current unit
|
||||||
@ -266,16 +266,10 @@ class DefaultDomain(SphinxDirective):
|
|||||||
self.env.temp_data['default_domain'] = self.env.domains.get(domain_name)
|
self.env.temp_data['default_domain'] = self.env.domains.get(domain_name)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
from sphinx.directives.code import ( # noqa
|
from sphinx.directives.code import CodeBlock, Highlight, LiteralInclude # noqa
|
||||||
Highlight, CodeBlock, LiteralInclude
|
from sphinx.directives.other import (Acks, Author, Centered, Class, HList, Include, # noqa
|
||||||
)
|
Only, SeeAlso, TabularColumns, TocTree, VersionChange)
|
||||||
from sphinx.directives.other import ( # noqa
|
from sphinx.directives.patches import Figure, Meta # noqa
|
||||||
TocTree, Author, VersionChange, SeeAlso,
|
|
||||||
TabularColumns, Centered, Acks, HList, Only, Include, Class
|
|
||||||
)
|
|
||||||
from sphinx.directives.patches import ( # noqa
|
|
||||||
Figure, Meta
|
|
||||||
)
|
|
||||||
from sphinx.domains.index import IndexDirective # noqa
|
from sphinx.domains.index import IndexDirective # noqa
|
||||||
|
|
||||||
deprecated_alias('sphinx.directives',
|
deprecated_alias('sphinx.directives',
|
||||||
@ -298,13 +292,35 @@ deprecated_alias('sphinx.directives',
|
|||||||
'Figure': Figure,
|
'Figure': Figure,
|
||||||
'Meta': Meta,
|
'Meta': Meta,
|
||||||
},
|
},
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning,
|
||||||
|
{
|
||||||
|
'Highlight': 'sphinx.directives.code.Highlight',
|
||||||
|
'CodeBlock': 'sphinx.directives.code.CodeBlock',
|
||||||
|
'LiteralInclude': 'sphinx.directives.code.LiteralInclude',
|
||||||
|
'TocTree': 'sphinx.directives.other.TocTree',
|
||||||
|
'Author': 'sphinx.directives.other.Author',
|
||||||
|
'Index': 'sphinx.directives.other.IndexDirective',
|
||||||
|
'VersionChange': 'sphinx.directives.other.VersionChange',
|
||||||
|
'SeeAlso': 'sphinx.directives.other.SeeAlso',
|
||||||
|
'TabularColumns': 'sphinx.directives.other.TabularColumns',
|
||||||
|
'Centered': 'sphinx.directives.other.Centered',
|
||||||
|
'Acks': 'sphinx.directives.other.Acks',
|
||||||
|
'HList': 'sphinx.directives.other.HList',
|
||||||
|
'Only': 'sphinx.directives.other.Only',
|
||||||
|
'Include': 'sphinx.directives.other.Include',
|
||||||
|
'Class': 'sphinx.directives.other.Class',
|
||||||
|
'Figure': 'sphinx.directives.patches.Figure',
|
||||||
|
'Meta': 'sphinx.directives.patches.Meta',
|
||||||
|
})
|
||||||
|
|
||||||
deprecated_alias('sphinx.directives',
|
deprecated_alias('sphinx.directives',
|
||||||
{
|
{
|
||||||
'DescDirective': ObjectDescription,
|
'DescDirective': ObjectDescription,
|
||||||
},
|
},
|
||||||
RemovedInSphinx50Warning)
|
RemovedInSphinx50Warning,
|
||||||
|
{
|
||||||
|
'DescDirective': 'sphinx.directives.ObjectDescription',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
|
@ -2,11 +2,12 @@
|
|||||||
sphinx.directives.code
|
sphinx.directives.code
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import textwrap
|
||||||
import warnings
|
import warnings
|
||||||
from difflib import unified_diff
|
from difflib import unified_diff
|
||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, List, Tuple
|
||||||
@ -19,9 +20,9 @@ from docutils.statemachine import StringList
|
|||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.config import Config
|
from sphinx.config import Config
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
|
from sphinx.directives import optional_int
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging, parselinenos
|
||||||
from sphinx.util import parselinenos
|
|
||||||
from sphinx.util.docutils import SphinxDirective
|
from sphinx.util.docutils import SphinxDirective
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
@ -69,10 +70,10 @@ class HighlightLang(Highlight):
|
|||||||
|
|
||||||
def dedent_lines(lines: List[str], dedent: int, location: Tuple[str, int] = None) -> List[str]:
|
def dedent_lines(lines: List[str], dedent: int, location: Tuple[str, int] = None) -> List[str]:
|
||||||
if not dedent:
|
if not dedent:
|
||||||
return lines
|
return textwrap.dedent(''.join(lines)).splitlines(True)
|
||||||
|
|
||||||
if any(s[:dedent].strip() for s in lines):
|
if any(s[:dedent].strip() for s in lines):
|
||||||
logger.warning(__('Over dedent has detected'), location=location)
|
logger.warning(__('non-whitespace stripped by dedent'), location=location)
|
||||||
|
|
||||||
new_lines = []
|
new_lines = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
@ -118,7 +119,7 @@ class CodeBlock(SphinxDirective):
|
|||||||
option_spec = {
|
option_spec = {
|
||||||
'force': directives.flag,
|
'force': directives.flag,
|
||||||
'linenos': directives.flag,
|
'linenos': directives.flag,
|
||||||
'dedent': int,
|
'dedent': optional_int,
|
||||||
'lineno-start': int,
|
'lineno-start': int,
|
||||||
'emphasize-lines': directives.unchanged_required,
|
'emphasize-lines': directives.unchanged_required,
|
||||||
'caption': directives.unchanged_required,
|
'caption': directives.unchanged_required,
|
||||||
@ -227,12 +228,13 @@ class LiteralIncludeReader:
|
|||||||
text = text.expandtabs(self.options['tab-width'])
|
text = text.expandtabs(self.options['tab-width'])
|
||||||
|
|
||||||
return text.splitlines(True)
|
return text.splitlines(True)
|
||||||
except OSError:
|
except OSError as exc:
|
||||||
raise OSError(__('Include file %r not found or reading it failed') % filename)
|
raise OSError(__('Include file %r not found or reading it failed') %
|
||||||
except UnicodeError:
|
filename) from exc
|
||||||
|
except UnicodeError as exc:
|
||||||
raise UnicodeError(__('Encoding %r used for reading included file %r seems to '
|
raise UnicodeError(__('Encoding %r used for reading included file %r seems to '
|
||||||
'be wrong, try giving an :encoding: option') %
|
'be wrong, try giving an :encoding: option') %
|
||||||
(self.encoding, filename))
|
(self.encoding, filename)) from exc
|
||||||
|
|
||||||
def read(self, location: Tuple[str, int] = None) -> Tuple[str, int]:
|
def read(self, location: Tuple[str, int] = None) -> Tuple[str, int]:
|
||||||
if 'diff' in self.options:
|
if 'diff' in self.options:
|
||||||
@ -391,7 +393,7 @@ class LiteralInclude(SphinxDirective):
|
|||||||
optional_arguments = 0
|
optional_arguments = 0
|
||||||
final_argument_whitespace = True
|
final_argument_whitespace = True
|
||||||
option_spec = {
|
option_spec = {
|
||||||
'dedent': int,
|
'dedent': optional_int,
|
||||||
'linenos': directives.flag,
|
'linenos': directives.flag,
|
||||||
'lineno-start': int,
|
'lineno-start': int,
|
||||||
'lineno-match': directives.flag,
|
'lineno-match': directives.flag,
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
sphinx.directives.other
|
sphinx.directives.other
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List, cast
|
||||||
from typing import cast
|
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Element, Node
|
from docutils.nodes import Element, Node
|
||||||
@ -21,7 +20,7 @@ from sphinx import addnodes
|
|||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
from sphinx.domains.changeset import VersionChange # NOQA # for compatibility
|
from sphinx.domains.changeset import VersionChange # NOQA # for compatibility
|
||||||
from sphinx.locale import _
|
from sphinx.locale import _
|
||||||
from sphinx.util import url_re, docname_join
|
from sphinx.util import docname_join, url_re
|
||||||
from sphinx.util.docutils import SphinxDirective
|
from sphinx.util.docutils import SphinxDirective
|
||||||
from sphinx.util.matching import Matcher, patfilter
|
from sphinx.util.matching import Matcher, patfilter
|
||||||
from sphinx.util.nodes import explicit_title_re
|
from sphinx.util.nodes import explicit_title_re
|
||||||
@ -368,7 +367,10 @@ deprecated_alias('sphinx.directives.other',
|
|||||||
{
|
{
|
||||||
'Index': IndexDirective,
|
'Index': IndexDirective,
|
||||||
},
|
},
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning,
|
||||||
|
{
|
||||||
|
'Index': 'sphinx.domains.index.IndexDirective',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
|
@ -2,17 +2,16 @@
|
|||||||
sphinx.directives.patches
|
sphinx.directives.patches
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, List, Tuple, cast
|
||||||
from typing import cast
|
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Node, make_id, system_message
|
from docutils.nodes import Node, make_id, system_message
|
||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
from docutils.parsers.rst.directives import images, html, tables
|
from docutils.parsers.rst.directives import html, images, tables
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.directives import optional_int
|
from sphinx.directives import optional_int
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user