mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge remote-tracking branch 'upstream/3.x' into exclude-members-fix
This commit is contained in:
commit
270921d73a
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
|
||||
- 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
|
||||
|
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@ -8,7 +8,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
tool: [docslint, flake8, mypy, twine]
|
||||
tool: [docslint, flake8, isort, mypy, twine]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
59
.github/workflows/main.yml
vendored
59
.github/workflows/main.yml
vendored
@ -1,9 +1,64 @@
|
||||
name: CI on Windows
|
||||
name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
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
|
||||
strategy:
|
||||
matrix:
|
||||
|
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
|
46
.travis.yml
46
.travis.yml
@ -1,46 +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
|
||||
|
||||
- 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 -- -vv; fi
|
||||
- if [ $IS_PYTHON = false ]; then npm test; fi
|
||||
|
||||
after_success:
|
||||
- if [[ -e .coverage ]]; then codecov -e $TOXENV; fi
|
346
CHANGES
346
CHANGES
@ -1,4 +1,127 @@
|
||||
Release 3.3.0 (in development)
|
||||
Release 3.5.0 (in development)
|
||||
==============================
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
* LaTeX: ``multicol`` (it is anyhow a required part of the official latex2e
|
||||
base distribution)
|
||||
|
||||
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`
|
||||
* #1638: html: Add permalink icons to glossary terms
|
||||
* #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
|
||||
* #7642: std domain: Optimize case-insensitive match of term
|
||||
* #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
|
||||
* #8134: autodoc: crashes when mocked decorator takes arguments
|
||||
* #8306: autosummary: mocked modules are documented as empty page when using
|
||||
:recursive: option
|
||||
* #8232: graphviz: Image node is not rendered if graph file is in subdirectory
|
||||
* #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
|
||||
* #8123: html search: fix searching for terms containing + (Requires a custom
|
||||
search language that does not split on +)
|
||||
* #8665: html theme: Could not override globaltoc_maxdepth in theme.conf
|
||||
* #8446: html: consecutive spaces are displayed as single space
|
||||
* #8745: i18n: crashes with KeyError when translation message adds a new auto
|
||||
footnote reference
|
||||
* #4304: linkcheck: Fix race condition that could lead to checking the
|
||||
availability of the same URL twice
|
||||
* #7118: sphinx-quickstart: questionare got Mojibake if libreadline unavailable
|
||||
* #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
|
||||
* #8756: viewcode: highlighted code is generated even if not referenced
|
||||
* #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
|
||||
* #7576: LaTeX with French babel and memoir crash: "Illegal parameter number
|
||||
in definition of ``\FNH@prefntext``"
|
||||
* #8072: LaTeX: Directive :rst:dir:`hlist` not implemented in LaTeX
|
||||
* #8214: LaTeX: The :rst:role:`index` role and the glossary generate duplicate
|
||||
entries in the LaTeX index (if both used for same term)
|
||||
* #8735: LaTeX: wrong internal links in pdf to captioned code-blocks when
|
||||
:confval:`numfig` is not True
|
||||
* #8442: LaTeX: some indexed terms are ignored when using xelatex engine
|
||||
(or pdflatex and :confval:`latex_use_xindy` set to True) with memoir class
|
||||
* #8780: LaTeX: long words in narrow columns may not be hyphenated
|
||||
* #8788: LaTeX: ``\titleformat`` last argument in sphinx.sty should be
|
||||
bracketed, not braced (and is anyhow not needed)
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
||||
Release 3.4.4 (in development)
|
||||
==============================
|
||||
|
||||
Dependencies
|
||||
@ -10,6 +133,175 @@ 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.
|
||||
* #8796: LaTeX: potentially critical low level TeX coding mistake has gone
|
||||
unnoticed so far
|
||||
|
||||
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``
|
||||
@ -26,6 +318,15 @@ Features added
|
||||
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
|
||||
----------
|
||||
@ -43,52 +344,45 @@ Bugs fixed
|
||||
* #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.2 (in development)
|
||||
==============================
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
Deprecated
|
||||
----------
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
* #8188: C, add missing items to internal object types dictionary,
|
||||
e.g., preventing intersphinx from resolving them.
|
||||
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
||||
Release 3.2.1 (released Aug 14, 2020)
|
||||
=====================================
|
||||
|
||||
|
@ -14,4 +14,5 @@ You can also browse it from this repository from
|
||||
``doc/internals/contributing.rst``
|
||||
|
||||
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.
|
||||
|
2
EXAMPLES
2
EXAMPLES
@ -230,6 +230,7 @@ Documentation using sphinx_rtd_theme
|
||||
* `MyHDL <http://docs.myhdl.org/>`__
|
||||
* `Nextflow <https://www.nextflow.io/docs/latest/index.html>`__
|
||||
* `NICOS <https://forge.frm2.tum.de/nicos/doc/nicos-master/>`__ (customized)
|
||||
* `OpenFAST <https://openfast.readthedocs.io/>`__
|
||||
* `Pelican <http://docs.getpelican.com/>`__
|
||||
* `picamera <https://picamera.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/>`__
|
||||
* `Doctrine <https://www.doctrine-project.org/>`__
|
||||
* `Enterprise Toolkit for Acrobat products <https://www.adobe.com/devnet-docs/acrobatetk/>`__
|
||||
* `FreeFEM <https://doc.freefem.org/introduction/>`__
|
||||
* `Gameduino <http://excamera.com/sphinx/gameduino/>`__
|
||||
* `gensim <https://radimrehurek.com/gensim/>`__
|
||||
* `GeoServer <http://docs.geoserver.org/>`__
|
||||
|
2
LICENSE
2
LICENSE
@ -1,7 +1,7 @@
|
||||
License for Sphinx
|
||||
==================
|
||||
|
||||
Copyright (c) 2007-2020 by the Sphinx team (see AUTHORS file).
|
||||
Copyright (c) 2007-2021 by the Sphinx team (see AUTHORS file).
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
4
Makefile
4
Makefile
@ -66,11 +66,11 @@ doclinter:
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
@$(PYTHON) -m pytest -v $(TEST)
|
||||
@$(PYTHON) -X dev -m pytest -v $(TEST)
|
||||
|
||||
.PHONY: 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
|
||||
build:
|
||||
|
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 |
6
doc/_templates/index.html
vendored
6
doc/_templates/index.html
vendored
@ -33,9 +33,9 @@
|
||||
<li>{%trans path=pathto('ext/builtins')%}<b>Extensions:</b> automatic testing of code snippets, inclusion of
|
||||
docstrings from Python modules (API docs), and
|
||||
<a href="{{ path }}#builtin-sphinx-extensions">more</a>{%endtrans%}</li>
|
||||
<li>{%trans path=pathto('develop')%}<b>Contributed extensions:</b> more than
|
||||
50 extensions <a href="{{ path }}#extensions">contributed by users</a>
|
||||
in a second repository; most of them installable from PyPI{%endtrans%}</li>
|
||||
<li>{%trans path=pathto("usage/extensions")%}<b>Contributed extensions:</b> dozens of
|
||||
extensions <a href="{{ path }}#third-party-extensions">contributed by users</a>;
|
||||
most of them installable from PyPI{%endtrans%}</li>
|
||||
</ul>
|
||||
<p>{%trans%}
|
||||
Sphinx uses <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>
|
||||
|
2
doc/_themes/sphinx13/layout.html
vendored
2
doc/_themes/sphinx13/layout.html
vendored
@ -67,7 +67,7 @@
|
||||
<li><a href="{{ pathto('index') }}">Home</a></li>
|
||||
<li><a href="{{ pathto('usage/installation') }}">Get it</a></li>
|
||||
<li><a href="{{ pathto('contents') }}">Docs</a></li>
|
||||
<li><a href="{{ pathto('develop') }}">Extend/Develop</a></li>
|
||||
<li><a href="{{ pathto('development') }}">Extend</a></li>
|
||||
</ul>
|
||||
<div>
|
||||
<a href="{{ pathto('index') }}">
|
||||
|
@ -8,4 +8,9 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\hypersetup{bookmarksdepth=1}% pdf bookmarks
|
||||
\addtocontents{toc}{\protect\setcounter{tocdepth}{1}}%
|
||||
|
||||
.. include:: ../CHANGES
|
||||
|
20
doc/conf.py
20
doc/conf.py
@ -4,7 +4,6 @@ import re
|
||||
|
||||
import sphinx
|
||||
|
||||
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo',
|
||||
'sphinx.ext.autosummary', 'sphinx.ext.extlinks',
|
||||
'sphinx.ext.intersphinx',
|
||||
@ -15,7 +14,7 @@ templates_path = ['_templates']
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
project = 'Sphinx'
|
||||
copyright = '2007-2020, Georg Brandl and the Sphinx team'
|
||||
copyright = '2007-2021, Georg Brandl and the Sphinx team'
|
||||
version = sphinx.__display_version__
|
||||
release = version
|
||||
show_authors = True
|
||||
@ -28,6 +27,7 @@ html_sidebars = {'index': ['indexsidebar.html', 'searchbox.html']}
|
||||
html_additional_pages = {'index': 'index.html'}
|
||||
html_use_opensearch = 'https://www.sphinx-doc.org/en/master'
|
||||
html_baseurl = 'https://www.sphinx-doc.org/en/master/'
|
||||
html_favicon = '_static/favicon.svg'
|
||||
|
||||
htmlhelp_basename = 'Sphinxdoc'
|
||||
|
||||
@ -69,8 +69,15 @@ latex_elements = {
|
||||
\substitutefont{X2}{\sfdefault}{cmss}
|
||||
\substitutefont{X2}{\ttdefault}{cmtt}
|
||||
''',
|
||||
'passoptionstopackages': '\\PassOptionsToPackage{svgnames}{xcolor}',
|
||||
'preamble': '\\DeclareUnicodeCharacter{229E}{\\ensuremath{\\boxplus}}',
|
||||
'passoptionstopackages': r'''
|
||||
\PassOptionsToPackage{svgnames}{xcolor}
|
||||
\PassOptionsToPackage{bookmarksdepth=3}{hyperref}% depth of pdf bookmarks
|
||||
''',
|
||||
'preamble': r'''
|
||||
\DeclareUnicodeCharacter{229E}{\ensuremath{\boxplus}}
|
||||
\setcounter{tocdepth}{3}% depth of what is kept from toc file
|
||||
\setcounter{secnumdepth}{1}% depth of section numbering
|
||||
''',
|
||||
'fvset': '\\fvset{fontsize=auto}',
|
||||
# fix missing index entry due to RTD doing only once pdflatex after makeindex
|
||||
'printindex': r'''
|
||||
@ -110,7 +117,10 @@ texinfo_documents = [
|
||||
1),
|
||||
]
|
||||
|
||||
intersphinx_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:
|
||||
locale_dirs = ['locale/']
|
||||
|
153
doc/develop.rst
153
doc/develop.rst
@ -1,153 +0,0 @@
|
||||
:orphan:
|
||||
|
||||
Sphinx development
|
||||
==================
|
||||
|
||||
Sphinx is a maintained by a group of volunteers. We value every contribution!
|
||||
|
||||
* The code can be found in a Git repository, at
|
||||
https://github.com/sphinx-doc/sphinx/.
|
||||
* Issues and feature requests should be raised in the `tracker
|
||||
<https://github.com/sphinx-doc/sphinx/issues>`_.
|
||||
* The mailing list for development is at `Google Groups
|
||||
<https://groups.google.com/forum/#!forum/sphinx-dev>`_.
|
||||
* There is also the #sphinx-doc IRC channel on `freenode
|
||||
<https://freenode.net/>`_.
|
||||
|
||||
For more about our development process and methods, refer to
|
||||
:doc:`/internals/index`.
|
||||
|
||||
Extensions
|
||||
==========
|
||||
|
||||
To learn how to write your own extension, see :ref:`dev-extensions`.
|
||||
|
||||
The `sphinx-contrib <https://bitbucket.org/birkenfeld/sphinx-contrib/>`_
|
||||
repository contains many contributed extensions. Some of them have their own
|
||||
releases on PyPI, others you can install from a checkout.
|
||||
|
||||
This is the current list of contributed extensions in that repository:
|
||||
|
||||
- aafig: render embedded ASCII art as nice images using aafigure_
|
||||
- actdiag: embed activity diagrams by using actdiag_
|
||||
- adadomain: an extension for Ada support (Sphinx 1.0 needed)
|
||||
- ansi: parse ANSI color sequences inside documents
|
||||
- argdoc: automatically generate documentation for command-line arguments,
|
||||
descriptions and help text
|
||||
- astah: embed diagram by using astah
|
||||
- autoanysrc: Gather reST documentation from any source files
|
||||
- autorun: Execute code in a ``runblock`` directive
|
||||
- beamer_: A builder for Beamer (LaTeX) output.
|
||||
- blockdiag: embed block diagrams by using blockdiag_
|
||||
- cacoo: embed diagram from Cacoo
|
||||
- cf3domain: a domain for CFEngine 3 policies
|
||||
- cheader: The missing c:header directive for Sphinx's built-in C domain
|
||||
- cheeseshop: easily link to PyPI packages
|
||||
- clearquest: create tables from ClearQuest_ queries
|
||||
- cmakedomain_: a domain for CMake_
|
||||
- coffeedomain: a domain for (auto)documenting CoffeeScript source code
|
||||
- context: a builder for ConTeXt
|
||||
- disqus: embed Disqus comments in documents
|
||||
- documentedlist: converts a Python list to a table in the generated
|
||||
documentation
|
||||
- doxylink: Link to external Doxygen-generated HTML documentation
|
||||
- domaintools_: A tool for easy domain creation
|
||||
- email: obfuscate email addresses
|
||||
- erlangdomain: an extension for Erlang support (Sphinx 1.0 needed)
|
||||
- exceltable: embed Excel spreadsheets into documents using exceltable_
|
||||
- feed: an extension for creating syndication feeds and time-based overviews
|
||||
from your site content
|
||||
- findanything_: an extension to add Sublime Text 2-like findanything panels
|
||||
to your documentation to find pages, sections and index entries while typing
|
||||
- gnuplot: produces images using gnuplot_ language
|
||||
- googleanalytics: track web visitor statistics by using `Google Analytics`_
|
||||
- googlechart: embed charts by using `Google Chart`_
|
||||
- googlemaps: embed maps by using `Google Maps`_
|
||||
- httpdomain: a domain for documenting RESTful HTTP APIs
|
||||
- hyphenator: client-side hyphenation of HTML using hyphenator_
|
||||
- imgur: embed Imgur images, albums, and metadata in documents
|
||||
- inlinesyntaxhighlight_: inline syntax highlighting
|
||||
- lassodomain: a domain for documenting Lasso_ source code
|
||||
- libreoffice: an extension to include any drawing supported by LibreOffice
|
||||
(e.g. odg, vsd, ...)
|
||||
- lilypond: an extension inserting music scripts from Lilypond_ in PNG format
|
||||
- makedomain_: a domain for `GNU Make`_
|
||||
- matlabdomain: document MATLAB_ code
|
||||
- mockautodoc: mock imports
|
||||
- mscgen: embed mscgen-formatted MSC (Message Sequence Chart)s
|
||||
- napoleon: supports `Google style`_ and `NumPy style`_ docstrings
|
||||
- nicovideo: embed videos from nicovideo
|
||||
- nwdiag: embed network diagrams by using nwdiag_
|
||||
- omegat: support tools to collaborate with OmegaT_ (Sphinx 1.1 needed)
|
||||
- osaka: convert standard Japanese doc to Osaka dialect (this is a joke
|
||||
extension)
|
||||
- paverutils: an alternate integration of Sphinx with Paver_
|
||||
- phpdomain: an extension for PHP support
|
||||
- plantuml: embed UML diagram by using PlantUML_
|
||||
- py_directive: Execute python code in a ``py`` directive and return a math
|
||||
node
|
||||
- rawfiles: copy raw files, like a CNAME
|
||||
- requirements: declare requirements wherever you need (e.g. in test
|
||||
docstrings), mark statuses and collect them in a single list
|
||||
- restbuilder: a builder for reST (reStructuredText) files
|
||||
- rubydomain: an extension for Ruby support (Sphinx 1.0 needed)
|
||||
- sadisplay: display SqlAlchemy model sadisplay_
|
||||
- sdedit: an extension inserting sequence diagram by using Quick Sequence
|
||||
Diagram Editor (sdedit_)
|
||||
- seqdiag: embed sequence diagrams by using seqdiag_
|
||||
- slide: embed presentation slides on slideshare_ and other sites
|
||||
- swf_: embed flash files
|
||||
- sword: an extension inserting Bible verses from Sword_
|
||||
- tikz: draw pictures with the `TikZ/PGF LaTeX package`_
|
||||
- traclinks: create TracLinks_ to a Trac_ instance from within Sphinx
|
||||
- versioning: Sphinx extension that allows building versioned docs for
|
||||
self-hosting
|
||||
- whooshindex: whoosh indexer extension
|
||||
- youtube: embed videos from YouTube_
|
||||
- zopeext: provide an ``autointerface`` directive for using `Zope interfaces`_
|
||||
|
||||
|
||||
See the :doc:`extension tutorials <../development/tutorials/index>` on getting
|
||||
started with writing your own extensions.
|
||||
|
||||
|
||||
.. _aafigure: https://launchpad.net/aafigure
|
||||
.. _gnuplot: http://www.gnuplot.info/
|
||||
.. _paver: https://paver.readthedocs.io/en/latest/
|
||||
.. _Sword: https://www.crosswire.org/sword/
|
||||
.. _Lilypond: http://lilypond.org/
|
||||
.. _sdedit: http://sdedit.sourceforge.net/
|
||||
.. _Trac: https://trac.edgewall.org/
|
||||
.. _TracLinks: https://trac.edgewall.org/wiki/TracLinks
|
||||
.. _OmegaT: https://omegat.org/
|
||||
.. _PlantUML: http://plantuml.com/
|
||||
.. _PyEnchant: https://pythonhosted.org/pyenchant/
|
||||
.. _sadisplay: https://bitbucket.org/estin/sadisplay/wiki/Home
|
||||
.. _blockdiag: http://blockdiag.com/en/
|
||||
.. _seqdiag: http://blockdiag.com/en/
|
||||
.. _actdiag: http://blockdiag.com/en/
|
||||
.. _nwdiag: http://blockdiag.com/en/
|
||||
.. _Google Analytics: https://www.google.com/analytics/
|
||||
.. _Google Chart: https://developers.google.com/chart/
|
||||
.. _Google Maps: https://www.google.com/maps
|
||||
.. _Google style: https://google.github.io/styleguide/pyguide.html
|
||||
.. _NumPy style: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
|
||||
.. _hyphenator: https://github.com/mnater/hyphenator
|
||||
.. _exceltable: https://pythonhosted.org/sphinxcontrib-exceltable/
|
||||
.. _YouTube: https://www.youtube.com/
|
||||
.. _ClearQuest: https://www.ibm.com/us-en/marketplace/rational-clearquest
|
||||
.. _Zope interfaces: https://zopeinterface.readthedocs.io/en/latest/README.html
|
||||
.. _slideshare: https://www.slideshare.net/
|
||||
.. _TikZ/PGF LaTeX package: https://sourceforge.net/projects/pgf/
|
||||
.. _MATLAB: https://www.mathworks.com/products/matlab.html
|
||||
.. _swf: https://github.com/sphinx-contrib/swf
|
||||
.. _findanything: https://github.com/sphinx-contrib/findanything
|
||||
.. _cmakedomain: https://github.com/sphinx-contrib/cmakedomain
|
||||
.. _GNU Make: https://www.gnu.org/software/make/
|
||||
.. _makedomain: https://github.com/sphinx-contrib/makedomain
|
||||
.. _inlinesyntaxhighlight: https://sphinxcontrib-inlinesyntaxhighlight.readthedocs.io/
|
||||
.. _CMake: https://cmake.org
|
||||
.. _domaintools: https://github.com/sphinx-contrib/domaintools
|
||||
.. _restbuilder: https://pypi.org/project/sphinxcontrib-restbuilder/
|
||||
.. _Lasso: http://www.lassosoft.com/
|
||||
.. _beamer: https://pypi.org/project/sphinxcontrib-beamer/
|
@ -2,10 +2,12 @@
|
||||
Extending Sphinx
|
||||
================
|
||||
|
||||
This guide is aimed at those wishing to develop their own extensions for
|
||||
Sphinx. Sphinx possesses significant extensibility capabilities including the
|
||||
ability to hook into almost every point of the build process. If you simply
|
||||
wish to use Sphinx with existing extensions, refer to :doc:`/usage/index`.
|
||||
This guide is aimed at giving a quick introduction for those wishing to
|
||||
develop their own extensions for Sphinx. Sphinx possesses significant
|
||||
extensibility capabilities including the ability to hook into almost every
|
||||
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::
|
||||
:maxdepth: 2
|
||||
|
@ -4,8 +4,7 @@ from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.domains import Domain
|
||||
from sphinx.domains import Index
|
||||
from sphinx.domains import Domain, Index
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util.nodes import make_refnode
|
||||
|
||||
|
@ -25,75 +25,75 @@ package.
|
||||
|
||||
.. 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
|
||||
|
||||
@ -107,9 +107,9 @@ Emitting events
|
||||
.. class:: Sphinx
|
||||
:noindex:
|
||||
|
||||
.. automethod:: emit(event, \*arguments)
|
||||
.. automethod:: emit
|
||||
|
||||
.. automethod:: emit_firstresult(event, \*arguments)
|
||||
.. automethod:: emit_firstresult
|
||||
|
||||
|
||||
Sphinx runtime information
|
||||
@ -186,6 +186,7 @@ type for that event::
|
||||
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)
|
||||
@ -284,6 +285,14 @@ Here is a more detailed list of these events.
|
||||
|
||||
.. 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)
|
||||
|
||||
Emitted when a doctree has been "resolved" by the environment, that is, all
|
||||
@ -360,6 +369,9 @@ Here is a more detailed list of these events.
|
||||
You can return a string from the handler, it will then replace
|
||||
``'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
|
||||
|
||||
.. versionchanged:: 1.3
|
||||
|
@ -12,20 +12,142 @@ The following is a list of deprecated interfaces.
|
||||
|
||||
.. tabularcolumns:: |>{\raggedright}\Y{.4}|>{\centering}\Y{.1}|>{\centering}\Y{.12}|>{\raggedright\arraybackslash}\Y{.38}|
|
||||
|
||||
.. |LaTeXHyphenate| raw:: latex
|
||||
|
||||
\hspace{0pt}
|
||||
|
||||
.. list-table:: deprecated APIs
|
||||
:header-rows: 1
|
||||
:class: deprecated
|
||||
:widths: 40, 10, 10, 40
|
||||
|
||||
* - Target
|
||||
- |LaTeXHyphenate|\ Deprecated
|
||||
- Deprecated
|
||||
- (will be) Removed
|
||||
- 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
|
||||
|
@ -1,7 +1,7 @@
|
||||
.. _domain-api:
|
||||
|
||||
Domain API
|
||||
----------
|
||||
==========
|
||||
|
||||
.. module:: sphinx.domains
|
||||
|
||||
@ -12,3 +12,16 @@ Domain API
|
||||
|
||||
.. autoclass:: Index
|
||||
:members:
|
||||
|
||||
|
||||
Python Domain
|
||||
-------------
|
||||
|
||||
.. module:: sphinx.domains.python
|
||||
|
||||
.. autoclass:: PythonDomain
|
||||
|
||||
.. autoattribute:: objects
|
||||
.. autoattribute:: modules
|
||||
.. automethod:: note_object
|
||||
.. automethod:: note_module
|
||||
|
@ -9,8 +9,8 @@ Glossary
|
||||
A class (inheriting from :class:`~sphinx.builders.Builder`) that takes
|
||||
parsed documents and performs an action on them. Normally, builders
|
||||
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
|
||||
documentation, or build coverage information.
|
||||
use builders that e.g. check for broken links in the documentation, or
|
||||
build coverage information.
|
||||
|
||||
See :doc:`/usage/builders/index` for an overview over Sphinx's built-in
|
||||
builders.
|
||||
|
@ -138,10 +138,7 @@ Coding style
|
||||
|
||||
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
|
||||
`Pocoo Styleguide`__ for more information.
|
||||
|
||||
__ http://flask.pocoo.org/docs/styleguide/
|
||||
* Try to use the same code style as used in the rest of the project.
|
||||
|
||||
* For non-trivial changes, please update the :file:`CHANGES` file. If your
|
||||
changes alter existing behavior, please document this.
|
||||
@ -272,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``.
|
||||
|
||||
The Sphinx core messages can also be translated on `Transifex
|
||||
<https://www.transifex.com/sphinx-doc/>`_. There ``tx`` client tool, which is
|
||||
provided by the ``transifex_client`` Python package, can be used to pull
|
||||
translations in ``.po`` format from Transifex. To do this, go to
|
||||
<https://www.transifex.com/sphinx-doc/sphinx-1/>`_. There ``tx`` client tool,
|
||||
which is provided by the ``transifex_client`` Python package, can be used 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
|
||||
existing language identifier. It is good practice to run ``python setup.py
|
||||
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
|
||||
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: ``''``
|
||||
|
||||
.. 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.
|
||||
|
||||
Default: ``'\\usepackage[Bjarne]{fncychap}'`` for English documents,
|
||||
``'\\usepackage[Sonny]{fncychap}'`` for internationalized documents, and
|
||||
``''`` for Japanese documents.
|
||||
``'\\usepackage[Sonny]{fncychap}'`` for internationalized documents, and
|
||||
``''`` for Japanese documents.
|
||||
|
||||
``'preamble'``
|
||||
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.
|
||||
|
||||
Default: ``'\\usepackage[utf8]{inputenc}'`` when using pdflatex, else
|
||||
``''``
|
||||
``''``
|
||||
|
||||
.. versionchanged:: 1.4.3
|
||||
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.
|
||||
|
||||
Default: ``'\\usepackage{textalpha}'`` or ``''`` if ``fontenc`` does not
|
||||
include the ``LGR`` option.
|
||||
include the ``LGR`` option.
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
@ -407,7 +413,7 @@ Keys that don't need to be overridden unless in special cases are:
|
||||
<latexsphinxsetup>`.
|
||||
|
||||
Default: ``'\\usepackage{geometry}'`` (or
|
||||
``'\\usepackage[dvipdfm]{geometry}'`` for Japanese documents)
|
||||
``'\\usepackage[dvipdfm]{geometry}'`` for Japanese documents)
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
@ -784,14 +790,14 @@ macros may be significant.
|
||||
|warningbdcolors|
|
||||
The colour for the admonition frame.
|
||||
|
||||
Default: ``{rgb}{0,0,0}`` (black)
|
||||
Default: ``{rgb}{0,0,0}`` (black)
|
||||
|
||||
.. only:: latex
|
||||
|
||||
|wgbdcolorslatex|
|
||||
The colour for the admonition frame.
|
||||
|
||||
Default: ``{rgb}{0,0,0}`` (black)
|
||||
Default: ``{rgb}{0,0,0}`` (black)
|
||||
|
||||
|warningbgcolors|
|
||||
The background colours for the respective admonitions.
|
||||
@ -1018,6 +1024,14 @@ Environments
|
||||
Miscellany
|
||||
~~~~~~~~~~
|
||||
|
||||
- Every text paragraph in document body starts with ``\sphinxAtStartPar``.
|
||||
Currently, this is used to insert a zero width horizontal skip which
|
||||
is a trick to allow TeX hyphenation of the first word of a paragraph
|
||||
in a narrow context (like a table cell). For ``'lualatex'`` which
|
||||
does not need the trick, the ``\sphinxAtStartPar`` does nothing.
|
||||
|
||||
.. versionadded:: 3.5.0
|
||||
|
||||
- The section, subsection, ... headings are set using *titlesec*'s
|
||||
``\titleformat`` command.
|
||||
|
||||
|
@ -33,6 +33,10 @@ Options
|
||||
|
||||
If specified, separate source and build directories.
|
||||
|
||||
.. option:: --no-sep
|
||||
|
||||
If specified, create build directroy under source directroy.
|
||||
|
||||
.. option:: --dot=DOT
|
||||
|
||||
Inside the root directory, two more directories will be created;
|
||||
|
@ -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.
|
||||
|
||||
.. versionchanged:: 3.4
|
||||
|
||||
The linkcheck builder retries links when servers apply rate limits.
|
||||
|
||||
.. module:: sphinx.builders.xml
|
||||
.. class:: XMLBuilder
|
||||
|
||||
|
@ -73,6 +73,12 @@ Project information
|
||||
|
||||
A copyright statement in the style ``'2008, Author Name'``.
|
||||
|
||||
.. confval:: project_copyright
|
||||
|
||||
An alias of :confval:`copyright`.
|
||||
|
||||
.. versionadded:: 3.5
|
||||
|
||||
.. confval:: version
|
||||
|
||||
The major project version, used as the replacement for ``|version|``. For
|
||||
@ -316,6 +322,7 @@ General configuration
|
||||
* ``toc.circular``
|
||||
* ``toc.secnum``
|
||||
* ``epub.unknown_project_files``
|
||||
* ``epub.duplicated_toc_entry``
|
||||
* ``autosectionlabel.*``
|
||||
|
||||
You can choose from these types.
|
||||
@ -340,6 +347,10 @@ General configuration
|
||||
|
||||
Added ``autosectionlabel.*``
|
||||
|
||||
.. versionchanged:: 3.3.0
|
||||
|
||||
Added ``epub.duplicated_toc_entry``
|
||||
|
||||
.. confval:: needs_sphinx
|
||||
|
||||
If set to a ``major.minor`` version string like ``'1.1'``, Sphinx will
|
||||
@ -551,7 +562,7 @@ General configuration
|
||||
* Otherwise, the current time is formatted using :func:`time.strftime` and
|
||||
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
|
||||
format for the selected locale).
|
||||
|
||||
@ -572,12 +583,27 @@ General configuration
|
||||
|
||||
.. confval:: highlight_options
|
||||
|
||||
A dictionary of options that modify how the lexer specified by
|
||||
:confval:`highlight_language` generates highlighted source code. These are
|
||||
lexer-specific; for the options understood by each, see the
|
||||
`Pygments documentation <https://pygments.org/docs/lexers>`_.
|
||||
A dictionary that maps language names to options for the lexer modules of
|
||||
Pygments. These are lexer-specific; for the options understood by each,
|
||||
see the `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
|
||||
.. versionchanged:: 3.5
|
||||
|
||||
Allow to configure highlight options for multiple languages
|
||||
|
||||
.. confval:: pygments_style
|
||||
|
||||
@ -932,8 +958,11 @@ that use Sphinx's HTMLWriter class.
|
||||
|
||||
.. confval:: html_baseurl
|
||||
|
||||
The URL which points to the root of the HTML documentation. It is used to
|
||||
indicate the location of document like ``canonical_url``.
|
||||
The base URL which points to the root of the HTML documentation. It is used
|
||||
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
|
||||
|
||||
@ -991,7 +1020,14 @@ that use Sphinx's HTMLWriter class.
|
||||
'https://example.com/css/custom.css',
|
||||
('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
|
||||
.. versionchanged:: 3.5
|
||||
|
||||
Support priority attribute
|
||||
|
||||
.. confval:: html_js_files
|
||||
|
||||
@ -1007,7 +1043,14 @@ that use Sphinx's HTMLWriter class.
|
||||
'https://example.com/scripts/custom.js',
|
||||
('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
|
||||
.. versionchanged:: 3.5
|
||||
|
||||
Support priority attribute
|
||||
|
||||
.. confval:: html_static_path
|
||||
|
||||
@ -1091,6 +1134,23 @@ that use Sphinx's HTMLWriter class.
|
||||
This can now be a string to select the actual text of the link.
|
||||
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
|
||||
|
||||
Custom sidebar templates, must be a dictionary that maps document names to
|
||||
@ -2520,6 +2580,23 @@ Options for the linkcheck builder
|
||||
|
||||
.. 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
|
||||
---------------------------
|
||||
|
@ -168,7 +168,7 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
||||
``:meta private:`` in its :ref:`info-field-lists`.
|
||||
For example:
|
||||
|
||||
.. code-block:: rst
|
||||
.. code-block:: python
|
||||
|
||||
def my_function(my_arg, my_other_arg):
|
||||
"""blah blah blah
|
||||
@ -183,7 +183,7 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
||||
an underscore.
|
||||
For example:
|
||||
|
||||
.. code-block:: rst
|
||||
.. code-block:: python
|
||||
|
||||
def _my_function(my_arg, my_other_arg):
|
||||
"""blah blah blah
|
||||
@ -193,6 +193,16 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
||||
|
||||
.. 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
|
||||
be included if the ``special-members`` flag option is given::
|
||||
|
||||
@ -337,6 +347,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
|
||||
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
|
||||
into a comment with special formatting (using a ``#:`` to start the comment
|
||||
instead of just ``#``), or in a docstring *after* the definition. Comments
|
||||
@ -376,6 +395,9 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
||||
option.
|
||||
.. versionchanged:: 2.0
|
||||
:rst:dir:`autodecorator` added.
|
||||
.. versionchanged:: 3.4
|
||||
:rst:dir:`autodata` and :rst:dir:`autoattribute` now have a ``no-value``
|
||||
option.
|
||||
|
||||
.. note::
|
||||
|
||||
@ -553,7 +575,7 @@ There are also config values that you can set:
|
||||
...
|
||||
|
||||
If you set ``autodoc_type_aliases`` as
|
||||
``{'AliasType': 'your.module.TypeAlias'}``, it generates a following document
|
||||
``{'AliasType': 'your.module.AliasType'}``, it generates the following document
|
||||
internally::
|
||||
|
||||
.. py:function:: f() -> your.module.AliasType:
|
||||
|
@ -304,7 +304,7 @@ The following variables available in the templates:
|
||||
.. data:: modules
|
||||
|
||||
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
|
||||
|
||||
|
@ -294,3 +294,21 @@ class ExampleClass:
|
||||
|
||||
def _private_without_docstring(self):
|
||||
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
|
@ -41,22 +41,20 @@ These extensions are built in and can be activated by respective entries in the
|
||||
Third-party extensions
|
||||
----------------------
|
||||
|
||||
.. todo:: This should reference the GitHub organization now
|
||||
You can find several extensions contributed by users in the `sphinx-contrib`__
|
||||
organization. If you wish to include your extension in this organization,
|
||||
simply follow the instructions provided in the `github-administration`__
|
||||
project. This is optional and there are several extensions hosted elsewhere.
|
||||
The `awesome-sphinxdoc`__ project contains a curated list of Sphinx packages,
|
||||
and many packages use the `Framework :: Sphinx :: Extension`__ and
|
||||
`Framework :: Sphinx :: Theme`__ trove classifiers for Sphinx extensions and
|
||||
themes, respectively.
|
||||
|
||||
You can find several extensions contributed by users in the `Sphinx Contrib`_
|
||||
repository. It is open for anyone who wants to maintain an extension publicly;
|
||||
just send a short message asking for write permissions.
|
||||
|
||||
There are also several extensions hosted elsewhere. The `Sphinx extension
|
||||
survey <https://sphinxext-survey.readthedocs.io/>`__ and `awesome-sphinxdoc
|
||||
<https://github.com/yoloseem/awesome-sphinxdoc>`__ contains a comprehensive
|
||||
list.
|
||||
|
||||
If you write an extension that you think others will find useful or you think
|
||||
should be included as a part of Sphinx, please write to the project mailing
|
||||
list (`join here <https://groups.google.com/forum/#!forum/sphinx-dev>`_).
|
||||
|
||||
.. _Sphinx Contrib: https://bitbucket.org/birkenfeld/sphinx-contrib
|
||||
.. __: https://github.com/sphinx-contrib/
|
||||
.. __: https://github.com/sphinx-contrib/github-administration
|
||||
.. __: https://github.com/yoloseem/awesome-sphinxdoc
|
||||
.. __: https://pypi.org/search/?c=Framework+%3A%3A+Sphinx+%3A%3A+Extension
|
||||
.. __: https://pypi.org/search/?c=Framework+%3A%3A+Sphinx+%3A%3A+Theme
|
||||
|
||||
Where to put your own extensions?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -75,8 +75,9 @@ linking:
|
||||
A dictionary mapping unique identifiers to a tuple ``(target, inventory)``.
|
||||
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
|
||||
inventory file can be found: it can be ``None`` (at the same location as
|
||||
the base URI) or another local or HTTP URI.
|
||||
inventory file can be found: it can be ``None`` (an :file:`objects.inv` file
|
||||
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
|
||||
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
|
||||
as new objects are added to the Python documentation.
|
||||
|
||||
**Multiple target for the inventory**
|
||||
**Multiple targets for the inventory**
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
@ -120,6 +121,16 @@ linking:
|
||||
intersphinx_mapping = {'python': ('https://docs.python.org/3',
|
||||
(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
|
||||
|
||||
The maximum number of days to cache remote inventories. The default is
|
||||
|
@ -203,7 +203,8 @@ Type Annotations
|
||||
This is an alternative to expressing types directly in docstrings.
|
||||
One benefit of expressing types according to `PEP 484`_ is that
|
||||
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::
|
||||
|
||||
@ -221,6 +222,19 @@ Google style with Python 3 type annotations::
|
||||
|
||||
"""
|
||||
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::
|
||||
|
||||
@ -238,6 +252,16 @@ Google style with types in docstrings::
|
||||
|
||||
"""
|
||||
return True
|
||||
|
||||
class Class:
|
||||
"""Summary line.
|
||||
|
||||
Extended description of class
|
||||
|
||||
Attributes:
|
||||
attr1 (int): Description of attr1
|
||||
attr2 (str): Description of attr2
|
||||
"""
|
||||
|
||||
.. Note::
|
||||
`Python 2/3 compatible annotations`_ aren't currently
|
||||
@ -246,6 +270,9 @@ Google style with types in docstrings::
|
||||
.. _PEP 484:
|
||||
https://www.python.org/dev/peps/pep-0484/
|
||||
|
||||
.. _PEP 526:
|
||||
https://www.python.org/dev/peps/pep-0526/
|
||||
|
||||
.. _Python 2/3 compatible annotations:
|
||||
https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
|
||||
|
||||
@ -275,6 +302,7 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
|
||||
napoleon_use_param = True
|
||||
napoleon_use_rtype = True
|
||||
napoleon_type_aliases = None
|
||||
napoleon_attr_annotations = True
|
||||
|
||||
.. _Google style:
|
||||
https://google.github.io/styleguide/pyguide.html
|
||||
@ -511,3 +539,35 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
|
||||
: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``
|
@ -569,12 +569,28 @@ __ http://pygments.org/docs/lexers
|
||||
|
||||
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
|
||||
|
||||
.. 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
|
||||
:dedent: 4
|
||||
@ -582,6 +598,8 @@ __ http://pygments.org/docs/lexers
|
||||
some ruby code
|
||||
|
||||
.. versionadded:: 1.3
|
||||
.. versionchanged:: 3.5
|
||||
Support automatic dedent.
|
||||
|
||||
.. rst:directive:option:: force
|
||||
:type: no value
|
||||
@ -742,6 +760,9 @@ __ http://pygments.org/docs/lexers
|
||||
.. versionchanged:: 2.1
|
||||
Added the ``force`` option.
|
||||
|
||||
.. versionchanged:: 3.5
|
||||
Support automatic dedent.
|
||||
|
||||
.. _glossary-directive:
|
||||
|
||||
Glossary
|
||||
@ -1199,20 +1220,29 @@ the definition of the symbol. There is this directive:
|
||||
the following definition. If the definition spans multiple lines, each
|
||||
continuation line must begin with a colon placed at the same column as in
|
||||
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
|
||||
distinguish different sets of production lists that belong to different
|
||||
grammars. Multiple production lists with the same *productionGroup* thus
|
||||
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
|
||||
(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`.
|
||||
However, if you have given a *productionGroup* argument you must prefix the
|
||||
Outside of the production list,
|
||||
if you have given a *productionGroup* argument you must prefix the
|
||||
token name in the cross-reference with the group name and a colon,
|
||||
e.g., "``myGroup:sum``" instead of just "``sum``".
|
||||
If the group should not be shown in the title of the link either
|
||||
|
@ -18,6 +18,7 @@ module.exports = function(config) {
|
||||
'sphinx/themes/basic/static/underscore.js',
|
||||
'sphinx/themes/basic/static/jquery.js',
|
||||
'sphinx/themes/basic/static/doctools.js',
|
||||
'sphinx/themes/basic/static/searchtools.js',
|
||||
'tests/js/*.js'
|
||||
],
|
||||
|
||||
|
10
setup.cfg
10
setup.cfg
@ -29,9 +29,11 @@ directory = sphinx/locale/
|
||||
[flake8]
|
||||
max-line-length = 95
|
||||
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
|
||||
import-order-style = smarkets
|
||||
per-file-ignores =
|
||||
tests/*: E501
|
||||
|
||||
[flake8:local-plugins]
|
||||
extension =
|
||||
@ -39,6 +41,9 @@ extension =
|
||||
paths =
|
||||
.
|
||||
|
||||
[isort]
|
||||
line_length = 95
|
||||
|
||||
[mypy]
|
||||
python_version = 3.5
|
||||
disallow_incomplete_defs = True
|
||||
@ -55,12 +60,11 @@ filterwarnings =
|
||||
all
|
||||
ignore::DeprecationWarning:docutils.io
|
||||
ignore::DeprecationWarning:pyximport.pyximport
|
||||
ignore::ImportWarning:importlib._bootstrap
|
||||
ignore::PendingDeprecationWarning:sphinx.util.pycompat
|
||||
markers =
|
||||
sphinx
|
||||
apidoc
|
||||
setup_command
|
||||
test_params
|
||||
testpaths = tests
|
||||
|
||||
[coverage:run]
|
||||
|
12
setup.py
12
setup.py
@ -43,15 +43,15 @@ extras_require = {
|
||||
],
|
||||
'lint': [
|
||||
'flake8>=3.5.0',
|
||||
'flake8-import-order',
|
||||
'mypy>=0.780',
|
||||
'isort',
|
||||
'mypy>=0.800',
|
||||
'docutils-stubs',
|
||||
],
|
||||
'test': [
|
||||
'pytest',
|
||||
'pytest-cov',
|
||||
'html5lib',
|
||||
'typed_ast', # for py35-37
|
||||
"typed_ast; python_version < '3.8'",
|
||||
'cython',
|
||||
],
|
||||
}
|
||||
@ -76,9 +76,10 @@ class Tee:
|
||||
|
||||
|
||||
try:
|
||||
from babel.messages.pofile import read_po
|
||||
from babel.messages.frontend import compile_catalog
|
||||
from json import dump
|
||||
|
||||
from babel.messages.frontend import compile_catalog
|
||||
from babel.messages.pofile import read_po
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
@ -203,6 +204,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Programming Language :: Python :: Implementation :: PyPy',
|
||||
'Framework :: Setuptools Plugin',
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -32,8 +32,8 @@ if 'PYTHONWARNINGS' not in os.environ:
|
||||
warnings.filterwarnings('ignore', "'U' mode is deprecated",
|
||||
DeprecationWarning, module='docutils.io')
|
||||
|
||||
__version__ = '3.3.0+'
|
||||
__released__ = '3.3.0' # used when Sphinx builds its own docs
|
||||
__version__ = '3.5.0+'
|
||||
__released__ = '3.5.0' # used when Sphinx builds its own docs
|
||||
|
||||
#: Version info for better programmatic use.
|
||||
#:
|
||||
@ -43,7 +43,7 @@ __released__ = '3.3.0' # used when Sphinx builds its own docs
|
||||
#:
|
||||
#: .. versionadded:: 1.2
|
||||
#: Before version 1.2, check the string ``sphinx.__version__``.
|
||||
version_info = (3, 3, 0, 'beta', 0)
|
||||
version_info = (3, 5, 0, 'beta', 0)
|
||||
|
||||
package_dir = path.abspath(path.dirname(__file__))
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -18,7 +18,7 @@ import warnings
|
||||
from collections import deque
|
||||
from io import StringIO
|
||||
from os import path
|
||||
from typing import Any, Callable, Dict, IO, List, Optional, Tuple, Union
|
||||
from typing import IO, Any, Callable, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, TextElement
|
||||
@ -28,7 +28,7 @@ from docutils.transforms import Transform
|
||||
from pygments.lexer import Lexer
|
||||
|
||||
import sphinx
|
||||
from sphinx import package_dir, locale
|
||||
from sphinx import locale, package_dir
|
||||
from sphinx.config import Config
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.domains import Domain, Index
|
||||
@ -43,9 +43,7 @@ from sphinx.project import Project
|
||||
from sphinx.registry import SphinxComponentRegistry
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.theming import Theme
|
||||
from sphinx.util import docutils
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import progress_message
|
||||
from sphinx.util import docutils, logging, progress_message
|
||||
from sphinx.util.build_phase import BuildPhase
|
||||
from sphinx.util.console import bold # type: ignore
|
||||
from sphinx.util.i18n import CatalogRepository
|
||||
@ -56,8 +54,10 @@ from sphinx.util.typing import RoleFunction, TitleGetter
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from docutils.nodes import Node # NOQA
|
||||
from typing import Type # for python3.5.1
|
||||
|
||||
from docutils.nodes import Node # NOQA
|
||||
|
||||
from sphinx.builders import Builder
|
||||
|
||||
|
||||
@ -135,7 +135,7 @@ class Sphinx:
|
||||
: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,
|
||||
status: IO = sys.stdout, warning: IO = sys.stderr,
|
||||
freshenv: bool = False, warningiserror: bool = False, tags: List[str] = None,
|
||||
@ -294,8 +294,8 @@ class Sphinx:
|
||||
if catalog.domain == 'sphinx' and catalog.is_outdated():
|
||||
catalog.write_mo(self.config.language)
|
||||
|
||||
locale_dirs = [None] # type: List[Optional[str]]
|
||||
locale_dirs += 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)
|
||||
@ -404,9 +404,10 @@ class Sphinx:
|
||||
def require_sphinx(self, version: str) -> None:
|
||||
"""Check the Sphinx version if requested.
|
||||
|
||||
Compare *version* (which must be a ``major.minor`` version string, e.g.
|
||||
``'1.1'``) with the version of the running Sphinx, and abort the build
|
||||
when it is too old.
|
||||
Compare *version* with the version of the running Sphinx, and abort the
|
||||
build when it is too old.
|
||||
|
||||
:param version: The required version in the form of ``major.minor``.
|
||||
|
||||
.. versionadded:: 1.0
|
||||
"""
|
||||
@ -420,11 +421,11 @@ class Sphinx:
|
||||
For details on available core events and the arguments of callback
|
||||
functions, please see :ref:`events`.
|
||||
|
||||
Registered callbacks will be invoked on event in the order of *priority* and
|
||||
registration. The priority is ascending order.
|
||||
|
||||
The method returns a "listener ID" that can be used as an argument to
|
||||
:meth:`disconnect`.
|
||||
:param event: The name of target event
|
||||
:param callback: Callback function for the event
|
||||
:param priority: The priority of the callback. The callbacks will be invoked
|
||||
in the order of *priority* in asending.
|
||||
:return: A listener ID. It can be used for :meth:`disconnect`.
|
||||
|
||||
.. versionchanged:: 3.0
|
||||
|
||||
@ -436,7 +437,10 @@ class Sphinx:
|
||||
return listener_id
|
||||
|
||||
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)
|
||||
self.events.disconnect(listener_id)
|
||||
|
||||
@ -447,6 +451,10 @@ class Sphinx:
|
||||
Return the return values of all callbacks as a list. Do not emit core
|
||||
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
|
||||
|
||||
Added *allowed_exceptions* to specify path-through exceptions
|
||||
@ -459,6 +467,10 @@ class Sphinx:
|
||||
|
||||
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
|
||||
.. versionchanged:: 3.1
|
||||
|
||||
@ -472,10 +484,9 @@ class Sphinx:
|
||||
def add_builder(self, builder: "Type[Builder]", override: bool = False) -> None:
|
||||
"""Register a new builder.
|
||||
|
||||
*builder* must be a class that inherits from :class:`~sphinx.builders.Builder`.
|
||||
|
||||
If *override* is True, the given *builder* is forcedly installed even if
|
||||
a builder having the same name is already installed.
|
||||
:param builder: A builder class
|
||||
:param override: If true, install the builder forcedly even if another builder
|
||||
is already installed as the same name
|
||||
|
||||
.. versionchanged:: 1.8
|
||||
Add *override* keyword.
|
||||
@ -488,27 +499,34 @@ class Sphinx:
|
||||
"""Register a configuration value.
|
||||
|
||||
This is necessary for Sphinx to recognize new values and set default
|
||||
values accordingly. The *name* should be prefixed with the extension
|
||||
name, to avoid clashes. The *default* value can be any Python object.
|
||||
The string value *rebuild* must be one of those values:
|
||||
values accordingly.
|
||||
|
||||
* ``'env'`` if a change in the setting only takes effect when a
|
||||
document is parsed -- this means that the whole environment must be
|
||||
rebuilt.
|
||||
* ``'html'`` if a change in the setting needs a full rebuild of HTML
|
||||
documents.
|
||||
* ``''`` if a change in the setting will not need any special rebuild.
|
||||
|
||||
.. versionchanged:: 0.6
|
||||
Changed *rebuild* from a simple boolean (equivalent to ``''`` or
|
||||
``'env'``) to a string. However, booleans are still accepted and
|
||||
converted internally.
|
||||
:param name: The name of configuration value. It is recommended to be prefixed
|
||||
with the extension name (ex. ``html_logo``, ``epub_title``)
|
||||
:param default: The default value of the configuration.
|
||||
:param rebuild: The condition of rebuild. It must be one of those values:
|
||||
|
||||
* ``'env'`` if a change in the setting only takes effect when a
|
||||
document is parsed -- this means that the whole environment must be
|
||||
rebuilt.
|
||||
* ``'html'`` if a change in the setting needs a full rebuild of HTML
|
||||
documents.
|
||||
* ``''`` if a change in the setting will not need any special rebuild.
|
||||
:param types: The type of configuration value. A list of types can be specified. For
|
||||
example, ``[str]`` is used to describe a configuration that takes string
|
||||
value.
|
||||
|
||||
.. versionchanged:: 0.4
|
||||
If the *default* value is a callable, it will be called with the
|
||||
config object as its argument in order to get the default value.
|
||||
This can be used to implement config values whose default depends on
|
||||
other values.
|
||||
|
||||
.. versionchanged:: 0.6
|
||||
Changed *rebuild* from a simple boolean (equivalent to ``''`` or
|
||||
``'env'``) to a string. However, booleans are still accepted and
|
||||
converted internally.
|
||||
"""
|
||||
logger.debug('[app] adding config value: %r',
|
||||
(name, default, rebuild) + ((types,) if types else ()))
|
||||
@ -520,6 +538,8 @@ class Sphinx:
|
||||
"""Register an event called *name*.
|
||||
|
||||
This is needed to be able to emit it.
|
||||
|
||||
:param name: The name of the event
|
||||
"""
|
||||
logger.debug('[app] adding event: %r', name)
|
||||
self.events.add(name)
|
||||
@ -532,8 +552,10 @@ class Sphinx:
|
||||
builtin translator. This allows extensions to use custom translator
|
||||
and define custom nodes for the translator (see :meth:`add_node`).
|
||||
|
||||
If *override* is True, the given *translator_class* is forcedly installed even if
|
||||
a translator for *name* is already installed.
|
||||
: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
|
||||
.. versionchanged:: 1.8
|
||||
@ -548,6 +570,11 @@ class Sphinx:
|
||||
This is necessary for Docutils internals. It may also be used in the
|
||||
future to validate nodes in the parsed documents.
|
||||
|
||||
:param node: A node class
|
||||
:param kwargs: Visitor functions for each builder (see below)
|
||||
:param override: If true, install the node forcedly even if another node is already
|
||||
installed as the same name
|
||||
|
||||
Node visitor functions for the Sphinx HTML, LaTeX, text and manpage
|
||||
writers can be given as keyword arguments: the keyword should be one or
|
||||
more of ``'html'``, ``'latex'``, ``'text'``, ``'man'``, ``'texinfo'``
|
||||
@ -569,9 +596,6 @@ class Sphinx:
|
||||
Obviously, translators for which you don't specify visitor methods will
|
||||
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
|
||||
Added the support for keyword arguments giving visit functions.
|
||||
"""
|
||||
@ -591,24 +615,21 @@ class Sphinx:
|
||||
Sphinx numbers the node automatically. And then the users can refer it
|
||||
using :rst:role:`numref`.
|
||||
|
||||
*figtype* is a type of enumerable nodes. Each figtypes have individual
|
||||
numbering sequences. As a system figtypes, ``figure``, ``table`` and
|
||||
``code-block`` are defined. It is able to add custom nodes to these
|
||||
default figtypes. It is also able to define new custom figtype if new
|
||||
figtype is given.
|
||||
|
||||
*title_getter* is a getter function to obtain the title of node. It
|
||||
takes an instance of the enumerable node, and it must return its title
|
||||
as string. The title is used to the default title of references for
|
||||
:rst:role:`ref`. By default, Sphinx searches
|
||||
``docutils.nodes.caption`` or ``docutils.nodes.title`` from the node as
|
||||
a title.
|
||||
|
||||
Other keyword arguments are used for node visitor functions. See the
|
||||
: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.
|
||||
:param node: A node class
|
||||
:param figtype: The type of enumerable nodes. Each figtypes have individual numbering
|
||||
sequences. As a system figtypes, ``figure``, ``table`` and
|
||||
``code-block`` are defined. It is able to add custom nodes to these
|
||||
default figtypes. It is also able to define new custom figtype if new
|
||||
figtype is given.
|
||||
:param title_getter: A getter function to obtain the title of node. It takes an
|
||||
instance of the enumerable node, and it must return its title as
|
||||
string. The title is used to the default title of references for
|
||||
:rst:role:`ref`. By default, Sphinx searches
|
||||
``docutils.nodes.caption`` or ``docutils.nodes.title`` from the
|
||||
node as a title.
|
||||
:param kwargs: Visitor functions for each builder (same as :meth:`add_node`)
|
||||
:param override: If true, install the node forcedly even if another node is already
|
||||
installed as the same name
|
||||
|
||||
.. versionadded:: 1.4
|
||||
"""
|
||||
@ -618,10 +639,10 @@ class Sphinx:
|
||||
def add_directive(self, name: str, cls: "Type[Directive]", override: bool = False) -> None:
|
||||
"""Register a Docutils directive.
|
||||
|
||||
*name* must be the prospective directive name. *cls* is a directive
|
||||
class which inherits ``docutils.parsers.rst.Directive``. For more
|
||||
details, see `the Docutils docs
|
||||
<http://docutils.sourceforge.net/docs/howto/rst-directives.html>`_ .
|
||||
:param name: The name of directive
|
||||
:param cls: A directive class
|
||||
:param override: If true, install the directive forcedly even if another directive
|
||||
is already installed as the same name
|
||||
|
||||
For example, a custom directive named ``my-directive`` would be added
|
||||
like this:
|
||||
@ -646,8 +667,8 @@ class Sphinx:
|
||||
def setup(app):
|
||||
add_directive('my-directive', MyDirective)
|
||||
|
||||
If *override* is True, the given *cls* is forcedly installed even if
|
||||
a directive named as *name* is already installed.
|
||||
For more details, see `the Docutils docs
|
||||
<http://docutils.sourceforge.net/docs/howto/rst-directives.html>`__ .
|
||||
|
||||
.. versionchanged:: 0.6
|
||||
Docutils 0.5-style directive classes are now supported.
|
||||
@ -666,13 +687,13 @@ class Sphinx:
|
||||
def add_role(self, name: str, role: Any, override: bool = False) -> None:
|
||||
"""Register a Docutils role.
|
||||
|
||||
*name* must be the role name that occurs in the source, *role* the role
|
||||
function. Refer to the `Docutils documentation
|
||||
<http://docutils.sourceforge.net/docs/howto/rst-roles.html>`_ for
|
||||
more information.
|
||||
:param name: The name of role
|
||||
:param role: A role function
|
||||
:param override: If true, install the role forcedly even if another role is already
|
||||
installed as the same name
|
||||
|
||||
If *override* is True, the given *role* is forcedly installed even if
|
||||
a role named as *name* is already installed.
|
||||
For more details about role functions, see `the Docutils docs
|
||||
<http://docutils.sourceforge.net/docs/howto/rst-roles.html>`__ .
|
||||
|
||||
.. versionchanged:: 1.8
|
||||
Add *override* keyword.
|
||||
@ -708,11 +729,9 @@ class Sphinx:
|
||||
def add_domain(self, domain: "Type[Domain]", override: bool = False) -> None:
|
||||
"""Register a domain.
|
||||
|
||||
Make the given *domain* (which must be a class; more precisely, a
|
||||
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.
|
||||
:param domain: A domain class
|
||||
:param override: If true, install the domain forcedly even if another domain
|
||||
is already installed as the same name
|
||||
|
||||
.. versionadded:: 1.0
|
||||
.. versionchanged:: 1.8
|
||||
@ -727,8 +746,11 @@ class Sphinx:
|
||||
Like :meth:`add_directive`, but the directive is added to the domain
|
||||
named *domain*.
|
||||
|
||||
If *override* is True, the given *directive* is forcedly installed even if
|
||||
a directive named as *name* is already installed.
|
||||
:param domain: The name of target domain
|
||||
:param name: A name of directive
|
||||
:param cls: A directive class
|
||||
:param override: If true, install the directive forcedly even if another directive
|
||||
is already installed as the same name
|
||||
|
||||
.. versionadded:: 1.0
|
||||
.. versionchanged:: 1.8
|
||||
@ -743,8 +765,11 @@ class Sphinx:
|
||||
Like :meth:`add_role`, but the role is added to the domain named
|
||||
*domain*.
|
||||
|
||||
If *override* is True, the given *role* is forcedly installed even if
|
||||
a role named as *name* is already installed.
|
||||
:param domain: The name of target domain
|
||||
:param name: A name of role
|
||||
:param role: A role function
|
||||
:param override: If true, install the role forcedly even if another role is already
|
||||
installed as the same name
|
||||
|
||||
.. versionadded:: 1.0
|
||||
.. versionchanged:: 1.8
|
||||
@ -756,11 +781,12 @@ class Sphinx:
|
||||
) -> None:
|
||||
"""Register a custom index for a domain.
|
||||
|
||||
Add a custom *index* class to the domain named *domain*. *index* must
|
||||
be a subclass of :class:`~sphinx.domains.Index`.
|
||||
Add a custom *index* class to the domain named *domain*.
|
||||
|
||||
If *override* is True, the given *index* is forcedly installed even if
|
||||
an index having the same name is already installed.
|
||||
:param domain: The name of target domain
|
||||
:param index: A index class
|
||||
:param override: If true, install the index forcedly even if another index is
|
||||
already installed as the same name
|
||||
|
||||
.. versionadded:: 1.0
|
||||
.. versionchanged:: 1.8
|
||||
@ -881,6 +907,8 @@ class Sphinx:
|
||||
the list of transforms that are applied after Sphinx parses a reST
|
||||
document.
|
||||
|
||||
:param transform: A transform class
|
||||
|
||||
.. list-table:: priority range categories for Sphinx transforms
|
||||
:widths: 20,80
|
||||
|
||||
@ -913,25 +941,29 @@ class Sphinx:
|
||||
Add the standard docutils :class:`Transform` subclass *transform* to
|
||||
the list of transforms that are applied before Sphinx writes a
|
||||
document.
|
||||
|
||||
:param transform: A transform class
|
||||
"""
|
||||
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`."""
|
||||
warnings.warn('The app.add_javascript() is deprecated. '
|
||||
'Please use app.add_js_file() instead.',
|
||||
RemovedInSphinx40Warning, stacklevel=2)
|
||||
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.
|
||||
|
||||
Add *filename* to the list of JavaScript files that the default HTML
|
||||
template will include. The filename must be relative to the HTML
|
||||
static path , or a full URI with scheme. If the keyword argument
|
||||
``body`` is given, its value will be added between the
|
||||
``<script>`` tags. Extra keyword arguments are included as
|
||||
attributes of the ``<script>`` tag.
|
||||
template will include in order of *priority* (ascending). The filename
|
||||
must be relative to the HTML static path , or a full URI with scheme.
|
||||
If the priority of JavaScript file is the same as others, the JavaScript
|
||||
files will be included in order of the registration. If the keyword
|
||||
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::
|
||||
|
||||
@ -944,23 +976,43 @@ class Sphinx:
|
||||
app.add_js_file(None, body="var myVariable = 'foo';")
|
||||
# => <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
|
||||
|
||||
.. versionchanged:: 1.8
|
||||
Renamed from ``app.add_javascript()``.
|
||||
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.
|
||||
|
||||
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,
|
||||
or a full URI with scheme. The keyword arguments are also accepted for
|
||||
attributes of ``<link>`` tag.
|
||||
will include in order of *priority* (ascending). The filename must be
|
||||
relative to the HTML static path, or a full URI with scheme. If the
|
||||
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::
|
||||
|
||||
@ -975,6 +1027,19 @@ class Sphinx:
|
||||
# => <link rel="alternate stylesheet" href="_static/fancy.css"
|
||||
# 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
|
||||
|
||||
.. versionchanged:: 1.6
|
||||
@ -987,11 +1052,14 @@ class Sphinx:
|
||||
.. versionchanged:: 1.8
|
||||
Renamed from ``app.add_stylesheet()``.
|
||||
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)
|
||||
self.registry.add_css_files(filename, **kwargs)
|
||||
self.registry.add_css_files(filename, priority=priority, **kwargs)
|
||||
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
|
||||
) -> None:
|
||||
@ -1000,7 +1068,7 @@ class Sphinx:
|
||||
'Please use app.add_css_file() instead.',
|
||||
RemovedInSphinx40Warning, stacklevel=2)
|
||||
|
||||
attributes = {} # type: Dict[str, str]
|
||||
attributes = {} # type: Dict[str, Any]
|
||||
if alternate:
|
||||
attributes['rel'] = 'alternate stylesheet'
|
||||
else:
|
||||
@ -1103,7 +1171,7 @@ class Sphinx:
|
||||
.. versionadded:: 1.1
|
||||
"""
|
||||
logger.debug('[app] adding search language: %r', cls)
|
||||
from sphinx.search import languages, SearchLanguage
|
||||
from sphinx.search import SearchLanguage, languages
|
||||
assert issubclass(cls, SearchLanguage)
|
||||
languages[cls.lang] = cls
|
||||
|
||||
@ -1175,9 +1243,10 @@ class Sphinx:
|
||||
def add_message_catalog(self, catalog: str, locale_dir: str) -> None:
|
||||
"""Register a message catalog.
|
||||
|
||||
The *catalog* is a name of catalog, and *locale_dir* is a base path
|
||||
of message catalog. For more details, see
|
||||
:func:`sphinx.locale.get_translation()`.
|
||||
:param catalog: A name of catalog
|
||||
:param locale_dir: The base path of message catalog
|
||||
|
||||
For more details, see :func:`sphinx.locale.get_translation()`.
|
||||
|
||||
.. versionadded:: 1.8
|
||||
"""
|
||||
@ -1188,7 +1257,7 @@ class Sphinx:
|
||||
def is_parallel_allowed(self, typ: str) -> bool:
|
||||
"""Check parallel processing is allowed or not.
|
||||
|
||||
``typ`` is a type of processing; ``'read'`` or ``'write'``.
|
||||
:param typ: A type of processing; ``'read'`` or ``'write'``.
|
||||
"""
|
||||
if typ == 'read':
|
||||
attrname = 'parallel_read_safe'
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -17,26 +17,24 @@ from docutils import nodes
|
||||
from docutils.nodes import Node
|
||||
|
||||
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.errors import SphinxError
|
||||
from sphinx.events import EventManager
|
||||
from sphinx.io import read_doc
|
||||
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.console import bold # type: ignore
|
||||
from sphinx.util.docutils import sphinx_domains
|
||||
from sphinx.util.i18n import CatalogInfo, CatalogRepository, docname_to_domain
|
||||
from sphinx.util.osutil import SEP, ensuredir, relative_uri, relpath
|
||||
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, \
|
||||
parallel_available
|
||||
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, parallel_available
|
||||
from sphinx.util.tags import Tags
|
||||
|
||||
# side effect: registers roles and directives
|
||||
from sphinx import roles # noqa
|
||||
from sphinx import directives # noqa
|
||||
|
||||
from sphinx import directives # NOQA isort:skip
|
||||
from sphinx import roles # NOQA isort:skip
|
||||
try:
|
||||
import multiprocessing
|
||||
except ImportError:
|
||||
@ -45,6 +43,7 @@ except ImportError:
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Type # for python3.5.1
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -25,11 +25,10 @@ from sphinx import addnodes
|
||||
from sphinx.builders.html import BuildInfo, StandaloneHTMLBuilder
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import status_iterator
|
||||
from sphinx.util import logging, status_iterator
|
||||
from sphinx.util.fileutil import copy_asset_file
|
||||
from sphinx.util.i18n import format_date
|
||||
from sphinx.util.osutil import ensuredir, copyfile
|
||||
from sphinx.util.osutil import copyfile, ensuredir
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
@ -208,7 +207,12 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
appeared = set() # type: Set[str]
|
||||
for node in nodes:
|
||||
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:
|
||||
appeared.add(node['refuri'])
|
||||
|
||||
|
@ -4,23 +4,19 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import warnings
|
||||
from typing import Any, Dict
|
||||
|
||||
from sphinxcontrib.applehelp import (
|
||||
AppleHelpCodeSigningFailed,
|
||||
AppleHelpIndexerFailed,
|
||||
AppleHelpBuilder,
|
||||
)
|
||||
from sphinxcontrib.applehelp import (AppleHelpBuilder, AppleHelpCodeSigningFailed,
|
||||
AppleHelpIndexerFailed)
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||
|
||||
|
||||
deprecated_alias('sphinx.builders.applehelp',
|
||||
{
|
||||
'AppleHelpCodeSigningFailed': AppleHelpCodeSigningFailed,
|
||||
|
@ -4,14 +4,13 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import html
|
||||
from os import path
|
||||
from typing import Any, Dict, List, Tuple
|
||||
from typing import cast
|
||||
from typing import Any, Dict, List, Tuple, cast
|
||||
|
||||
from sphinx import package_dir
|
||||
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.osutil import ensuredir, os_path
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
.. _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.
|
||||
"""
|
||||
|
||||
@ -18,7 +18,6 @@ from sphinxcontrib.devhelp import DevhelpBuilder
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||
|
||||
|
||||
deprecated_alias('sphinx.builders.devhelp',
|
||||
{
|
||||
'DevhelpBuilder': DevhelpBuilder,
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
Build epub3 files.
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -18,7 +18,7 @@ from typing import Any, Dict, List, Set, Tuple
|
||||
from sphinx import package_dir
|
||||
from sphinx.application import Sphinx
|
||||
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.locale import __
|
||||
from sphinx.util import logging, xmlname_checker
|
||||
|
@ -4,33 +4,32 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
from codecs import open
|
||||
from collections import defaultdict, OrderedDict
|
||||
from datetime import datetime, tzinfo, timedelta
|
||||
from os import path, walk, getenv
|
||||
from collections import OrderedDict, defaultdict
|
||||
from datetime import datetime, timedelta, tzinfo
|
||||
from os import getenv, path, walk
|
||||
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 docutils import nodes
|
||||
from docutils.nodes import Element
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx import package_dir
|
||||
from sphinx import addnodes, package_dir
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.domains.python import pairindextypes
|
||||
from sphinx.errors import ThemeError
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import split_index_msg, logging, status_iterator
|
||||
from sphinx.util import logging, split_index_msg, status_iterator
|
||||
from sphinx.util.console import bold # type: ignore
|
||||
from sphinx.util.i18n import CatalogInfo, docname_to_domain
|
||||
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.template import SphinxRenderer
|
||||
|
||||
@ -316,7 +315,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_builder(MessageCatalogBuilder)
|
||||
|
||||
app.add_config_value('gettext_compact', True, 'gettext', Any)
|
||||
app.add_config_value('gettext_compact', True, 'gettext', {bool, str})
|
||||
app.add_config_value('gettext_location', True, 'gettext')
|
||||
app.add_config_value('gettext_uuid', False, 'gettext')
|
||||
app.add_config_value('gettext_auto_build', True, 'env')
|
||||
|
@ -4,17 +4,18 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import html
|
||||
import os
|
||||
import posixpath
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
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
|
||||
@ -24,10 +25,10 @@ from docutils.io import DocTreeInput, StringOutput
|
||||
from docutils.nodes import Node
|
||||
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.builders import Builder
|
||||
from sphinx.config import Config, ENUM
|
||||
from sphinx.config import ENUM, Config
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.domains import Domain, Index, IndexEntry
|
||||
from sphinx.environment.adapters.asset import ImageAdapter
|
||||
@ -38,15 +39,15 @@ from sphinx.highlighting import PygmentsBridge
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.search import js_index
|
||||
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.fileutil import copy_asset
|
||||
from sphinx.util.i18n import format_date
|
||||
from sphinx.util.inventory import InventoryFile
|
||||
from sphinx.util.matching import patmatch, Matcher, DOTFILES
|
||||
from sphinx.util.osutil import os_path, relative_uri, ensuredir, movefile, copyfile
|
||||
from sphinx.util.matching import DOTFILES, Matcher, patmatch
|
||||
from sphinx.util.osutil import copyfile, ensuredir, os_path, relative_uri
|
||||
from sphinx.util.tags import Tags
|
||||
from sphinx.writers.html import HTMLWriter, HTMLTranslator
|
||||
from sphinx.writers.html import HTMLTranslator, HTMLWriter
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
@ -89,10 +90,13 @@ class Stylesheet(str):
|
||||
|
||||
attributes = None # type: Dict[str, str]
|
||||
filename = None # type: str
|
||||
priority = None # type: int
|
||||
|
||||
def __new__(cls, filename: str, *args: str, **attributes: str) -> "Stylesheet":
|
||||
self = str.__new__(cls, filename) # type: ignore
|
||||
def __new__(cls, filename: str, *args: str, priority: int = 500, **attributes: Any
|
||||
) -> "Stylesheet":
|
||||
self = str.__new__(cls, filename)
|
||||
self.filename = filename
|
||||
self.priority = priority
|
||||
self.attributes = attributes
|
||||
self.attributes.setdefault('rel', 'stylesheet')
|
||||
self.attributes.setdefault('type', 'text/css')
|
||||
@ -112,10 +116,12 @@ class JavaScript(str):
|
||||
|
||||
attributes = None # type: Dict[str, str]
|
||||
filename = None # type: str
|
||||
priority = None # type: int
|
||||
|
||||
def __new__(cls, filename: str, **attributes: str) -> "JavaScript":
|
||||
self = str.__new__(cls, filename) # type: ignore
|
||||
def __new__(cls, filename: str, priority: int = 500, **attributes: str) -> "JavaScript":
|
||||
self = str.__new__(cls, filename)
|
||||
self.filename = filename
|
||||
self.priority = priority
|
||||
self.attributes = attributes
|
||||
|
||||
return self
|
||||
@ -289,30 +295,31 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.add_css_file(filename, **attrs)
|
||||
|
||||
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)
|
||||
|
||||
def add_css_file(self, filename: str, **kwargs: str) -> None:
|
||||
def add_css_file(self, filename: str, **kwargs: Any) -> None:
|
||||
if '://' not in filename:
|
||||
filename = posixpath.join('_static', filename)
|
||||
|
||||
self.css_files.append(Stylesheet(filename, **kwargs)) # type: ignore
|
||||
|
||||
def init_js_files(self) -> None:
|
||||
self.add_js_file('jquery.js')
|
||||
self.add_js_file('underscore.js')
|
||||
self.add_js_file('doctools.js')
|
||||
self.add_js_file('language_data.js')
|
||||
self.add_js_file('jquery.js', priority=200)
|
||||
self.add_js_file('underscore.js', priority=200)
|
||||
self.add_js_file('doctools.js', priority=200)
|
||||
|
||||
for filename, attrs in self.app.registry.js_files:
|
||||
self.add_js_file(filename, **attrs)
|
||||
|
||||
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)
|
||||
|
||||
if self.config.language and self._get_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:
|
||||
filename = posixpath.join('_static', filename)
|
||||
|
||||
@ -448,9 +455,6 @@ class StandaloneHTMLBuilder(Builder):
|
||||
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 ''
|
||||
|
||||
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()
|
||||
|
||||
rellinks = [] # type: List[Tuple[str, str, str, str]]
|
||||
@ -462,6 +466,10 @@ class StandaloneHTMLBuilder(Builder):
|
||||
rellinks.append((indexname, indexcls.localname,
|
||||
'', 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:
|
||||
stylename = self.config.html_style
|
||||
elif self.theme:
|
||||
@ -1012,12 +1020,20 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.add_sidebars(pagename, ctx)
|
||||
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)
|
||||
newtmpl = self.app.emit_firstresult('html-page-context', pagename,
|
||||
templatename, ctx, event_arg)
|
||||
if 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:
|
||||
output = self.templates.render(templatename, ctx)
|
||||
except UnicodeError:
|
||||
@ -1071,7 +1087,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
else:
|
||||
with open(searchindexfn + '.tmp', 'wb') as fb:
|
||||
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:
|
||||
@ -1189,10 +1205,21 @@ def validate_html_favicon(app: Sphinx, config: Config) -> None:
|
||||
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
|
||||
import sphinxcontrib.serializinghtml # NOQA
|
||||
|
||||
import sphinx.builders.dirhtml # NOQA
|
||||
import sphinx.builders.singlehtml # NOQA
|
||||
import sphinxcontrib.serializinghtml # NOQA
|
||||
|
||||
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
@ -1218,7 +1245,9 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_config_value('html_sidebars', {}, 'html')
|
||||
app.add_config_value('html_additional_pages', {}, 'html')
|
||||
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_split_index', False, 'html')
|
||||
app.add_config_value('html_copy_source', True, 'html')
|
||||
@ -1243,9 +1272,14 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_config_value('html_math_renderer', None, 'env')
|
||||
app.add_config_value('html4_writer', False, 'html')
|
||||
|
||||
# events
|
||||
app.add_event('html-collect-pages')
|
||||
app.add_event('html-page-context')
|
||||
|
||||
# event handlers
|
||||
app.connect('config-inited', convert_html_css_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_static_path, priority=800)
|
||||
app.connect('config-inited', validate_html_logo, priority=800)
|
||||
|
@ -4,12 +4,12 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import Any, Dict
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
@ -28,7 +28,7 @@ class KeyboardTransform(SphinxPostTransform):
|
||||
|
||||
After::
|
||||
|
||||
<literal class="kbd">
|
||||
<literal class="kbd compound">
|
||||
<literal class="kbd">
|
||||
Control
|
||||
-
|
||||
@ -37,18 +37,30 @@ class KeyboardTransform(SphinxPostTransform):
|
||||
"""
|
||||
default_priority = 400
|
||||
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:
|
||||
matcher = NodeMatcher(nodes.literal, classes=["kbd"])
|
||||
for node in self.document.traverse(matcher): # type: nodes.literal
|
||||
parts = self.pattern.split(node[-1].astext())
|
||||
if len(parts) == 1:
|
||||
if len(parts) == 1 or self.is_multiwords_key(parts):
|
||||
continue
|
||||
|
||||
node['classes'].append('compound')
|
||||
node.pop()
|
||||
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"])
|
||||
|
||||
try:
|
||||
@ -58,6 +70,16 @@ class KeyboardTransform(SphinxPostTransform):
|
||||
except IndexError:
|
||||
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]:
|
||||
app.add_post_transform(KeyboardTransform)
|
||||
|
@ -5,21 +5,19 @@
|
||||
Build HTML help support files.
|
||||
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.
|
||||
"""
|
||||
|
||||
import warnings
|
||||
from typing import Any, Dict
|
||||
|
||||
from sphinxcontrib.htmlhelp import (
|
||||
chm_locales, chm_htmlescape, HTMLHelpBuilder, default_htmlhelp_basename
|
||||
)
|
||||
from sphinxcontrib.htmlhelp import (HTMLHelpBuilder, chm_htmlescape, chm_locales,
|
||||
default_htmlhelp_basename)
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||
|
||||
|
||||
deprecated_alias('sphinx.builders.htmlhelp',
|
||||
{
|
||||
'chm_locales': chm_locales,
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -17,18 +17,18 @@ from docutils.frontend import OptionParser
|
||||
from docutils.nodes import Node
|
||||
|
||||
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.builders import Builder
|
||||
from sphinx.builders.latex.constants import ADDITIONAL_SETTINGS, DEFAULT_SETTINGS, SHORTHANDOFF
|
||||
from sphinx.builders.latex.theming import Theme, ThemeFactory
|
||||
from sphinx.builders.latex.util import ExtBabel
|
||||
from sphinx.config import Config, ENUM
|
||||
from sphinx.config import ENUM, Config
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning
|
||||
from sphinx.environment.adapters.asset import ImageAdapter
|
||||
from sphinx.errors import NoUri, SphinxError
|
||||
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.docutils import SphinxFileOutput, new_document
|
||||
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.osutil import SEP, make_filename_from_project
|
||||
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
|
||||
from docutils import nodes # NOQA
|
||||
|
||||
from docutils import nodes # isort:skip
|
||||
|
||||
XINDY_LANG_OPTIONS = {
|
||||
# language codes from docutils.writers.latex2e.Babel
|
||||
|
@ -4,13 +4,12 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict
|
||||
|
||||
|
||||
PDFLATEX_DEFAULT_FONTPKG = r'''
|
||||
\usepackage{times}
|
||||
\expandafter\ifx\csname T@LGR\endcsname\relax
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -4,21 +4,20 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Set, Tuple
|
||||
from typing import cast
|
||||
from typing import Any, Dict, List, Set, Tuple, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
from docutils.transforms.references import Substitutions
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders.latex.nodes import (
|
||||
captioned_literal_block, footnotemark, footnotetext, math_reference, thebibliography
|
||||
)
|
||||
from sphinx.builders.latex.nodes import (captioned_literal_block, footnotemark, footnotetext,
|
||||
math_reference, thebibliography)
|
||||
from sphinx.domains.citation import CitationDomain
|
||||
from sphinx.transforms import SphinxTransform
|
||||
from sphinx.transforms.post_transforms import SphinxPostTransform
|
||||
@ -38,6 +37,18 @@ class FootnoteDocnameUpdater(SphinxTransform):
|
||||
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):
|
||||
"""Expand references to inline text or footnotes.
|
||||
|
||||
@ -602,6 +613,7 @@ class IndexInSectionTitleTransform(SphinxTransform):
|
||||
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_transform(FootnoteDocnameUpdater)
|
||||
app.add_post_transform(SubstitutionDefinitionsRemover)
|
||||
app.add_post_transform(BibliographyTransform)
|
||||
app.add_post_transform(CitationReferenceTransform)
|
||||
app.add_post_transform(DocumentTargetTransform)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -13,34 +13,55 @@ import queue
|
||||
import re
|
||||
import socket
|
||||
import threading
|
||||
import time
|
||||
import warnings
|
||||
from datetime import datetime, timezone
|
||||
from email.utils import parsedate_to_datetime
|
||||
from html.parser import HTMLParser
|
||||
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, urlparse
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Node
|
||||
from requests.exceptions import HTTPError
|
||||
from docutils.nodes import Element
|
||||
from requests import Response
|
||||
from requests.exceptions import HTTPError, TooManyRedirects
|
||||
|
||||
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.util import encode_uri, requests, logging
|
||||
from sphinx.util.console import ( # type: ignore
|
||||
purple, red, darkgreen, darkgray, turquoise
|
||||
)
|
||||
from sphinx.transforms.post_transforms import SphinxPostTransform
|
||||
from sphinx.util import encode_uri, logging, requests
|
||||
from sphinx.util.console import darkgray, darkgreen, purple, red, turquoise # type: ignore
|
||||
from sphinx.util.nodes import get_node_line
|
||||
from sphinx.util.requests import is_ssl_error
|
||||
|
||||
|
||||
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):
|
||||
@ -77,7 +98,7 @@ def check_anchor(response: requests.requests.Response, anchor: str) -> bool:
|
||||
return parser.found
|
||||
|
||||
|
||||
class CheckExternalLinksBuilder(Builder):
|
||||
class CheckExternalLinksBuilder(DummyBuilder):
|
||||
"""
|
||||
Checks for broken external links.
|
||||
"""
|
||||
@ -86,37 +107,59 @@ class CheckExternalLinksBuilder(Builder):
|
||||
'%(outdir)s/output.txt')
|
||||
|
||||
def init(self) -> None:
|
||||
self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
|
||||
self.hyperlinks = {} # type: Dict[str, Hyperlink]
|
||||
self.to_ignore = [re.compile(x) for x in self.config.linkcheck_ignore]
|
||||
self.anchors_ignore = [re.compile(x)
|
||||
for x in self.app.config.linkcheck_anchors_ignore]
|
||||
for x in self.config.linkcheck_anchors_ignore]
|
||||
self.auth = [(re.compile(pattern), auth_info) for pattern, auth_info
|
||||
in self.app.config.linkcheck_auth]
|
||||
self.good = set() # type: Set[str]
|
||||
self.broken = {} # type: Dict[str, str]
|
||||
self.redirected = {} # type: Dict[str, Tuple[str, int]]
|
||||
in self.config.linkcheck_auth]
|
||||
self._good = set() # type: Set[str]
|
||||
self._broken = {} # type: Dict[str, str]
|
||||
self._redirected = {} # type: Dict[str, Tuple[str, int]]
|
||||
# set a timeout for non-responding servers
|
||||
socket.setdefaulttimeout(5.0)
|
||||
# create output file
|
||||
open(path.join(self.outdir, 'output.txt'), 'w').close()
|
||||
# create JSON output file
|
||||
open(path.join(self.outdir, 'output.json'), 'w').close()
|
||||
|
||||
# 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.workers = [] # type: List[threading.Thread]
|
||||
for i in range(self.app.config.linkcheck_workers):
|
||||
thread = threading.Thread(target=self.check_thread)
|
||||
thread.setDaemon(True)
|
||||
for i in range(self.config.linkcheck_workers):
|
||||
thread = threading.Thread(target=self.check_thread, daemon=True)
|
||||
thread.start()
|
||||
self.workers.append(thread)
|
||||
|
||||
@property
|
||||
def good(self) -> Set[str]:
|
||||
warnings.warn(
|
||||
"%s.%s is deprecated." % (self.__class__.__name__, "good"),
|
||||
RemovedInSphinx50Warning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return self._good
|
||||
|
||||
@property
|
||||
def broken(self) -> Dict[str, str]:
|
||||
warnings.warn(
|
||||
"%s.%s is deprecated." % (self.__class__.__name__, "broken"),
|
||||
RemovedInSphinx50Warning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return self._broken
|
||||
|
||||
@property
|
||||
def redirected(self) -> Dict[str, Tuple[str, int]]:
|
||||
warnings.warn(
|
||||
"%s.%s is deprecated." % (self.__class__.__name__, "redirected"),
|
||||
RemovedInSphinx50Warning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return self._redirected
|
||||
|
||||
def check_thread(self) -> None:
|
||||
kwargs = {
|
||||
'allow_redirects': True,
|
||||
} # type: Dict
|
||||
if self.app.config.linkcheck_timeout:
|
||||
kwargs['timeout'] = self.app.config.linkcheck_timeout
|
||||
kwargs = {}
|
||||
if self.config.linkcheck_timeout:
|
||||
kwargs['timeout'] = self.config.linkcheck_timeout
|
||||
|
||||
def get_request_headers() -> Dict:
|
||||
url = urlparse(uri)
|
||||
@ -162,9 +205,9 @@ class CheckExternalLinksBuilder(Builder):
|
||||
kwargs['headers'] = get_request_headers()
|
||||
|
||||
try:
|
||||
if anchor and self.app.config.linkcheck_anchors:
|
||||
if anchor and self.config.linkcheck_anchors:
|
||||
# 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.config,
|
||||
auth=auth_info, **kwargs)
|
||||
response.raise_for_status()
|
||||
found = check_anchor(response, unquote(anchor))
|
||||
@ -175,29 +218,42 @@ class CheckExternalLinksBuilder(Builder):
|
||||
try:
|
||||
# try a HEAD request first, which should be easier on
|
||||
# the server and the network
|
||||
response = requests.head(req_url, config=self.app.config,
|
||||
auth=auth_info, **kwargs)
|
||||
response = requests.head(req_url, allow_redirects=True,
|
||||
config=self.config, auth=auth_info,
|
||||
**kwargs)
|
||||
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
|
||||
# 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.config,
|
||||
auth=auth_info, **kwargs)
|
||||
response.raise_for_status()
|
||||
except HTTPError as err:
|
||||
if err.response.status_code == 401:
|
||||
# We'll take "Unauthorized" as working.
|
||||
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:
|
||||
# We'll take "Service Unavailable" as ignored.
|
||||
return 'ignored', str(err), 0
|
||||
else:
|
||||
return 'broken', str(err), 0
|
||||
except Exception as err:
|
||||
if is_ssl_error(err):
|
||||
return 'ignored', str(err), 0
|
||||
else:
|
||||
return 'broken', str(err), 0
|
||||
return 'broken', str(err), 0
|
||||
else:
|
||||
netloc = urlparse(req_url).netloc
|
||||
try:
|
||||
del self.rate_limits[netloc]
|
||||
except KeyError:
|
||||
pass
|
||||
if response.url.rstrip('/') == req_url.rstrip('/'):
|
||||
return 'working', '', 0
|
||||
else:
|
||||
@ -213,7 +269,7 @@ class CheckExternalLinksBuilder(Builder):
|
||||
|
||||
def check(docname: str) -> Tuple[str, str, int]:
|
||||
# check for various conditions without bothering the network
|
||||
if len(uri) == 0 or uri.startswith(('#', 'mailto:')):
|
||||
if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'tel:')):
|
||||
return 'unchecked', '', 0
|
||||
elif not uri.startswith(('http:', 'https:')):
|
||||
if uri_re.match(uri):
|
||||
@ -228,38 +284,97 @@ class CheckExternalLinksBuilder(Builder):
|
||||
if rex.match(uri):
|
||||
return 'ignored', '', 0
|
||||
else:
|
||||
self._broken[uri] = ''
|
||||
return 'broken', '', 0
|
||||
elif uri in self.good:
|
||||
elif uri in self._good:
|
||||
return 'working', 'old', 0
|
||||
elif uri in self.broken:
|
||||
return 'broken', self.broken[uri], 0
|
||||
elif uri in self.redirected:
|
||||
return 'redirected', self.redirected[uri][0], self.redirected[uri][1]
|
||||
elif uri in self._broken:
|
||||
return 'broken', self._broken[uri], 0
|
||||
elif uri in self._redirected:
|
||||
return 'redirected', self._redirected[uri][0], self._redirected[uri][1]
|
||||
for rex in self.to_ignore:
|
||||
if rex.match(uri):
|
||||
return 'ignored', '', 0
|
||||
|
||||
# need to actually check the URI
|
||||
for _ in range(self.app.config.linkcheck_retries):
|
||||
for _ in range(self.config.linkcheck_retries):
|
||||
status, info, code = check_uri()
|
||||
if status != "broken":
|
||||
break
|
||||
|
||||
if status == "working":
|
||||
self.good.add(uri)
|
||||
self._good.add(uri)
|
||||
elif status == "broken":
|
||||
self.broken[uri] = info
|
||||
self._broken[uri] = info
|
||||
elif status == "redirected":
|
||||
self.redirected[uri] = (info, code)
|
||||
self._redirected[uri] = (info, code)
|
||||
|
||||
return (status, info, code)
|
||||
|
||||
while True:
|
||||
uri, docname, lineno = self.wqueue.get()
|
||||
next_check, uri, docname, lineno = self.wqueue.get()
|
||||
if uri is None:
|
||||
break
|
||||
netloc = urlparse(uri).netloc
|
||||
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)
|
||||
self.rqueue.put((uri, docname, lineno, status, info, code))
|
||||
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.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:
|
||||
uri, docname, lineno, status, info, code = result
|
||||
@ -313,62 +428,71 @@ class CheckExternalLinksBuilder(Builder):
|
||||
self.write_entry('redirected ' + text, docname, filename,
|
||||
lineno, uri + ' to ' + info)
|
||||
self.write_linkstat(linkstat)
|
||||
else:
|
||||
raise ValueError("Unknown status %s." % status)
|
||||
|
||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||
return ''
|
||||
def write_entry(self, what: str, docname: str, filename: str, line: int,
|
||||
uri: str) -> None:
|
||||
self.txt_outfile.write("%s:%s: [%s] %s\n" % (filename, line, what, uri))
|
||||
|
||||
def get_outdated_docs(self) -> Set[str]:
|
||||
return self.env.found_docs
|
||||
def write_linkstat(self, data: dict) -> None:
|
||||
self.json_outfile.write(json.dumps(data))
|
||||
self.json_outfile.write('\n')
|
||||
|
||||
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||
return
|
||||
|
||||
def write_doc(self, docname: str, doctree: Node) -> None:
|
||||
def finish(self) -> None:
|
||||
logger.info('')
|
||||
n = 0
|
||||
|
||||
for hyperlink in self.hyperlinks.values():
|
||||
self.wqueue.put(hyperlink, False)
|
||||
|
||||
total_links = len(self.hyperlinks)
|
||||
done = 0
|
||||
with open(path.join(self.outdir, 'output.txt'), 'w') as self.txt_outfile,\
|
||||
open(path.join(self.outdir, 'output.json'), 'w') as self.json_outfile:
|
||||
while done < total_links:
|
||||
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:
|
||||
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 doctree.traverse(nodes.reference):
|
||||
for refnode in self.document.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
|
||||
uri_info = Hyperlink(CHECK_IMMEDIATELY, uri, self.env.docname, lineno)
|
||||
if uri not in hyperlinks:
|
||||
hyperlinks[uri] = uri_info
|
||||
|
||||
# image nodes
|
||||
for imgnode in doctree.traverse(nodes.image):
|
||||
for imgnode in self.document.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,
|
||||
uri: str) -> None:
|
||||
with open(path.join(self.outdir, 'output.txt'), 'a') as output:
|
||||
output.write("%s:%s: [%s] %s\n" % (filename, line, what, uri))
|
||||
|
||||
def write_linkstat(self, data: dict) -> None:
|
||||
with open(path.join(self.outdir, 'output.json'), 'a') as output:
|
||||
output.write(json.dumps(data))
|
||||
output.write('\n')
|
||||
|
||||
def finish(self) -> None:
|
||||
for worker in self.workers:
|
||||
self.wqueue.put((None, None, None), False)
|
||||
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]:
|
||||
app.add_builder(CheckExternalLinksBuilder)
|
||||
app.add_post_transform(HyperlinkCollector)
|
||||
|
||||
app.add_config_value('linkcheck_ignore', [], None)
|
||||
app.add_config_value('linkcheck_auth', [], None)
|
||||
@ -380,6 +504,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
# Anchors starting with ! are ignored since they are
|
||||
# commonly used for dynamic pages
|
||||
app.add_config_value('linkcheck_anchors_ignore', ["^!"], None)
|
||||
app.add_config_value('linkcheck_rate_limit_timeout', 300.0, None)
|
||||
|
||||
return {
|
||||
'version': 'builtin',
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -20,13 +20,11 @@ from sphinx.builders import Builder
|
||||
from sphinx.config import Config
|
||||
from sphinx.errors import NoUri
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import progress_message
|
||||
from sphinx.util import logging, progress_message
|
||||
from sphinx.util.console import darkgreen # type: ignore
|
||||
from sphinx.util.nodes import inline_all_toctrees
|
||||
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__)
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -17,7 +17,6 @@ import sphinx
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||
|
||||
|
||||
deprecated_alias('sphinx.builders.qthelp',
|
||||
{
|
||||
'render_file': render_file,
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -19,8 +19,7 @@ from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||
from sphinx.environment.adapters.toctree import TocTree
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import progress_message
|
||||
from sphinx.util import logging, progress_message
|
||||
from sphinx.util.console import darkgreen # type: ignore
|
||||
from sphinx.util.nodes import inline_all_toctrees
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -16,23 +16,20 @@ from docutils import nodes
|
||||
from docutils.frontend import OptionParser
|
||||
from docutils.io import FileOutput
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx import package_dir
|
||||
from sphinx import addnodes, package_dir
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.config import Config
|
||||
from sphinx.environment.adapters.asset import ImageAdapter
|
||||
from sphinx.errors import NoUri
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import progress_message, status_iterator
|
||||
from sphinx.util import logging, progress_message, status_iterator
|
||||
from sphinx.util.console import darkgreen # type: ignore
|
||||
from sphinx.util.docutils import new_document
|
||||
from sphinx.util.fileutil import copy_asset_file
|
||||
from sphinx.util.nodes import inline_all_toctrees
|
||||
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__)
|
||||
template_dir = os.path.join(package_dir, 'templates', 'texinfo')
|
||||
@ -182,7 +179,8 @@ class TexinfoBuilder(Builder):
|
||||
try:
|
||||
imagedir = path.join(self.outdir, targetname + '-figures')
|
||||
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:
|
||||
logger.warning(__('cannot copy image file %r: %s'),
|
||||
path.join(self.srcdir, src), err)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -19,7 +19,7 @@ from sphinx.builders import Builder
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
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__)
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -21,7 +21,7 @@ from sphinx.builders import Builder
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.osutil import ensuredir, os_path
|
||||
from sphinx.writers.xml import XMLWriter, PseudoXMLWriter
|
||||
from sphinx.writers.xml import PseudoXMLWriter, XMLWriter
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
|
@ -4,6 +4,6 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -16,7 +16,7 @@ import os
|
||||
import pdb
|
||||
import sys
|
||||
import traceback
|
||||
from typing import Any, IO, List
|
||||
from typing import IO, Any, List
|
||||
|
||||
from docutils.utils import SystemMessage
|
||||
|
||||
@ -26,7 +26,7 @@ from sphinx.application import Sphinx
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.locale import __
|
||||
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
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
This is in its own module so that importing it is fast. It should not
|
||||
import the main Sphinx modules (like sphinx.applications, sphinx.builders).
|
||||
|
||||
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
@ -22,10 +22,9 @@ from typing import List
|
||||
|
||||
import sphinx
|
||||
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
|
||||
|
||||
|
||||
BUILDERS = [
|
||||
("", "html", "to make standalone HTML files"),
|
||||
("", "dirhtml", "to make HTML files named index.html in directories"),
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -29,6 +29,7 @@ try:
|
||||
readline.parse_and_bind("tab: complete")
|
||||
USE_LIBEDIT = False
|
||||
except ImportError:
|
||||
readline = None
|
||||
USE_LIBEDIT = False
|
||||
|
||||
from docutils.utils import column_width
|
||||
@ -37,9 +38,8 @@ import sphinx.locale
|
||||
from sphinx import __display_version__, package_dir
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.locale import __
|
||||
from sphinx.util.console import ( # type: ignore
|
||||
colorize, bold, red, turquoise, nocolor, color_terminal
|
||||
)
|
||||
from sphinx.util.console import (bold, color_terminal, colorize, nocolor, red, # type: ignore
|
||||
turquoise)
|
||||
from sphinx.util.osutil import ensuredir
|
||||
from sphinx.util.template import SphinxRenderer
|
||||
|
||||
@ -170,8 +170,11 @@ def do_prompt(text: str, default: str = None, validator: Callable[[str], Any] =
|
||||
# sequence (see #5335). To avoid the problem, all prompts are not colored
|
||||
# on libedit.
|
||||
pass
|
||||
else:
|
||||
elif readline:
|
||||
# pass input_mode=True if readline available
|
||||
prompt = colorize(COLOR_QUESTION, prompt, input_mode=True)
|
||||
else:
|
||||
prompt = colorize(COLOR_QUESTION, prompt, input_mode=False)
|
||||
x = term_input(prompt).strip()
|
||||
if default and not x:
|
||||
x = default
|
||||
@ -489,8 +492,10 @@ def get_parser() -> argparse.ArgumentParser:
|
||||
help=__('project root'))
|
||||
|
||||
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'))
|
||||
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='_',
|
||||
help=__('replacement for dot in _templates etc.'))
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -13,10 +13,9 @@ import traceback
|
||||
import types
|
||||
import warnings
|
||||
from collections import OrderedDict
|
||||
from os import path, getenv
|
||||
from typing import (
|
||||
Any, Callable, Dict, Generator, Iterator, List, NamedTuple, Set, Tuple, Union
|
||||
)
|
||||
from os import getenv, path
|
||||
from typing import (Any, Callable, Dict, Generator, Iterator, List, NamedTuple, Set, Tuple,
|
||||
Union)
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.errors import ConfigError, ExtensionError
|
||||
@ -99,7 +98,8 @@ class Config:
|
||||
# general options
|
||||
'project': ('Python', 'env', []),
|
||||
'author': ('unknown', 'env', []),
|
||||
'copyright': ('', 'html', []),
|
||||
'project_copyright': ('', 'html', [str]),
|
||||
'copyright': (lambda c: c.project_copyright, 'html', [str]),
|
||||
'version': ('', 'env', []),
|
||||
'release': ('', 'env', []),
|
||||
'today': ('', 'env', []),
|
||||
@ -181,6 +181,14 @@ class Config:
|
||||
defvalue = self.values[name][0]
|
||||
if self.values[name][2] == Any:
|
||||
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]:
|
||||
if value == '0':
|
||||
# given falsy string from command line option
|
||||
@ -359,6 +367,18 @@ def convert_source_suffix(app: "Sphinx", config: Config) -> None:
|
||||
"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:
|
||||
"""Initialize :confval:`numfig_format`."""
|
||||
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]:
|
||||
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', correct_copyright_year, priority=800)
|
||||
app.connect('config-inited', check_confval_types, priority=800)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -26,6 +26,10 @@ class RemovedInSphinx50Warning(PendingDeprecationWarning):
|
||||
pass
|
||||
|
||||
|
||||
class RemovedInSphinx60Warning(PendingDeprecationWarning):
|
||||
pass
|
||||
|
||||
|
||||
RemovedInNextVersionWarning = RemovedInSphinx40Warning
|
||||
|
||||
|
||||
|
@ -4,13 +4,12 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import Any, Dict, List, Tuple
|
||||
from typing import cast
|
||||
from typing import Any, Dict, Generic, List, Tuple, TypeVar, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Node
|
||||
@ -18,9 +17,8 @@ from docutils.parsers.rst import directives, roles
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import desc_signature
|
||||
from sphinx.deprecation import (
|
||||
RemovedInSphinx40Warning, RemovedInSphinx50Warning, deprecated_alias
|
||||
)
|
||||
from sphinx.deprecation import (RemovedInSphinx40Warning, RemovedInSphinx50Warning,
|
||||
deprecated_alias)
|
||||
from sphinx.util import docutils
|
||||
from sphinx.util.docfields import DocFieldTransformer, Field, TypedField
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
@ -35,6 +33,8 @@ if False:
|
||||
nl_escape_re = re.compile(r'\\\n')
|
||||
strip_backslash_re = re.compile(r'\\(.)')
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
def optional_int(argument: str) -> int:
|
||||
"""
|
||||
@ -49,7 +49,7 @@ def optional_int(argument: str) -> int:
|
||||
return value
|
||||
|
||||
|
||||
class ObjectDescription(SphinxDirective):
|
||||
class ObjectDescription(SphinxDirective, Generic[T]):
|
||||
"""
|
||||
Directive to describe a class, function or similar object. Not used
|
||||
directly, but subclassed (in domain-specific directives) to add custom
|
||||
@ -99,7 +99,7 @@ class ObjectDescription(SphinxDirective):
|
||||
else:
|
||||
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
|
||||
*signode*. If ValueError is raised, parsing is aborted and the whole
|
||||
@ -111,7 +111,7 @@ class ObjectDescription(SphinxDirective):
|
||||
"""
|
||||
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.
|
||||
|
||||
@ -175,7 +175,7 @@ class ObjectDescription(SphinxDirective):
|
||||
if self.domain:
|
||||
node['classes'].append(self.domain)
|
||||
|
||||
self.names = [] # type: List[Any]
|
||||
self.names = [] # type: List[T]
|
||||
signatures = self.get_signatures()
|
||||
for i, sig in enumerate(signatures):
|
||||
# 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)
|
||||
return []
|
||||
|
||||
from sphinx.directives.code import ( # noqa
|
||||
Highlight, CodeBlock, LiteralInclude
|
||||
)
|
||||
from sphinx.directives.other import ( # noqa
|
||||
TocTree, Author, VersionChange, SeeAlso,
|
||||
TabularColumns, Centered, Acks, HList, Only, Include, Class
|
||||
)
|
||||
from sphinx.directives.patches import ( # noqa
|
||||
Figure, Meta
|
||||
)
|
||||
from sphinx.directives.code import CodeBlock, Highlight, LiteralInclude # noqa
|
||||
from sphinx.directives.other import (Acks, Author, Centered, Class, HList, Include, # noqa
|
||||
Only, SeeAlso, TabularColumns, TocTree, VersionChange)
|
||||
from sphinx.directives.patches import Figure, Meta # noqa
|
||||
from sphinx.domains.index import IndexDirective # noqa
|
||||
|
||||
deprecated_alias('sphinx.directives',
|
||||
|
@ -2,11 +2,12 @@
|
||||
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.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import textwrap
|
||||
import warnings
|
||||
from difflib import unified_diff
|
||||
from typing import Any, Dict, List, Tuple
|
||||
@ -19,9 +20,9 @@ from docutils.statemachine import StringList
|
||||
from sphinx import addnodes
|
||||
from sphinx.config import Config
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.directives import optional_int
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import parselinenos
|
||||
from sphinx.util import logging, parselinenos
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
|
||||
if False:
|
||||
@ -69,7 +70,7 @@ class HighlightLang(Highlight):
|
||||
|
||||
def dedent_lines(lines: List[str], dedent: int, location: Tuple[str, int] = None) -> List[str]:
|
||||
if not dedent:
|
||||
return lines
|
||||
return textwrap.dedent(''.join(lines)).splitlines(True)
|
||||
|
||||
if any(s[:dedent].strip() for s in lines):
|
||||
logger.warning(__('non-whitespace stripped by dedent'), location=location)
|
||||
@ -118,7 +119,7 @@ class CodeBlock(SphinxDirective):
|
||||
option_spec = {
|
||||
'force': directives.flag,
|
||||
'linenos': directives.flag,
|
||||
'dedent': int,
|
||||
'dedent': optional_int,
|
||||
'lineno-start': int,
|
||||
'emphasize-lines': directives.unchanged_required,
|
||||
'caption': directives.unchanged_required,
|
||||
@ -392,7 +393,7 @@ class LiteralInclude(SphinxDirective):
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec = {
|
||||
'dedent': int,
|
||||
'dedent': optional_int,
|
||||
'linenos': directives.flag,
|
||||
'lineno-start': int,
|
||||
'lineno-match': directives.flag,
|
||||
|
@ -2,13 +2,12 @@
|
||||
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.
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import Any, Dict, List
|
||||
from typing import cast
|
||||
from typing import Any, Dict, List, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
@ -21,7 +20,7 @@ from sphinx import addnodes
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||
from sphinx.domains.changeset import VersionChange # NOQA # for compatibility
|
||||
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.matching import Matcher, patfilter
|
||||
from sphinx.util.nodes import explicit_title_re
|
||||
@ -277,6 +276,7 @@ class HList(SphinxDirective):
|
||||
npercol, nmore = divmod(len(fulllist), ncolumns)
|
||||
index = 0
|
||||
newnode = addnodes.hlist()
|
||||
newnode['ncolumns'] = str(ncolumns)
|
||||
for column in range(ncolumns):
|
||||
endindex = index + ((npercol + 1) if column < nmore else npercol)
|
||||
bullet_list = nodes.bullet_list()
|
||||
|
@ -2,17 +2,16 @@
|
||||
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.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Tuple
|
||||
from typing import cast
|
||||
from typing import Any, Dict, List, Tuple, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Node, make_id, system_message
|
||||
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.directives import optional_int
|
||||
|
@ -5,13 +5,12 @@
|
||||
Support for domains, which are groupings of description directives
|
||||
and roles describing e.g. constructs of one programming language.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
import copy
|
||||
from typing import Any, Callable, Dict, Iterable, List, NamedTuple, Tuple, Union
|
||||
from typing import cast
|
||||
from typing import Any, Callable, Dict, Iterable, List, NamedTuple, Tuple, Union, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node, system_message
|
||||
@ -26,6 +25,7 @@ from sphinx.util.typing import RoleFunction
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Type # for python3.5.1
|
||||
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.environment import BuildEnvironment
|
||||
|
||||
|
@ -4,15 +4,13 @@
|
||||
|
||||
The C language domain.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import (
|
||||
Any, Callable, Dict, Generator, Iterator, List, Type, TypeVar, Tuple, Union
|
||||
)
|
||||
from typing import cast
|
||||
from typing import (Any, Callable, Dict, Generator, Iterator, List, Tuple, Type, TypeVar,
|
||||
Union, cast)
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node, TextElement, system_message
|
||||
@ -31,15 +29,13 @@ from sphinx.roles import SphinxRole, XRefRole
|
||||
from sphinx.transforms import SphinxTransform
|
||||
from sphinx.transforms.post_transforms import ReferencesResolver
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.cfamily import (
|
||||
NoOldIdError, ASTBaseBase, ASTAttribute, ASTBaseParenExprList,
|
||||
verify_description_mode, StringifyTransform,
|
||||
BaseParser, DefinitionError, UnsupportedMultiCharacterCharLiteral,
|
||||
identifier_re, anon_identifier_re, integer_literal_re, octal_literal_re,
|
||||
hex_literal_re, binary_literal_re, integers_literal_suffix_re,
|
||||
float_literal_re, float_literal_suffix_re,
|
||||
char_literal_re
|
||||
)
|
||||
from sphinx.util.cfamily import (ASTAttribute, ASTBaseBase, ASTBaseParenExprList, BaseParser,
|
||||
DefinitionError, NoOldIdError, StringifyTransform,
|
||||
UnsupportedMultiCharacterCharLiteral, anon_identifier_re,
|
||||
binary_literal_re, char_literal_re, float_literal_re,
|
||||
float_literal_suffix_re, hex_literal_re, identifier_re,
|
||||
integer_literal_re, integers_literal_suffix_re,
|
||||
octal_literal_re, verify_description_mode)
|
||||
from sphinx.util.docfields import Field, TypedField
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.nodes import make_refnode
|
||||
@ -47,6 +43,11 @@ from sphinx.util.nodes import make_refnode
|
||||
logger = logging.getLogger(__name__)
|
||||
T = TypeVar('T')
|
||||
|
||||
DeclarationType = Union[
|
||||
"ASTStruct", "ASTUnion", "ASTEnum", "ASTEnumerator",
|
||||
"ASTType", "ASTTypeWithInit", "ASTMacro",
|
||||
]
|
||||
|
||||
# https://en.cppreference.com/w/c/keyword
|
||||
_keywords = [
|
||||
'auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', 'double',
|
||||
@ -136,8 +137,7 @@ class ASTIdentifier(ASTBaseBase):
|
||||
reftype='identifier',
|
||||
reftarget=targetText, modname=None,
|
||||
classname=None)
|
||||
key = symbol.get_lookup_key()
|
||||
pnode['c:parent_key'] = key
|
||||
pnode['c:parent_key'] = symbol.get_lookup_key()
|
||||
if self.is_anon():
|
||||
pnode += nodes.strong(text="[anonymous]")
|
||||
else:
|
||||
@ -636,6 +636,10 @@ class ASTFunctionParameter(ASTBase):
|
||||
self.arg = arg
|
||||
self.ellipsis = ellipsis
|
||||
|
||||
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
|
||||
# the anchor will be our parent
|
||||
return symbol.parent.declaration.get_id(version, prefixed=False)
|
||||
|
||||
def _stringify(self, transform: StringifyTransform) -> str:
|
||||
if self.ellipsis:
|
||||
return '...'
|
||||
@ -1149,6 +1153,9 @@ class ASTType(ASTBase):
|
||||
def name(self) -> ASTNestedName:
|
||||
return self.decl.name
|
||||
|
||||
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
|
||||
return symbol.get_full_nested_name().get_id(version)
|
||||
|
||||
@property
|
||||
def function_params(self) -> List[ASTFunctionParameter]:
|
||||
return self.decl.function_params
|
||||
@ -1191,6 +1198,9 @@ class ASTTypeWithInit(ASTBase):
|
||||
def name(self) -> ASTNestedName:
|
||||
return self.type.name
|
||||
|
||||
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
|
||||
return self.type.get_id(version, objectType, symbol)
|
||||
|
||||
def _stringify(self, transform: StringifyTransform) -> str:
|
||||
res = []
|
||||
res.append(transform(self.type))
|
||||
@ -1242,6 +1252,9 @@ class ASTMacro(ASTBase):
|
||||
def name(self) -> ASTNestedName:
|
||||
return self.ident
|
||||
|
||||
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
|
||||
return symbol.get_full_nested_name().get_id(version)
|
||||
|
||||
def _stringify(self, transform: StringifyTransform) -> str:
|
||||
res = []
|
||||
res.append(transform(self.ident))
|
||||
@ -1342,7 +1355,8 @@ class ASTEnumerator(ASTBase):
|
||||
|
||||
|
||||
class ASTDeclaration(ASTBaseBase):
|
||||
def __init__(self, objectType: str, directiveType: str, declaration: Any,
|
||||
def __init__(self, objectType: str, directiveType: str,
|
||||
declaration: Union[DeclarationType, ASTFunctionParameter],
|
||||
semicolon: bool = False) -> None:
|
||||
self.objectType = objectType
|
||||
self.directiveType = directiveType
|
||||
@ -1359,18 +1373,20 @@ class ASTDeclaration(ASTBaseBase):
|
||||
|
||||
@property
|
||||
def name(self) -> ASTNestedName:
|
||||
return self.declaration.name
|
||||
decl = cast(DeclarationType, self.declaration)
|
||||
return decl.name
|
||||
|
||||
@property
|
||||
def function_params(self) -> List[ASTFunctionParameter]:
|
||||
if self.objectType != 'function':
|
||||
return None
|
||||
return self.declaration.function_params
|
||||
decl = cast(ASTType, self.declaration)
|
||||
return decl.function_params
|
||||
|
||||
def get_id(self, version: int, prefixed: bool = True) -> str:
|
||||
if self.objectType == 'enumerator' and self.enumeratorScopedSymbol:
|
||||
return self.enumeratorScopedSymbol.declaration.get_id(version, prefixed)
|
||||
id_ = self.symbol.get_full_nested_name().get_id(version)
|
||||
id_ = self.declaration.get_id(version, self.objectType, self.symbol)
|
||||
if prefixed:
|
||||
return _id_prefix[version] + id_
|
||||
else:
|
||||
@ -1413,7 +1429,8 @@ class ASTDeclaration(ASTBaseBase):
|
||||
elif self.objectType == 'enumerator':
|
||||
mainDeclNode += addnodes.desc_annotation('enumerator ', 'enumerator ')
|
||||
elif self.objectType == 'type':
|
||||
prefix = self.declaration.get_type_declaration_prefix()
|
||||
decl = cast(ASTType, self.declaration)
|
||||
prefix = decl.get_type_declaration_prefix()
|
||||
prefix += ' '
|
||||
mainDeclNode += addnodes.desc_annotation(prefix, prefix)
|
||||
else:
|
||||
@ -1454,7 +1471,7 @@ class Symbol:
|
||||
assert False # shouldn't happen
|
||||
else:
|
||||
# the domain base class makes a copy of the initial data, which is fine
|
||||
return Symbol(None, None, None, None)
|
||||
return Symbol(None, None, None, None, None)
|
||||
|
||||
@staticmethod
|
||||
def debug_print(*args: Any) -> None:
|
||||
@ -1477,7 +1494,7 @@ class Symbol:
|
||||
return super().__setattr__(key, value)
|
||||
|
||||
def __init__(self, parent: "Symbol", ident: ASTIdentifier,
|
||||
declaration: ASTDeclaration, docname: str) -> None:
|
||||
declaration: ASTDeclaration, docname: str, line: int) -> None:
|
||||
self.parent = parent
|
||||
# declarations in a single directive are linked together
|
||||
self.siblingAbove = None # type: Symbol
|
||||
@ -1485,6 +1502,7 @@ class Symbol:
|
||||
self.ident = ident
|
||||
self.declaration = declaration
|
||||
self.docname = docname
|
||||
self.line = line
|
||||
self.isRedeclaration = False
|
||||
self._assert_invariants()
|
||||
|
||||
@ -1500,15 +1518,18 @@ class Symbol:
|
||||
# Do symbol addition after self._children has been initialised.
|
||||
self._add_function_params()
|
||||
|
||||
def _fill_empty(self, declaration: ASTDeclaration, docname: str) -> None:
|
||||
def _fill_empty(self, declaration: ASTDeclaration, docname: str, line: int) -> None:
|
||||
self._assert_invariants()
|
||||
assert not self.declaration
|
||||
assert not self.docname
|
||||
assert declaration
|
||||
assert docname
|
||||
assert self.declaration is None
|
||||
assert self.docname is None
|
||||
assert self.line is None
|
||||
assert declaration is not None
|
||||
assert docname is not None
|
||||
assert line is not None
|
||||
self.declaration = declaration
|
||||
self.declaration.symbol = self
|
||||
self.docname = docname
|
||||
self.line = line
|
||||
self._assert_invariants()
|
||||
# and symbol addition should be done as well
|
||||
self._add_function_params()
|
||||
@ -1532,7 +1553,7 @@ class Symbol:
|
||||
decl = ASTDeclaration('functionParam', None, p)
|
||||
assert not nn.rooted
|
||||
assert len(nn.names) == 1
|
||||
self._add_symbols(nn, decl, self.docname)
|
||||
self._add_symbols(nn, decl, self.docname, self.line)
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent -= 1
|
||||
|
||||
@ -1549,6 +1570,7 @@ class Symbol:
|
||||
if sChild.declaration and sChild.docname == docname:
|
||||
sChild.declaration = None
|
||||
sChild.docname = None
|
||||
sChild.line = None
|
||||
if sChild.siblingAbove is not None:
|
||||
sChild.siblingAbove.siblingBelow = sChild.siblingBelow
|
||||
if sChild.siblingBelow is not None:
|
||||
@ -1559,13 +1581,11 @@ class Symbol:
|
||||
def get_all_symbols(self) -> Iterator["Symbol"]:
|
||||
yield self
|
||||
for sChild in self._children:
|
||||
for s in sChild.get_all_symbols():
|
||||
yield s
|
||||
yield from sChild.get_all_symbols()
|
||||
|
||||
@property
|
||||
def children(self) -> Iterator["Symbol"]:
|
||||
for c in self._children:
|
||||
yield c
|
||||
yield from self._children
|
||||
|
||||
@property
|
||||
def children_recurse_anon(self) -> Iterator["Symbol"]:
|
||||
@ -1742,7 +1762,7 @@ class Symbol:
|
||||
return SymbolLookupResult(symbols, parentSymbol, ident)
|
||||
|
||||
def _add_symbols(self, nestedName: ASTNestedName,
|
||||
declaration: ASTDeclaration, docname: str) -> "Symbol":
|
||||
declaration: ASTDeclaration, docname: str, line: int) -> "Symbol":
|
||||
# TODO: further simplification from C++ to C
|
||||
# Used for adding a whole path of symbols, where the last may or may not
|
||||
# be an actual declaration.
|
||||
@ -1751,9 +1771,9 @@ class Symbol:
|
||||
Symbol.debug_indent += 1
|
||||
Symbol.debug_print("_add_symbols:")
|
||||
Symbol.debug_indent += 1
|
||||
Symbol.debug_print("nn: ", nestedName)
|
||||
Symbol.debug_print("decl: ", declaration)
|
||||
Symbol.debug_print("doc: ", docname)
|
||||
Symbol.debug_print("nn: ", nestedName)
|
||||
Symbol.debug_print("decl: ", declaration)
|
||||
Symbol.debug_print("location: {}:{}".format(docname, line))
|
||||
|
||||
def onMissingQualifiedSymbol(parentSymbol: "Symbol", ident: ASTIdentifier) -> "Symbol":
|
||||
if Symbol.debug_lookup:
|
||||
@ -1763,7 +1783,7 @@ class Symbol:
|
||||
Symbol.debug_print("ident: ", ident)
|
||||
Symbol.debug_indent -= 2
|
||||
return Symbol(parent=parentSymbol, ident=ident,
|
||||
declaration=None, docname=None)
|
||||
declaration=None, docname=None, line=None)
|
||||
|
||||
lookupResult = self._symbol_lookup(nestedName,
|
||||
onMissingQualifiedSymbol,
|
||||
@ -1779,12 +1799,12 @@ class Symbol:
|
||||
Symbol.debug_indent += 1
|
||||
Symbol.debug_print("ident: ", lookupResult.ident)
|
||||
Symbol.debug_print("declaration: ", declaration)
|
||||
Symbol.debug_print("docname: ", docname)
|
||||
Symbol.debug_print("location: {}:{}".format(docname, line))
|
||||
Symbol.debug_indent -= 1
|
||||
symbol = Symbol(parent=lookupResult.parentSymbol,
|
||||
ident=lookupResult.ident,
|
||||
declaration=declaration,
|
||||
docname=docname)
|
||||
docname=docname, line=line)
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent -= 2
|
||||
return symbol
|
||||
@ -1832,7 +1852,7 @@ class Symbol:
|
||||
symbol = Symbol(parent=lookupResult.parentSymbol,
|
||||
ident=lookupResult.ident,
|
||||
declaration=declaration,
|
||||
docname=docname)
|
||||
docname=docname, line=line)
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_print("end: creating candidate symbol")
|
||||
return symbol
|
||||
@ -1898,7 +1918,7 @@ class Symbol:
|
||||
# .. namespace:: Test
|
||||
# .. namespace:: nullptr
|
||||
# .. class:: Test
|
||||
symbol._fill_empty(declaration, docname)
|
||||
symbol._fill_empty(declaration, docname, line)
|
||||
return symbol
|
||||
|
||||
def merge_with(self, other: "Symbol", docnames: List[str],
|
||||
@ -1919,13 +1939,15 @@ class Symbol:
|
||||
continue
|
||||
if otherChild.declaration and otherChild.docname in docnames:
|
||||
if not ourChild.declaration:
|
||||
ourChild._fill_empty(otherChild.declaration, otherChild.docname)
|
||||
ourChild._fill_empty(otherChild.declaration,
|
||||
otherChild.docname, otherChild.line)
|
||||
elif ourChild.docname != otherChild.docname:
|
||||
name = str(ourChild.declaration)
|
||||
msg = __("Duplicate C declaration, also defined in '%s'.\n"
|
||||
"Declaration is '%s'.")
|
||||
msg = msg % (ourChild.docname, name)
|
||||
logger.warning(msg, location=otherChild.docname)
|
||||
msg = __("Duplicate C declaration, also defined at %s:%s.\n"
|
||||
"Declaration is '.. c:%s:: %s'.")
|
||||
msg = msg % (ourChild.docname, ourChild.line,
|
||||
ourChild.declaration.directiveType, name)
|
||||
logger.warning(msg, location=(otherChild.docname, otherChild.line))
|
||||
else:
|
||||
# Both have declarations, and in the same docname.
|
||||
# This can apparently happen, it should be safe to
|
||||
@ -1939,19 +1961,21 @@ class Symbol:
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent += 1
|
||||
Symbol.debug_print("add_name:")
|
||||
res = self._add_symbols(nestedName, declaration=None, docname=None)
|
||||
res = self._add_symbols(nestedName, declaration=None, docname=None, line=None)
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent -= 1
|
||||
return res
|
||||
|
||||
def add_declaration(self, declaration: ASTDeclaration, docname: str) -> "Symbol":
|
||||
def add_declaration(self, declaration: ASTDeclaration,
|
||||
docname: str, line: int) -> "Symbol":
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent += 1
|
||||
Symbol.debug_print("add_declaration:")
|
||||
assert declaration
|
||||
assert docname
|
||||
assert declaration is not None
|
||||
assert docname is not None
|
||||
assert line is not None
|
||||
nestedName = declaration.name
|
||||
res = self._add_symbols(nestedName, declaration, docname)
|
||||
res = self._add_symbols(nestedName, declaration, docname, line)
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent -= 1
|
||||
return res
|
||||
@ -2988,7 +3012,7 @@ class DefinitionParser(BaseParser):
|
||||
|
||||
def parse_pre_v3_type_definition(self) -> ASTDeclaration:
|
||||
self.skip_ws()
|
||||
declaration = None # type: Any
|
||||
declaration = None # type: DeclarationType
|
||||
if self.skip_word('struct'):
|
||||
typ = 'struct'
|
||||
declaration = self._parse_struct()
|
||||
@ -3011,7 +3035,7 @@ class DefinitionParser(BaseParser):
|
||||
'macro', 'struct', 'union', 'enum', 'enumerator', 'type'):
|
||||
raise Exception('Internal error, unknown directiveType "%s".' % directiveType)
|
||||
|
||||
declaration = None # type: Any
|
||||
declaration = None # type: DeclarationType
|
||||
if objectType == 'member':
|
||||
declaration = self._parse_type_with_init(named=True, outer='member')
|
||||
elif objectType == 'function':
|
||||
@ -3074,7 +3098,7 @@ def _make_phony_error_name() -> ASTNestedName:
|
||||
return ASTNestedName([ASTIdentifier("PhonyNameDueToError")], rooted=False)
|
||||
|
||||
|
||||
class CObject(ObjectDescription):
|
||||
class CObject(ObjectDescription[ASTDeclaration]):
|
||||
"""
|
||||
Description of a C language object.
|
||||
"""
|
||||
@ -3128,7 +3152,7 @@ class CObject(ObjectDescription):
|
||||
declClone.enumeratorScopedSymbol = symbol
|
||||
Symbol(parent=targetSymbol, ident=symbol.ident,
|
||||
declaration=declClone,
|
||||
docname=self.env.docname)
|
||||
docname=self.env.docname, line=self.get_source_info()[1])
|
||||
|
||||
def add_target_and_index(self, ast: ASTDeclaration, sig: str,
|
||||
signode: TextElement) -> None:
|
||||
@ -3158,10 +3182,6 @@ class CObject(ObjectDescription):
|
||||
|
||||
self.state.document.note_explicit_target(signode)
|
||||
|
||||
domain = cast(CDomain, self.env.get_domain('c'))
|
||||
if name not in domain.objects:
|
||||
domain.objects[name] = (domain.env.docname, newestId, self.objtype)
|
||||
|
||||
if 'noindexentry' not in self.options:
|
||||
indexText = self.get_index_text(name)
|
||||
self.indexnode['entries'].append(('single', indexText, newestId, '', None))
|
||||
@ -3183,7 +3203,8 @@ class CObject(ObjectDescription):
|
||||
def parse_pre_v3_type_definition(self, parser: DefinitionParser) -> ASTDeclaration:
|
||||
return parser.parse_pre_v3_type_definition()
|
||||
|
||||
def describe_signature(self, signode: TextElement, ast: Any, options: Dict) -> None:
|
||||
def describe_signature(self, signode: TextElement, ast: ASTDeclaration,
|
||||
options: Dict) -> None:
|
||||
ast.describe_signature(signode, 'lastIsName', self.env, options)
|
||||
|
||||
def run(self) -> List[Node]:
|
||||
@ -3235,7 +3256,8 @@ class CObject(ObjectDescription):
|
||||
raise ValueError from e
|
||||
|
||||
try:
|
||||
symbol = parentSymbol.add_declaration(ast, docname=self.env.docname)
|
||||
symbol = parentSymbol.add_declaration(
|
||||
ast, docname=self.env.docname, line=self.get_source_info()[1])
|
||||
# append the new declaration to the sibling list
|
||||
assert symbol.siblingAbove is None
|
||||
assert symbol.siblingBelow is None
|
||||
@ -3248,9 +3270,9 @@ class CObject(ObjectDescription):
|
||||
# Assume we are actually in the old symbol,
|
||||
# instead of the newly created duplicate.
|
||||
self.env.temp_data['c:last_symbol'] = e.symbol
|
||||
msg = __("Duplicate C declaration, also defined in '%s'.\n"
|
||||
"Declaration is '%s'.")
|
||||
msg = msg % (e.symbol.docname, sig)
|
||||
msg = __("Duplicate C declaration, also defined at %s:%s.\n"
|
||||
"Declaration is '.. c:%s:: %s'.")
|
||||
msg = msg % (e.symbol.docname, e.symbol.line, self.display_object_type, sig)
|
||||
logger.warning(msg, location=signode)
|
||||
|
||||
if ast.objectType == 'enumerator':
|
||||
@ -3429,8 +3451,9 @@ class AliasNode(nodes.Element):
|
||||
assert parentKey is not None
|
||||
self.parentKey = parentKey
|
||||
|
||||
def copy(self: T) -> T:
|
||||
return self.__class__(self.sig, env=None, parentKey=self.parentKey) # type: ignore
|
||||
def copy(self) -> 'AliasNode':
|
||||
return self.__class__(self.sig, self.maxdepth, self.document,
|
||||
env=None, parentKey=self.parentKey)
|
||||
|
||||
|
||||
class AliasTransform(SphinxTransform):
|
||||
@ -3619,7 +3642,7 @@ class CExprRole(SphinxRole):
|
||||
location=self.get_source_info())
|
||||
# see below
|
||||
return [self.node_type(text, text, classes=classes)], []
|
||||
parentSymbol = self.env.temp_data.get('cpp:parent_symbol', None)
|
||||
parentSymbol = self.env.temp_data.get('c:parent_symbol', None)
|
||||
if parentSymbol is None:
|
||||
parentSymbol = self.env.domaindata['c']['root_symbol']
|
||||
# ...most if not all of these classes should really apply to the individual references,
|
||||
@ -3634,15 +3657,18 @@ class CDomain(Domain):
|
||||
name = 'c'
|
||||
label = 'C'
|
||||
object_types = {
|
||||
'function': ObjType(_('function'), 'func'),
|
||||
'member': ObjType(_('member'), 'member'),
|
||||
'macro': ObjType(_('macro'), 'macro'),
|
||||
'type': ObjType(_('type'), 'type'),
|
||||
'var': ObjType(_('variable'), 'data'),
|
||||
'enum': ObjType(_('enum'), 'enum'),
|
||||
'enumerator': ObjType(_('enumerator'), 'enumerator'),
|
||||
'struct': ObjType(_('struct'), 'struct'),
|
||||
'union': ObjType(_('union'), 'union'),
|
||||
# 'identifier' is the one used for xrefs generated in signatures, not in roles
|
||||
'member': ObjType(_('member'), 'var', 'member', 'data', 'identifier'),
|
||||
'var': ObjType(_('variable'), 'var', 'member', 'data', 'identifier'),
|
||||
'function': ObjType(_('function'), 'func', 'identifier', 'type'),
|
||||
'macro': ObjType(_('macro'), 'macro', 'identifier'),
|
||||
'struct': ObjType(_('struct'), 'struct', 'identifier', 'type'),
|
||||
'union': ObjType(_('union'), 'union', 'identifier', 'type'),
|
||||
'enum': ObjType(_('enum'), 'enum', 'identifier', 'type'),
|
||||
'enumerator': ObjType(_('enumerator'), 'enumerator', 'identifier'),
|
||||
'type': ObjType(_('type'), 'identifier', 'type'),
|
||||
# generated object types
|
||||
'functionParam': ObjType(_('function parameter'), 'identifier', 'var', 'member', 'data'), # noqa
|
||||
}
|
||||
|
||||
directives = {
|
||||
@ -3677,14 +3703,10 @@ class CDomain(Domain):
|
||||
'texpr': CExprRole(asCode=False)
|
||||
}
|
||||
initial_data = {
|
||||
'root_symbol': Symbol(None, None, None, None),
|
||||
'root_symbol': Symbol(None, None, None, None, None),
|
||||
'objects': {}, # fullname -> docname, node_id, objtype
|
||||
} # type: Dict[str, Union[Symbol, Dict[str, Tuple[str, str, str]]]]
|
||||
|
||||
@property
|
||||
def objects(self) -> Dict[str, Tuple[str, str, str]]:
|
||||
return self.data.setdefault('objects', {}) # fullname -> docname, node_id, objtype
|
||||
|
||||
def clear_doc(self, docname: str) -> None:
|
||||
if Symbol.debug_show_tree:
|
||||
print("clear_doc:", docname)
|
||||
@ -3700,9 +3722,6 @@ class CDomain(Domain):
|
||||
print(self.data['root_symbol'].dump(1))
|
||||
print("\tafter end")
|
||||
print("clear_doc end:", docname)
|
||||
for fullname, (fn, _id, _l) in list(self.objects.items()):
|
||||
if fn == docname:
|
||||
del self.objects[fullname]
|
||||
|
||||
def process_doc(self, env: BuildEnvironment, docname: str,
|
||||
document: nodes.document) -> None:
|
||||
@ -3788,8 +3807,18 @@ class CDomain(Domain):
|
||||
return []
|
||||
|
||||
def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]:
|
||||
for refname, (docname, node_id, objtype) in list(self.objects.items()):
|
||||
yield (refname, refname, objtype, docname, node_id, 1)
|
||||
rootSymbol = self.data['root_symbol']
|
||||
for symbol in rootSymbol.get_all_symbols():
|
||||
if symbol.declaration is None:
|
||||
continue
|
||||
assert symbol.docname
|
||||
fullNestedName = symbol.get_full_nested_name()
|
||||
name = str(fullNestedName).lstrip('.')
|
||||
dispname = fullNestedName.get_display_string().lstrip('.')
|
||||
objectType = symbol.declaration.objectType
|
||||
docname = symbol.docname
|
||||
newestId = symbol.declaration.get_newest_id()
|
||||
yield (name, dispname, objectType, docname, newestId, 1)
|
||||
|
||||
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
|
@ -4,13 +4,12 @@
|
||||
|
||||
The changeset domain.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
from collections import namedtuple
|
||||
from typing import Any, Dict, List
|
||||
from typing import cast
|
||||
from typing import Any, Dict, List, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Node
|
||||
@ -20,7 +19,6 @@ from sphinx.domains import Domain
|
||||
from sphinx.locale import _
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from sphinx.application import Sphinx
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
The citation domain.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Set, Tuple
|
||||
from typing import cast
|
||||
from typing import Any, Dict, List, Set, Tuple, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element
|
||||
|
@ -4,14 +4,13 @@
|
||||
|
||||
The C++ language domain.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import (
|
||||
Any, Callable, Dict, Generator, Iterator, List, Tuple, Type, TypeVar, Union, Optional
|
||||
)
|
||||
from typing import (Any, Callable, Dict, Generator, Iterator, List, Optional, Tuple, Type,
|
||||
TypeVar, Union)
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node, TextElement, system_message
|
||||
@ -30,20 +29,17 @@ from sphinx.roles import SphinxRole, XRefRole
|
||||
from sphinx.transforms import SphinxTransform
|
||||
from sphinx.transforms.post_transforms import ReferencesResolver
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.cfamily import (
|
||||
NoOldIdError, ASTBaseBase, ASTAttribute, ASTBaseParenExprList,
|
||||
verify_description_mode, StringifyTransform,
|
||||
BaseParser, DefinitionError, UnsupportedMultiCharacterCharLiteral,
|
||||
identifier_re, anon_identifier_re, integer_literal_re, octal_literal_re,
|
||||
hex_literal_re, binary_literal_re, integers_literal_suffix_re,
|
||||
float_literal_re, float_literal_suffix_re,
|
||||
char_literal_re
|
||||
)
|
||||
from sphinx.util.cfamily import (ASTAttribute, ASTBaseBase, ASTBaseParenExprList, BaseParser,
|
||||
DefinitionError, NoOldIdError, StringifyTransform,
|
||||
UnsupportedMultiCharacterCharLiteral, anon_identifier_re,
|
||||
binary_literal_re, char_literal_re, float_literal_re,
|
||||
float_literal_suffix_re, hex_literal_re, identifier_re,
|
||||
integer_literal_re, integers_literal_suffix_re,
|
||||
octal_literal_re, verify_description_mode)
|
||||
from sphinx.util.docfields import Field, GroupedField
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.nodes import make_refnode
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
T = TypeVar('T')
|
||||
|
||||
@ -1596,6 +1592,15 @@ class ASTOperator(ASTBase):
|
||||
identifier = str(self)
|
||||
if mode == 'lastIsName':
|
||||
signode += addnodes.desc_name(identifier, identifier)
|
||||
elif mode == 'markType':
|
||||
targetText = prefix + identifier + templateArgs
|
||||
pnode = addnodes.pending_xref('', refdomain='cpp',
|
||||
reftype='identifier',
|
||||
reftarget=targetText, modname=None,
|
||||
classname=None)
|
||||
pnode['cpp:parent_key'] = symbol.get_lookup_key()
|
||||
pnode += nodes.Text(identifier)
|
||||
signode += pnode
|
||||
else:
|
||||
signode += addnodes.desc_addname(identifier, identifier)
|
||||
|
||||
@ -1836,7 +1841,7 @@ class ASTFunctionParameter(ASTBase):
|
||||
# this is not part of the normal name mangling in C++
|
||||
if symbol:
|
||||
# the anchor will be our parent
|
||||
return symbol.parent.declaration.get_id(version, prefixed=None)
|
||||
return symbol.parent.declaration.get_id(version, prefixed=False)
|
||||
# else, do the usual
|
||||
if self.ellipsis:
|
||||
return 'z'
|
||||
@ -3798,7 +3803,7 @@ class Symbol:
|
||||
assert False # shouldn't happen
|
||||
else:
|
||||
# the domain base class makes a copy of the initial data, which is fine
|
||||
return Symbol(None, None, None, None, None, None)
|
||||
return Symbol(None, None, None, None, None, None, None)
|
||||
|
||||
@staticmethod
|
||||
def debug_print(*args: Any) -> None:
|
||||
@ -3825,7 +3830,8 @@ class Symbol:
|
||||
|
||||
def __init__(self, parent: "Symbol", identOrOp: Union[ASTIdentifier, ASTOperator],
|
||||
templateParams: Union[ASTTemplateParams, ASTTemplateIntroduction],
|
||||
templateArgs: Any, declaration: ASTDeclaration, docname: str) -> None:
|
||||
templateArgs: Any, declaration: ASTDeclaration,
|
||||
docname: str, line: int) -> None:
|
||||
self.parent = parent
|
||||
# declarations in a single directive are linked together
|
||||
self.siblingAbove = None # type: Symbol
|
||||
@ -3835,6 +3841,7 @@ class Symbol:
|
||||
self.templateArgs = templateArgs # identifier<templateArgs>
|
||||
self.declaration = declaration
|
||||
self.docname = docname
|
||||
self.line = line
|
||||
self.isRedeclaration = False
|
||||
self._assert_invariants()
|
||||
|
||||
@ -3850,15 +3857,18 @@ class Symbol:
|
||||
# Do symbol addition after self._children has been initialised.
|
||||
self._add_template_and_function_params()
|
||||
|
||||
def _fill_empty(self, declaration: ASTDeclaration, docname: str) -> None:
|
||||
def _fill_empty(self, declaration: ASTDeclaration, docname: str, line: int) -> None:
|
||||
self._assert_invariants()
|
||||
assert not self.declaration
|
||||
assert not self.docname
|
||||
assert declaration
|
||||
assert docname
|
||||
assert self.declaration is None
|
||||
assert self.docname is None
|
||||
assert self.line is None
|
||||
assert declaration is not None
|
||||
assert docname is not None
|
||||
assert line is not None
|
||||
self.declaration = declaration
|
||||
self.declaration.symbol = self
|
||||
self.docname = docname
|
||||
self.line = line
|
||||
self._assert_invariants()
|
||||
# and symbol addition should be done as well
|
||||
self._add_template_and_function_params()
|
||||
@ -3882,7 +3892,7 @@ class Symbol:
|
||||
decl = None
|
||||
nne = ASTNestedNameElement(tp.get_identifier(), None)
|
||||
nn = ASTNestedName([nne], [False], rooted=False)
|
||||
self._add_symbols(nn, [], decl, self.docname)
|
||||
self._add_symbols(nn, [], decl, self.docname, self.line)
|
||||
# add symbols for function parameters, if any
|
||||
if self.declaration is not None and self.declaration.function_params is not None:
|
||||
for fp in self.declaration.function_params:
|
||||
@ -3895,7 +3905,7 @@ class Symbol:
|
||||
decl = ASTDeclaration('functionParam', None, None, None, None, fp, None)
|
||||
assert not nn.rooted
|
||||
assert len(nn.names) == 1
|
||||
self._add_symbols(nn, [], decl, self.docname)
|
||||
self._add_symbols(nn, [], decl, self.docname, self.line)
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent -= 1
|
||||
|
||||
@ -3913,6 +3923,7 @@ class Symbol:
|
||||
if sChild.declaration and sChild.docname == docname:
|
||||
sChild.declaration = None
|
||||
sChild.docname = None
|
||||
sChild.line = None
|
||||
if sChild.siblingAbove is not None:
|
||||
sChild.siblingAbove.siblingBelow = sChild.siblingBelow
|
||||
if sChild.siblingBelow is not None:
|
||||
@ -3925,8 +3936,7 @@ class Symbol:
|
||||
def get_all_symbols(self) -> Iterator[Any]:
|
||||
yield self
|
||||
for sChild in self._children:
|
||||
for s in sChild.get_all_symbols():
|
||||
yield s
|
||||
yield from sChild.get_all_symbols()
|
||||
|
||||
@property
|
||||
def children_recurse_anon(self) -> Generator["Symbol", None, None]:
|
||||
@ -4107,7 +4117,7 @@ class Symbol:
|
||||
Symbol.debug_print("self:")
|
||||
print(self.to_string(Symbol.debug_indent + 1), end="")
|
||||
Symbol.debug_print("nestedName: ", nestedName)
|
||||
Symbol.debug_print("templateDecls: ", templateDecls)
|
||||
Symbol.debug_print("templateDecls: ", ",".join(str(t) for t in templateDecls))
|
||||
Symbol.debug_print("strictTemplateParamArgLists:", strictTemplateParamArgLists)
|
||||
Symbol.debug_print("ancestorLookupType:", ancestorLookupType)
|
||||
Symbol.debug_print("templateShorthand: ", templateShorthand)
|
||||
@ -4223,7 +4233,7 @@ class Symbol:
|
||||
identOrOp, templateParams, templateArgs)
|
||||
|
||||
def _add_symbols(self, nestedName: ASTNestedName, templateDecls: List[Any],
|
||||
declaration: ASTDeclaration, docname: str) -> "Symbol":
|
||||
declaration: ASTDeclaration, docname: str, line: int) -> "Symbol":
|
||||
# Used for adding a whole path of symbols, where the last may or may not
|
||||
# be an actual declaration.
|
||||
|
||||
@ -4231,10 +4241,10 @@ class Symbol:
|
||||
Symbol.debug_indent += 1
|
||||
Symbol.debug_print("_add_symbols:")
|
||||
Symbol.debug_indent += 1
|
||||
Symbol.debug_print("tdecls:", templateDecls)
|
||||
Symbol.debug_print("nn: ", nestedName)
|
||||
Symbol.debug_print("decl: ", declaration)
|
||||
Symbol.debug_print("doc: ", docname)
|
||||
Symbol.debug_print("tdecls:", ",".join(str(t) for t in templateDecls))
|
||||
Symbol.debug_print("nn: ", nestedName)
|
||||
Symbol.debug_print("decl: ", declaration)
|
||||
Symbol.debug_print("location: {}:{}".format(docname, line))
|
||||
|
||||
def onMissingQualifiedSymbol(parentSymbol: "Symbol",
|
||||
identOrOp: Union[ASTIdentifier, ASTOperator],
|
||||
@ -4251,7 +4261,7 @@ class Symbol:
|
||||
return Symbol(parent=parentSymbol, identOrOp=identOrOp,
|
||||
templateParams=templateParams,
|
||||
templateArgs=templateArgs, declaration=None,
|
||||
docname=None)
|
||||
docname=None, line=None)
|
||||
|
||||
lookupResult = self._symbol_lookup(nestedName, templateDecls,
|
||||
onMissingQualifiedSymbol,
|
||||
@ -4272,14 +4282,14 @@ class Symbol:
|
||||
Symbol.debug_print("identOrOp: ", lookupResult.identOrOp)
|
||||
Symbol.debug_print("templateArgs: ", lookupResult.templateArgs)
|
||||
Symbol.debug_print("declaration: ", declaration)
|
||||
Symbol.debug_print("docname: ", docname)
|
||||
Symbol.debug_print("location: {}:{}".format(docname, line))
|
||||
Symbol.debug_indent -= 1
|
||||
symbol = Symbol(parent=lookupResult.parentSymbol,
|
||||
identOrOp=lookupResult.identOrOp,
|
||||
templateParams=lookupResult.templateParams,
|
||||
templateArgs=lookupResult.templateArgs,
|
||||
declaration=declaration,
|
||||
docname=docname)
|
||||
docname=docname, line=line)
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent -= 2
|
||||
return symbol
|
||||
@ -4328,7 +4338,7 @@ class Symbol:
|
||||
templateParams=lookupResult.templateParams,
|
||||
templateArgs=lookupResult.templateArgs,
|
||||
declaration=declaration,
|
||||
docname=docname)
|
||||
docname=docname, line=line)
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_print("end: creating candidate symbol")
|
||||
return symbol
|
||||
@ -4360,6 +4370,11 @@ class Symbol:
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_print("candId:", candId)
|
||||
for symbol in withDecl:
|
||||
# but all existing must be functions as well,
|
||||
# otherwise we declare it to be a duplicate
|
||||
if symbol.declaration.objectType != 'function':
|
||||
handleDuplicateDeclaration(symbol, candSymbol)
|
||||
# (not reachable)
|
||||
oldId = symbol.declaration.get_newest_id()
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_print("oldId: ", oldId)
|
||||
@ -4370,7 +4385,11 @@ class Symbol:
|
||||
# if there is an empty symbol, fill that one
|
||||
if len(noDecl) == 0:
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_print("no match, no empty, candSybmol is not None?:", candSymbol is not None) # NOQA
|
||||
Symbol.debug_print("no match, no empty")
|
||||
if candSymbol is not None:
|
||||
Symbol.debug_print("result is already created candSymbol")
|
||||
else:
|
||||
Symbol.debug_print("result is makeCandSymbol()")
|
||||
Symbol.debug_indent -= 2
|
||||
if candSymbol is not None:
|
||||
return candSymbol
|
||||
@ -4391,7 +4410,7 @@ class Symbol:
|
||||
# .. namespace:: Test
|
||||
# .. namespace:: nullptr
|
||||
# .. class:: Test
|
||||
symbol._fill_empty(declaration, docname)
|
||||
symbol._fill_empty(declaration, docname, line)
|
||||
return symbol
|
||||
|
||||
def merge_with(self, other: "Symbol", docnames: List[str],
|
||||
@ -4470,13 +4489,15 @@ class Symbol:
|
||||
continue
|
||||
if otherChild.declaration and otherChild.docname in docnames:
|
||||
if not ourChild.declaration:
|
||||
ourChild._fill_empty(otherChild.declaration, otherChild.docname)
|
||||
ourChild._fill_empty(otherChild.declaration,
|
||||
otherChild.docname, otherChild.line)
|
||||
elif ourChild.docname != otherChild.docname:
|
||||
name = str(ourChild.declaration)
|
||||
msg = __("Duplicate C++ declaration, also defined in '%s'.\n"
|
||||
"Declaration is '%s'.")
|
||||
msg = msg % (ourChild.docname, name)
|
||||
logger.warning(msg, location=otherChild.docname)
|
||||
msg = __("Duplicate C++ declaration, also defined at %s:%s.\n"
|
||||
"Declaration is '.. cpp:%s:: %s'.")
|
||||
msg = msg % (ourChild.docname, ourChild.line,
|
||||
ourChild.declaration.directiveType, name)
|
||||
logger.warning(msg, location=(otherChild.docname, otherChild.line))
|
||||
else:
|
||||
# Both have declarations, and in the same docname.
|
||||
# This can apparently happen, it should be safe to
|
||||
@ -4500,23 +4521,25 @@ class Symbol:
|
||||
else:
|
||||
templateDecls = []
|
||||
res = self._add_symbols(nestedName, templateDecls,
|
||||
declaration=None, docname=None)
|
||||
declaration=None, docname=None, line=None)
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent -= 1
|
||||
return res
|
||||
|
||||
def add_declaration(self, declaration: ASTDeclaration, docname: str) -> "Symbol":
|
||||
def add_declaration(self, declaration: ASTDeclaration,
|
||||
docname: str, line: int) -> "Symbol":
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent += 1
|
||||
Symbol.debug_print("add_declaration:")
|
||||
assert declaration
|
||||
assert docname
|
||||
assert declaration is not None
|
||||
assert docname is not None
|
||||
assert line is not None
|
||||
nestedName = declaration.name
|
||||
if declaration.templatePrefix:
|
||||
templateDecls = declaration.templatePrefix.templates
|
||||
else:
|
||||
templateDecls = []
|
||||
res = self._add_symbols(nestedName, templateDecls, declaration, docname)
|
||||
res = self._add_symbols(nestedName, templateDecls, declaration, docname, line)
|
||||
if Symbol.debug_lookup:
|
||||
Symbol.debug_indent -= 1
|
||||
return res
|
||||
@ -4711,7 +4734,8 @@ class Symbol:
|
||||
templateParams=lookupResult.templateParams,
|
||||
templateArgs=lookupResult.templateArgs,
|
||||
declaration=declaration,
|
||||
docname='fakeDocnameForQuery')
|
||||
docname='fakeDocnameForQuery',
|
||||
line=42)
|
||||
queryId = declaration.get_newest_id()
|
||||
for symbol in symbols:
|
||||
if symbol.declaration is None:
|
||||
@ -6655,7 +6679,7 @@ def _make_phony_error_name() -> ASTNestedName:
|
||||
return ASTNestedName([nne], [False], rooted=False)
|
||||
|
||||
|
||||
class CPPObject(ObjectDescription):
|
||||
class CPPObject(ObjectDescription[ASTDeclaration]):
|
||||
"""Description of a C++ language object."""
|
||||
|
||||
doc_field_types = [
|
||||
@ -6717,7 +6741,7 @@ class CPPObject(ObjectDescription):
|
||||
Symbol(parent=targetSymbol, identOrOp=symbol.identOrOp,
|
||||
templateParams=None, templateArgs=None,
|
||||
declaration=declClone,
|
||||
docname=self.env.docname)
|
||||
docname=self.env.docname, line=self.get_source_info()[1])
|
||||
|
||||
def add_target_and_index(self, ast: ASTDeclaration, sig: str,
|
||||
signode: TextElement) -> None:
|
||||
@ -6814,10 +6838,12 @@ class CPPObject(ObjectDescription):
|
||||
parentSymbol = env.temp_data['cpp:parent_symbol']
|
||||
parentDecl = parentSymbol.declaration
|
||||
if parentDecl is not None and parentDecl.objectType == 'function':
|
||||
logger.warning("C++ declarations inside functions are not supported." +
|
||||
" Parent function is " +
|
||||
str(parentSymbol.get_full_nested_name()),
|
||||
location=self.get_source_info())
|
||||
msg = "C++ declarations inside functions are not supported." \
|
||||
" Parent function: {}\nDirective name: {}\nDirective arg: {}"
|
||||
logger.warning(msg.format(
|
||||
str(parentSymbol.get_full_nested_name()),
|
||||
self.name, self.arguments[0]
|
||||
), location=self.get_source_info())
|
||||
name = _make_phony_error_name()
|
||||
symbol = parentSymbol.add_name(name)
|
||||
env.temp_data['cpp:last_symbol'] = symbol
|
||||
@ -6829,7 +6855,7 @@ class CPPObject(ObjectDescription):
|
||||
return super().run()
|
||||
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> ASTDeclaration:
|
||||
parentSymbol = self.env.temp_data['cpp:parent_symbol']
|
||||
parentSymbol = self.env.temp_data['cpp:parent_symbol'] # type: Symbol
|
||||
|
||||
parser = DefinitionParser(sig, location=signode, config=self.env.config)
|
||||
try:
|
||||
@ -6845,7 +6871,8 @@ class CPPObject(ObjectDescription):
|
||||
raise ValueError from e
|
||||
|
||||
try:
|
||||
symbol = parentSymbol.add_declaration(ast, docname=self.env.docname)
|
||||
symbol = parentSymbol.add_declaration(
|
||||
ast, docname=self.env.docname, line=self.get_source_info()[1])
|
||||
# append the new declaration to the sibling list
|
||||
assert symbol.siblingAbove is None
|
||||
assert symbol.siblingBelow is None
|
||||
@ -6858,9 +6885,10 @@ class CPPObject(ObjectDescription):
|
||||
# Assume we are actually in the old symbol,
|
||||
# instead of the newly created duplicate.
|
||||
self.env.temp_data['cpp:last_symbol'] = e.symbol
|
||||
msg = __("Duplicate C++ declaration, also defined in '%s'.\n"
|
||||
"Declaration is '%s'.")
|
||||
msg = msg % (e.symbol.docname, sig)
|
||||
msg = __("Duplicate C++ declaration, also defined at %s:%s.\n"
|
||||
"Declaration is '.. cpp:%s:: %s'.")
|
||||
msg = msg % (e.symbol.docname, e.symbol.line,
|
||||
self.display_object_type, sig)
|
||||
logger.warning(msg, location=signode)
|
||||
|
||||
if ast.objectType == 'enumerator':
|
||||
@ -7031,8 +7059,8 @@ class AliasNode(nodes.Element):
|
||||
assert parentKey is not None
|
||||
self.parentKey = parentKey
|
||||
|
||||
def copy(self: T) -> T:
|
||||
return self.__class__(self.sig, env=None, parentKey=self.parentKey) # type: ignore
|
||||
def copy(self) -> 'AliasNode':
|
||||
return self.__class__(self.sig, env=None, parentKey=self.parentKey)
|
||||
|
||||
|
||||
class AliasTransform(SphinxTransform):
|
||||
@ -7232,14 +7260,18 @@ class CPPDomain(Domain):
|
||||
name = 'cpp'
|
||||
label = 'C++'
|
||||
object_types = {
|
||||
'class': ObjType(_('class'), 'class', 'type', 'identifier'),
|
||||
'union': ObjType(_('union'), 'union', 'type', 'identifier'),
|
||||
'function': ObjType(_('function'), 'function', 'func', 'type', 'identifier'),
|
||||
'member': ObjType(_('member'), 'member', 'var'),
|
||||
'type': ObjType(_('type'), 'type', 'identifier'),
|
||||
'concept': ObjType(_('concept'), 'concept', 'identifier'),
|
||||
'enum': ObjType(_('enum'), 'enum', 'type', 'identifier'),
|
||||
'enumerator': ObjType(_('enumerator'), 'enumerator')
|
||||
'class': ObjType(_('class'), 'class', 'struct', 'identifier', 'type'),
|
||||
'union': ObjType(_('union'), 'union', 'identifier', 'type'),
|
||||
'function': ObjType(_('function'), 'func', 'identifier', 'type'),
|
||||
'member': ObjType(_('member'), 'member', 'var', 'identifier'),
|
||||
'type': ObjType(_('type'), 'identifier', 'type'),
|
||||
'concept': ObjType(_('concept'), 'concept', 'identifier'),
|
||||
'enum': ObjType(_('enum'), 'enum', 'identifier', 'type'),
|
||||
'enumerator': ObjType(_('enumerator'), 'enumerator', 'identifier'),
|
||||
# generated object types
|
||||
'functionParam': ObjType(_('function parameter'), 'identifier', 'member', 'var'), # noqa
|
||||
'templateParam': ObjType(_('template parameter'),
|
||||
'identifier', 'class', 'struct', 'union', 'member', 'var', 'type'), # noqa
|
||||
}
|
||||
|
||||
directives = {
|
||||
@ -7279,7 +7311,7 @@ class CPPDomain(Domain):
|
||||
'texpr': CPPExprRole(asCode=False)
|
||||
}
|
||||
initial_data = {
|
||||
'root_symbol': Symbol(None, None, None, None, None, None),
|
||||
'root_symbol': Symbol(None, None, None, None, None, None, None),
|
||||
'names': {} # full name for indexing -> docname
|
||||
}
|
||||
|
||||
@ -7416,30 +7448,19 @@ class CPPDomain(Domain):
|
||||
|
||||
if typ.startswith('cpp:'):
|
||||
typ = typ[4:]
|
||||
origTyp = typ
|
||||
if typ == 'func':
|
||||
typ = 'function'
|
||||
if typ == 'struct':
|
||||
typ = 'class'
|
||||
declTyp = s.declaration.objectType
|
||||
|
||||
def checkType() -> bool:
|
||||
if typ == 'any' or typ == 'identifier':
|
||||
if typ == 'any':
|
||||
return True
|
||||
if declTyp == 'templateParam':
|
||||
# TODO: perhaps this should be strengthened one day
|
||||
return True
|
||||
if declTyp == 'functionParam':
|
||||
if typ == 'var' or typ == 'member':
|
||||
return True
|
||||
objtypes = self.objtypes_for_role(typ)
|
||||
if objtypes:
|
||||
return declTyp in objtypes
|
||||
print("Type is %s (originally: %s), declType is %s" % (typ, origTyp, declTyp))
|
||||
print("Type is %s, declaration type is %s" % (typ, declTyp))
|
||||
assert False
|
||||
if not checkType():
|
||||
logger.warning("cpp:%s targets a %s (%s).",
|
||||
origTyp, s.declaration.objectType,
|
||||
typ, s.declaration.objectType,
|
||||
s.get_full_nested_name(),
|
||||
location=node)
|
||||
|
||||
@ -7469,10 +7490,10 @@ class CPPDomain(Domain):
|
||||
if env.config.add_function_parentheses and typ == 'any':
|
||||
addParen += 1
|
||||
# and now this stuff for operator()
|
||||
if (env.config.add_function_parentheses and typ == 'function' and
|
||||
if (env.config.add_function_parentheses and typ == 'func' and
|
||||
title.endswith('operator()')):
|
||||
addParen += 1
|
||||
if ((typ == 'any' or typ == 'function') and
|
||||
if ((typ == 'any' or typ == 'func') and
|
||||
title.endswith('operator') and
|
||||
displayName.endswith('operator()')):
|
||||
addParen += 1
|
||||
@ -7481,7 +7502,7 @@ class CPPDomain(Domain):
|
||||
if env.config.add_function_parentheses:
|
||||
if typ == 'any' and displayName.endswith('()'):
|
||||
addParen += 1
|
||||
elif typ == 'function':
|
||||
elif typ == 'func':
|
||||
if title.endswith('()') and not displayName.endswith('()'):
|
||||
title = title[:-2]
|
||||
else:
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
The index domain.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
@ -17,8 +17,7 @@ from docutils.parsers.rst import directives
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains import Domain
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import split_index_msg
|
||||
from sphinx.util import logging, split_index_msg
|
||||
from sphinx.util.docutils import ReferenceRole, SphinxDirective
|
||||
from sphinx.util.nodes import process_index_entry
|
||||
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
The JavaScript domain.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, Iterator, List, Tuple
|
||||
from typing import cast
|
||||
from typing import Any, Dict, Iterator, List, Tuple, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
@ -30,11 +29,10 @@ from sphinx.util.docfields import Field, GroupedField, TypedField
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.nodes import make_id, make_refnode
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class JSObject(ObjectDescription):
|
||||
class JSObject(ObjectDescription[Tuple[str, str]]):
|
||||
"""
|
||||
Description of a JavaScript object.
|
||||
"""
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
The math domain.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
@ -12,8 +12,7 @@ import warnings
|
||||
from typing import Any, Dict, Iterable, List, Tuple
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node, system_message
|
||||
from docutils.nodes import make_id
|
||||
from docutils.nodes import Element, Node, make_id, system_message
|
||||
|
||||
from sphinx.addnodes import pending_xref
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
@ -158,8 +157,11 @@ class MathDomain(Domain):
|
||||
targets = [eq for eq in self.equations.values() if eq[0] == docname]
|
||||
return len(targets) + 1
|
||||
|
||||
def has_equations(self) -> bool:
|
||||
return any(self.data['has_equations'].values())
|
||||
def has_equations(self, docname: str = None) -> bool:
|
||||
if docname:
|
||||
return self.data['has_equations'].get(docname, False)
|
||||
else:
|
||||
return any(self.data['has_equations'].values())
|
||||
|
||||
|
||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
The Python domain.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
@ -15,23 +15,23 @@ import sys
|
||||
import typing
|
||||
import warnings
|
||||
from inspect import Parameter
|
||||
from typing import Any, Dict, Iterable, Iterator, List, NamedTuple, Tuple
|
||||
from typing import cast
|
||||
from typing import Any, Dict, Iterable, Iterator, List, NamedTuple, Tuple, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import pending_xref, desc_signature
|
||||
from sphinx.addnodes import desc_signature, pending_xref
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.domains import Domain, ObjType, Index, IndexEntry
|
||||
from sphinx.domains import Domain, Index, IndexEntry, ObjType
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.pycode.ast import ast, parse as ast_parse
|
||||
from sphinx.pycode.ast import ast
|
||||
from sphinx.pycode.ast import parse as ast_parse
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.docfields import Field, GroupedField, TypedField
|
||||
@ -272,6 +272,8 @@ class PyXrefMixin:
|
||||
result = super().make_xref(rolename, domain, target, # type: ignore
|
||||
innernode, contnode, env)
|
||||
result['refspecific'] = True
|
||||
result['py:module'] = env.ref_context.get('py:module')
|
||||
result['py:class'] = env.ref_context.get('py:class')
|
||||
if target.startswith(('.', '~')):
|
||||
prefix, result['reftarget'] = target[0], target[1:]
|
||||
if prefix == '.':
|
||||
@ -332,7 +334,7 @@ class PyTypedField(PyXrefMixin, TypedField):
|
||||
return super().make_xref(rolename, domain, target, innernode, contnode, env)
|
||||
|
||||
|
||||
class PyObject(ObjectDescription):
|
||||
class PyObject(ObjectDescription[Tuple[str, str]]):
|
||||
"""
|
||||
Description of a general Python object.
|
||||
|
||||
|
@ -4,13 +4,12 @@
|
||||
|
||||
The reStructuredText domain.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import Any, Dict, Iterator, List, Tuple
|
||||
from typing import cast
|
||||
from typing import Any, Dict, Iterator, List, Tuple, cast
|
||||
|
||||
from docutils.nodes import Element
|
||||
from docutils.parsers.rst import directives
|
||||
@ -27,13 +26,12 @@ from sphinx.roles import XRefRole
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.nodes import make_id, make_refnode
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
dir_sig_re = re.compile(r'\.\. (.+?)::(.*)$')
|
||||
|
||||
|
||||
class ReSTMarkup(ObjectDescription):
|
||||
class ReSTMarkup(ObjectDescription[str]):
|
||||
"""
|
||||
Description of generic reST markup.
|
||||
"""
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
The standard domain.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
@ -12,8 +12,7 @@ import re
|
||||
import unicodedata
|
||||
import warnings
|
||||
from copy import copy
|
||||
from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Tuple, Union
|
||||
from typing import cast
|
||||
from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Tuple, Union, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node, system_message
|
||||
@ -27,7 +26,7 @@ from sphinx.directives import ObjectDescription
|
||||
from sphinx.domains import Domain, ObjType
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util import ws_re, logging, docname_join
|
||||
from sphinx.util import docname_join, logging, ws_re
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.nodes import clean_astext, make_id, make_refnode
|
||||
from sphinx.util.typing import RoleFunction
|
||||
@ -35,6 +34,7 @@ from sphinx.util.typing import RoleFunction
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Type # for python3.5.1
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.environment import BuildEnvironment
|
||||
@ -43,12 +43,12 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# RE for option descriptions
|
||||
option_desc_re = re.compile(r'((?:/|--|-|\+)?[^\s=[]+)(=?\s*.*)')
|
||||
option_desc_re = re.compile(r'((?:/|--|-|\+)?[^\s=]+)(=?\s*.*)')
|
||||
# RE for grammar tokens
|
||||
token_re = re.compile(r'`(\w+)`', re.U)
|
||||
token_re = re.compile(r'`((~?\w*:)?\w+)`', re.U)
|
||||
|
||||
|
||||
class GenericObject(ObjectDescription):
|
||||
class GenericObject(ObjectDescription[str]):
|
||||
"""
|
||||
A generic x-ref directive registered with Sphinx.add_object_type().
|
||||
"""
|
||||
@ -178,7 +178,7 @@ class Target(SphinxDirective):
|
||||
return self.name + '-' + name
|
||||
|
||||
|
||||
class Cmdoption(ObjectDescription):
|
||||
class Cmdoption(ObjectDescription[str]):
|
||||
"""
|
||||
Description of a command-line option (.. option).
|
||||
"""
|
||||
@ -197,6 +197,11 @@ class Cmdoption(ObjectDescription):
|
||||
location=signode)
|
||||
continue
|
||||
optname, args = m.groups()
|
||||
if optname.endswith('[') and args.endswith(']'):
|
||||
# optional value surrounded by brackets (ex. foo[=bar])
|
||||
optname = optname[:-1]
|
||||
args = '[' + args
|
||||
|
||||
if count:
|
||||
signode += addnodes.desc_addname(', ', ', ')
|
||||
signode += addnodes.desc_name(optname, optname)
|
||||
@ -318,7 +323,7 @@ def make_glossary_term(env: "BuildEnvironment", textnodes: Iterable[Node], index
|
||||
term['ids'].append(node_id)
|
||||
|
||||
std = cast(StandardDomain, env.get_domain('std'))
|
||||
std.note_object('term', termtext, node_id, location=term)
|
||||
std._note_term(termtext, node_id, location=term)
|
||||
|
||||
# add an index entry too
|
||||
indexnode = addnodes.index()
|
||||
@ -459,9 +464,23 @@ def token_xrefs(text: str, productionGroup: str = '') -> List[Node]:
|
||||
if m.start() > pos:
|
||||
txt = text[pos:m.start()]
|
||||
retnodes.append(nodes.Text(txt, txt))
|
||||
refnode = pending_xref(m.group(1), reftype='token', refdomain='std',
|
||||
reftarget=productionGroup + m.group(1))
|
||||
refnode += nodes.literal(m.group(1), m.group(1), classes=['xref'])
|
||||
token = m.group(1)
|
||||
if ':' in token:
|
||||
if token[0] == '~':
|
||||
_, title = token.split(':')
|
||||
target = token[1:]
|
||||
elif token[0] == ':':
|
||||
title = token[1:]
|
||||
target = title
|
||||
else:
|
||||
title = token
|
||||
target = token
|
||||
else:
|
||||
title = token
|
||||
target = productionGroup + token
|
||||
refnode = pending_xref(title, reftype='token', refdomain='std',
|
||||
reftarget=target)
|
||||
refnode += nodes.literal(token, title, classes=['xref'])
|
||||
retnodes.append(refnode)
|
||||
pos = m.end()
|
||||
if pos < len(text):
|
||||
@ -610,8 +629,6 @@ class StandardDomain(Domain):
|
||||
|
||||
dangling_warnings = {
|
||||
'term': 'term not in glossary: %(target)s',
|
||||
'ref': 'undefined label: %(target)s (if the link has no caption '
|
||||
'the label must precede a section header)',
|
||||
'numref': 'undefined label: %(target)s',
|
||||
'keyword': 'unknown keyword: %(target)s',
|
||||
'doc': 'unknown document: %(target)s',
|
||||
@ -677,6 +694,20 @@ class StandardDomain(Domain):
|
||||
RemovedInSphinx50Warning, stacklevel=2)
|
||||
self.objects[objtype, name] = (docname, labelid)
|
||||
|
||||
@property
|
||||
def _terms(self) -> Dict[str, Tuple[str, str]]:
|
||||
""".. note:: Will be removed soon. internal use only."""
|
||||
return self.data.setdefault('terms', {}) # (name) -> docname, labelid
|
||||
|
||||
def _note_term(self, term: str, labelid: str, location: Any = None) -> None:
|
||||
"""Note a term for cross reference.
|
||||
|
||||
.. note:: Will be removed soon. internal use only.
|
||||
"""
|
||||
self.note_object('term', term, labelid, location)
|
||||
|
||||
self._terms[term.lower()] = (self.env.docname, labelid)
|
||||
|
||||
@property
|
||||
def progoptions(self) -> Dict[Tuple[str, str], Tuple[str, str]]:
|
||||
return self.data.setdefault('progoptions', {}) # (program, name) -> docname, labelid
|
||||
@ -697,6 +728,9 @@ class StandardDomain(Domain):
|
||||
for key, (fn, _l) in list(self.objects.items()):
|
||||
if fn == docname:
|
||||
del self.objects[key]
|
||||
for key, (fn, _l) in list(self._terms.items()):
|
||||
if fn == docname:
|
||||
del self._terms[key]
|
||||
for key, (fn, _l, _l) in list(self.labels.items()):
|
||||
if fn == docname:
|
||||
del self.labels[key]
|
||||
@ -712,6 +746,9 @@ class StandardDomain(Domain):
|
||||
for key, data in otherdata['objects'].items():
|
||||
if data[0] in docnames:
|
||||
self.objects[key] = data
|
||||
for key, data in otherdata['terms'].items():
|
||||
if data[0] in docnames:
|
||||
self._terms[key] = data
|
||||
for key, data in otherdata['labels'].items():
|
||||
if data[0] in docnames:
|
||||
self.labels[key] = data
|
||||
@ -742,9 +779,11 @@ class StandardDomain(Domain):
|
||||
name, env.doc2path(self.labels[name][0]),
|
||||
location=node)
|
||||
self.anonlabels[name] = docname, labelid
|
||||
if node.tagname in ('section', 'rubric'):
|
||||
if node.tagname == 'section':
|
||||
title = cast(nodes.title, node[0])
|
||||
sectname = clean_astext(title)
|
||||
elif node.tagname == 'rubric':
|
||||
sectname = clean_astext(node)
|
||||
elif self.is_enumerable_node(node):
|
||||
sectname = self.get_numfig_title(node)
|
||||
if not sectname:
|
||||
@ -854,8 +893,9 @@ class StandardDomain(Domain):
|
||||
if fignumber is None:
|
||||
return contnode
|
||||
except ValueError:
|
||||
logger.warning(__("no number is assigned for %s: %s"), figtype, labelid,
|
||||
location=node)
|
||||
logger.warning(__("Failed to create a cross reference. Any number is not "
|
||||
"assigned: %s"),
|
||||
labelid, location=node)
|
||||
return contnode
|
||||
|
||||
try:
|
||||
@ -947,19 +987,12 @@ class StandardDomain(Domain):
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
for objtype, term in self.objects:
|
||||
if objtype == 'term' and term.lower() == target.lower():
|
||||
docname, labelid = self.objects[objtype, term]
|
||||
logger.warning(__('term %s not found in case sensitive match.'
|
||||
'made a reference to %s instead.'),
|
||||
target, term, location=node, type='ref', subtype='term')
|
||||
break
|
||||
# fallback to case insentive match
|
||||
if target.lower() in self._terms:
|
||||
docname, labelid = self._terms[target.lower()]
|
||||
return make_refnode(builder, fromdocname, docname, labelid, contnode)
|
||||
else:
|
||||
docname, labelid = '', ''
|
||||
if not docname:
|
||||
return None
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
|
||||
def _resolve_obj_xref(self, env: "BuildEnvironment", fromdocname: str,
|
||||
builder: "Builder", typ: str, target: str,
|
||||
@ -1107,12 +1140,27 @@ class StandardDomain(Domain):
|
||||
RemovedInSphinx40Warning, stacklevel=2)
|
||||
|
||||
|
||||
def warn_missing_reference(app: "Sphinx", domain: Domain, node: pending_xref) -> bool:
|
||||
if (domain and domain.name != 'std') or node['reftype'] != 'ref':
|
||||
return None
|
||||
else:
|
||||
target = node['reftarget']
|
||||
if target not in domain.anonlabels: # type: ignore
|
||||
msg = __('undefined label: %s')
|
||||
else:
|
||||
msg = __('Failed to create a cross reference. A title or caption not found: %s')
|
||||
|
||||
logger.warning(msg % target, location=node, type='ref', subtype=node['reftype'])
|
||||
return True
|
||||
|
||||
|
||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||
app.add_domain(StandardDomain)
|
||||
app.connect('warn-missing-reference', warn_missing_reference)
|
||||
|
||||
return {
|
||||
'version': 'builtin',
|
||||
'env_version': 1,
|
||||
'env_version': 2,
|
||||
'parallel_read_safe': True,
|
||||
'parallel_write_safe': True,
|
||||
}
|
||||
|
@ -4,18 +4,18 @@
|
||||
|
||||
Global creation environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
import os
|
||||
import pickle
|
||||
import posixpath
|
||||
import warnings
|
||||
from collections import defaultdict
|
||||
from copy import copy
|
||||
from os import path
|
||||
from typing import Any, Callable, Dict, Generator, Iterator, List, Set, Tuple, Union
|
||||
from typing import cast
|
||||
from typing import Any, Callable, Dict, Generator, Iterator, List, Set, Tuple, Union, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Node
|
||||
@ -25,13 +25,12 @@ from sphinx.config import Config
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.domains import Domain
|
||||
from sphinx.environment.adapters.toctree import TocTree
|
||||
from sphinx.errors import SphinxError, BuildEnvironmentError, DocumentError, ExtensionError
|
||||
from sphinx.errors import BuildEnvironmentError, DocumentError, ExtensionError, SphinxError
|
||||
from sphinx.events import EventManager
|
||||
from sphinx.locale import __
|
||||
from sphinx.project import Project
|
||||
from sphinx.transforms import SphinxTransformer
|
||||
from sphinx.util import DownloadFiles, FilenameUniqDict
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import DownloadFiles, FilenameUniqDict, logging
|
||||
from sphinx.util.docutils import LoggingReporter
|
||||
from sphinx.util.i18n import CatalogRepository, docname_to_domain
|
||||
from sphinx.util.nodes import is_translatable
|
||||
@ -358,9 +357,9 @@ class BuildEnvironment:
|
||||
docdir = path.dirname(self.doc2path(docname or self.docname,
|
||||
base=None))
|
||||
rel_fn = path.join(docdir, filename)
|
||||
# the path.abspath() might seem redundant, but otherwise artifacts
|
||||
# such as ".." will remain in the path
|
||||
return rel_fn, path.abspath(path.join(self.srcdir, rel_fn))
|
||||
|
||||
return (posixpath.normpath(rel_fn),
|
||||
path.normpath(path.join(self.srcdir, rel_fn)))
|
||||
|
||||
@property
|
||||
def found_docs(self) -> Set[str]:
|
||||
|
@ -4,6 +4,6 @@
|
||||
|
||||
Sphinx environment adapters
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
Assets adapter for sphinx.environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
|
@ -4,23 +4,21 @@
|
||||
|
||||
Index entries adapters for sphinx.environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
import re
|
||||
import unicodedata
|
||||
from itertools import groupby
|
||||
from typing import Any, Dict, Pattern, List, Tuple
|
||||
from typing import cast
|
||||
from typing import Any, Dict, List, Pattern, Tuple, cast
|
||||
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.domains.index import IndexDomain
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.errors import NoUri
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.util import split_into, logging
|
||||
|
||||
from sphinx.util import logging, split_into
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -4,19 +4,18 @@
|
||||
|
||||
Toctree adapter for sphinx.environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
from typing import Any, Iterable, List
|
||||
from typing import cast
|
||||
from typing import Any, Iterable, List, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import url_re, logging
|
||||
from sphinx.util import logging, url_re
|
||||
from sphinx.util.matching import Matcher
|
||||
from sphinx.util.nodes import clean_astext, process_only_nodes
|
||||
|
||||
@ -321,8 +320,10 @@ class TocTree:
|
||||
toctrees = [] # type: List[Element]
|
||||
if 'includehidden' not in kwargs:
|
||||
kwargs['includehidden'] = True
|
||||
if 'maxdepth' not in kwargs:
|
||||
if 'maxdepth' not in kwargs or not kwargs['maxdepth']:
|
||||
kwargs['maxdepth'] = 0
|
||||
else:
|
||||
kwargs['maxdepth'] = int(kwargs['maxdepth'])
|
||||
kwargs['collapse'] = collapse
|
||||
for toctreenode in doctree.traverse(addnodes.toctree):
|
||||
toctree = self.resolve(docname, builder, toctreenode, prune=True, **kwargs)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
The data collector components for sphinx.environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
The image collector for sphinx.environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
@ -26,7 +26,6 @@ from sphinx.util import logging
|
||||
from sphinx.util.i18n import get_image_filename_for_language, search_image_for_language
|
||||
from sphinx.util.images import guess_mimetype
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
The dependencies collector components for sphinx.environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
Index entries collector for sphinx.environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
@ -18,8 +18,7 @@ from sphinx.application import Sphinx
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.environment.collectors import EnvironmentCollector
|
||||
from sphinx.util import split_index_msg, logging
|
||||
|
||||
from sphinx.util import logging, split_index_msg
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
The metadata collector components for sphinx.environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Set
|
||||
from typing import cast
|
||||
from typing import Any, Dict, List, Set, cast
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
The title collector components for sphinx.environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
Toctree collector for sphinx.environment.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Set, Tuple, TypeVar
|
||||
from typing import cast
|
||||
from typing import Any, Dict, List, Set, Tuple, TypeVar, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
@ -21,7 +20,7 @@ from sphinx.environment.adapters.toctree import TocTree
|
||||
from sphinx.environment.collectors import EnvironmentCollector
|
||||
from sphinx.locale import __
|
||||
from sphinx.transforms import SphinxContentsFilter
|
||||
from sphinx.util import url_re, logging
|
||||
from sphinx.util import logging, url_re
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user