mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '3.x' into 6040_autosummary_recursive
This commit is contained in:
commit
b9da9237bc
@ -7,5 +7,5 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run: /python3.6/bin/pip install -U pip setuptools
|
- run: /python3.6/bin/pip install -U pip setuptools
|
||||||
- run: /python3.6/bin/pip install -U .[test,websupport]
|
- run: /python3.6/bin/pip install -U .[test]
|
||||||
- run: make test PYTHON=/python3.6/bin/python
|
- run: make test PYTHON=/python3.6/bin/python
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
comment: false
|
||||||
coverage:
|
coverage:
|
||||||
status:
|
status:
|
||||||
project:
|
project:
|
||||||
|
6
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
6
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Ref: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
|
||||||
|
blank_issues_enabled: false # default: true
|
||||||
|
contact_links:
|
||||||
|
- name: Question
|
||||||
|
url: https://groups.google.com/forum/#!forum/sphinx-users
|
||||||
|
about: For Q&A purpose, please use sphinx-users mailing list.
|
17
.github/ISSUE_TEMPLATE/question.md
vendored
17
.github/ISSUE_TEMPLATE/question.md
vendored
@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
name: Question
|
|
||||||
about: For Q&A purpose, please use https://groups.google.com/forum/#!forum/sphinx-users
|
|
||||||
title: For Q&A purpose, please use sphinx-users group
|
|
||||||
labels: 'question'
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Important
|
|
||||||
|
|
||||||
This is a list of issues for Sphinx, **not a forum**.
|
|
||||||
If you'd like to post a question, please move to sphinx-users group.
|
|
||||||
https://groups.google.com/forum/#!forum/sphinx-users
|
|
||||||
|
|
||||||
Thanks,
|
|
||||||
|
|
11
.github/PULL_REQUEST_TEMPLATE.md
vendored
11
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,9 +1,20 @@
|
|||||||
Subject: <short purpose of this pull request>
|
Subject: <short purpose of this pull request>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Before posting a pull request, please choose a appropriate branch:
|
||||||
|
|
||||||
|
- Breaking changes: master
|
||||||
|
- 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
|
||||||
|
-->
|
||||||
|
|
||||||
### Feature or Bugfix
|
### Feature or Bugfix
|
||||||
<!-- please choose -->
|
<!-- please choose -->
|
||||||
- Feature
|
- Feature
|
||||||
- Bugfix
|
- Bugfix
|
||||||
|
- Refactoring
|
||||||
|
|
||||||
### Purpose
|
### Purpose
|
||||||
- <long purpose of this pull request>
|
- <long purpose of this pull request>
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -23,6 +23,7 @@ distribute-*
|
|||||||
env/
|
env/
|
||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
|
docker/
|
||||||
Sphinx.egg-info/
|
Sphinx.egg-info/
|
||||||
doc/_build/
|
doc/_build/
|
||||||
doc/locale/
|
doc/locale/
|
||||||
|
17
.travis.yml
17
.travis.yml
@ -1,6 +1,6 @@
|
|||||||
language: python
|
os: linux
|
||||||
sudo: false
|
|
||||||
dist: xenial
|
dist: xenial
|
||||||
|
language: python
|
||||||
cache: pip
|
cache: pip
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@ -9,7 +9,7 @@ env:
|
|||||||
- SKIP_LATEX_BUILD=1
|
- SKIP_LATEX_BUILD=1
|
||||||
- IS_PYTHON=true
|
- IS_PYTHON=true
|
||||||
|
|
||||||
matrix:
|
jobs:
|
||||||
include:
|
include:
|
||||||
- python: '3.5'
|
- python: '3.5'
|
||||||
env:
|
env:
|
||||||
@ -19,10 +19,14 @@ matrix:
|
|||||||
- TOXENV=du13
|
- TOXENV=du13
|
||||||
- python: '3.7'
|
- python: '3.7'
|
||||||
env:
|
env:
|
||||||
- TOXENV=py37
|
- TOXENV=du14
|
||||||
|
- python: '3.8'
|
||||||
|
env:
|
||||||
|
- TOXENV=du15
|
||||||
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
|
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
|
||||||
- python: 'nightly'
|
- python: 'nightly'
|
||||||
env: TOXENV=py38
|
env:
|
||||||
|
- TOXENV=du16
|
||||||
- python: '3.6'
|
- python: '3.6'
|
||||||
env: TOXENV=docs
|
env: TOXENV=docs
|
||||||
- python: '3.6'
|
- python: '3.6'
|
||||||
@ -33,8 +37,7 @@ matrix:
|
|||||||
env: TOXENV=flake8
|
env: TOXENV=flake8
|
||||||
|
|
||||||
- language: node_js
|
- language: node_js
|
||||||
node_js:
|
node_js: '10.7'
|
||||||
- 10.7
|
|
||||||
env: IS_PYTHON=false
|
env: IS_PYTHON=false
|
||||||
services: xvfb
|
services: xvfb
|
||||||
|
|
||||||
|
4
AUTHORS
4
AUTHORS
@ -25,6 +25,7 @@ Other contributors, listed alphabetically, are:
|
|||||||
* Henrique Bastos -- SVG support for graphviz extension
|
* Henrique Bastos -- SVG support for graphviz extension
|
||||||
* Daniel Bültmann -- todo extension
|
* Daniel Bültmann -- todo extension
|
||||||
* Marco Buttu -- doctest extension (pyversion option)
|
* Marco Buttu -- doctest extension (pyversion option)
|
||||||
|
* Nathan Damon -- bugfix in validation of static paths in html builders
|
||||||
* Etienne Desautels -- apidoc module
|
* Etienne Desautels -- apidoc module
|
||||||
* Michael Droettboom -- inheritance_diagram extension
|
* Michael Droettboom -- inheritance_diagram extension
|
||||||
* Charles Duffy -- original graphviz extension
|
* Charles Duffy -- original graphviz extension
|
||||||
@ -35,7 +36,7 @@ Other contributors, listed alphabetically, are:
|
|||||||
* Hernan Grecco -- search improvements
|
* Hernan Grecco -- search improvements
|
||||||
* Horst Gutmann -- internationalization support
|
* Horst Gutmann -- internationalization support
|
||||||
* Martin Hans -- autodoc improvements
|
* Martin Hans -- autodoc improvements
|
||||||
* Zac Hatfield-Dodds -- doctest reporting improvements
|
* Zac Hatfield-Dodds -- doctest reporting improvements, intersphinx performance
|
||||||
* Doug Hellmann -- graphviz improvements
|
* Doug Hellmann -- graphviz improvements
|
||||||
* Tim Hoffmann -- theme improvements
|
* Tim Hoffmann -- theme improvements
|
||||||
* Antti Kaihola -- doctest extension (skipif option)
|
* Antti Kaihola -- doctest extension (skipif option)
|
||||||
@ -63,6 +64,7 @@ Other contributors, listed alphabetically, are:
|
|||||||
* \T. Powers -- HTML output improvements
|
* \T. Powers -- HTML output improvements
|
||||||
* Jeppe Pihl -- literalinclude improvements
|
* Jeppe Pihl -- literalinclude improvements
|
||||||
* Rob Ruana -- napoleon extension
|
* Rob Ruana -- napoleon extension
|
||||||
|
* Vince Salvino -- JavaScript search improvements
|
||||||
* Stefan Seefeld -- toctree improvements
|
* Stefan Seefeld -- toctree improvements
|
||||||
* Gregory Szorc -- performance improvements
|
* Gregory Szorc -- performance improvements
|
||||||
* Taku Shimizu -- epub3 builder
|
* Taku Shimizu -- epub3 builder
|
||||||
|
621
CHANGES
621
CHANGES
@ -1,4 +1,4 @@
|
|||||||
Release 3.0.0 (in development)
|
Release 3.1.0 (in development)
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
@ -7,18 +7,35 @@ Dependencies
|
|||||||
Incompatible changes
|
Incompatible changes
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
* Drop features and APIs deprecated in 1.8.x
|
* #7477: imgconverter: Invoke "magick convert" command by default on Windows
|
||||||
* #247: autosummary: stub files are overwritten automatically by default. see
|
|
||||||
:confval:`autosummary_generate_overwrite` to change the behavior
|
|
||||||
|
|
||||||
Deprecated
|
Deprecated
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
* The ``module`` argument of ``sphinx.ext.autosummary.generate.
|
||||||
|
find_autosummary_in_docstring()``
|
||||||
|
|
||||||
Features added
|
Features added
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* #247: autosummary: Add :confval:`autosummary_generate_overwrite` to overwrite
|
* LaTeX: Make the ``toplevel_sectioning`` setting optional in LaTeX theme
|
||||||
old stub file
|
* LaTeX: Allow to override papersize and pointsize from LaTeX themes
|
||||||
|
* LaTeX: Add :confval:`latex_theme_options` to override theme options
|
||||||
|
* #7410: Allow to suppress "circular toctree references detected" warnings using
|
||||||
|
:confval:`suppress_warnings`
|
||||||
|
* C, added scope control directives, :rst:dir:`c:namespace`,
|
||||||
|
:rst:dir:`c:namespace-push`, and :rst:dir:`c:namespace-pop`.
|
||||||
|
* #7466: autosummary: headings in generated documents are not translated
|
||||||
|
* #7490: autosummary: Add ``:caption:`` option to autosummary directive to set a
|
||||||
|
caption to the toctree
|
||||||
|
* #7481: html theme: Add right margin to footnote/citation labels
|
||||||
|
* #7482: html theme: CSS spacing for code blocks with captions and line numbers
|
||||||
|
* #7443: html theme: Add new options :confval:`globaltoc_collapse` and
|
||||||
|
:confval:`globaltoc_includehidden` to control the behavior of globaltoc in
|
||||||
|
sidebar
|
||||||
|
* #7484: html theme: Avoid clashes between sidebar and other blocks
|
||||||
|
* #7476: html theme: Relbar breadcrumb should contain current page
|
||||||
|
* #7506: html theme: A canonical URL is not escaped
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
@ -26,7 +43,7 @@ Bugs fixed
|
|||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Release 2.2.0 (in development)
|
Release 3.0.3 (in development)
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
@ -35,7 +52,546 @@ Dependencies
|
|||||||
Incompatible changes
|
Incompatible changes
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
Testing
|
||||||
|
--------
|
||||||
|
|
||||||
|
Release 3.0.2 (released Apr 19, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* C, parse attributes and add :confval:`c_id_attributes`
|
||||||
|
and :confval:`c_paren_attributes` to support user-defined attributes.
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #7461: py domain: fails with IndexError for empty tuple in type annotation
|
||||||
|
* #7510: py domain: keyword-only arguments are documented as having a default of
|
||||||
|
None
|
||||||
|
* #7418: std domain: :rst:role:`term` role could not match case-insensitively
|
||||||
|
* #7461: autodoc: empty tuple in type annotation is not shown correctly
|
||||||
|
* #7479: autodoc: Sphinx builds has been slower since 3.0.0 on mocking
|
||||||
|
* C++, fix spacing issue in east-const declarations.
|
||||||
|
* #7414: LaTeX: Xindy language options were incorrect
|
||||||
|
* sphinx crashes with ImportError on python3.5.1
|
||||||
|
|
||||||
|
Release 3.0.1 (released Apr 11, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* #7418: std domain: :rst:dir:`term` role becomes case sensitive
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #7428: py domain: a reference to class ``None`` emits a nitpicky warning
|
||||||
|
* #7445: py domain: a return annotation ``None`` in the function signature is
|
||||||
|
not converted to a hyperlink when using intersphinx
|
||||||
|
* #7418: std domain: duplication warning for glossary terms is case insensitive
|
||||||
|
* #7438: C++, fix merging overloaded functions in parallel builds.
|
||||||
|
* #7422: autodoc: fails with ValueError when using autodoc_mock_imports
|
||||||
|
* #7435: autodoc: ``autodoc_typehints='description'`` doesn't suppress typehints
|
||||||
|
in signature for classes/methods
|
||||||
|
* #7451: autodoc: fails with AttributeError when an object returns non-string
|
||||||
|
object as a ``__doc__`` member
|
||||||
|
* #7423: crashed when giving a non-string object to logger
|
||||||
|
* #7479: html theme: Do not include xmlns attribute with HTML 5 doctype
|
||||||
|
* #7426: html theme: Escape some links in HTML templates
|
||||||
|
|
||||||
|
Release 3.0.0 (released Apr 06, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
3.0.0b1
|
||||||
|
|
||||||
|
* LaTeX: drop dependency on :program:`extractbb` for image inclusion in
|
||||||
|
Japanese documents as ``.xbb`` files are unneeded by :program:`dvipdfmx`
|
||||||
|
since TeXLive2015 (refs: #6189)
|
||||||
|
* babel-2.0 or above is available (Unpinned)
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
3.0.0b1
|
||||||
|
|
||||||
|
* Drop features and APIs deprecated in 1.8.x
|
||||||
|
* #247: autosummary: stub files are overwritten automatically by default. see
|
||||||
|
:confval:`autosummary_generate_overwrite` to change the behavior
|
||||||
|
* #5923: autodoc: the members of ``object`` class are not documented by default
|
||||||
|
when ``:inherited-members:`` and ``:special-members:`` are given.
|
||||||
|
* #6830: py domain: ``meta`` fields in info-field-list becomes reserved. They
|
||||||
|
are not displayed on output document now
|
||||||
|
* #6417: py domain: doctree of desc_parameterlist has been changed. The
|
||||||
|
argument names, annotations and default values are wrapped with inline node
|
||||||
|
* The structure of ``sphinx.events.EventManager.listeners`` has changed
|
||||||
|
* Due to the scoping changes for :rst:dir:`productionlist` some uses of
|
||||||
|
:rst:role:`token` must be modified to include the scope which was previously
|
||||||
|
ignored.
|
||||||
|
* #6903: Internal data structure of Python, reST and standard domains have
|
||||||
|
changed. The node_id is added to the index of objects and modules. Now they
|
||||||
|
contains a pair of docname and node_id for cross reference.
|
||||||
|
* #7276: C++ domain: Non intended behavior is removed such as ``say_hello_``
|
||||||
|
links to ``.. cpp:function:: say_hello()``
|
||||||
|
* #7210: js domain: Non intended behavior is removed such as ``parseInt_`` links
|
||||||
|
to ``.. js:function:: parseInt``
|
||||||
|
* #7229: rst domain: Non intended behavior is removed such as ``numref_`` links
|
||||||
|
to ``.. rst:role:: numref``
|
||||||
|
* #6903: py domain: Non intended behavior is removed such as ``say_hello_``
|
||||||
|
links to ``.. py:function:: say_hello()``
|
||||||
|
* #7246: py domain: Drop special cross reference helper for exceptions,
|
||||||
|
functions and methods
|
||||||
|
* The C domain has been rewritten, with additional directives and roles.
|
||||||
|
The existing ones are now more strict, resulting in new warnings.
|
||||||
|
* The attribute ``sphinx_cpp_tagname`` in the ``desc_signature_line`` node
|
||||||
|
has been renamed to ``sphinx_line_type``.
|
||||||
|
* #6462: double backslashes in domain directives are no longer replaced by
|
||||||
|
single backslashes as default. A new configuration value
|
||||||
|
:confval:`strip_signature_backslash` can be used by users to reenable it.
|
||||||
|
|
||||||
|
3.0.0 final
|
||||||
|
|
||||||
|
* #7222: ``sphinx.util.inspect.unwrap()`` is renamed to ``unwrap_all()``
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
3.0.0b1
|
||||||
|
|
||||||
|
* ``desc_signature['first']``
|
||||||
|
* ``sphinx.directives.DescDirective``
|
||||||
|
* ``sphinx.domains.std.StandardDomain.add_object()``
|
||||||
|
* ``sphinx.domains.python.PyDecoratorMixin``
|
||||||
|
* ``sphinx.ext.autodoc.get_documenters()``
|
||||||
|
* ``sphinx.ext.autosummary.process_autosummary_toc()``
|
||||||
|
* ``sphinx.parsers.Parser.app``
|
||||||
|
* ``sphinx.testing.path.Path.text()``
|
||||||
|
* ``sphinx.testing.path.Path.bytes()``
|
||||||
|
* ``sphinx.util.inspect.getargspec()``
|
||||||
|
* ``sphinx.writers.latex.LaTeXWriter.format_docclass()``
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
3.0.0b1
|
||||||
|
|
||||||
|
* #247: autosummary: Add :confval:`autosummary_generate_overwrite` to overwrite
|
||||||
|
old stub file
|
||||||
|
* #5923: autodoc: ``:inherited-members:`` option takes a name of anchestor class
|
||||||
|
not to document inherited members of the class and uppers
|
||||||
|
* #6830: autodoc: consider a member private if docstring contains
|
||||||
|
``:meta private:`` in info-field-list
|
||||||
|
* #7165: autodoc: Support Annotated type (PEP-593)
|
||||||
|
* #2815: autodoc: Support singledispatch functions and methods
|
||||||
|
* #7079: autodoc: :confval:`autodoc_typehints` accepts ``"description"``
|
||||||
|
configuration. It shows typehints as object description
|
||||||
|
* #7314: apidoc: Propagate ``--maxdepth`` option through package documents
|
||||||
|
* #6558: glossary: emit a warning for duplicated glossary entry
|
||||||
|
* #3106: domain: Register hyperlink target for index page automatically
|
||||||
|
* #6558: std domain: emit a warning for duplicated generic objects
|
||||||
|
* #6830: py domain: Add new event: :event:`object-description-transform`
|
||||||
|
* #6895: py domain: Do not emit nitpicky warnings for built-in types
|
||||||
|
* py domain: Support lambda functions in function signature
|
||||||
|
* #6417: py domain: Allow to make a style for arguments of functions and methods
|
||||||
|
* #7238, #7239: py domain: Emit a warning on describing a python object if the
|
||||||
|
entry is already added as the same name
|
||||||
|
* #7341: py domain: type annotations in singature are converted to cross refs
|
||||||
|
* Support priority of event handlers. For more detail, see
|
||||||
|
:py:meth:`.Sphinx.connect()`
|
||||||
|
* #3077: Implement the scoping for :rst:dir:`productionlist` as indicated
|
||||||
|
in the documentation.
|
||||||
|
* #1027: Support backslash line continuation in :rst:dir:`productionlist`.
|
||||||
|
* #7108: config: Allow to show an error message from conf.py via ``ConfigError``
|
||||||
|
* #7032: html: :confval:`html_scaled_image_link` will be disabled for images having
|
||||||
|
``no-scaled-link`` class
|
||||||
|
* #7144: Add CSS class indicating its domain for each desc node
|
||||||
|
* #7211: latex: Use babel for Chinese document when using XeLaTeX
|
||||||
|
* #6672: LaTeX: Support LaTeX Theming (experimental)
|
||||||
|
* #7005: LaTeX: Add LaTeX styling macro for :rst:role:`kbd` role
|
||||||
|
* #7220: genindex: Show "main" index entries at first
|
||||||
|
* #7103: linkcheck: writes all links to ``output.json``
|
||||||
|
* #7025: html search: full text search can be disabled for individual document
|
||||||
|
using ``:nosearch:`` file-wide metadata
|
||||||
|
* #7293: html search: Allow to override JavaScript splitter via
|
||||||
|
``SearchLanguage.js_splitter_code``
|
||||||
|
* #7142: html theme: Add a theme option: ``pygments_dark_style`` to switch the
|
||||||
|
style of code-blocks in dark mode
|
||||||
|
* The C domain has been rewritten adding for example:
|
||||||
|
|
||||||
|
- Cross-referencing respecting the current scope.
|
||||||
|
- Possible to document anonymous entities.
|
||||||
|
- More specific directives and roles for each type of entitiy,
|
||||||
|
e.g., handling scoping of enumerators.
|
||||||
|
- New role :rst:role:`c:expr` for rendering expressions and types
|
||||||
|
in text.
|
||||||
|
|
||||||
|
* Added ``SphinxDirective.get_source_info()``
|
||||||
|
and ``SphinxRole.get_source_info()``.
|
||||||
|
* #7324: sphinx-build: Emit a warning if multiple files having different file
|
||||||
|
extensions for same document found
|
||||||
|
|
||||||
|
3.0.0 final
|
||||||
|
|
||||||
|
* Added ``ObjectDescription.transform_content()``.
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
3.0.0b1
|
||||||
|
|
||||||
|
* C++, fix cross reference lookup in certain cases involving
|
||||||
|
function overloads.
|
||||||
|
* #5078: C++, fix cross reference lookup when a directive contains multiple
|
||||||
|
declarations.
|
||||||
|
* C++, suppress warnings for directly dependent typenames in cross references
|
||||||
|
generated automatically in signatures.
|
||||||
|
* #5637: autodoc: Incorrect handling of nested class names on show-inheritance
|
||||||
|
* #7267: autodoc: error message for invalid directive options has wrong location
|
||||||
|
* #7329: autodoc: info-field-list is wrongly generated from type hints into the
|
||||||
|
class description even if ``autoclass_content='class'`` set
|
||||||
|
* #7331: autodoc: a cython-function is not recognized as a function
|
||||||
|
* #5637: inheritance_diagram: Incorrect handling of nested class names
|
||||||
|
* #7139: ``code-block:: guess`` does not work
|
||||||
|
* #7325: html: source_suffix containing dot leads to wrong source link
|
||||||
|
* #7357: html: Resizing SVG image fails with ValueError
|
||||||
|
* #7278: html search: Fix use of ``html_file_suffix`` instead of
|
||||||
|
``html_link_suffix`` in search results
|
||||||
|
* #7297: html theme: ``bizstyle`` does not support ``sidebarwidth``
|
||||||
|
* #3842: singlehtml: Path to images broken when master doc is not in source root
|
||||||
|
* #7179: std domain: Fix whitespaces are suppressed on referring GenericObject
|
||||||
|
* #7289: console: use bright colors instead of bold
|
||||||
|
* #1539: C, parse array types.
|
||||||
|
* #2377: C, parse function pointers even in complex types.
|
||||||
|
* #7345: sphinx-build: Sphinx crashes if output directory exists as a file
|
||||||
|
* #7290: sphinx-build: Ignore bdb.BdbQuit when handling exceptions
|
||||||
|
* #6240: napoleon: Attributes and Methods sections ignore :noindex: option
|
||||||
|
|
||||||
|
3.0.0 final
|
||||||
|
|
||||||
|
* #7364: autosummary: crashed when :confval:`autosummary_generate` is False
|
||||||
|
* #7370: autosummary: raises UnboundLocalError when unknown module given
|
||||||
|
* #7367: C++, alternate operator spellings are now supported.
|
||||||
|
* C, alternate operator spellings are now supported.
|
||||||
|
* #7368: C++, comma operator in expressions, pack expansion in template
|
||||||
|
argument lists, and more comprehensive error messages in some cases.
|
||||||
|
* C, C++, fix crash and wrong duplicate warnings related to anon symbols.
|
||||||
|
* #6477: Escape first "!" in a cross reference linking no longer possible
|
||||||
|
* #7219: py domain: The index entry generated by ``py:function`` directive is
|
||||||
|
different with one from ``index`` directive with "builtin" type
|
||||||
|
* #7301: capital characters are not allowed for node_id
|
||||||
|
* #7301: epub: duplicated node_ids are generated
|
||||||
|
* #6564: html: a width of table was ignored on HTML builder
|
||||||
|
* #7401: Incorrect argument is passed for :event:`env-get-outdated` handlers
|
||||||
|
* #7355: autodoc: a signature of cython-function is not recognized well
|
||||||
|
* #7222: autodoc: ``__wrapped__`` functions are not documented correctly
|
||||||
|
* #7409: intersphinx: ValueError is raised when an extension sets up
|
||||||
|
:confval:`intersphinx_mapping` on :event:`config-inited` event
|
||||||
|
* #7343: Sphinx builds has been slower since 2.4.0 on debug mode
|
||||||
|
|
||||||
|
Release 2.4.4 (released Mar 05, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #7197: LaTeX: platex cause error to build image directive with target url
|
||||||
|
* #7223: Sphinx builds has been slower since 2.4.0
|
||||||
|
|
||||||
|
Release 2.4.3 (released Feb 22, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #7184: autodoc: ``*args`` and ``**kwarg`` in type comments are not handled
|
||||||
|
properly
|
||||||
|
* #7189: autodoc: classmethod coroutines are not detected
|
||||||
|
* #7183: intersphinx: ``:attr:`` reference to property is broken
|
||||||
|
* #6244, #6387: html search: Search breaks/hangs when built with dirhtml builder
|
||||||
|
* #7195: todo: emit doctree-resolved event with non-document node incorrectly
|
||||||
|
|
||||||
|
Release 2.4.2 (released Feb 19, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #7138: autodoc: ``autodoc.typehints`` crashed when variable has unbound object
|
||||||
|
as a value
|
||||||
|
* #7156: autodoc: separator for keyword only arguments is not shown
|
||||||
|
* #7146: autodoc: IndexError is raised on suppressed type_comment found
|
||||||
|
* #7161: autodoc: typehints extension does not support parallel build
|
||||||
|
* #7178: autodoc: TypeError is raised on fetching type annotations
|
||||||
|
* #7151: crashed when extension assigns a value to ``env.indexentries``
|
||||||
|
* #7170: text: Remove debug print
|
||||||
|
* #7137: viewcode: Avoid to crash when non-python code given
|
||||||
|
|
||||||
|
Release 2.4.1 (released Feb 11, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #7120: html: crashed when on scaling SVG images which have float dimentions
|
||||||
|
* #7126: autodoc: TypeError: 'getset_descriptor' object is not iterable
|
||||||
|
|
||||||
|
Release 2.4.0 (released Feb 09, 2020)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
* The ``decode`` argument of ``sphinx.pycode.ModuleAnalyzer()``
|
||||||
|
* ``sphinx.directives.other.Index``
|
||||||
|
* ``sphinx.environment.temp_data['gloss_entries']``
|
||||||
|
* ``sphinx.environment.BuildEnvironment.indexentries``
|
||||||
|
* ``sphinx.environment.collectors.indexentries.IndexEntriesCollector``
|
||||||
|
* ``sphinx.ext.apidoc.INITPY``
|
||||||
|
* ``sphinx.ext.apidoc.shall_skip()``
|
||||||
|
* ``sphinx.io.FiletypeNotFoundError``
|
||||||
|
* ``sphinx.io.get_filetype()``
|
||||||
|
* ``sphinx.pycode.ModuleAnalyzer.encoding``
|
||||||
|
* ``sphinx.roles.Index``
|
||||||
|
* ``sphinx.util.detect_encoding()``
|
||||||
|
* ``sphinx.util.get_module_source()``
|
||||||
|
* ``sphinx.util.inspect.Signature``
|
||||||
|
* ``sphinx.util.inspect.safe_getmembers()``
|
||||||
|
* ``sphinx.writers.latex.LaTeXTranslator.settings.author``
|
||||||
|
* ``sphinx.writers.latex.LaTeXTranslator.settings.contentsname``
|
||||||
|
* ``sphinx.writers.latex.LaTeXTranslator.settings.docclass``
|
||||||
|
* ``sphinx.writers.latex.LaTeXTranslator.settings.docname``
|
||||||
|
* ``sphinx.writers.latex.LaTeXTranslator.settings.title``
|
||||||
|
* ``sphinx.writers.latex.ADDITIONAL_SETTINGS``
|
||||||
|
* ``sphinx.writers.latex.DEFAULT_SETTINGS``
|
||||||
|
* ``sphinx.writers.latex.LUALATEX_DEFAULT_FONTPKG``
|
||||||
|
* ``sphinx.writers.latex.PDFLATEX_DEFAULT_FONTPKG``
|
||||||
|
* ``sphinx.writers.latex.XELATEX_DEFAULT_FONTPKG``
|
||||||
|
* ``sphinx.writers.latex.XELATEX_GREEK_DEFAULT_FONTPKG``
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* #6910: inheritance_diagram: Make the background of diagrams transparent
|
||||||
|
* #6446: duration: Add ``sphinx.ext.durations`` to inspect which documents slow
|
||||||
|
down the build
|
||||||
|
* #6837: LaTeX: Support a nested table
|
||||||
|
* #7115: LaTeX: Allow to override LATEXOPTS and LATEXMKOPTS via environment
|
||||||
|
variable
|
||||||
|
* #6966: graphviz: Support ``:class:`` option
|
||||||
|
* #6696: html: ``:scale:`` option of image/figure directive not working for SVG
|
||||||
|
images (imagesize-1.2.0 or above is required)
|
||||||
|
* #6994: imgconverter: Support illustrator file (.ai) to .png conversion
|
||||||
|
* autodoc: Support Positional-Only Argument separator (PEP-570 compliant)
|
||||||
|
* autodoc: Support type annotations for variables
|
||||||
|
* #2755: autodoc: Add new event: :event:`autodoc-before-process-signature`
|
||||||
|
* #2755: autodoc: Support type_comment style (ex. ``# type: (str) -> str``)
|
||||||
|
annotation (python3.8+ or `typed_ast <https://github.com/python/typed_ast>`_
|
||||||
|
is required)
|
||||||
|
* #7051: autodoc: Support instance variables without defaults (PEP-526)
|
||||||
|
* #6418: autodoc: Add a new extension ``sphinx.ext.autodoc.typehints``. It shows
|
||||||
|
typehints as object description if ``autodoc_typehints = "description"`` set.
|
||||||
|
This is an experimental extension and it will be integrated into autodoc core
|
||||||
|
in Sphinx-3.0
|
||||||
|
* SphinxTranslator now calls visitor/departure method for super node class if
|
||||||
|
visitor/departure method for original node class not found
|
||||||
|
* #6418: Add new event: :event:`object-description-transform`
|
||||||
|
* py domain: :rst:dir:`py:data` and :rst:dir:`py:attribute` take new options
|
||||||
|
named ``:type:`` and ``:value:`` to describe its type and initial value
|
||||||
|
* #6785: py domain: ``:py:attr:`` is able to refer properties again
|
||||||
|
* #6772: apidoc: Add ``-q`` option for quiet mode
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #6925: html: Remove redundant type="text/javascript" from <script> elements
|
||||||
|
* #7112: html: SVG image is not layouted as float even if aligned
|
||||||
|
* #6906, #6907: autodoc: failed to read the source codes encoeded in cp1251
|
||||||
|
* #6961: latex: warning for babel shown twice
|
||||||
|
* #7059: latex: LaTeX compilation falls into infinite loop (wrapfig issue)
|
||||||
|
* #6581: latex: ``:reversed:`` option for toctree does not effect to LaTeX build
|
||||||
|
* #6559: Wrong node-ids are generated in glossary directive
|
||||||
|
* #6986: apidoc: misdetects module name for .so file inside module
|
||||||
|
* #6899: apidoc: private members are not shown even if ``--private`` given
|
||||||
|
* #6327: apidoc: Support a python package consisted of __init__.so file
|
||||||
|
* #6999: napoleon: fails to parse tilde in :exc: role
|
||||||
|
* #7019: gettext: Absolute path used in message catalogs
|
||||||
|
* #7023: autodoc: nested partial functions are not listed
|
||||||
|
* #7023: autodoc: partial functions imported from other modules are listed as
|
||||||
|
module members without :impoprted-members: option
|
||||||
|
* #6889: autodoc: Trailing comma in ``:members::`` option causes cryptic warning
|
||||||
|
* #6568: autosummary: ``autosummary_imported_members`` is ignored on generating
|
||||||
|
a stub file for submodule
|
||||||
|
* #7055: linkcheck: redirect is treated as an error
|
||||||
|
* #7088: HTML template: If ``navigation_with_keys`` option is activated,
|
||||||
|
modifier keys are ignored, which means the feature can interfere with browser
|
||||||
|
features
|
||||||
|
* #7090: std domain: Can't assign numfig-numbers for custom container nodes
|
||||||
|
* #7106: std domain: enumerated nodes are marked as duplicated when extensions
|
||||||
|
call ``note_explicit_target()``
|
||||||
|
* #7095: dirhtml: Cross references are broken via intersphinx and ``:doc:`` role
|
||||||
|
* C++:
|
||||||
|
|
||||||
|
- Don't crash when using the ``struct`` role in some cases.
|
||||||
|
- Don't warn when using the ``var``/``member`` role for function
|
||||||
|
parameters.
|
||||||
|
- Render call and braced-init expressions correctly.
|
||||||
|
* #7097: Filenames of images generated by
|
||||||
|
``sphinx.transforms.post_transforms.images.ImageConverter``
|
||||||
|
or its subclasses (used for latex build) are now sanitized,
|
||||||
|
to prevent broken paths
|
||||||
|
|
||||||
|
Release 2.3.1 (released Dec 22, 2019)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #6936: sphinx-autogen: raises AttributeError
|
||||||
|
|
||||||
|
Release 2.3.0 (released Dec 15, 2019)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* #6742: ``end-before`` option of :rst:dir:`literalinclude` directive does not
|
||||||
|
match the first line of the code block.
|
||||||
|
* #1331: Change default User-Agent header to ``"Sphinx/X.Y.Z requests/X.Y.Z
|
||||||
|
python/X.Y.Z"``. It can be changed via :confval:`user_agent`.
|
||||||
|
* #6867: text: content of admonitions starts after a blank line
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
----------
|
||||||
|
|
||||||
|
* ``sphinx.builders.gettext.POHEADER``
|
||||||
|
* ``sphinx.io.SphinxStandaloneReader.app``
|
||||||
|
* ``sphinx.io.SphinxStandaloneReader.env``
|
||||||
|
* ``sphinx.util.texescape.tex_escape_map``
|
||||||
|
* ``sphinx.util.texescape.tex_hl_escape_map_new``
|
||||||
|
* ``sphinx.writers.latex.LaTeXTranslator.no_contractions``
|
||||||
|
|
||||||
|
Features added
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* #6707: C++, support bit-fields.
|
||||||
|
* #267: html: Eliminate prompt characters of doctest block from copyable text
|
||||||
|
* #6548: html: Use favicon for OpenSearch if available
|
||||||
|
* #6729: html theme: agogo theme now supports ``rightsidebar`` option
|
||||||
|
* #6780: Add PEP-561 Support
|
||||||
|
* #6762: latex: Allow to load additonal LaTeX packages via ``extrapackages`` key
|
||||||
|
of :confval:`latex_elements`
|
||||||
|
* #1331: Add new config variable: :confval:`user_agent`
|
||||||
|
* #6000: LaTeX: have backslash also be an inline literal word wrap break
|
||||||
|
character
|
||||||
|
* #4186: LaTeX: Support upLaTeX as a new :confval:`latex_engine` (experimental)
|
||||||
|
* #6812: Improve a warning message when extensions are not parallel safe
|
||||||
|
* #6818: Improve Intersphinx performance for multiple remote inventories.
|
||||||
|
* #2546: apidoc: .so file support
|
||||||
|
* #6798: autosummary: emit ``autodoc-skip-member`` event on generating stub file
|
||||||
|
* #6483: i18n: make explicit titles in toctree translatable
|
||||||
|
* #6816: linkcheck: Add :confval:`linkcheck_auth` option to provide
|
||||||
|
authentication information when doing ``linkcheck`` builds
|
||||||
|
* #6872: linkcheck: Handles HTTP 308 Permanent Redirect
|
||||||
|
* #6613: html: Wrap section number in span tag
|
||||||
|
* #6781: gettext: Add :confval:`gettext_last_translator' and
|
||||||
|
:confval:`gettext_language_team` to customize headers of POT file
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #6668: LaTeX: Longtable before header has incorrect distance
|
||||||
|
(refs: `latex3/latex2e#173`_)
|
||||||
|
|
||||||
|
.. _latex3/latex2e#173: https://github.com/latex3/latex2e/issues/173
|
||||||
|
* #6618: LaTeX: Avoid section names at the end of a page
|
||||||
|
* #6738: LaTeX: Do not replace unicode characters by LaTeX macros on unicode
|
||||||
|
supported LaTeX engines: ¶, §, €, ∞, ±, →, ‣, –, superscript and subscript
|
||||||
|
digits go through "as is" (as default OpenType font supports them)
|
||||||
|
* #6704: linkcheck: Be defensive and handle newly defined HTTP error code
|
||||||
|
* #6806: linkcheck: Failure on parsing content
|
||||||
|
* #6655: image URLs containing ``data:`` causes gettext builder crashed
|
||||||
|
* #6584: i18n: Error when compiling message catalogs on Hindi
|
||||||
|
* #6718: i18n: KeyError is raised if section title and table title are same
|
||||||
|
* #6743: i18n: :confval:`rst_prolog` breaks the translation
|
||||||
|
* #6708: mathbase: Some deprecated functions have removed
|
||||||
|
* #6709: autodoc: mock object does not work as a class decorator
|
||||||
|
* #5070: epub: Wrong internal href fragment links
|
||||||
|
* #6712: Allow not to install sphinx.testing as runtime (mainly for ALT Linux)
|
||||||
|
* #6741: html: search result was broken with empty :confval:`html_file_suffix`
|
||||||
|
* #6001: LaTeX does not wrap long code lines at backslash character
|
||||||
|
* #6804: LaTeX: PDF build breaks if admonition of danger type contains
|
||||||
|
code-block long enough not to fit on one page
|
||||||
|
* #6809: LaTeX: code-block in a danger type admonition can easily spill over
|
||||||
|
bottom of page
|
||||||
|
* #6793: texinfo: Code examples broken following "sidebar"
|
||||||
|
* #6813: An orphan warning is emitted for included document on Windows. Thanks
|
||||||
|
to @drillan
|
||||||
|
* #6850: Fix smartypants module calls re.sub() with wrong options
|
||||||
|
* #6824: HTML search: If a search term is partially matched in the title and
|
||||||
|
fully matched in a text paragraph on the same page, the search does not
|
||||||
|
include this match.
|
||||||
|
* #6848: config.py shouldn't pop extensions from overrides
|
||||||
|
* #6867: text: extra spaces are inserted to hyphenated words on folding lines
|
||||||
|
* #6886: LaTeX: xelatex converts straight double quotes into right curly ones
|
||||||
|
(shows when :confval:`smartquotes` is ``False``)
|
||||||
|
* #6890: LaTeX: even with smartquotes off, PDF output transforms straight
|
||||||
|
quotes and consecutive hyphens into curly quotes and dashes
|
||||||
|
* #6876: LaTeX: multi-line display of authors on title page has ragged edges
|
||||||
|
* #6887: Sphinx crashes with docutils-0.16b0
|
||||||
|
* #6920: sphinx-build: A console message is wrongly highlighted
|
||||||
|
* #6900: sphinx-build: ``-D`` option does not considers ``0`` and ``1`` as a
|
||||||
|
boolean value
|
||||||
|
|
||||||
|
Release 2.2.2 (released Dec 03, 2019)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* #6803: For security reason of python, parallel mode is disabled on macOS and
|
||||||
|
Python3.8+
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #6776: LaTeX: 2019-10-01 LaTeX release breaks :file:`sphinxcyrillic.sty`
|
||||||
|
* #6815: i18n: French, Hindi, Chinese, Japanese and Korean translation messages
|
||||||
|
has been broken
|
||||||
|
* #6803: parallel build causes AttributeError on macOS and Python3.8
|
||||||
|
|
||||||
|
Release 2.2.1 (released Oct 26, 2019)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #6641: LaTeX: Undefined control sequence ``\sphinxmaketitle``
|
||||||
|
* #6710: LaTeX not well configured for Greek language as main language
|
||||||
|
* #6759: validation of html static paths and extra paths no longer throws
|
||||||
|
an error if the paths are in different directories
|
||||||
|
|
||||||
|
Release 2.2.0 (released Aug 19, 2019)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
* apidoc: template files are renamed to ``.rst_t``
|
* apidoc: template files are renamed to ``.rst_t``
|
||||||
|
* html: Field lists will be styled by grid layout
|
||||||
|
|
||||||
Deprecated
|
Deprecated
|
||||||
----------
|
----------
|
||||||
@ -60,7 +616,12 @@ Features added
|
|||||||
* #6514: html: Add a label to search input for accessability purposes
|
* #6514: html: Add a label to search input for accessability purposes
|
||||||
* #5602: apidoc: Add ``--templatedir`` option
|
* #5602: apidoc: Add ``--templatedir`` option
|
||||||
* #6475: Add ``override`` argument to ``app.add_autodocumenter()``
|
* #6475: Add ``override`` argument to ``app.add_autodocumenter()``
|
||||||
|
* #6310: imgmath: let :confval:`imgmath_use_preview` work also with the SVG
|
||||||
|
format for images rendering inline math
|
||||||
* #6533: LaTeX: refactor visit_enumerated_list() to use ``\sphinxsetlistlabels``
|
* #6533: LaTeX: refactor visit_enumerated_list() to use ``\sphinxsetlistlabels``
|
||||||
|
* #6628: quickstart: Use ``https://docs.python.org/3/`` for default setting of
|
||||||
|
:confval:`intersphinx_mapping`
|
||||||
|
* #6419: sphinx-build: give reasons why rebuilded
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
@ -72,6 +633,13 @@ Bugs fixed
|
|||||||
* #5502: linkcheck: Consider HTTP 503 response as not an error
|
* #5502: linkcheck: Consider HTTP 503 response as not an error
|
||||||
* #6439: Make generated download links reproducible
|
* #6439: Make generated download links reproducible
|
||||||
* #6486: UnboundLocalError is raised if broken extension installed
|
* #6486: UnboundLocalError is raised if broken extension installed
|
||||||
|
* #6567: autodoc: :confval:`autodoc_inherit_docstrings` does not effect to
|
||||||
|
``__init__()`` and ``__new__()``
|
||||||
|
* #6574: autodoc: :confval:`autodoc_member_order` does not refer order of
|
||||||
|
imports when ``'bysource'`` order
|
||||||
|
* #6574: autodoc: missing type annotation for variadic and keyword parameters
|
||||||
|
* #6589: autodoc: Formatting issues with autodoc_typehints='none'
|
||||||
|
* #6605: autodoc: crashed when target code contains custom method-like objects
|
||||||
* #6498: autosummary: crashed with wrong autosummary_generate setting
|
* #6498: autosummary: crashed with wrong autosummary_generate setting
|
||||||
* #6507: autosummary: crashes without no autosummary_generate setting
|
* #6507: autosummary: crashes without no autosummary_generate setting
|
||||||
* #6511: LaTeX: autonumbered list can not be customized in LaTeX
|
* #6511: LaTeX: autonumbered list can not be customized in LaTeX
|
||||||
@ -81,30 +649,13 @@ Bugs fixed
|
|||||||
* #6527: :confval:`last_updated` wrongly assumes timezone as UTC
|
* #6527: :confval:`last_updated` wrongly assumes timezone as UTC
|
||||||
* #5592: std domain: :rst:dir:`option` directive registers an index entry for
|
* #5592: std domain: :rst:dir:`option` directive registers an index entry for
|
||||||
each comma separated option
|
each comma separated option
|
||||||
|
* #6549: sphinx-build: Escaped characters in error messages
|
||||||
Testing
|
* #6545: doctest comments not getting trimmed since Sphinx 1.8.0
|
||||||
--------
|
* #6561: glossary: Wrong hyperlinks are generated for non alphanumeric terms
|
||||||
|
* #6620: i18n: classifiers of definition list are not translated with
|
||||||
Release 2.1.3 (in development)
|
docutils-0.15
|
||||||
==============================
|
* #6474: ``DocFieldTransformer`` raises AttributeError when given directive is
|
||||||
|
not a subclass of ObjectDescription
|
||||||
Dependencies
|
|
||||||
------------
|
|
||||||
|
|
||||||
Incompatible changes
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Deprecated
|
|
||||||
----------
|
|
||||||
|
|
||||||
Features added
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Bugs fixed
|
|
||||||
----------
|
|
||||||
|
|
||||||
Testing
|
|
||||||
--------
|
|
||||||
|
|
||||||
Release 2.1.2 (released Jun 19, 2019)
|
Release 2.1.2 (released Jun 19, 2019)
|
||||||
=====================================
|
=====================================
|
||||||
@ -212,8 +763,6 @@ Features added
|
|||||||
|
|
||||||
* #6180: Support ``--keep-going`` with BuildDoc setup command
|
* #6180: Support ``--keep-going`` with BuildDoc setup command
|
||||||
* ``math`` directive now supports ``:class:`` option
|
* ``math`` directive now supports ``:class:`` option
|
||||||
* #6310: imgmath: let :confval:`imgmath_use_preview` work also with the SVG
|
|
||||||
format for images rendering inline math
|
|
||||||
* todo: ``todo`` directive now supports ``:name:`` option
|
* todo: ``todo`` directive now supports ``:name:`` option
|
||||||
* Enable override via environment of ``SPHINXOPTS`` and ``SPHINXBUILD`` Makefile
|
* Enable override via environment of ``SPHINXOPTS`` and ``SPHINXBUILD`` Makefile
|
||||||
variables (refs: #6232, #6303)
|
variables (refs: #6232, #6303)
|
||||||
@ -968,6 +1517,8 @@ Features added
|
|||||||
* #5029: autosummary: expose ``inherited_members`` to template
|
* #5029: autosummary: expose ``inherited_members`` to template
|
||||||
* #3784: mathjax: Add :confval:`mathjax_options` to give options to script tag
|
* #3784: mathjax: Add :confval:`mathjax_options` to give options to script tag
|
||||||
for mathjax
|
for mathjax
|
||||||
|
* #726, #969: mathjax: Add :confval:`mathjax_config` to give in-line
|
||||||
|
configurations for mathjax
|
||||||
* #4362: latex: Don't overwrite .tex file if document not changed
|
* #4362: latex: Don't overwrite .tex file if document not changed
|
||||||
* #1431: latex: Add alphanumeric enumerated list support
|
* #1431: latex: Add alphanumeric enumerated list support
|
||||||
* Add :confval:`latex_use_xindy` for UTF-8 savvy indexing, defaults to ``True``
|
* Add :confval:`latex_use_xindy` for UTF-8 savvy indexing, defaults to ``True``
|
||||||
@ -1787,7 +2338,7 @@ Features removed
|
|||||||
|
|
||||||
* ``termsep`` node
|
* ``termsep`` node
|
||||||
* defindex.html template
|
* defindex.html template
|
||||||
* LDML format support in `today`, `today_fmt` and `html_last_updated_fmt`
|
* LDML format support in ``today``, ``today_fmt`` and ``html_last_updated_fmt``
|
||||||
* ``:inline:`` option for the directives of sphinx.ext.graphviz extension
|
* ``:inline:`` option for the directives of sphinx.ext.graphviz extension
|
||||||
* sphinx.ext.pngmath extension
|
* sphinx.ext.pngmath extension
|
||||||
* ``sphinx.util.compat.make_admonition()``
|
* ``sphinx.util.compat.make_admonition()``
|
||||||
@ -4591,7 +5142,7 @@ Features added
|
|||||||
|
|
||||||
- Added a "nitpicky" mode that emits warnings for all missing
|
- Added a "nitpicky" mode that emits warnings for all missing
|
||||||
references. It is activated by the :option:`sphinx-build -n` command-line
|
references. It is activated by the :option:`sphinx-build -n` command-line
|
||||||
switch or the `nitpicky` config value.
|
switch or the :confval:`nitpicky` config value.
|
||||||
- Added ``latexpdf`` target in quickstart Makefile.
|
- Added ``latexpdf`` target in quickstart Makefile.
|
||||||
|
|
||||||
* Markup:
|
* Markup:
|
||||||
|
76
CODE_OF_CONDUCT
Normal file
76
CODE_OF_CONDUCT
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
Like the technical community as a whole, the Sphinx team and community is made
|
||||||
|
up of volunteers from all over the world.
|
||||||
|
Diversity is a strength, but it can also lead to communication issues and
|
||||||
|
unhappiness. To that end, we have a few ground rules that we ask people to
|
||||||
|
adhere to.
|
||||||
|
|
||||||
|
* **Be friendly and patient.**
|
||||||
|
|
||||||
|
* **Be welcoming.**
|
||||||
|
We strive to be a community that welcomes and supports people of all
|
||||||
|
backgrounds and identities. This includes, but is not limited to members of
|
||||||
|
any race, ethnicity, culture, national origin, colour, immigration status,
|
||||||
|
social and economic class, educational level, sex, sexual orientation, gender
|
||||||
|
identity and expression, age, size, family status, political belief, religion,
|
||||||
|
and mental and physical ability.
|
||||||
|
|
||||||
|
* **Be considerate.**
|
||||||
|
Your work will be used by other people, and you in turn will depend on the
|
||||||
|
work of others. Any decision you take will affect users and colleagues, and
|
||||||
|
you should take those consequences into account when making decisions.
|
||||||
|
Remember that we're a world-wide community, so you might not be communicating
|
||||||
|
in someone else's primary language.
|
||||||
|
|
||||||
|
* **Be respectful.**
|
||||||
|
Not all of us will agree all the time, but disagreement is no excuse for poor
|
||||||
|
behavior and poor manners. We might all experience some frustration now and
|
||||||
|
then, but we cannot allow that frustration to turn into a personal attack.
|
||||||
|
It’s important to remember that a community where people feel uncomfortable or
|
||||||
|
threatened is not a productive one. Members of the Sphinx community should be
|
||||||
|
respectful when dealing with other members as well as with people outside the
|
||||||
|
Sphinx community.
|
||||||
|
|
||||||
|
* **Be careful in the words that you choose.**
|
||||||
|
We are a community of professionals, and we conduct ourselves professionally.
|
||||||
|
Be kind to others. Do not insult or put down other participants. Harassment
|
||||||
|
and other exclusionary behavior aren't acceptable. This includes, but is not
|
||||||
|
limited to:
|
||||||
|
|
||||||
|
* Violent threats or language directed against another person.
|
||||||
|
|
||||||
|
* Discriminatory jokes and language.
|
||||||
|
|
||||||
|
* Posting sexually explicit or violent material.
|
||||||
|
|
||||||
|
* Posting (or threatening to post) other people's personally identifying
|
||||||
|
information ("doxing").
|
||||||
|
|
||||||
|
* Personal insults, especially those using racist or sexist terms.
|
||||||
|
|
||||||
|
* Unwelcome sexual attention.
|
||||||
|
|
||||||
|
* Advocating for, or encouraging, any of the above behavior.
|
||||||
|
|
||||||
|
* Repeated harassment of others. In general, if someone asks you to stop, then
|
||||||
|
stop.
|
||||||
|
|
||||||
|
* **When we disagree, try to understand why.**
|
||||||
|
Disagreements, both social and technical, happen all the time and Sphinx is no
|
||||||
|
exception. It is important that we resolve disagreements and differing views
|
||||||
|
constructively. Remember that we’re different. Different people have different
|
||||||
|
perspectives on issues. Being unable to understand why someone holds a
|
||||||
|
viewpoint doesn’t mean that they’re wrong. Don’t forget that it is human to
|
||||||
|
err and blaming each other doesn’t get us anywhere. Instead, focus on helping
|
||||||
|
to resolve issues and learning from mistakes.
|
||||||
|
|
||||||
|
This isn’t an exhaustive list of things that you can’t do.
|
||||||
|
Rather, take it in the spirit in which it’s intended - a guide to make it easier
|
||||||
|
to enrich all of us and the technical communities in which we participate.
|
||||||
|
This code of conduct applies to all spaces of the Sphinx community.
|
||||||
|
|
||||||
|
Attribution
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Original text courtesy of the Speak Up! project:
|
||||||
|
http://web.archive.org/web/20141109123859/http://speakup.io/coc.html.
|
||||||
|
|
115
CONTRIBUTING.rst
115
CONTRIBUTING.rst
@ -61,7 +61,7 @@ of the core developers before it is merged into the main repository.
|
|||||||
#. If you feel uncomfortable or uncertain about an issue or your changes, feel
|
#. If you feel uncomfortable or uncertain about an issue or your changes, feel
|
||||||
free to email the *sphinx-dev* mailing list.
|
free to email the *sphinx-dev* mailing list.
|
||||||
#. Fork `the repository`_ on GitHub to start making your changes to the
|
#. Fork `the repository`_ on GitHub to start making your changes to the
|
||||||
``master`` branch for next MAJOR version, or ``X.Y`` branch for next
|
``master`` branch for next MAJOR version, or ``A.x`` branch for next
|
||||||
MINOR version (see `Branch Model`_).
|
MINOR version (see `Branch Model`_).
|
||||||
#. Write a test which shows that the bug was fixed or that the feature works
|
#. Write a test which shows that the bug was fixed or that the feature works
|
||||||
as expected.
|
as expected.
|
||||||
@ -94,10 +94,10 @@ These are the basic steps needed to start developing on Sphinx.
|
|||||||
Sphinx adopts Semantic Versioning 2.0.0 (refs: https://semver.org/ ).
|
Sphinx adopts Semantic Versioning 2.0.0 (refs: https://semver.org/ ).
|
||||||
|
|
||||||
For changes that preserves backwards-compatibility of API and features,
|
For changes that preserves backwards-compatibility of API and features,
|
||||||
they should be included in the next MINOR release, use the ``X.Y`` branch.
|
they should be included in the next MINOR release, use the ``A.x`` branch.
|
||||||
::
|
::
|
||||||
|
|
||||||
git checkout X.Y
|
git checkout A.x
|
||||||
|
|
||||||
For incompatible or other substantial changes that should wait until the
|
For incompatible or other substantial changes that should wait until the
|
||||||
next MAJOR release, use the ``master`` branch.
|
next MAJOR release, use the ``master`` branch.
|
||||||
@ -199,11 +199,19 @@ These are the basic steps needed to start developing on Sphinx.
|
|||||||
git push origin feature-xyz
|
git push origin feature-xyz
|
||||||
|
|
||||||
#. Submit a pull request from your branch to the respective branch (``master``
|
#. Submit a pull request from your branch to the respective branch (``master``
|
||||||
or ``X.Y``).
|
or ``A.x``).
|
||||||
|
|
||||||
#. Wait for a core developer to review your changes.
|
#. Wait for a core developer to review your changes.
|
||||||
|
|
||||||
|
|
||||||
|
Translations
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The Sphinx core messages and documentations are translated on `Transifex
|
||||||
|
<https://www.transifex.com/>`_. Please join `Sphinx project on Transifex
|
||||||
|
<https://www.transifex.com/sphinx-doc/>`_ and translate them.
|
||||||
|
|
||||||
|
|
||||||
Core Developers
|
Core Developers
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -228,39 +236,6 @@ The following are some general guidelines for core developers:
|
|||||||
author in the commit message and any relevant :file:`CHANGES` entry.
|
author in the commit message and any relevant :file:`CHANGES` entry.
|
||||||
|
|
||||||
|
|
||||||
Locale updates
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The parts of messages in Sphinx that go into builds are translated into several
|
|
||||||
locales. The translations are kept as gettext ``.po`` files translated from the
|
|
||||||
master template ``sphinx/locale/sphinx.pot``.
|
|
||||||
|
|
||||||
Sphinx uses `Babel <http://babel.pocoo.org/en/latest/>`_ to extract messages
|
|
||||||
and maintain the catalog files. It is integrated in ``setup.py``:
|
|
||||||
|
|
||||||
* Use ``python setup.py extract_messages`` to update the ``.pot`` template.
|
|
||||||
* Use ``python setup.py update_catalog`` to update all existing language
|
|
||||||
catalogs in ``sphinx/locale/*/LC_MESSAGES`` with the current messages in the
|
|
||||||
template file.
|
|
||||||
* Use ``python setup.py compile_catalog`` to compile the ``.po`` files to binary
|
|
||||||
``.mo`` files and ``.js`` files.
|
|
||||||
|
|
||||||
When an updated ``.po`` file is submitted, run compile_catalog to commit both
|
|
||||||
the source and the compiled catalogs.
|
|
||||||
|
|
||||||
When a new locale is submitted, add a new directory with the ISO 639-1 language
|
|
||||||
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/>`_. There exists a client tool named ``tx`` in the
|
|
||||||
Python package "transifex_client", which 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 Babel formatting.
|
|
||||||
|
|
||||||
|
|
||||||
Coding Guide
|
Coding Guide
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@ -325,8 +300,8 @@ Versioning 2.0.0 (refs: https://semver.org/ ).
|
|||||||
All changes including incompatible behaviors and public API updates are
|
All changes including incompatible behaviors and public API updates are
|
||||||
allowed.
|
allowed.
|
||||||
|
|
||||||
``X.Y``
|
``A.x`` (ex. ``2.x``)
|
||||||
Where ``X.Y`` is the ``MAJOR.MINOR`` release. Used to maintain current
|
Where ``A.x`` is the ``MAJOR.MINOR`` release. Used to maintain current
|
||||||
MINOR release. All changes are allowed if the change preserves
|
MINOR release. All changes are allowed if the change preserves
|
||||||
backwards-compatibility of API and features.
|
backwards-compatibility of API and features.
|
||||||
|
|
||||||
@ -334,8 +309,8 @@ Versioning 2.0.0 (refs: https://semver.org/ ).
|
|||||||
new MAJOR version is released, the old ``MAJOR.MINOR`` branch will be
|
new MAJOR version is released, the old ``MAJOR.MINOR`` branch will be
|
||||||
deleted and replaced by an equivalent tag.
|
deleted and replaced by an equivalent tag.
|
||||||
|
|
||||||
``X.Y.Z``
|
``A.B.x`` (ex. ``2.4.x``)
|
||||||
Where ``X.Y.Z`` is the ``MAJOR.MINOR.PATCH`` release. Only
|
Where ``A.B.x`` is the ``MAJOR.MINOR.PATCH`` release. Only
|
||||||
backwards-compatible bug fixes are allowed. In Sphinx project, PATCH
|
backwards-compatible bug fixes are allowed. In Sphinx project, PATCH
|
||||||
version is used for urgent bug fix.
|
version is used for urgent bug fix.
|
||||||
|
|
||||||
@ -387,18 +362,31 @@ Sphinx 2.x:
|
|||||||
|
|
||||||
* Sphinx 2.x will contain a backwards-compatible replica of the function
|
* Sphinx 2.x will contain a backwards-compatible replica of the function
|
||||||
which will raise a ``RemovedInSphinx40Warning``.
|
which will raise a ``RemovedInSphinx40Warning``.
|
||||||
|
This is a subclass of :exc:`python:PendingDeprecationWarning`, i.e. it
|
||||||
|
will not get displayed by default.
|
||||||
|
|
||||||
* Sphinx 3.x will still contain the backwards-compatible replica.
|
* Sphinx 3.x will still contain the backwards-compatible replica, but
|
||||||
|
``RemovedInSphinx40Warning`` will be a subclass of
|
||||||
|
:exc:`python:DeprecationWarning` then, and gets displayed by default.
|
||||||
|
|
||||||
* Sphinx 4.0 will remove the feature outright.
|
* Sphinx 4.0 will remove the feature outright.
|
||||||
|
|
||||||
The warnings are displayed by default. You can turn off display of these
|
Deprecation warnings
|
||||||
warnings with:
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Sphinx will enable its ``RemovedInNextVersionWarning`` warnings by default,
|
||||||
|
if :envvar:`python:PYTHONWARNINGS` is not set.
|
||||||
|
Therefore you can disable them using:
|
||||||
|
|
||||||
* ``PYTHONWARNINGS= make html`` (Linux/Mac)
|
* ``PYTHONWARNINGS= make html`` (Linux/Mac)
|
||||||
* ``export PYTHONWARNINGS=`` and do ``make html`` (Linux/Mac)
|
* ``export PYTHONWARNINGS=`` and do ``make html`` (Linux/Mac)
|
||||||
* ``set PYTHONWARNINGS=`` and do ``make html`` (Windows)
|
* ``set PYTHONWARNINGS=`` and do ``make html`` (Windows)
|
||||||
|
|
||||||
|
But you can also explicitly enable the pending ones using e.g.
|
||||||
|
``PYTHONWARNINGS=default`` (see the
|
||||||
|
:ref:`Python docs on configuring warnings <python:describing-warning-filters>`)
|
||||||
|
for more details.
|
||||||
|
|
||||||
Unit Testing
|
Unit Testing
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@ -426,3 +414,42 @@ and other ``test_*.py`` files under ``tests`` directory.
|
|||||||
|
|
||||||
.. versionadded:: 1.8
|
.. versionadded:: 1.8
|
||||||
Sphinx also runs JavaScript tests.
|
Sphinx also runs JavaScript tests.
|
||||||
|
|
||||||
|
|
||||||
|
Release procedures
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The release procedures are listed on ``utils/release-checklist``.
|
||||||
|
|
||||||
|
|
||||||
|
Locale Updates
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The parts of messages in Sphinx that go into builds are translated into several
|
||||||
|
locales. The translations are kept as gettext ``.po`` files translated from the
|
||||||
|
master template :file:`sphinx/locale/sphinx.pot`.
|
||||||
|
|
||||||
|
Sphinx uses `Babel <http://babel.pocoo.org/en/latest/>`_ to extract messages
|
||||||
|
and maintain the catalog files. It is integrated in ``setup.py``:
|
||||||
|
|
||||||
|
* Use ``python setup.py extract_messages`` to update the ``.pot`` template.
|
||||||
|
* Use ``python setup.py update_catalog`` to update all existing language
|
||||||
|
catalogs in ``sphinx/locale/*/LC_MESSAGES`` with the current messages in the
|
||||||
|
template file.
|
||||||
|
* Use ``python setup.py compile_catalog`` to compile the ``.po`` files to binary
|
||||||
|
``.mo`` files and ``.js`` files.
|
||||||
|
|
||||||
|
When an updated ``.po`` file is submitted, run compile_catalog to commit both
|
||||||
|
the source and the compiled catalogs.
|
||||||
|
|
||||||
|
When a new locale is submitted, add a new directory with the ISO 639-1 language
|
||||||
|
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/>`_. There exists a client tool named ``tx`` in the
|
||||||
|
Python package "transifex_client", which 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 Babel formatting.
|
||||||
|
4
EXAMPLES
4
EXAMPLES
@ -183,6 +183,7 @@ Documentation using sphinx_rtd_theme
|
|||||||
* `Databricks <https://docs.databricks.com/>`__ (customized)
|
* `Databricks <https://docs.databricks.com/>`__ (customized)
|
||||||
* `Dataiku DSS <https://doc.dataiku.com/>`__
|
* `Dataiku DSS <https://doc.dataiku.com/>`__
|
||||||
* `DNF <https://dnf.readthedocs.io/>`__
|
* `DNF <https://dnf.readthedocs.io/>`__
|
||||||
|
* `Django-cas-ng <https://djangocas.dev/docs/>`__
|
||||||
* `edX <https://docs.edx.org/>`__
|
* `edX <https://docs.edx.org/>`__
|
||||||
* `Electrum <http://docs.electrum.org/>`__
|
* `Electrum <http://docs.electrum.org/>`__
|
||||||
* `Elemental <http://libelemental.org/documentation/dev/>`__
|
* `Elemental <http://libelemental.org/documentation/dev/>`__
|
||||||
@ -212,6 +213,7 @@ Documentation using sphinx_rtd_theme
|
|||||||
* `Lasagne <https://lasagne.readthedocs.io/>`__
|
* `Lasagne <https://lasagne.readthedocs.io/>`__
|
||||||
* `latexindent.pl <https://latexindentpl.readthedocs.io/>`__
|
* `latexindent.pl <https://latexindentpl.readthedocs.io/>`__
|
||||||
* `Learning Apache Spark with Python <https://runawayhorse001.github.io/LearningApacheSpark>`__
|
* `Learning Apache Spark with Python <https://runawayhorse001.github.io/LearningApacheSpark>`__
|
||||||
|
* `LibCEED <https://libceed.readthedocs.io/>`__
|
||||||
* `Linguistica <https://linguistica-uchicago.github.io/lxa5/>`__
|
* `Linguistica <https://linguistica-uchicago.github.io/lxa5/>`__
|
||||||
* `Linux kernel <https://www.kernel.org/doc/html/latest/index.html>`__
|
* `Linux kernel <https://www.kernel.org/doc/html/latest/index.html>`__
|
||||||
* `Mailman <http://docs.list.org/>`__
|
* `Mailman <http://docs.list.org/>`__
|
||||||
@ -242,6 +244,7 @@ Documentation using sphinx_rtd_theme
|
|||||||
* `PyPy <http://doc.pypy.org/>`__
|
* `PyPy <http://doc.pypy.org/>`__
|
||||||
* `python-sqlparse <https://sqlparse.readthedocs.io/>`__
|
* `python-sqlparse <https://sqlparse.readthedocs.io/>`__
|
||||||
* `PyVISA <https://pyvisa.readthedocs.io/>`__
|
* `PyVISA <https://pyvisa.readthedocs.io/>`__
|
||||||
|
* `pyvista <https://docs.pyvista.org/>`__
|
||||||
* `Read The Docs <https://docs.readthedocs.io/>`__
|
* `Read The Docs <https://docs.readthedocs.io/>`__
|
||||||
* `Free your information from their silos (French) <http://redaction-technique.org/>`__ (customized)
|
* `Free your information from their silos (French) <http://redaction-technique.org/>`__ (customized)
|
||||||
* `Releases Sphinx extension <https://releases.readthedocs.io/>`__
|
* `Releases Sphinx extension <https://releases.readthedocs.io/>`__
|
||||||
@ -404,6 +407,7 @@ Books produced using Sphinx
|
|||||||
* `"Python Professional Programming" (in Japanese) <http://www.amazon.co.jp/dp/4798032948/>`__
|
* `"Python Professional Programming" (in Japanese) <http://www.amazon.co.jp/dp/4798032948/>`__
|
||||||
* `"Python Professional Programming 2nd Edition" (in Japanese) <https://www.amazon.co.jp/dp/479804315X/>`__
|
* `"Python Professional Programming 2nd Edition" (in Japanese) <https://www.amazon.co.jp/dp/479804315X/>`__
|
||||||
* `"Python Professional Programming 3rd Edition" (in Japanese) <https://www.amazon.co.jp/dp/4798053821/>`__
|
* `"Python Professional Programming 3rd Edition" (in Japanese) <https://www.amazon.co.jp/dp/4798053821/>`__
|
||||||
|
* `Python Course by Yuri Petrov (Russian) <https://www.yuripetrov.ru/edu/python>`__
|
||||||
* `"Real World HTTP -- Learning The Internet and Web Technology via its history and code (Japanese)" <https://www.oreilly.co.jp/books/9784873118048/>`__
|
* `"Real World HTTP -- Learning The Internet and Web Technology via its history and code (Japanese)" <https://www.oreilly.co.jp/books/9784873118048/>`__
|
||||||
* `"Redmine Primer 5th Edition (in Japanese)" <https://www.shuwasystem.co.jp/products/7980html/4825.html>`__
|
* `"Redmine Primer 5th Edition (in Japanese)" <https://www.shuwasystem.co.jp/products/7980html/4825.html>`__
|
||||||
* `"The repoze.bfg Web Application Framework" <https://www.amazon.com/repoze-bfg-Web-Application-Framework-Version/dp/0615345379>`__
|
* `"The repoze.bfg Web Application Framework" <https://www.amazon.com/repoze-bfg-Web-Application-Framework-Version/dp/0615345379>`__
|
||||||
|
3
Makefile
3
Makefile
@ -31,6 +31,7 @@ clean-backupfiles:
|
|||||||
clean-generated:
|
clean-generated:
|
||||||
find . -name '.DS_Store' -exec rm -f {} +
|
find . -name '.DS_Store' -exec rm -f {} +
|
||||||
rm -rf Sphinx.egg-info/
|
rm -rf Sphinx.egg-info/
|
||||||
|
rm -rf dist/
|
||||||
rm -rf doc/_build/
|
rm -rf doc/_build/
|
||||||
rm -f sphinx/pycode/*.pickle
|
rm -f sphinx/pycode/*.pickle
|
||||||
rm -f utils/*3.py*
|
rm -f utils/*3.py*
|
||||||
@ -49,7 +50,7 @@ clean-buildfiles:
|
|||||||
|
|
||||||
.PHONY: clean-mypyfiles
|
.PHONY: clean-mypyfiles
|
||||||
clean-mypyfiles:
|
clean-mypyfiles:
|
||||||
rm -rf .mypy_cache/
|
find . -name '.mypy_cache' -exec rm -rf {} +
|
||||||
|
|
||||||
.PHONY: style-check
|
.PHONY: style-check
|
||||||
style-check:
|
style-check:
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
:target: https://codecov.io/gh/sphinx-doc/sphinx
|
:target: https://codecov.io/gh/sphinx-doc/sphinx
|
||||||
:alt: Code Coverage Status (Codecov)
|
:alt: Code Coverage Status (Codecov)
|
||||||
|
|
||||||
|
.. image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg
|
||||||
|
:target: https://opensource.org/licenses/BSD-3-Clause
|
||||||
|
:alt: BSD 3 Clause
|
||||||
|
|
||||||
Sphinx is a tool that makes it easy to create intelligent and beautiful
|
Sphinx is a tool that makes it easy to create intelligent and beautiful
|
||||||
documentation for Python projects (or other documents consisting of multiple
|
documentation for Python projects (or other documents consisting of multiple
|
||||||
reStructuredText sources), written by Georg Brandl. It was originally created
|
reStructuredText sources), written by Georg Brandl. It was originally created
|
||||||
@ -90,6 +94,10 @@ Get in touch
|
|||||||
.. _on GitHub: https://github.com/sphinx-doc/sphinx
|
.. _on GitHub: https://github.com/sphinx-doc/sphinx
|
||||||
.. _mailing list: https://groups.google.com/forum/#!forum/sphinx-users
|
.. _mailing list: https://groups.google.com/forum/#!forum/sphinx-users
|
||||||
|
|
||||||
|
Please adhere to our `code of conduct`__.
|
||||||
|
|
||||||
|
__ http://www.sphinx-doc.org/en/master/code_of_conduct.html
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ PYTHON ?= python3
|
|||||||
# You can set these variables from the command line.
|
# You can set these variables from the command line.
|
||||||
SPHINXOPTS =
|
SPHINXOPTS =
|
||||||
SPHINXBUILD = $(PYTHON) ../sphinx/cmd/build.py
|
SPHINXBUILD = $(PYTHON) ../sphinx/cmd/build.py
|
||||||
SPHINXPROJ = sphinx
|
|
||||||
SOURCEDIR = .
|
SOURCEDIR = .
|
||||||
BUILDDIR = _build
|
BUILDDIR = _build
|
||||||
|
|
||||||
|
4
doc/_static/Makefile
vendored
Normal file
4
doc/_static/Makefile
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
translation.svg: translation.puml
|
||||||
|
plantuml -tsvg $<
|
||||||
|
clean:
|
||||||
|
rm translation.svg
|
BIN
doc/_static/translation.png
vendored
BIN
doc/_static/translation.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
16
doc/_static/translation.puml
vendored
Normal file
16
doc/_static/translation.puml
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
@startuml
|
||||||
|
file "SphinxProject"
|
||||||
|
file ".rst"
|
||||||
|
database ".pot"
|
||||||
|
database ".po"
|
||||||
|
database ".mo"
|
||||||
|
actor translator
|
||||||
|
file TranslatedBuild
|
||||||
|
translator -l-> .po
|
||||||
|
SphinxProject -r-> .rst
|
||||||
|
.rst -r-> .pot : sphinx-build gettext
|
||||||
|
.pot -r-> .po : Pootle
|
||||||
|
.po -d-> .mo : msgfmt
|
||||||
|
.mo -l-> TranslatedBuild
|
||||||
|
.rst -d-> TranslatedBuild : "sphinx-buid -Dlanguage="
|
||||||
|
@enduml
|
29
doc/_static/translation.svg
vendored
Normal file
29
doc/_static/translation.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 7.6 KiB |
8
doc/_templates/index.html
vendored
8
doc/_templates/index.html
vendored
@ -92,8 +92,8 @@
|
|||||||
create a customized documentation using Sphinx written by the matplotlib
|
create a customized documentation using Sphinx written by the matplotlib
|
||||||
developers.{%endtrans%}</p>
|
developers.{%endtrans%}</p>
|
||||||
|
|
||||||
<p>{%trans%}There is a <a href="http://docs.sphinx-users.jp/">Japanese translation</a>
|
<p>{%trans%}There is a translation team in <a href="https://www.transifex.com/sphinx-doc/sphinx-doc/dashboard/">Transifex</a>
|
||||||
of this documentation, thanks to the Japanese Sphinx user group.{%endtrans%}</p>
|
of this documentation, thanks to the Sphinx document translators.{%endtrans%}</p>
|
||||||
<p>{%trans%}A Japanese book about Sphinx has been published by O'Reilly:
|
<p>{%trans%}A Japanese book about Sphinx has been published by O'Reilly:
|
||||||
<a href="https://www.oreilly.co.jp/books/9784873116488/">Sphinxをはじめよう /
|
<a href="https://www.oreilly.co.jp/books/9784873116488/">Sphinxをはじめよう /
|
||||||
Learning Sphinx</a>.{%endtrans%}</p>
|
Learning Sphinx</a>.{%endtrans%}</p>
|
||||||
@ -120,4 +120,8 @@
|
|||||||
<li>{%trans path=pathto("authors")%}<a href="{{ path }}">Sphinx Authors</a></li>{%endtrans%}
|
<li>{%trans path=pathto("authors")%}<a href="{{ path }}">Sphinx Authors</a></li>{%endtrans%}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<h2>{%trans%}Code of Conduct{%endtrans%}</h2>
|
||||||
|
|
||||||
|
{%trans path=pathto("code_of_conduct")%}Please adhere to our <a href="{{ path }}">Code of Conduct</a>.{%endtrans%}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
7
doc/_themes/sphinx13/layout.html
vendored
7
doc/_themes/sphinx13/layout.html
vendored
@ -13,11 +13,6 @@
|
|||||||
{% block sidebar1 %}{{ sidebar() }}{% endblock %}
|
{% block sidebar1 %}{{ sidebar() }}{% endblock %}
|
||||||
{% block sidebar2 %}{% endblock %}
|
{% block sidebar2 %}{% endblock %}
|
||||||
|
|
||||||
{% block linktags %}
|
|
||||||
{{ super() }}
|
|
||||||
<link rel="canonical" href="http://www.sphinx-doc.org/en/master/{{ pagename }}{{ file_suffix }}" />
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block extrahead %}
|
{% block extrahead %}
|
||||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,700'
|
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,700'
|
||||||
rel='stylesheet' type='text/css' />
|
rel='stylesheet' type='text/css' />
|
||||||
@ -30,7 +25,7 @@
|
|||||||
.related { display: none; }
|
.related { display: none; }
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</style>
|
</style>
|
||||||
<script type="text/javascript">
|
<script>
|
||||||
// intelligent scrolling of the sidebar content
|
// intelligent scrolling of the sidebar content
|
||||||
$(window).scroll(function() {
|
$(window).scroll(function() {
|
||||||
var sb = $('.sphinxsidebarwrapper');
|
var sb = $('.sphinxsidebarwrapper');
|
||||||
|
5
doc/_themes/sphinx13/static/sphinx13.css
vendored
5
doc/_themes/sphinx13/static/sphinx13.css
vendored
@ -299,6 +299,11 @@ a.headerlink:hover {
|
|||||||
color: white!important;
|
color: white!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* avoid font-size when :mod: role in headings */
|
||||||
|
h1 code, h2 code, h3 code, h4 code {
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
cite, code, tt {
|
cite, code, tt {
|
||||||
font-family: 'Consolas', 'DejaVu Sans Mono',
|
font-family: 'Consolas', 'DejaVu Sans Mono',
|
||||||
'Bitstream Vera Sans Mono', monospace;
|
'Bitstream Vera Sans Mono', monospace;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
:tocdepth: 2
|
:tocdepth: 1
|
||||||
|
|
||||||
.. default-role:: any
|
.. default-role:: any
|
||||||
|
|
||||||
|
8
doc/code_of_conduct.rst
Normal file
8
doc/code_of_conduct.rst
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
:tocdepth: 2
|
||||||
|
|
||||||
|
.. _code_of_conduct:
|
||||||
|
|
||||||
|
Sphinx Code of Conduct
|
||||||
|
======================
|
||||||
|
|
||||||
|
.. include:: ../CODE_OF_CONDUCT
|
@ -7,6 +7,7 @@ import sphinx
|
|||||||
|
|
||||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo',
|
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo',
|
||||||
'sphinx.ext.autosummary', 'sphinx.ext.extlinks',
|
'sphinx.ext.autosummary', 'sphinx.ext.extlinks',
|
||||||
|
'sphinx.ext.intersphinx',
|
||||||
'sphinx.ext.viewcode', 'sphinx.ext.inheritance_diagram']
|
'sphinx.ext.viewcode', 'sphinx.ext.inheritance_diagram']
|
||||||
|
|
||||||
master_doc = 'contents'
|
master_doc = 'contents'
|
||||||
@ -14,7 +15,7 @@ templates_path = ['_templates']
|
|||||||
exclude_patterns = ['_build']
|
exclude_patterns = ['_build']
|
||||||
|
|
||||||
project = 'Sphinx'
|
project = 'Sphinx'
|
||||||
copyright = '2007-2019, Georg Brandl and the Sphinx team'
|
copyright = '2007-2020, Georg Brandl and the Sphinx team'
|
||||||
version = sphinx.__display_version__
|
version = sphinx.__display_version__
|
||||||
release = version
|
release = version
|
||||||
show_authors = True
|
show_authors = True
|
||||||
@ -25,7 +26,8 @@ modindex_common_prefix = ['sphinx.']
|
|||||||
html_static_path = ['_static']
|
html_static_path = ['_static']
|
||||||
html_sidebars = {'index': ['indexsidebar.html', 'searchbox.html']}
|
html_sidebars = {'index': ['indexsidebar.html', 'searchbox.html']}
|
||||||
html_additional_pages = {'index': 'index.html'}
|
html_additional_pages = {'index': 'index.html'}
|
||||||
html_use_opensearch = 'http://sphinx-doc.org'
|
html_use_opensearch = 'https://www.sphinx-doc.org/en/master'
|
||||||
|
html_baseurl = 'https://www.sphinx-doc.org/en/master/'
|
||||||
|
|
||||||
htmlhelp_basename = 'Sphinxdoc'
|
htmlhelp_basename = 'Sphinxdoc'
|
||||||
|
|
||||||
@ -146,6 +148,9 @@ def setup(app):
|
|||||||
app.add_object_type('confval', 'confval',
|
app.add_object_type('confval', 'confval',
|
||||||
objname='configuration value',
|
objname='configuration value',
|
||||||
indextemplate='pair: %s; configuration value')
|
indextemplate='pair: %s; configuration value')
|
||||||
|
app.add_object_type('setuptools-confval', 'setuptools-confval',
|
||||||
|
objname='setuptools configuration value',
|
||||||
|
indextemplate='pair: %s; setuptools configuration value')
|
||||||
fdesc = GroupedField('parameter', label='Parameters',
|
fdesc = GroupedField('parameter', label='Parameters',
|
||||||
names=['param'], can_collapse=True)
|
names=['param'], can_collapse=True)
|
||||||
app.add_object_type('event', 'event', 'pair: %s; event', parse_event,
|
app.add_object_type('event', 'event', 'pair: %s; event', parse_event,
|
||||||
|
@ -34,6 +34,7 @@ Sphinx documentation contents
|
|||||||
changes
|
changes
|
||||||
examples
|
examples
|
||||||
authors
|
authors
|
||||||
|
code_of_conduct
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ This is the current list of contributed extensions in that repository:
|
|||||||
- astah: embed diagram by using astah
|
- astah: embed diagram by using astah
|
||||||
- autoanysrc: Gather reST documentation from any source files
|
- autoanysrc: Gather reST documentation from any source files
|
||||||
- autorun: Execute code in a ``runblock`` directive
|
- autorun: Execute code in a ``runblock`` directive
|
||||||
|
- beamer_: A builder for Beamer (LaTeX) output.
|
||||||
- blockdiag: embed block diagrams by using blockdiag_
|
- blockdiag: embed block diagrams by using blockdiag_
|
||||||
- cacoo: embed diagram from Cacoo
|
- cacoo: embed diagram from Cacoo
|
||||||
- cf3domain: a domain for CFEngine 3 policies
|
- cf3domain: a domain for CFEngine 3 policies
|
||||||
@ -148,3 +149,4 @@ started with writing your own extensions.
|
|||||||
.. _domaintools: https://bitbucket.org/klorenz/sphinxcontrib-domaintools
|
.. _domaintools: https://bitbucket.org/klorenz/sphinxcontrib-domaintools
|
||||||
.. _restbuilder: https://pypi.org/project/sphinxcontrib-restbuilder/
|
.. _restbuilder: https://pypi.org/project/sphinxcontrib-restbuilder/
|
||||||
.. _Lasso: http://www.lassosoft.com/
|
.. _Lasso: http://www.lassosoft.com/
|
||||||
|
.. _beamer: https://pypi.org/project/sphinxcontrib-beamer/
|
||||||
|
@ -70,6 +70,9 @@ def process_todo_nodes(app, doctree, fromdocname):
|
|||||||
# Augment each todo with a backlink to the original location.
|
# Augment each todo with a backlink to the original location.
|
||||||
env = app.builder.env
|
env = app.builder.env
|
||||||
|
|
||||||
|
if not hasattr(env, 'todo_all_todos'):
|
||||||
|
env.todo_all_todos = []
|
||||||
|
|
||||||
for node in doctree.traverse(todolist):
|
for node in doctree.traverse(todolist):
|
||||||
if not app.config.todo_include_todos:
|
if not app.config.todo_include_todos:
|
||||||
node.replace_self([])
|
node.replace_self([])
|
||||||
|
@ -75,7 +75,7 @@ The first thing to examine is the ``RecipeDirective`` directive:
|
|||||||
.. literalinclude:: examples/recipe.py
|
.. literalinclude:: examples/recipe.py
|
||||||
:language: python
|
:language: python
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 17-37
|
:pyobject: RecipeDirective
|
||||||
|
|
||||||
Unlike :doc:`helloworld` and :doc:`todo`, this directive doesn't derive from
|
Unlike :doc:`helloworld` and :doc:`todo`, this directive doesn't derive from
|
||||||
:class:`docutils.parsers.rst.Directive` and doesn't define a ``run`` method.
|
:class:`docutils.parsers.rst.Directive` and doesn't define a ``run`` method.
|
||||||
@ -103,7 +103,12 @@ reStructuredText in the body.
|
|||||||
.. literalinclude:: examples/recipe.py
|
.. literalinclude:: examples/recipe.py
|
||||||
:language: python
|
:language: python
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 40-102
|
:pyobject: IngredientIndex
|
||||||
|
|
||||||
|
.. literalinclude:: examples/recipe.py
|
||||||
|
:language: python
|
||||||
|
:linenos:
|
||||||
|
:pyobject: RecipeIndex
|
||||||
|
|
||||||
Both ``IngredientIndex`` and ``RecipeIndex`` are derived from :class:`Index`.
|
Both ``IngredientIndex`` and ``RecipeIndex`` are derived from :class:`Index`.
|
||||||
They implement custom logic to generate a tuple of values that define the
|
They implement custom logic to generate a tuple of values that define the
|
||||||
@ -117,6 +122,10 @@ all it really is is a list of tuples like ``('tomato', 'TomatoSoup', 'test',
|
|||||||
'rec-TomatoSoup',...)``. Refer to the :doc:`domain API guide
|
'rec-TomatoSoup',...)``. Refer to the :doc:`domain API guide
|
||||||
</extdev/domainapi>` for more information on this API.
|
</extdev/domainapi>` for more information on this API.
|
||||||
|
|
||||||
|
These index pages can be referred by combination of domain name and its
|
||||||
|
``name`` using :rst:role:`ref` role. For example, ``RecipeIndex`` can be
|
||||||
|
referred by ``:ref:`recipe-recipe```.
|
||||||
|
|
||||||
.. rubric:: The domain
|
.. rubric:: The domain
|
||||||
|
|
||||||
A Sphinx domain is a specialized container that ties together roles,
|
A Sphinx domain is a specialized container that ties together roles,
|
||||||
@ -126,7 +135,7 @@ creating here.
|
|||||||
.. literalinclude:: examples/recipe.py
|
.. literalinclude:: examples/recipe.py
|
||||||
:language: python
|
:language: python
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 105-155
|
:pyobject: RecipeDomain
|
||||||
|
|
||||||
There are some interesting things to note about this ``recipe`` domain and domains
|
There are some interesting things to note about this ``recipe`` domain and domains
|
||||||
in general. Firstly, we actually register our directives, roles and indices
|
in general. Firstly, we actually register our directives, roles and indices
|
||||||
@ -164,7 +173,7 @@ hook the various parts of our extension into Sphinx. Let's look at the
|
|||||||
.. literalinclude:: examples/recipe.py
|
.. literalinclude:: examples/recipe.py
|
||||||
:language: python
|
:language: python
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 158-
|
:pyobject: setup
|
||||||
|
|
||||||
This looks a little different to what we're used to seeing. There are no calls
|
This looks a little different to what we're used to seeing. There are no calls
|
||||||
to :meth:`~Sphinx.add_directive` or even :meth:`~Sphinx.add_role`. Instead, we
|
to :meth:`~Sphinx.add_directive` or even :meth:`~Sphinx.add_role`. Instead, we
|
||||||
|
@ -107,6 +107,20 @@ is just a "general" node.
|
|||||||
<http://docutils.sourceforge.net/docs/ref/doctree.html>`__ and :ref:`Sphinx
|
<http://docutils.sourceforge.net/docs/ref/doctree.html>`__ and :ref:`Sphinx
|
||||||
<nodes>`.
|
<nodes>`.
|
||||||
|
|
||||||
|
.. attention::
|
||||||
|
|
||||||
|
It is important to know that while you can extend Sphinx without
|
||||||
|
leaving your ``conf.py``, if you declare an inherited node right
|
||||||
|
there, you'll hit an unobvious :py:class:`PickleError`. So if
|
||||||
|
something goes wrong, please make sure that you put inherited nodes
|
||||||
|
into a separate Python module.
|
||||||
|
|
||||||
|
For more details, see:
|
||||||
|
|
||||||
|
- https://github.com/sphinx-doc/sphinx/issues/6751
|
||||||
|
- https://github.com/sphinx-doc/sphinx/issues/1493
|
||||||
|
- https://github.com/sphinx-doc/sphinx/issues/1424
|
||||||
|
|
||||||
.. rubric:: The directive classes
|
.. rubric:: The directive classes
|
||||||
|
|
||||||
A directive class is a class deriving usually from
|
A directive class is a class deriving usually from
|
||||||
|
@ -45,7 +45,6 @@ package.
|
|||||||
|
|
||||||
.. automethod:: Sphinx.add_enumerable_node(node, figtype, title_getter=None, \*\*kwds)
|
.. automethod:: Sphinx.add_enumerable_node(node, figtype, title_getter=None, \*\*kwds)
|
||||||
|
|
||||||
.. method:: Sphinx.add_directive(name, func, content, arguments, \*\*options)
|
|
||||||
.. automethod:: Sphinx.add_directive(name, directiveclass)
|
.. automethod:: Sphinx.add_directive(name, directiveclass)
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_role(name, role)
|
.. automethod:: Sphinx.add_role(name, role)
|
||||||
@ -54,7 +53,6 @@ package.
|
|||||||
|
|
||||||
.. automethod:: Sphinx.add_domain(domain)
|
.. automethod:: Sphinx.add_domain(domain)
|
||||||
|
|
||||||
.. method:: Sphinx.add_directive_to_domain(domain, name, func, content, arguments, \*\*options)
|
|
||||||
.. automethod:: Sphinx.add_directive_to_domain(domain, name, directiveclass)
|
.. automethod:: Sphinx.add_directive_to_domain(domain, name, directiveclass)
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_role_to_domain(domain, name, role)
|
.. automethod:: Sphinx.add_role_to_domain(domain, name, role)
|
||||||
@ -107,6 +105,7 @@ Emitting events
|
|||||||
---------------
|
---------------
|
||||||
|
|
||||||
.. class:: Sphinx
|
.. class:: Sphinx
|
||||||
|
:noindex:
|
||||||
|
|
||||||
.. automethod:: emit(event, \*arguments)
|
.. automethod:: emit(event, \*arguments)
|
||||||
|
|
||||||
@ -216,6 +215,14 @@ connect handlers to the events. Example:
|
|||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
|
|
||||||
|
.. event:: object-description-transform (app, domain, objtype, contentnode)
|
||||||
|
|
||||||
|
Emitted when an object description directive has run. The *domain* and
|
||||||
|
*objtype* arguments are strings indicating object description of the object.
|
||||||
|
And *contentnode* is a content for the object. It can be modified in-place.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
.. event:: doctree-read (app, doctree)
|
.. event:: doctree-read (app, doctree)
|
||||||
|
|
||||||
Emitted when a doctree has been parsed and read by the environment, and is
|
Emitted when a doctree has been parsed and read by the environment, and is
|
||||||
@ -260,11 +267,6 @@ connect handlers to the events. Example:
|
|||||||
environment from the main process. *docnames* is a set of document names
|
environment from the main process. *docnames* is a set of document names
|
||||||
that have been read in the subprocess.
|
that have been read in the subprocess.
|
||||||
|
|
||||||
For a sample of how to deal with this event, look at the standard
|
|
||||||
``sphinx.ext.todo`` extension. The implementation is often similar to that
|
|
||||||
of :event:`env-purge-doc`, only that information is not removed, but added to
|
|
||||||
the main environment from the other environment.
|
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
.. event:: env-updated (app, env)
|
.. event:: env-updated (app, env)
|
||||||
|
@ -26,6 +26,228 @@ The following is a list of deprecated interfaces.
|
|||||||
- (will be) Removed
|
- (will be) Removed
|
||||||
- Alternatives
|
- Alternatives
|
||||||
|
|
||||||
|
* - The ``module`` argument of
|
||||||
|
``sphinx.ext.autosummary.generate.find_autosummary_in_docstring()``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``desc_signature['first']``
|
||||||
|
-
|
||||||
|
- 3.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.directives.DescDirective``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.directives.ObjectDescription``
|
||||||
|
|
||||||
|
* - ``sphinx.domains.std.StandardDomain.add_object()``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.domains.std.StandardDomain.note_object()``
|
||||||
|
|
||||||
|
* - ``sphinx.domains.python.PyDecoratorMixin``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.get_documenters()``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.registry.documenters``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autosummary.process_autosummary_toc()``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.parsers.Parser.app``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.testing.path.Path.text()``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.testing.path.Path.read_text()``
|
||||||
|
|
||||||
|
* - ``sphinx.testing.path.Path.bytes()``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.testing.path.Path.read_bytes()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.inspect.getargspec()``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- ``inspect.getargspec()``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXWriter.format_docclass()``
|
||||||
|
- 3.0
|
||||||
|
- 5.0
|
||||||
|
- LaTeX Themes
|
||||||
|
|
||||||
|
* - ``decode`` argument of ``sphinx.pycode.ModuleAnalyzer()``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.directives.other.Index``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.domains.index.IndexDirective``
|
||||||
|
|
||||||
|
* - ``sphinx.environment.temp_data['gloss_entries']``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``documents.nameids``
|
||||||
|
|
||||||
|
* - ``sphinx.environment.BuildEnvironment.indexentries``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.domains.index.IndexDomain``
|
||||||
|
|
||||||
|
* - ``sphinx.environment.collectors.indexentries.IndexEntriesCollector``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.domains.index.IndexDomain``
|
||||||
|
|
||||||
|
* - ``sphinx.io.FiletypeNotFoundError``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.errors.FiletypeNotFoundError``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.apidoc.INITPY``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.ext.apidoc.shall_skip()``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.ext.apidoc.is_skipped_package``
|
||||||
|
|
||||||
|
* - ``sphinx.io.get_filetype()``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.util.get_filetype()``
|
||||||
|
|
||||||
|
* - ``sphinx.pycode.ModuleAnalyzer.encoding``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.roles.Index``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.domains.index.IndexRole``
|
||||||
|
|
||||||
|
* - ``sphinx.util.detect_encoding()``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``tokenize.detect_encoding()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.get_module_source()``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.util.inspect.Signature``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.util.inspect.signature`` and
|
||||||
|
``sphinx.util.inspect.stringify_signature()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.inspect.safe_getmembers()``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``inspect.getmembers()``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXTranslator.settings.author``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXTranslator.settings.contentsname``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``document['contentsname']``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXTranslator.settings.docclass``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``document['docclass']``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXTranslator.settings.docname``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXTranslator.settings.title``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.ADDITIONAL_SETTINGS``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.latex.constants.ADDITIONAL_SETTINGS``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.DEFAULT_SETTINGS``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.latex.constants.DEFAULT_SETTINGS``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LUALATEX_DEFAULT_FONTPKG``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.latex.constants.LUALATEX_DEFAULT_FONTPKG``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.PDFLATEX_DEFAULT_FONTPKG``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.latex.constants.PDFLATEX_DEFAULT_FONTPKG``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.XELATEX_DEFAULT_FONTPKG``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.latex.constants.XELATEX_DEFAULT_FONTPKG``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.XELATEX_GREEK_DEFAULT_FONTPKG``
|
||||||
|
- 2.4
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.builders.latex.constants.XELATEX_GREEK_DEFAULT_FONTPKG``
|
||||||
|
|
||||||
|
* - ``sphinx.builders.gettext.POHEADER``
|
||||||
|
- 2.3
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx/templates/gettext/message.pot_t`` (template file)
|
||||||
|
|
||||||
|
* - ``sphinx.io.SphinxStandaloneReader.app``
|
||||||
|
- 2.3
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.io.SphinxStandaloneReader.setup()``
|
||||||
|
|
||||||
|
* - ``sphinx.io.SphinxStandaloneReader.env``
|
||||||
|
- 2.3
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.io.SphinxStandaloneReader.setup()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.texescape.tex_escape_map``
|
||||||
|
- 2.3
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.util.texescape.escape()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.texescape.tex_hl_escape_map_new``
|
||||||
|
- 2.3
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.util.texescape.hlescape()``
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXTranslator.no_contractions``
|
||||||
|
- 2.3
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
* - ``sphinx.domains.math.MathDomain.add_equation()``
|
* - ``sphinx.domains.math.MathDomain.add_equation()``
|
||||||
- 2.2
|
- 2.2
|
||||||
- 4.0
|
- 4.0
|
||||||
|
@ -35,25 +35,25 @@ In practice, you have to:
|
|||||||
:func:`sphinx.locale.get_translation` function, usually renamed ``_()``,
|
:func:`sphinx.locale.get_translation` function, usually renamed ``_()``,
|
||||||
e.g.:
|
e.g.:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:caption: src/__init__.py
|
:caption: src/__init__.py
|
||||||
|
|
||||||
from sphinx.locale import get_translation
|
from sphinx.locale import get_translation
|
||||||
|
|
||||||
MESSAGE_CATALOG_NAME = 'myextension'
|
MESSAGE_CATALOG_NAME = 'myextension'
|
||||||
_ = get_translation(MESSAGE_CATALOG_NAME)
|
_ = get_translation(MESSAGE_CATALOG_NAME)
|
||||||
|
|
||||||
translated_text = _('Hello Sphinx!')
|
translated_text = _('Hello Sphinx!')
|
||||||
|
|
||||||
#. Set up your extension to be aware of its dedicated translations:
|
#. Set up your extension to be aware of its dedicated translations:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:caption: src/__init__.py
|
:caption: src/__init__.py
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
package_dir = path.abspath(path.dirname(__file__))
|
package_dir = path.abspath(path.dirname(__file__))
|
||||||
locale_dir = os.path.join(package_dir, 'locales')
|
locale_dir = os.path.join(package_dir, 'locales')
|
||||||
app.add_message_catalog(MESSAGE_CATALOG_NAME, locale_dir)
|
app.add_message_catalog(MESSAGE_CATALOG_NAME, locale_dir)
|
||||||
|
|
||||||
#. Generate message catalog template ``*.pot`` file, usually in ``locale/``
|
#. Generate message catalog template ``*.pot`` file, usually in ``locale/``
|
||||||
source directory, for example via `Babel`_:
|
source directory, for example via `Babel`_:
|
||||||
|
@ -27,7 +27,7 @@ Discovery of builders by entry point
|
|||||||
|
|
||||||
.. versionadded:: 1.6
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
:term:`Builder` extensions can be discovered by means of `entry points`_ so
|
:term:`builder` extensions can be discovered by means of `entry points`_ so
|
||||||
that they do not have to be listed in the :confval:`extensions` configuration
|
that they do not have to be listed in the :confval:`extensions` configuration
|
||||||
value.
|
value.
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ Google Analytics
|
|||||||
|
|
||||||
{%- block extrahead %}
|
{%- block extrahead %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script type="text/javascript">
|
<script>
|
||||||
var _gaq = _gaq || [];
|
var _gaq = _gaq || [];
|
||||||
_gaq.push(['_setAccount', 'XXX account number XXX']);
|
_gaq.push(['_setAccount', 'XXX account number XXX']);
|
||||||
_gaq.push(['_trackPageview']);
|
_gaq.push(['_trackPageview']);
|
||||||
@ -101,7 +101,7 @@ Google Analytics
|
|||||||
<div class="footer">This page uses <a href="https://analytics.google.com/">
|
<div class="footer">This page uses <a href="https://analytics.google.com/">
|
||||||
Google Analytics</a> to collect statistics. You can disable it by blocking
|
Google Analytics</a> to collect statistics. You can disable it by blocking
|
||||||
the JavaScript coming from www.google-analytics.com.
|
the JavaScript coming from www.google-analytics.com.
|
||||||
<script type="text/javascript">
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
var ga = document.createElement('script');
|
var ga = document.createElement('script');
|
||||||
ga.src = ('https:' == document.location.protocol ?
|
ga.src = ('https:' == document.location.protocol ?
|
||||||
@ -132,7 +132,6 @@ Google Search
|
|||||||
(function() {
|
(function() {
|
||||||
var cx = '......';
|
var cx = '......';
|
||||||
var gcse = document.createElement('script');
|
var gcse = document.createElement('script');
|
||||||
gcse.type = 'text/javascript';
|
|
||||||
gcse.async = true;
|
gcse.async = true;
|
||||||
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
|
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
|
||||||
var s = document.getElementsByTagName('script')[0];
|
var s = document.getElementsByTagName('script')[0];
|
||||||
|
@ -55,9 +55,9 @@ See the :ref:`pertinent section in the FAQ list <usingwith>`.
|
|||||||
Prerequisites
|
Prerequisites
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Sphinx needs at least **Python 3.5** to run, as well as the docutils_ and
|
Sphinx needs at least **Python 3.5** to run.
|
||||||
Jinja2_ libraries. Sphinx should work with docutils version 0.12 or some (not
|
It also depends on 3rd party libraries such as docutils_ and jinja2_, but they
|
||||||
broken) SVN trunk snapshot.
|
are automatically installed when sphinx is installed.
|
||||||
|
|
||||||
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
|
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
|
||||||
.. _docutils: http://docutils.sourceforge.net/
|
.. _docutils: http://docutils.sourceforge.net/
|
||||||
|
@ -226,6 +226,25 @@ into the generated ``.tex`` files. Its ``'sphinxsetup'`` key is described
|
|||||||
|
|
||||||
.. versionadded:: 1.5
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
``'extrapackages'``
|
||||||
|
Additional LaTeX packages. For example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
latex_elements = {
|
||||||
|
'packages': r'\usepackage{isodate}'
|
||||||
|
}
|
||||||
|
|
||||||
|
It defaults to empty.
|
||||||
|
|
||||||
|
The specified LaTeX packages will be loaded before
|
||||||
|
hyperref package and packages loaded from Sphinx extensions.
|
||||||
|
|
||||||
|
.. hint:: If you'd like to load additional LaTeX packages after hyperref, use
|
||||||
|
``'preamble'`` key instead.
|
||||||
|
|
||||||
|
.. versionadded:: 2.3
|
||||||
|
|
||||||
``'footer'``
|
``'footer'``
|
||||||
Additional footer content (before the indices), default empty.
|
Additional footer content (before the indices), default empty.
|
||||||
|
|
||||||
@ -289,6 +308,11 @@ into the generated ``.tex`` files. Its ``'sphinxsetup'`` key is described
|
|||||||
|
|
||||||
.. attention::
|
.. attention::
|
||||||
|
|
||||||
|
If Greek is main language, do not use this key. Since Sphinx 2.2.1,
|
||||||
|
``xelatex`` will be used automatically as :confval:`latex_engine`.
|
||||||
|
Formerly, Sphinx did not support producing PDF via LaTeX with Greek as
|
||||||
|
main language.
|
||||||
|
|
||||||
Prior to 2.0, Unicode Greek letters were escaped to use LaTeX math
|
Prior to 2.0, Unicode Greek letters were escaped to use LaTeX math
|
||||||
mark-up. This is not the case anymore, and the above must be used
|
mark-up. This is not the case anymore, and the above must be used
|
||||||
(only in case of ``'pdflatex'`` engine) if the source contains such
|
(only in case of ``'pdflatex'`` engine) if the source contains such
|
||||||
@ -310,12 +334,19 @@ into the generated ``.tex`` files. Its ``'sphinxsetup'`` key is described
|
|||||||
.. versionchanged:: 2.0
|
.. versionchanged:: 2.0
|
||||||
``'lualatex'`` executes
|
``'lualatex'`` executes
|
||||||
``\defaultfontfeatures[\rmfamily,\sffamily]{}`` to disable TeX
|
``\defaultfontfeatures[\rmfamily,\sffamily]{}`` to disable TeX
|
||||||
ligatures.
|
ligatures transforming `<<` and `>>` as escaping working with
|
||||||
|
``pdflatex/xelatex`` failed with ``lualatex``.
|
||||||
.. versionchanged:: 2.0
|
.. versionchanged:: 2.0
|
||||||
Detection of ``LGR``, ``T2A``, ``X2`` to trigger support of
|
Detection of ``LGR``, ``T2A``, ``X2`` to trigger support of
|
||||||
occasional Greek or Cyrillic (``'pdflatex'`` only, as this support
|
occasional Greek or Cyrillic (``'pdflatex'`` only, as this support
|
||||||
is provided natively by ``'platex'`` and only requires suitable
|
is provided natively by ``'platex'`` and only requires suitable
|
||||||
font with ``'xelatex'/'lualatex'``).
|
font with ``'xelatex'/'lualatex'``).
|
||||||
|
.. versionchanged:: 2.3.0
|
||||||
|
``'xelatex'`` also executes
|
||||||
|
``\defaultfontfeatures[\rmfamily,\sffamily]{}`` in order to avoid
|
||||||
|
contractions of ``--`` into en-dash or transforms of straight quotes
|
||||||
|
into curly ones in PDF (in non-literal text paragraphs) despite
|
||||||
|
:confval:`smartquotes` being set to ``False``.
|
||||||
|
|
||||||
``'textgreek'``
|
``'textgreek'``
|
||||||
The default (``'pdflatex'`` only) is
|
The default (``'pdflatex'`` only) is
|
||||||
@ -595,12 +626,15 @@ macros may be significant.
|
|||||||
default ``true``. Allows linebreaks inside inline literals: but extra
|
default ``true``. Allows linebreaks inside inline literals: but extra
|
||||||
potential break-points (additionally to those allowed by LaTeX at spaces
|
potential break-points (additionally to those allowed by LaTeX at spaces
|
||||||
or for hyphenation) are currently inserted only after the characters
|
or for hyphenation) are currently inserted only after the characters
|
||||||
``. , ; ? ! /``. Due to TeX internals, white space in the line will be
|
``. , ; ? ! /`` and ``\``. Due to TeX internals, white space in the line
|
||||||
stretched (or shrunk) in order to accomodate the linebreak.
|
will be stretched (or shrunk) in order to accomodate the linebreak.
|
||||||
|
|
||||||
.. versionadded:: 1.5
|
.. versionadded:: 1.5
|
||||||
set this option value to ``false`` to recover former behaviour.
|
set this option value to ``false`` to recover former behaviour.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.3.0
|
||||||
|
added potential breakpoint at ``\`` characters.
|
||||||
|
|
||||||
``verbatimvisiblespace``
|
``verbatimvisiblespace``
|
||||||
default ``\textcolor{red}{\textvisiblespace}``. When a long code line is
|
default ``\textcolor{red}{\textvisiblespace}``. When a long code line is
|
||||||
split, the last space character from the source code line right before the
|
split, the last space character from the source code line right before the
|
||||||
@ -783,6 +817,8 @@ Macros
|
|||||||
multiple paragraphs in header cells of tables.
|
multiple paragraphs in header cells of tables.
|
||||||
.. versionadded:: 1.6.3
|
.. versionadded:: 1.6.3
|
||||||
``\sphinxstylecodecontinued`` and ``\sphinxstylecodecontinues``.
|
``\sphinxstylecodecontinued`` and ``\sphinxstylecodecontinues``.
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
``\sphinxkeyboard``
|
||||||
- ``\sphinxtableofcontents``: it is a
|
- ``\sphinxtableofcontents``: it is a
|
||||||
wrapper (defined differently in :file:`sphinxhowto.cls` and in
|
wrapper (defined differently in :file:`sphinxhowto.cls` and in
|
||||||
:file:`sphinxmanual.cls`) of standard ``\tableofcontents``. The macro
|
:file:`sphinxmanual.cls`) of standard ``\tableofcontents``. The macro
|
||||||
|
@ -7,7 +7,6 @@ if "%SPHINXBUILD%" == "" (
|
|||||||
)
|
)
|
||||||
set SOURCEDIR=.
|
set SOURCEDIR=.
|
||||||
set BUILDDIR=_build
|
set BUILDDIR=_build
|
||||||
set SPHINXPROJ=sphinx-doc
|
|
||||||
|
|
||||||
if "%1" == "" goto help
|
if "%1" == "" goto help
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ Synopsis
|
|||||||
--------
|
--------
|
||||||
|
|
||||||
**sphinx-apidoc** [*OPTIONS*] -o <*OUTPUT_PATH*> <*MODULE_PATH*>
|
**sphinx-apidoc** [*OPTIONS*] -o <*OUTPUT_PATH*> <*MODULE_PATH*>
|
||||||
[*EXCLUDE_PATTERN*, ...]
|
[*EXCLUDE_PATTERN* ...]
|
||||||
|
|
||||||
Description
|
Description
|
||||||
-----------
|
-----------
|
||||||
@ -39,6 +39,11 @@ Options
|
|||||||
|
|
||||||
Directory to place the output files. If it does not exist, it is created.
|
Directory to place the output files. If it does not exist, it is created.
|
||||||
|
|
||||||
|
.. option:: -q
|
||||||
|
|
||||||
|
Do not output anything on standard output, only write warnings and errors to
|
||||||
|
standard error.
|
||||||
|
|
||||||
.. option:: -f, --force
|
.. option:: -f, --force
|
||||||
|
|
||||||
Force overwriting of any existing generated files.
|
Force overwriting of any existing generated files.
|
||||||
|
@ -73,7 +73,7 @@ If you run the following:
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
$ PYTHONPATH=. sphinx-autodoc doc/index.rst
|
$ PYTHONPATH=. sphinx-autogen docs/index.rst
|
||||||
|
|
||||||
then the following stub files will be created in ``docs``::
|
then the following stub files will be created in ``docs``::
|
||||||
|
|
||||||
|
@ -121,6 +121,17 @@ The following blocks exist in the ``layout.html`` template:
|
|||||||
The contents of the document itself. It contains the block "body" where the
|
The contents of the document itself. It contains the block "body" where the
|
||||||
individual content is put by subtemplates like ``page.html``.
|
individual content is put by subtemplates like ``page.html``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
In order for the built-in JavaScript search to show a page preview on
|
||||||
|
the results page, the document or body content should be wrapped in an
|
||||||
|
HTML element containing the ``role="main"`` attribute. For example:
|
||||||
|
|
||||||
|
.. sourcecode:: html+jinja
|
||||||
|
|
||||||
|
<div role="main">
|
||||||
|
{% block document %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
|
||||||
`sidebar1` / `sidebar2`
|
`sidebar1` / `sidebar2`
|
||||||
A possible location for a sidebar. `sidebar1` appears before the document
|
A possible location for a sidebar. `sidebar1` appears before the document
|
||||||
and is empty by default, `sidebar2` after the document and contains the
|
and is empty by default, `sidebar2` after the document and contains the
|
||||||
@ -216,6 +227,7 @@ them to generate links or output multiply used elements.
|
|||||||
documents.
|
documents.
|
||||||
|
|
||||||
.. function:: pathto(file, 1)
|
.. function:: pathto(file, 1)
|
||||||
|
:noindex:
|
||||||
|
|
||||||
Return the path to a *file* which is a filename relative to the root of the
|
Return the path to a *file* which is a filename relative to the root of the
|
||||||
generated output. Use this to refer to static files.
|
generated output. Use this to refer to static files.
|
||||||
@ -402,10 +414,6 @@ are in HTML form), these variables are also available:
|
|||||||
nonempty if the :confval:`html_copy_source` value is ``True``.
|
nonempty if the :confval:`html_copy_source` value is ``True``.
|
||||||
This has empty value on creating automatically-generated files.
|
This has empty value on creating automatically-generated files.
|
||||||
|
|
||||||
.. data:: title
|
|
||||||
|
|
||||||
The page title.
|
|
||||||
|
|
||||||
.. data:: toc
|
.. data:: toc
|
||||||
|
|
||||||
The local table of contents for the current page, rendered as HTML bullet
|
The local table of contents for the current page, rendered as HTML bullet
|
||||||
@ -427,5 +435,3 @@ are in HTML form), these variables are also available:
|
|||||||
|
|
||||||
* ``includehidden`` (``False`` by default): if true, the TOC tree will also
|
* ``includehidden`` (``False`` by default): if true, the TOC tree will also
|
||||||
contain hidden entries.
|
contain hidden entries.
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,6 +63,11 @@ Python :mod:`ConfigParser` module) and has the following structure:
|
|||||||
highlighting. This can be overridden by the user in the
|
highlighting. This can be overridden by the user in the
|
||||||
:confval:`pygments_style` config value.
|
:confval:`pygments_style` config value.
|
||||||
|
|
||||||
|
* The **pygments_dark_style** setting gives the name of a Pygments style to use
|
||||||
|
for highlighting when the CSS media query ``(prefers-color-scheme: dark)``
|
||||||
|
evaluates to true. It is injected into the page using
|
||||||
|
:meth:`~Sphinx.add_css_file()`.
|
||||||
|
|
||||||
* The **sidebars** setting gives the comma separated list of sidebar templates
|
* The **sidebars** setting gives the comma separated list of sidebar templates
|
||||||
for constructing sidebars. This can be overridden by the user in the
|
for constructing sidebars. This can be overridden by the user in the
|
||||||
:confval:`html_sidebars` config value.
|
:confval:`html_sidebars` config value.
|
||||||
|
@ -9,11 +9,11 @@ Complementary to translations provided for Sphinx-generated messages such as
|
|||||||
navigation bars, Sphinx provides mechanisms facilitating *document* translations
|
navigation bars, Sphinx provides mechanisms facilitating *document* translations
|
||||||
in itself. See the :ref:`intl-options` for details on configuration.
|
in itself. See the :ref:`intl-options` for details on configuration.
|
||||||
|
|
||||||
.. figure:: /_static/translation.png
|
.. figure:: /_static/translation.svg
|
||||||
:width: 100%
|
:width: 100%
|
||||||
|
|
||||||
Workflow visualization of translations in Sphinx. (The stick-figure is taken
|
Workflow visualization of translations in Sphinx. (The figure is created by
|
||||||
from an `XKCD comic <https://xkcd.com/779/>`_.)
|
`plantuml <http://plantuml.com>`_.)
|
||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
:local:
|
:local:
|
||||||
@ -90,9 +90,9 @@ section describe an easy way to translate with *sphinx-intl*.
|
|||||||
locale_dirs = ['locale/'] # path is example but recommended.
|
locale_dirs = ['locale/'] # path is example but recommended.
|
||||||
gettext_compact = False # optional.
|
gettext_compact = False # optional.
|
||||||
|
|
||||||
This case-study assumes that :confval:`locale_dirs` is set to ``locale/`` and
|
This case-study assumes that BUILDDIR is set to ``_build``,
|
||||||
:confval:`gettext_compact` is set to ``False`` (the Sphinx document is
|
:confval:`locale_dirs` is set to ``locale/`` and :confval:`gettext_compact`
|
||||||
already configured as such).
|
is set to ``False`` (the Sphinx document is already configured as such).
|
||||||
|
|
||||||
#. Extract translatable messages into pot files.
|
#. Extract translatable messages into pot files.
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ Once configured, call this by calling the relevant command on ``setup.py``::
|
|||||||
Options for setuptools integration
|
Options for setuptools integration
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
.. confval:: fresh-env
|
.. setuptools-confval:: fresh-env
|
||||||
|
|
||||||
A boolean that determines whether the saved environment should be discarded
|
A boolean that determines whether the saved environment should be discarded
|
||||||
on build. Default is false.
|
on build. Default is false.
|
||||||
@ -68,7 +68,7 @@ Options for setuptools integration
|
|||||||
|
|
||||||
$ python setup.py build_sphinx -E
|
$ python setup.py build_sphinx -E
|
||||||
|
|
||||||
.. confval:: all-files
|
.. setuptools-confval:: all-files
|
||||||
|
|
||||||
A boolean that determines whether all files should be built from scratch.
|
A boolean that determines whether all files should be built from scratch.
|
||||||
Default is false.
|
Default is false.
|
||||||
@ -79,7 +79,7 @@ Options for setuptools integration
|
|||||||
|
|
||||||
$ python setup.py build_sphinx -a
|
$ python setup.py build_sphinx -a
|
||||||
|
|
||||||
.. confval:: source-dir
|
.. setuptools-confval:: source-dir
|
||||||
|
|
||||||
The target source directory. This can be relative to the ``setup.py`` or
|
The target source directory. This can be relative to the ``setup.py`` or
|
||||||
``setup.cfg`` file, or it can be absolute. It defaults to ``./doc`` or
|
``setup.cfg`` file, or it can be absolute. It defaults to ``./doc`` or
|
||||||
@ -92,12 +92,12 @@ Options for setuptools integration
|
|||||||
|
|
||||||
$ python setup.py build_sphinx -s $SOURCE_DIR
|
$ python setup.py build_sphinx -s $SOURCE_DIR
|
||||||
|
|
||||||
.. confval:: build-dir
|
.. setuptools-confval:: build-dir
|
||||||
|
|
||||||
The target build directory. This can be relative to the ``setup.py`` or
|
The target build directory. This can be relative to the ``setup.py`` or
|
||||||
``setup.cfg`` file, or it can be absolute. Default is ``./build/sphinx``.
|
``setup.cfg`` file, or it can be absolute. Default is ``./build/sphinx``.
|
||||||
|
|
||||||
.. confval:: config-dir
|
.. setuptools-confval:: config-dir
|
||||||
|
|
||||||
Location of the configuration directory. This can be relative to the
|
Location of the configuration directory. This can be relative to the
|
||||||
``setup.py`` or ``setup.cfg`` file, or it can be absolute. Default is to use
|
``setup.py`` or ``setup.cfg`` file, or it can be absolute. Default is to use
|
||||||
@ -111,7 +111,7 @@ Options for setuptools integration
|
|||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
|
|
||||||
.. confval:: builder
|
.. setuptools-confval:: builder
|
||||||
|
|
||||||
The builder or list of builders to use. Default is ``html``.
|
The builder or list of builders to use. Default is ``html``.
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ Options for setuptools integration
|
|||||||
.. versionchanged:: 1.6
|
.. versionchanged:: 1.6
|
||||||
This can now be a comma- or space-separated list of builders
|
This can now be a comma- or space-separated list of builders
|
||||||
|
|
||||||
.. confval:: warning-is-error
|
.. setuptools-confval:: warning-is-error
|
||||||
|
|
||||||
A boolean that ensures Sphinx warnings will result in a failed build.
|
A boolean that ensures Sphinx warnings will result in a failed build.
|
||||||
Default is false.
|
Default is false.
|
||||||
@ -137,32 +137,32 @@ Options for setuptools integration
|
|||||||
|
|
||||||
.. versionadded:: 1.5
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
.. confval:: project
|
.. setuptools-confval:: project
|
||||||
|
|
||||||
The documented project's name. Default is ``''``.
|
The documented project's name. Default is ``''``.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
|
|
||||||
.. confval:: version
|
.. setuptools-confval:: version
|
||||||
|
|
||||||
The short X.Y version. Default is ``''``.
|
The short X.Y version. Default is ``''``.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
|
|
||||||
.. confval:: release
|
.. setuptools-confval:: release
|
||||||
|
|
||||||
The full version, including alpha/beta/rc tags. Default is ``''``.
|
The full version, including alpha/beta/rc tags. Default is ``''``.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
|
|
||||||
.. confval:: today
|
.. setuptools-confval:: today
|
||||||
|
|
||||||
How to format the current date, used as the replacement for ``|today|``.
|
How to format the current date, used as the replacement for ``|today|``.
|
||||||
Default is ``''``.
|
Default is ``''``.
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
|
|
||||||
.. confval:: link-index
|
.. setuptools-confval:: link-index
|
||||||
|
|
||||||
A boolean that ensures index.html will be linked to the master doc. Default
|
A boolean that ensures index.html will be linked to the master doc. Default
|
||||||
is false.
|
is false.
|
||||||
@ -175,13 +175,13 @@ Options for setuptools integration
|
|||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
|
|
||||||
.. confval:: copyright
|
.. setuptools-confval:: copyright
|
||||||
|
|
||||||
The copyright string. Default is ``''``.
|
The copyright string. Default is ``''``.
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
.. confval:: nitpicky
|
.. setuptools-confval:: nitpicky
|
||||||
|
|
||||||
Run in nit-picky mode. Currently, this generates warnings for all missing
|
Run in nit-picky mode. Currently, this generates warnings for all missing
|
||||||
references. See the config value :confval:`nitpick_ignore` for a way to
|
references. See the config value :confval:`nitpick_ignore` for a way to
|
||||||
@ -189,7 +189,7 @@ Options for setuptools integration
|
|||||||
|
|
||||||
.. versionadded:: 1.8
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
.. confval:: pdb
|
.. setuptools-confval:: pdb
|
||||||
|
|
||||||
A boolean to configure ``pdb`` on exception. Default is false.
|
A boolean to configure ``pdb`` on exception. Default is false.
|
||||||
|
|
||||||
|
@ -313,6 +313,7 @@ General configuration
|
|||||||
* ``ref.doc``
|
* ``ref.doc``
|
||||||
* ``ref.python``
|
* ``ref.python``
|
||||||
* ``misc.highlighting_failure``
|
* ``misc.highlighting_failure``
|
||||||
|
* ``toc.circular``
|
||||||
* ``toc.secnum``
|
* ``toc.secnum``
|
||||||
* ``epub.unknown_project_files``
|
* ``epub.unknown_project_files``
|
||||||
* ``autosectionlabel.*``
|
* ``autosectionlabel.*``
|
||||||
@ -510,6 +511,14 @@ General configuration
|
|||||||
|
|
||||||
.. versionadded:: 1.6.6
|
.. versionadded:: 1.6.6
|
||||||
|
|
||||||
|
.. confval:: user_agent
|
||||||
|
|
||||||
|
A User-Agent of Sphinx. It is used for a header on HTTP access (ex.
|
||||||
|
linkcheck, intersphinx and so on). Default is ``"Sphinx/X.Y.Z
|
||||||
|
requests/X.Y.Z python/X.Y.Z"``.
|
||||||
|
|
||||||
|
.. versionadded:: 2.3
|
||||||
|
|
||||||
.. confval:: tls_verify
|
.. confval:: tls_verify
|
||||||
|
|
||||||
If true, Sphinx verifies server certifications. Default is ``True``.
|
If true, Sphinx verifies server certifications. Default is ``True``.
|
||||||
@ -530,7 +539,7 @@ General configuration
|
|||||||
directory pointed ``REQUESTS_CA_BUNDLE`` environment
|
directory pointed ``REQUESTS_CA_BUNDLE`` environment
|
||||||
variable if ``tls_cacerts`` not set.
|
variable if ``tls_cacerts`` not set.
|
||||||
|
|
||||||
.. _requests: http://docs.python-requests.org/en/master/
|
.. _requests: https://requests.readthedocs.io/en/master/
|
||||||
|
|
||||||
.. confval:: today
|
.. confval:: today
|
||||||
today_fmt
|
today_fmt
|
||||||
@ -566,7 +575,7 @@ General configuration
|
|||||||
A dictionary of options that modify how the lexer specified by
|
A dictionary of options that modify how the lexer specified by
|
||||||
:confval:`highlight_language` generates highlighted source code. These are
|
:confval:`highlight_language` generates highlighted source code. These are
|
||||||
lexer-specific; for the options understood by each, see the
|
lexer-specific; for the options understood by each, see the
|
||||||
`Pygments documentation <http://pygments.org/docs/lexers/>`_.
|
`Pygments documentation <https://pygments.org/docs/lexers.html>`_.
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
@ -626,6 +635,16 @@ General configuration
|
|||||||
.. versionchanged:: 1.1
|
.. versionchanged:: 1.1
|
||||||
Now also removes ``<BLANKLINE>``.
|
Now also removes ``<BLANKLINE>``.
|
||||||
|
|
||||||
|
.. confval:: strip_signature_backslash
|
||||||
|
|
||||||
|
Default is ``False``.
|
||||||
|
When backslash stripping is enabled then every occurrence of ``\\`` in a
|
||||||
|
domain directive will be changed to ``\``, even within string literals.
|
||||||
|
This was the behaviour before version 3.0, and setting this variable to
|
||||||
|
``True`` will reinstate that behaviour.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
|
||||||
.. _intl-options:
|
.. _intl-options:
|
||||||
|
|
||||||
@ -654,12 +673,18 @@ documentation on :ref:`intl` for details.
|
|||||||
|
|
||||||
Currently supported languages by Sphinx are:
|
Currently supported languages by Sphinx are:
|
||||||
|
|
||||||
|
* ``ar`` -- Arabic
|
||||||
|
* ``bg`` -- Bulgarian
|
||||||
* ``bn`` -- Bengali
|
* ``bn`` -- Bengali
|
||||||
* ``ca`` -- Catalan
|
* ``ca`` -- Catalan
|
||||||
|
* ``cak`` -- Kaqchikel
|
||||||
* ``cs`` -- Czech
|
* ``cs`` -- Czech
|
||||||
|
* ``cy`` -- Welsh
|
||||||
* ``da`` -- Danish
|
* ``da`` -- Danish
|
||||||
* ``de`` -- German
|
* ``de`` -- German
|
||||||
|
* ``el`` -- Greek
|
||||||
* ``en`` -- English
|
* ``en`` -- English
|
||||||
|
* ``eo`` -- Esperanto
|
||||||
* ``es`` -- Spanish
|
* ``es`` -- Spanish
|
||||||
* ``et`` -- Estonian
|
* ``et`` -- Estonian
|
||||||
* ``eu`` -- Basque
|
* ``eu`` -- Basque
|
||||||
@ -667,6 +692,8 @@ documentation on :ref:`intl` for details.
|
|||||||
* ``fi`` -- Finnish
|
* ``fi`` -- Finnish
|
||||||
* ``fr`` -- French
|
* ``fr`` -- French
|
||||||
* ``he`` -- Hebrew
|
* ``he`` -- Hebrew
|
||||||
|
* ``hi`` -- Hindi
|
||||||
|
* ``hi_IN`` -- Hindi (India)
|
||||||
* ``hr`` -- Croatian
|
* ``hr`` -- Croatian
|
||||||
* ``hu`` -- Hungarian
|
* ``hu`` -- Hungarian
|
||||||
* ``id`` -- Indonesian
|
* ``id`` -- Indonesian
|
||||||
@ -680,15 +707,24 @@ documentation on :ref:`intl` for details.
|
|||||||
* ``ne`` -- Nepali
|
* ``ne`` -- Nepali
|
||||||
* ``nl`` -- Dutch
|
* ``nl`` -- Dutch
|
||||||
* ``pl`` -- Polish
|
* ``pl`` -- Polish
|
||||||
|
* ``pt`` -- Portuguese
|
||||||
* ``pt_BR`` -- Brazilian Portuguese
|
* ``pt_BR`` -- Brazilian Portuguese
|
||||||
* ``pt_PT`` -- European Portuguese
|
* ``pt_PT`` -- European Portuguese
|
||||||
|
* ``ro`` -- Romanian
|
||||||
* ``ru`` -- Russian
|
* ``ru`` -- Russian
|
||||||
* ``si`` -- Sinhala
|
* ``si`` -- Sinhala
|
||||||
* ``sk`` -- Slovak
|
* ``sk`` -- Slovak
|
||||||
* ``sl`` -- Slovenian
|
* ``sl`` -- Slovenian
|
||||||
|
* ``sq`` -- Albanian
|
||||||
|
* ``sr`` -- Serbian
|
||||||
|
* ``sr@latin`` -- Serbian (Latin)
|
||||||
|
* ``sr_RS`` -- Serbian (Cyrillic)
|
||||||
* ``sv`` -- Swedish
|
* ``sv`` -- Swedish
|
||||||
|
* ``ta`` -- Tamil
|
||||||
|
* ``te`` -- Telugu
|
||||||
* ``tr`` -- Turkish
|
* ``tr`` -- Turkish
|
||||||
* ``uk_UA`` -- Ukrainian
|
* ``uk_UA`` -- Ukrainian
|
||||||
|
* ``ur`` -- Urdu
|
||||||
* ``vi`` -- Vietnamese
|
* ``vi`` -- Vietnamese
|
||||||
* ``zh_CN`` -- Simplified Chinese
|
* ``zh_CN`` -- Simplified Chinese
|
||||||
* ``zh_TW`` -- Traditional Chinese
|
* ``zh_TW`` -- Traditional Chinese
|
||||||
@ -762,7 +798,7 @@ documentation on :ref:`intl` for details.
|
|||||||
i18n additionally. You can specify below names:
|
i18n additionally. You can specify below names:
|
||||||
|
|
||||||
:index: index terms
|
:index: index terms
|
||||||
:literal-block: literal blocks: ``::`` and ``code-block``.
|
:literal-block: literal blocks (``::`` annotation and ``code-block`` directive)
|
||||||
:doctest-block: doctest block
|
:doctest-block: doctest block
|
||||||
:raw: raw content
|
:raw: raw content
|
||||||
:image: image/figure uri and alt
|
:image: image/figure uri and alt
|
||||||
@ -930,7 +966,7 @@ that use Sphinx's HTMLWriter class.
|
|||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
html_css_files = ['custom.css'
|
html_css_files = ['custom.css',
|
||||||
'https://example.com/css/custom.css',
|
'https://example.com/css/custom.css',
|
||||||
('print.css', {'media': 'print'})]
|
('print.css', {'media': 'print'})]
|
||||||
|
|
||||||
@ -1338,8 +1374,21 @@ that use Sphinx's HTMLWriter class.
|
|||||||
'target' option or scale related options: 'scale', 'width', 'height'.
|
'target' option or scale related options: 'scale', 'width', 'height'.
|
||||||
The default is ``True``.
|
The default is ``True``.
|
||||||
|
|
||||||
|
Document authors can this feature manually with giving ``no-scaled-link``
|
||||||
|
class to the image:
|
||||||
|
|
||||||
|
.. code-block:: rst
|
||||||
|
|
||||||
|
.. image:: sphinx.png
|
||||||
|
:scale: 50%
|
||||||
|
:class: no-scaled-link
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
.. versionchanged:: 2.4
|
||||||
|
|
||||||
|
It is disabled for images having ``no-scaled-link`` class
|
||||||
|
|
||||||
.. confval:: html_math_renderer
|
.. confval:: html_math_renderer
|
||||||
|
|
||||||
The name of math_renderer extension for HTML output. The default is
|
The name of math_renderer extension for HTML output. The default is
|
||||||
@ -1828,6 +1877,7 @@ These options influence LaTeX output.
|
|||||||
* ``'xelatex'`` -- XeLaTeX
|
* ``'xelatex'`` -- XeLaTeX
|
||||||
* ``'lualatex'`` -- LuaLaTeX
|
* ``'lualatex'`` -- LuaLaTeX
|
||||||
* ``'platex'`` -- pLaTeX (default if :confval:`language` is ``'ja'``)
|
* ``'platex'`` -- pLaTeX (default if :confval:`language` is ``'ja'``)
|
||||||
|
* ``'uplatex'`` -- upLaTeX (experimental)
|
||||||
|
|
||||||
``'pdflatex'``\ 's support for Unicode characters is limited.
|
``'pdflatex'``\ 's support for Unicode characters is limited.
|
||||||
|
|
||||||
@ -1841,7 +1891,21 @@ These options influence LaTeX output.
|
|||||||
``'xelatex'`` or ``'lualatex'`` and making sure to use an OpenType font
|
``'xelatex'`` or ``'lualatex'`` and making sure to use an OpenType font
|
||||||
with wide-enough glyph coverage is often easier than trying to make
|
with wide-enough glyph coverage is often easier than trying to make
|
||||||
``'pdflatex'`` work with the extra Unicode characters. Since Sphinx 2.0
|
``'pdflatex'`` work with the extra Unicode characters. Since Sphinx 2.0
|
||||||
the default is the GNU FreeFont which covers well Latin, Cyrillic and Greek.
|
the default is the GNU FreeFont which covers well Latin, Cyrillic and
|
||||||
|
Greek.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.1.0
|
||||||
|
|
||||||
|
Use ``xelatex`` (and LaTeX package ``xeCJK``) by default for Chinese
|
||||||
|
documents.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.2.1
|
||||||
|
|
||||||
|
Use ``xelatex`` by default for Greek documents.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.3
|
||||||
|
|
||||||
|
Add ``uplatex`` support.
|
||||||
|
|
||||||
Contrarily to :ref:`MathJaX math rendering in HTML output <math-support>`,
|
Contrarily to :ref:`MathJaX math rendering in HTML output <math-support>`,
|
||||||
LaTeX requires some extra configuration to support Unicode literals in
|
LaTeX requires some extra configuration to support Unicode literals in
|
||||||
@ -1857,7 +1921,7 @@ These options influence LaTeX output.
|
|||||||
|
|
||||||
This value determines how to group the document tree into LaTeX source files.
|
This value determines how to group the document tree into LaTeX source files.
|
||||||
It must be a list of tuples ``(startdocname, targetname, title, author,
|
It must be a list of tuples ``(startdocname, targetname, title, author,
|
||||||
documentclass, toctree_only)``, where the items are:
|
theme, toctree_only)``, where the items are:
|
||||||
|
|
||||||
*startdocname*
|
*startdocname*
|
||||||
String that specifies the :term:`document name` of the LaTeX file's master
|
String that specifies the :term:`document name` of the LaTeX file's master
|
||||||
@ -1879,13 +1943,8 @@ These options influence LaTeX output.
|
|||||||
applies. Use ``\\and`` to separate multiple authors, as in:
|
applies. Use ``\\and`` to separate multiple authors, as in:
|
||||||
``'John \\and Sarah'`` (backslashes must be Python-escaped to reach LaTeX).
|
``'John \\and Sarah'`` (backslashes must be Python-escaped to reach LaTeX).
|
||||||
|
|
||||||
*documentclass*
|
*theme*
|
||||||
Normally, one of ``'manual'`` or ``'howto'`` (provided by Sphinx and based
|
LaTeX theme. See :confval:`latex_theme`.
|
||||||
on ``'report'``, resp. ``'article'``; Japanese documents use ``'jsbook'``,
|
|
||||||
resp. ``'jreport'``.) "howto" (non-Japanese) documents will not get
|
|
||||||
appendices. Also they have a simpler title page. Other document classes
|
|
||||||
can be given. Independently of the document class, the "sphinx" package is
|
|
||||||
always loaded in order to define Sphinx's custom LaTeX commands.
|
|
||||||
|
|
||||||
*toctree_only*
|
*toctree_only*
|
||||||
Must be ``True`` or ``False``. If true, the *startdoc* document itself is
|
Must be ``True`` or ``False``. If true, the *startdoc* document itself is
|
||||||
@ -2040,6 +2099,40 @@ These options influence LaTeX output.
|
|||||||
This overrides the files which is provided from Sphinx such as
|
This overrides the files which is provided from Sphinx such as
|
||||||
``sphinx.sty``.
|
``sphinx.sty``.
|
||||||
|
|
||||||
|
.. confval:: latex_theme
|
||||||
|
|
||||||
|
The "theme" that the LaTeX output should use. It is a collection of settings
|
||||||
|
for LaTeX output (ex. document class, top level sectioning unit and so on).
|
||||||
|
|
||||||
|
As a built-in LaTeX themes, ``manual`` and ``howto`` are bundled.
|
||||||
|
|
||||||
|
``manual``
|
||||||
|
A LaTeX theme for writing a manual. It imports the ``report`` document
|
||||||
|
class (Japanese documents use ``jsbook``).
|
||||||
|
|
||||||
|
``howto``
|
||||||
|
A LaTeX theme for writing an article. It imports the ``article`` document
|
||||||
|
class (Japanese documents use ``jreport`` rather). :confval:`latex_appendices`
|
||||||
|
is available only for this theme.
|
||||||
|
|
||||||
|
It defaults to ``'manual'``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
.. confval:: latex_theme_options
|
||||||
|
|
||||||
|
A dictionary of options that influence the look and feel of the selected
|
||||||
|
theme.
|
||||||
|
|
||||||
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
.. confval:: latex_theme_path
|
||||||
|
|
||||||
|
A list of paths that contain custom LaTeX themes as subdirectories. Relative
|
||||||
|
paths are taken as relative to the configuration directory.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
|
||||||
.. _text-options:
|
.. _text-options:
|
||||||
|
|
||||||
@ -2346,6 +2439,34 @@ Options for the linkcheck builder
|
|||||||
|
|
||||||
.. versionadded:: 1.5
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
.. confval:: linkcheck_auth
|
||||||
|
|
||||||
|
Pass authentication information when doing a ``linkcheck`` build.
|
||||||
|
|
||||||
|
A list of ``(regex_pattern, auth_info)`` tuples where the items are:
|
||||||
|
|
||||||
|
*regex_pattern*
|
||||||
|
A regular expression that matches a URI.
|
||||||
|
*auth_info*
|
||||||
|
Authentication information to use for that URI. The value can be anything
|
||||||
|
that is understood by the ``requests`` library (see `requests
|
||||||
|
Authentication <requests-auth>`_ for details).
|
||||||
|
|
||||||
|
.. _requests-auth: https://requests.readthedocs.io/en/master/user/authentication/
|
||||||
|
|
||||||
|
The ``linkcheck`` builder will use the first matching ``auth_info`` value
|
||||||
|
it can find in the :confval:`linkcheck_auth` list, so values earlier in the
|
||||||
|
list have higher priority.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
linkcheck_auth = [
|
||||||
|
('https://foo\.yourcompany\.com/.+', ('johndoe', 'secret')),
|
||||||
|
('https://.+\.yourcompany\.com/.+', HTTPDigestAuth(...)),
|
||||||
|
]
|
||||||
|
|
||||||
|
.. versionadded:: 2.3
|
||||||
|
|
||||||
|
|
||||||
Options for the XML builder
|
Options for the XML builder
|
||||||
---------------------------
|
---------------------------
|
||||||
@ -2365,6 +2486,30 @@ Options for the XML builder
|
|||||||
match any sequence of characters *including* slashes.
|
match any sequence of characters *including* slashes.
|
||||||
|
|
||||||
|
|
||||||
|
.. _c-config:
|
||||||
|
|
||||||
|
Options for the C domain
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
.. confval:: c_id_attributes
|
||||||
|
|
||||||
|
A list of strings that the parser additionally should accept as attributes.
|
||||||
|
This can for example be used when attributes have been ``#define`` d for
|
||||||
|
portability.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
.. confval:: c_paren_attributes
|
||||||
|
|
||||||
|
A list of strings that the parser additionally should accept as attributes
|
||||||
|
with one argument. That is, if ``my_align_as`` is in the list, then
|
||||||
|
``my_align_as(X)`` is parsed as an attribute for all strings ``X`` that have
|
||||||
|
balanced braces (``()``, ``[]``, and ``{}``). This can for example be used
|
||||||
|
when attributes have been ``#define`` d for portability.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
|
||||||
.. _cpp-config:
|
.. _cpp-config:
|
||||||
|
|
||||||
Options for the C++ domain
|
Options for the C++ domain
|
||||||
|
@ -140,6 +140,20 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
|
|
||||||
.. versionadded:: 1.1
|
.. versionadded:: 1.1
|
||||||
|
|
||||||
|
* autodoc considers a member private if its docstring contains
|
||||||
|
``:meta private:`` in its :ref:`info-field-lists`.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
.. code-block:: rst
|
||||||
|
|
||||||
|
def my_function(my_arg, my_other_arg):
|
||||||
|
"""blah blah blah
|
||||||
|
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
* Python "special" members (that is, those named like ``__special__``) will
|
* Python "special" members (that is, those named like ``__special__``) will
|
||||||
be included if the ``special-members`` flag option is given::
|
be included if the ``special-members`` flag option is given::
|
||||||
|
|
||||||
@ -157,7 +171,7 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
|
|
||||||
* For classes and exceptions, members inherited from base classes will be
|
* For classes and exceptions, members inherited from base classes will be
|
||||||
left out when documenting all members, unless you give the
|
left out when documenting all members, unless you give the
|
||||||
``inherited-members`` flag option, in addition to ``members``::
|
``inherited-members`` option, in addition to ``members``::
|
||||||
|
|
||||||
.. autoclass:: Noodle
|
.. autoclass:: Noodle
|
||||||
:members:
|
:members:
|
||||||
@ -166,11 +180,29 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
This can be combined with ``undoc-members`` to document *all* available
|
This can be combined with ``undoc-members`` to document *all* available
|
||||||
members of the class or module.
|
members of the class or module.
|
||||||
|
|
||||||
|
It can take an ancestor class not to document inherited members from it.
|
||||||
|
By default, members of ``object`` class are not documented. To show them
|
||||||
|
all, give ``None`` to the option.
|
||||||
|
|
||||||
|
For example; If your class ``Foo`` is derived from ``list`` class and
|
||||||
|
you don't want to document ``list.__len__()``, you should specify a
|
||||||
|
option ``:inherited-members: list`` to avoid special members of list
|
||||||
|
class.
|
||||||
|
|
||||||
|
Another example; If your class Foo has ``__str__`` special method and
|
||||||
|
autodoc directive has both ``inherited-members`` and ``special-members``,
|
||||||
|
``__str__`` will be documented as in the past, but other special method
|
||||||
|
that are not implemented in your class ``Foo``.
|
||||||
|
|
||||||
Note: this will lead to markup errors if the inherited members come from a
|
Note: this will lead to markup errors if the inherited members come from a
|
||||||
module whose docstrings are not reST formatted.
|
module whose docstrings are not reST formatted.
|
||||||
|
|
||||||
.. versionadded:: 0.3
|
.. versionadded:: 0.3
|
||||||
|
|
||||||
|
.. versionchanged:: 3.0
|
||||||
|
|
||||||
|
It takes an anchestor class name as an argument.
|
||||||
|
|
||||||
* It's possible to override the signature for explicitly documented callable
|
* It's possible to override the signature for explicitly documented callable
|
||||||
objects (functions, methods, classes) with the regular syntax that will
|
objects (functions, methods, classes) with the regular syntax that will
|
||||||
override the signature gained from introspection::
|
override the signature gained from introspection::
|
||||||
@ -308,9 +340,6 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
a decorator replaces the decorated function with another, it must copy the
|
a decorator replaces the decorated function with another, it must copy the
|
||||||
original ``__doc__`` to the new function.
|
original ``__doc__`` to the new function.
|
||||||
|
|
||||||
From Python 2.5, :func:`functools.wraps` can be used to create
|
|
||||||
well-behaved decorating functions.
|
|
||||||
|
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
@ -437,9 +466,13 @@ There are also config values that you can set:
|
|||||||
following values:
|
following values:
|
||||||
|
|
||||||
* ``'signature'`` -- Show typehints as its signature (default)
|
* ``'signature'`` -- Show typehints as its signature (default)
|
||||||
|
* ``'description'`` -- Show typehints as content of function or method
|
||||||
* ``'none'`` -- Do not show typehints
|
* ``'none'`` -- Do not show typehints
|
||||||
|
|
||||||
.. versionadded: 2.1
|
.. versionadded:: 2.1
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
New option ``'description'`` is added.
|
||||||
|
|
||||||
.. confval:: autodoc_warningiserror
|
.. confval:: autodoc_warningiserror
|
||||||
|
|
||||||
@ -494,6 +527,17 @@ autodoc provides the following additional events:
|
|||||||
auto directive
|
auto directive
|
||||||
:param lines: the lines of the docstring, see above
|
:param lines: the lines of the docstring, see above
|
||||||
|
|
||||||
|
.. event:: autodoc-before-process-signature (app, obj, bound_method)
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
|
Emitted before autodoc formats a signature for an object. The event handler
|
||||||
|
can modify an object to change its signature.
|
||||||
|
|
||||||
|
:param app: the Sphinx application object
|
||||||
|
:param obj: the object itself
|
||||||
|
:param bound_method: a boolean indicates an object is bound method or not
|
||||||
|
|
||||||
.. event:: autodoc-process-signature (app, what, name, obj, options, signature, return_annotation)
|
.. event:: autodoc-process-signature (app, what, name, obj, options, signature, return_annotation)
|
||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
|
@ -81,6 +81,12 @@ The :mod:`sphinx.ext.autosummary` extension does this in three parts:
|
|||||||
directory. If no argument is given, output is placed in the same directory
|
directory. If no argument is given, output is placed in the same directory
|
||||||
as the file that contains the directive.
|
as the file that contains the directive.
|
||||||
|
|
||||||
|
You can also use ``caption`` option to give a caption to the toctree.
|
||||||
|
|
||||||
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
caption option added.
|
||||||
|
|
||||||
* If you don't want the :rst:dir:`autosummary` to show function signatures in
|
* If you don't want the :rst:dir:`autosummary` to show function signatures in
|
||||||
the listing, include the ``nosignatures`` option::
|
the listing, include the ``nosignatures`` option::
|
||||||
|
|
||||||
@ -162,6 +168,11 @@ also use these config values:
|
|||||||
The new files will be placed in the directories specified in the
|
The new files will be placed in the directories specified in the
|
||||||
``:toctree:`` options of the directives.
|
``:toctree:`` options of the directives.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.3
|
||||||
|
|
||||||
|
Emits :event:`autodoc-skip-member` event as :mod:`~sphinx.ext.autodoc`
|
||||||
|
does.
|
||||||
|
|
||||||
.. confval:: autosummary_generate_overwrite
|
.. confval:: autosummary_generate_overwrite
|
||||||
|
|
||||||
If true, autosummary already overwrites stub files by generated contents.
|
If true, autosummary already overwrites stub files by generated contents.
|
||||||
@ -300,6 +311,7 @@ Additionally, the following filters are available
|
|||||||
replaces the builtin Jinja `escape filter`_ that does html-escaping.
|
replaces the builtin Jinja `escape filter`_ that does html-escaping.
|
||||||
|
|
||||||
.. function:: underline(s, line='=')
|
.. function:: underline(s, line='=')
|
||||||
|
:noindex:
|
||||||
|
|
||||||
Add a title underline to a piece of text.
|
Add a title underline to a piece of text.
|
||||||
|
|
||||||
|
@ -11,11 +11,15 @@
|
|||||||
pair: testing; snippets
|
pair: testing; snippets
|
||||||
|
|
||||||
|
|
||||||
This extension allows you to test snippets in the documentation in a natural
|
It is often helpful to include snippets of code in your documentation and
|
||||||
way. It works by collecting specially-marked up code blocks and running them as
|
demonstrate the results of executing them. But it is important to ensure that
|
||||||
doctest tests.
|
the documentation stays up-to-date with the code.
|
||||||
|
|
||||||
Within one document, test code is partitioned in *groups*, where each group
|
This extension allows you to test such code snippets in the documentation in
|
||||||
|
a natural way. If you mark the code blocks as shown here, the ``doctest``
|
||||||
|
builder will collect them and run them as doctest tests.
|
||||||
|
|
||||||
|
Within each document, you can assign each snippet to a *group*. Each group
|
||||||
consists of:
|
consists of:
|
||||||
|
|
||||||
* zero or more *setup code* blocks (e.g. importing the module to test)
|
* zero or more *setup code* blocks (e.g. importing the module to test)
|
||||||
|
11
doc/usage/extensions/duration.rst
Normal file
11
doc/usage/extensions/duration.rst
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
:mod:`sphinx.ext.duration` -- Measure durations of Sphinx processing
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
.. module:: sphinx.ext.duration
|
||||||
|
:synopsis: Measure durations of Sphinx processing
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
|
This extension measures durations of Sphinx processing and show its
|
||||||
|
result at end of the build. It is useful for inspecting what document
|
||||||
|
is slowly built.
|
@ -82,6 +82,13 @@ It adds these directives:
|
|||||||
|
|
||||||
.. versionadded:: 1.6
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
|
.. rst:directive:option:: class: class names
|
||||||
|
:type: a list of class names separeted by spaces
|
||||||
|
|
||||||
|
The class name of the graph.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
|
|
||||||
.. rst:directive:: graph
|
.. rst:directive:: graph
|
||||||
|
|
||||||
@ -131,6 +138,13 @@ It adds these directives:
|
|||||||
|
|
||||||
.. versionadded:: 1.6
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
|
.. rst:directive:option:: class: class names
|
||||||
|
:type: a list of class names separeted by spaces
|
||||||
|
|
||||||
|
The class name of the graph.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
|
|
||||||
.. rst:directive:: digraph
|
.. rst:directive:: digraph
|
||||||
|
|
||||||
@ -176,6 +190,13 @@ It adds these directives:
|
|||||||
|
|
||||||
.. versionadded:: 1.6
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
|
.. rst:directive:option:: class: class names
|
||||||
|
:type: a list of class names separeted by spaces
|
||||||
|
|
||||||
|
The class name of the graph.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
|
|
||||||
There are also these config values:
|
There are also these config values:
|
||||||
|
|
||||||
|
@ -34,7 +34,19 @@ Configuration
|
|||||||
A path to :command:`convert` command. By default, the imgconverter uses
|
A path to :command:`convert` command. By default, the imgconverter uses
|
||||||
the command from search paths.
|
the command from search paths.
|
||||||
|
|
||||||
|
On windows platform, :command:`magick` command is used by default.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.1
|
||||||
|
|
||||||
|
Use :command:`magick` command by default on windows
|
||||||
|
|
||||||
.. confval:: image_converter_args
|
.. confval:: image_converter_args
|
||||||
|
|
||||||
Additional command-line arguments to give to :command:`convert`, as a list.
|
Additional command-line arguments to give to :command:`convert`, as a list.
|
||||||
The default is an empty list ``[]``.
|
The default is an empty list ``[]``.
|
||||||
|
|
||||||
|
On windows platform, it defaults to ``["convert"]``.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.1
|
||||||
|
|
||||||
|
Use ``["convert"]`` by default on windows
|
||||||
|
@ -23,6 +23,7 @@ These extensions are built in and can be activated by respective entries in the
|
|||||||
autosummary
|
autosummary
|
||||||
coverage
|
coverage
|
||||||
doctest
|
doctest
|
||||||
|
duration
|
||||||
extlinks
|
extlinks
|
||||||
githubpages
|
githubpages
|
||||||
graphviz
|
graphviz
|
||||||
|
@ -148,3 +148,13 @@ project. The following example prints the Intersphinx mapping of the Python 3
|
|||||||
documentation::
|
documentation::
|
||||||
|
|
||||||
$ python -msphinx.ext.intersphinx https://docs.python.org/3/objects.inv
|
$ python -msphinx.ext.intersphinx https://docs.python.org/3/objects.inv
|
||||||
|
|
||||||
|
Using Intersphinx with inventory file under Basic Authorization
|
||||||
|
---------------------------------------------------------------
|
||||||
|
|
||||||
|
Intersphinx supports Basic Authorization like this::
|
||||||
|
|
||||||
|
intersphinx_mapping = {'python': ('https://user:password@docs.python.org/3',
|
||||||
|
None)}
|
||||||
|
|
||||||
|
The user and password will be stripped from the URL when generating the links.
|
||||||
|
@ -50,7 +50,7 @@ are built:
|
|||||||
``preview-latex-style`` on Ubuntu xenial). Therefore, the default for this
|
``preview-latex-style`` on Ubuntu xenial). Therefore, the default for this
|
||||||
option is ``False`` but it is strongly recommended to set it to ``True``.
|
option is ``False`` but it is strongly recommended to set it to ``True``.
|
||||||
|
|
||||||
.. versionchanged:: 2.1
|
.. versionchanged:: 2.2
|
||||||
|
|
||||||
This option can be used with the ``'svg'`` :confval:`imgmath_image_format`.
|
This option can be used with the ``'svg'`` :confval:`imgmath_image_format`.
|
||||||
|
|
||||||
@ -80,6 +80,14 @@ are built:
|
|||||||
This value should only contain the path to the latex executable, not further
|
This value should only contain the path to the latex executable, not further
|
||||||
arguments; use :confval:`imgmath_latex_args` for that purpose.
|
arguments; use :confval:`imgmath_latex_args` for that purpose.
|
||||||
|
|
||||||
|
.. hint::
|
||||||
|
|
||||||
|
Some fancy LaTeX mark-up (an example was reported which used TikZ to add
|
||||||
|
various decorations to the equation) require multiple runs of the LaTeX
|
||||||
|
executable. To handle this, set this configuration setting to
|
||||||
|
``'latexmk'`` (or a full path to it) as this Perl script reliably
|
||||||
|
chooses dynamically how many latex runs are needed.
|
||||||
|
|
||||||
.. confval:: imgmath_latex_args
|
.. confval:: imgmath_latex_args
|
||||||
|
|
||||||
Additional arguments to give to latex, as a list. The default is an empty
|
Additional arguments to give to latex, as a list. The default is an empty
|
||||||
@ -183,6 +191,8 @@ Sphinx but is set to automatically include it from a third-party site.
|
|||||||
|
|
||||||
The default is empty (``{}``).
|
The default is empty (``{}``).
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
.. confval:: mathjax_config
|
.. confval:: mathjax_config
|
||||||
|
|
||||||
The inline configuration options for mathjax. The value is used as a
|
The inline configuration options for mathjax. The value is used as a
|
||||||
@ -198,6 +208,8 @@ Sphinx but is set to automatically include it from a third-party site.
|
|||||||
|
|
||||||
The default is empty (not configured).
|
The default is empty (not configured).
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
.. _Using in-line configuration options: https://docs.mathjax.org/en/latest/configuration.html#using-in-line-configuration-options
|
.. _Using in-line configuration options: https://docs.mathjax.org/en/latest/configuration.html#using-in-line-configuration-options
|
||||||
|
|
||||||
:mod:`sphinx.ext.jsmath` -- Render math via JavaScript
|
:mod:`sphinx.ext.jsmath` -- Render math via JavaScript
|
||||||
|
@ -56,7 +56,7 @@ source code files.
|
|||||||
.. _Google:
|
.. _Google:
|
||||||
https://google.github.io/styleguide/pyguide.html#Comments
|
https://google.github.io/styleguide/pyguide.html#Comments
|
||||||
.. _NumPy:
|
.. _NumPy:
|
||||||
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
|
https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard
|
||||||
.. _Khan Academy:
|
.. _Khan Academy:
|
||||||
https://github.com/Khan/style-guides/blob/master/style/python.md#docstrings
|
https://github.com/Khan/style-guides/blob/master/style/python.md#docstrings
|
||||||
|
|
||||||
|
@ -23,8 +23,7 @@ Linux
|
|||||||
Debian/Ubuntu
|
Debian/Ubuntu
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
Install either ``python3-sphinx`` (Python 3) or ``python-sphinx`` (Python 2)
|
Install either ``python3-sphinx`` using :command:`apt-get`:
|
||||||
using :command:`apt-get`:
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -77,23 +76,22 @@ __ https://formulae.brew.sh/formula/sphinx-doc
|
|||||||
MacPorts
|
MacPorts
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
Install either ``python36-sphinx`` (Python 3) or ``python27-sphinx`` (Python 2)
|
Install either ``python3x-sphinx`` using :command:`port`:
|
||||||
using :command:`port`:
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
$ sudo port install py36-sphinx
|
$ sudo port install py38-sphinx
|
||||||
|
|
||||||
To set up the executable paths, use the ``port select`` command:
|
To set up the executable paths, use the ``port select`` command:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
$ sudo port select --set python python36
|
$ sudo port select --set python python38
|
||||||
$ sudo port select --set sphinx py36-sphinx
|
$ sudo port select --set sphinx py38-sphinx
|
||||||
|
|
||||||
For more information, refer to the `package overview`__.
|
For more information, refer to the `package overview`__.
|
||||||
|
|
||||||
__ https://www.macports.org/ports.php?by=library&substr=py36-sphinx
|
__ https://www.macports.org/ports.php?by=library&substr=py38-sphinx
|
||||||
|
|
||||||
Anaconda
|
Anaconda
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
@ -161,6 +159,37 @@ the ``--pre`` flag.
|
|||||||
$ pip install -U --pre sphinx
|
$ pip install -U --pre sphinx
|
||||||
|
|
||||||
|
|
||||||
|
Docker
|
||||||
|
------
|
||||||
|
|
||||||
|
Docker images for Sphinx are published on the `Docker Hub <https://hub.docker.com/>`_. There are two kind of images:
|
||||||
|
|
||||||
|
- `sphinxdoc/sphinx <https://hub.docker.com/repository/docker/sphinxdoc/sphinx>`_
|
||||||
|
- `sphinxdoc/sphinx-latexpdf <https://hub.docker.com/repository/docker/sphinxdoc/sphinx-latexpdf>`_
|
||||||
|
|
||||||
|
Former one is used for standard usage of Sphinx, and latter one is mainly used for PDF builds using LaTeX.
|
||||||
|
Please choose one for your purpose.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
sphinxdoc/sphinx-latexpdf contains TeXLive packages. So the image is very large (over 2GB!).
|
||||||
|
|
||||||
|
.. hint::
|
||||||
|
|
||||||
|
When using docker images, please use ``docker run`` command to invoke sphinx commands. For example,
|
||||||
|
you can use following command to create a Sphinx project::
|
||||||
|
|
||||||
|
$ docker run --rm -v /path/to/document:/docs sphinxdoc/sphinx sphinx-quickstart
|
||||||
|
|
||||||
|
And you can following command this to build HTML document::
|
||||||
|
|
||||||
|
$ docker run --rm -v /path/to/document:/docs sphinxdoc/sphinx make html
|
||||||
|
|
||||||
|
For more details, please read `README file`__ of docker images.
|
||||||
|
|
||||||
|
.. __: https://hub.docker.com/repository/docker/sphinxdoc/sphinx
|
||||||
|
|
||||||
|
|
||||||
Installation from source
|
Installation from source
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
@ -26,9 +26,6 @@ configuration values from a few questions it asks you. To use this, run:
|
|||||||
|
|
||||||
$ sphinx-quickstart
|
$ sphinx-quickstart
|
||||||
|
|
||||||
Answer each question asked. Be sure to say "yes" to the ``autodoc`` extension, as
|
|
||||||
we will use this later.
|
|
||||||
|
|
||||||
There is also an automatic "API documentation" generator called
|
There is also an automatic "API documentation" generator called
|
||||||
:program:`sphinx-apidoc`; see :doc:`/man/sphinx-apidoc` for details.
|
:program:`sphinx-apidoc`; see :doc:`/man/sphinx-apidoc` for details.
|
||||||
|
|
||||||
@ -37,12 +34,11 @@ Defining document structure
|
|||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
Let's assume you've run :program:`sphinx-quickstart`. It created a source
|
Let's assume you've run :program:`sphinx-quickstart`. It created a source
|
||||||
directory with :file:`conf.py` and a master document, :file:`index.rst` (if you
|
directory with :file:`conf.py` and a master document, :file:`index.rst`. The
|
||||||
accepted the defaults). The main function of the :term:`master document` is to
|
main function of the :term:`master document` is to serve as a welcome page, and
|
||||||
serve as a welcome page, and to contain the root of the "table of contents
|
to contain the root of the "table of contents tree" (or *toctree*). This is one
|
||||||
tree" (or *toctree*). This is one of the main things that Sphinx adds to
|
of the main things that Sphinx adds to reStructuredText, a way to connect
|
||||||
reStructuredText, a way to connect multiple files to a single hierarchy of
|
multiple files to a single hierarchy of documents.
|
||||||
documents.
|
|
||||||
|
|
||||||
.. sidebar:: reStructuredText directives
|
.. sidebar:: reStructuredText directives
|
||||||
|
|
||||||
@ -233,8 +229,7 @@ customize a config value that is not automatically added by
|
|||||||
|
|
||||||
Keep in mind that the file uses Python syntax for strings, numbers, lists and
|
Keep in mind that the file uses Python syntax for strings, numbers, lists and
|
||||||
so on. The file is saved in UTF-8 by default, as indicated by the encoding
|
so on. The file is saved in UTF-8 by default, as indicated by the encoding
|
||||||
declaration in the first line. If you use non-ASCII characters in any string
|
declaration in the first line.
|
||||||
value, you need to use Python Unicode strings (like ``project = u'Exposé'``).
|
|
||||||
|
|
||||||
|more| See :doc:`/usage/configuration` for documentation of all available
|
|more| See :doc:`/usage/configuration` for documentation of all available
|
||||||
config values.
|
config values.
|
||||||
@ -252,10 +247,12 @@ module that provides additional features for Sphinx projects) called *autodoc*.
|
|||||||
|
|
||||||
In order to use *autodoc*, you need to activate it in :file:`conf.py` by
|
In order to use *autodoc*, you need to activate it in :file:`conf.py` by
|
||||||
putting the string ``'sphinx.ext.autodoc'`` into the list assigned to the
|
putting the string ``'sphinx.ext.autodoc'`` into the list assigned to the
|
||||||
:confval:`extensions` config value. Then, you have a few additional directives
|
:confval:`extensions` config value::
|
||||||
at your disposal.
|
|
||||||
|
|
||||||
For example, to document the function ``io.open()``, reading its signature and
|
extensions = ['sphinx.ext.autodoc']
|
||||||
|
|
||||||
|
Then, you have a few additional directives at your disposal. For example, to
|
||||||
|
document the function ``io.open()``, reading its signature and
|
||||||
docstring from the source file, you'd write this::
|
docstring from the source file, you'd write this::
|
||||||
|
|
||||||
.. autofunction:: io.open
|
.. autofunction:: io.open
|
||||||
|
@ -372,7 +372,8 @@ Docutils supports the following directives:
|
|||||||
|
|
||||||
* HTML specifics:
|
* HTML specifics:
|
||||||
|
|
||||||
- :dudir:`meta` (generation of HTML ``<meta>`` tags)
|
- :dudir:`meta`
|
||||||
|
(generation of HTML ``<meta>`` tags, see also :ref:`html-meta` below)
|
||||||
- :dudir:`title <metadata-document-title>` (override document title)
|
- :dudir:`title <metadata-document-title>` (override document title)
|
||||||
|
|
||||||
* Influencing markup:
|
* Influencing markup:
|
||||||
@ -538,6 +539,45 @@ You can indent text after a comment start to form multiline comments::
|
|||||||
Still in the comment.
|
Still in the comment.
|
||||||
|
|
||||||
|
|
||||||
|
.. _html-meta:
|
||||||
|
|
||||||
|
HTML Metadata
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The :rst:dir:`meta` directive (:dudir:`ref <meta>`) allows specifying the HTML
|
||||||
|
`metadata element`_ of a Sphinx documentation page. For example, the
|
||||||
|
directive::
|
||||||
|
|
||||||
|
.. meta::
|
||||||
|
:description: The Sphinx documentation builder
|
||||||
|
:keywords: Sphinx, documentation, builder
|
||||||
|
|
||||||
|
will generate the following HTML output:
|
||||||
|
|
||||||
|
.. code:: html
|
||||||
|
|
||||||
|
<meta name="description" content="The Sphinx documentation builder">
|
||||||
|
<meta name="keywords" content="Sphinx, documentation, builder">
|
||||||
|
|
||||||
|
Also, Sphinx will add the keywords as specified in the meta directive to the
|
||||||
|
search index. Thereby, the ``lang`` attribute of the meta element is
|
||||||
|
considered. For example, the directive::
|
||||||
|
|
||||||
|
.. meta::
|
||||||
|
:keywords: backup
|
||||||
|
:keywords lang=en: pleasefindthiskey pleasefindthiskeytoo
|
||||||
|
:keywords lang=de: bittediesenkeyfinden
|
||||||
|
|
||||||
|
adds the following words to the search indices of builds with different language
|
||||||
|
configurations:
|
||||||
|
|
||||||
|
* ``pleasefindthiskey``, ``pleasefindthiskeytoo`` to *English* builds;
|
||||||
|
* ``bittediesenkeyfinden`` to *German* builds;
|
||||||
|
* ``backup`` to builds in all languages.
|
||||||
|
|
||||||
|
.. _metadata element: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
|
||||||
|
|
||||||
|
|
||||||
Source encoding
|
Source encoding
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
@ -48,6 +48,12 @@ tables of contents. The ``toctree`` directive is the central element.
|
|||||||
to the source directory. A numeric ``maxdepth`` option may be given to
|
to the source directory. A numeric ``maxdepth`` option may be given to
|
||||||
indicate the depth of the tree; by default, all levels are included. [#]_
|
indicate the depth of the tree; by default, all levels are included. [#]_
|
||||||
|
|
||||||
|
The representation of "TOC tree" is changed in each output format. The
|
||||||
|
builders that output multiple files (ex. HTML) treat it as a collection of
|
||||||
|
hyperlinks. On the other hand, the builders that output a single file (ex.
|
||||||
|
LaTeX, man page, etc.) replace it with the content of the documents on the
|
||||||
|
TOC tree.
|
||||||
|
|
||||||
Consider this example (taken from the Python docs' library reference index)::
|
Consider this example (taken from the Python docs' library reference index)::
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
@ -441,7 +447,7 @@ If highlighting with the selected language fails (i.e. Pygments emits an
|
|||||||
want to ensure consistent highlighting, you should fix your version of
|
want to ensure consistent highlighting, you should fix your version of
|
||||||
Pygments.
|
Pygments.
|
||||||
|
|
||||||
__ http://pygments.org/docs/lexers/
|
__ http://pygments.org/docs/lexers
|
||||||
|
|
||||||
.. rst:directive:: .. highlight:: language
|
.. rst:directive:: .. highlight:: language
|
||||||
|
|
||||||
@ -453,21 +459,29 @@ __ http://pygments.org/docs/lexers/
|
|||||||
As discussed previously, *language* can be any lexer alias supported by
|
As discussed previously, *language* can be any lexer alias supported by
|
||||||
Pygments.
|
Pygments.
|
||||||
|
|
||||||
**Additional options**
|
.. rubric:: options
|
||||||
|
|
||||||
Pygments can generate line numbers for code blocks. To enable this, use the
|
.. rst:directive:option:: linenothreshold: threshold
|
||||||
``linenothreshold`` option. ::
|
:type: number (optional)
|
||||||
|
|
||||||
.. highlight:: python
|
Enable to generate line numbers for code blocks.
|
||||||
:linenothreshold: 5
|
|
||||||
|
|
||||||
This will produce line numbers for all code blocks longer than five lines.
|
This option takes an optional number as threshold parameter. If any
|
||||||
|
threshold given, the directive will produce line numbers only for the code
|
||||||
|
blocks longer than N lines. If not given, line numbers will be produced
|
||||||
|
for all of code blocks.
|
||||||
|
|
||||||
To ignore minor errors on highlighting, you can specifiy ``:force:`` option.
|
Example::
|
||||||
|
|
||||||
.. versionchanged:: 2.1
|
.. highlight:: python
|
||||||
|
:linenothreshold: 5
|
||||||
|
|
||||||
``:force:`` option.
|
.. rst:directive:option:: force
|
||||||
|
:type: no value
|
||||||
|
|
||||||
|
If given, minor errors on highlighting are ignored.
|
||||||
|
|
||||||
|
.. versionadded:: 2.1
|
||||||
|
|
||||||
.. rst:directive:: .. code-block:: [language]
|
.. rst:directive:: .. code-block:: [language]
|
||||||
|
|
||||||
@ -483,72 +497,98 @@ __ http://pygments.org/docs/lexers/
|
|||||||
:rst:dir:`highlight` directive will be used. If not set,
|
:rst:dir:`highlight` directive will be used. If not set,
|
||||||
:confval:`highlight_language` will be used.
|
:confval:`highlight_language` will be used.
|
||||||
|
|
||||||
**Additional options**
|
|
||||||
|
|
||||||
Pygments can generate line numbers for code blocks. To enable this for, use
|
|
||||||
the ``linenos`` flag option. ::
|
|
||||||
|
|
||||||
.. code-block:: ruby
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
Some more Ruby code.
|
|
||||||
|
|
||||||
The first line number can be selected with the ``lineno-start`` option. If
|
|
||||||
present, ``linenos`` flag is automatically activated::
|
|
||||||
|
|
||||||
.. code-block:: ruby
|
|
||||||
:lineno-start: 10
|
|
||||||
|
|
||||||
Some more Ruby code, with line numbering starting at 10.
|
|
||||||
|
|
||||||
Additionally, an ``emphasize-lines`` option can be given to have Pygments
|
|
||||||
emphasize particular lines::
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
:emphasize-lines: 3,5
|
|
||||||
|
|
||||||
def some_function():
|
|
||||||
interesting = False
|
|
||||||
print 'This line is highlighted.'
|
|
||||||
print 'This one is not...'
|
|
||||||
print '...but this one is.'
|
|
||||||
|
|
||||||
A ``caption`` option can be given to show that name before the code block.
|
|
||||||
A ``name`` option can be provided implicit target name that can be
|
|
||||||
referenced by using :rst:role:`ref`. For example::
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
:caption: this.py
|
|
||||||
:name: this-py
|
|
||||||
|
|
||||||
print 'Explicit is better than implicit.'
|
|
||||||
|
|
||||||
A ``dedent`` option can be given to strip indentation characters from the
|
|
||||||
code block. For example::
|
|
||||||
|
|
||||||
.. code-block:: ruby
|
|
||||||
:dedent: 4
|
|
||||||
|
|
||||||
some ruby code
|
|
||||||
|
|
||||||
A ``force`` option can ignore minor errors on highlighting.
|
|
||||||
|
|
||||||
.. versionchanged:: 1.1
|
|
||||||
The ``emphasize-lines`` option has been added.
|
|
||||||
|
|
||||||
.. versionchanged:: 1.3
|
|
||||||
The ``lineno-start``, ``caption``, ``name`` and ``dedent`` options have
|
|
||||||
been added.
|
|
||||||
|
|
||||||
.. versionchanged:: 1.6.6
|
|
||||||
LaTeX supports the ``emphasize-lines`` option.
|
|
||||||
|
|
||||||
.. versionchanged:: 2.0
|
.. versionchanged:: 2.0
|
||||||
The ``language`` argument becomes optional.
|
The ``language`` argument becomes optional.
|
||||||
|
|
||||||
.. versionchanged:: 2.1
|
.. rubric:: options
|
||||||
|
|
||||||
``:force:`` option has been added.
|
.. rst:directive:option:: linenos
|
||||||
|
:type: no value
|
||||||
|
|
||||||
|
Enable to generate line numbers for the code block::
|
||||||
|
|
||||||
|
.. code-block:: ruby
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
Some more Ruby code.
|
||||||
|
|
||||||
|
.. rst:directive:option:: lineno-start: number
|
||||||
|
:type: number
|
||||||
|
|
||||||
|
Set the first line number of the code block. If present, ``linenos``
|
||||||
|
option is also automatically activated::
|
||||||
|
|
||||||
|
.. code-block:: ruby
|
||||||
|
:lineno-start: 10
|
||||||
|
|
||||||
|
Some more Ruby code, with line numbering starting at 10.
|
||||||
|
|
||||||
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
.. rst:directive:option:: emphasize-lines: line numbers
|
||||||
|
:type: comma separated numbers
|
||||||
|
|
||||||
|
Emphasize particular lines of the code block::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
:emphasize-lines: 3,5
|
||||||
|
|
||||||
|
def some_function():
|
||||||
|
interesting = False
|
||||||
|
print 'This line is highlighted.'
|
||||||
|
print 'This one is not...'
|
||||||
|
print '...but this one is.'
|
||||||
|
|
||||||
|
.. versionadded:: 1.1
|
||||||
|
.. versionchanged:: 1.6.6
|
||||||
|
LaTeX supports the ``emphasize-lines`` option.
|
||||||
|
|
||||||
|
.. rst:directive:option: force
|
||||||
|
:type: no value
|
||||||
|
|
||||||
|
Ignore minor errors on highlighting
|
||||||
|
|
||||||
|
.. versionchanged:: 2.1
|
||||||
|
|
||||||
|
.. rst:directive:option:: caption: caption of code block
|
||||||
|
:type: text
|
||||||
|
|
||||||
|
Set a caption to the code block.
|
||||||
|
|
||||||
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
.. rst:directive:option:: name: a label for hyperlink
|
||||||
|
:type: text
|
||||||
|
|
||||||
|
Define implicit target name that can be referenced by using
|
||||||
|
:rst:role:`ref`. For example::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
:caption: this.py
|
||||||
|
:name: this-py
|
||||||
|
|
||||||
|
print 'Explicit is better than implicit.'
|
||||||
|
|
||||||
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
.. rst:directive:option:: dedent: number
|
||||||
|
:type: number
|
||||||
|
|
||||||
|
Strip indentation characters from the code block. For example::
|
||||||
|
|
||||||
|
.. code-block:: ruby
|
||||||
|
:dedent: 4
|
||||||
|
|
||||||
|
some ruby code
|
||||||
|
|
||||||
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
.. rst:directive:option:: force
|
||||||
|
:type: no value
|
||||||
|
|
||||||
|
If given, minor errors on highlighting are ignored.
|
||||||
|
|
||||||
|
.. versionadded:: 2.1
|
||||||
|
|
||||||
.. rst:directive:: .. literalinclude:: filename
|
.. rst:directive:: .. literalinclude:: filename
|
||||||
|
|
||||||
@ -840,6 +880,19 @@ mainly contained in information units, such as the language reference.
|
|||||||
.. versionchanged:: 1.1
|
.. versionchanged:: 1.1
|
||||||
Added ``see`` and ``seealso`` types, as well as marking main entries.
|
Added ``see`` and ``seealso`` types, as well as marking main entries.
|
||||||
|
|
||||||
|
.. rubric:: options
|
||||||
|
|
||||||
|
.. rst:directive:option:: name: a label for hyperlink
|
||||||
|
:type: text
|
||||||
|
|
||||||
|
Define implicit target name that can be referenced by using
|
||||||
|
:rst:role:`ref`. For example::
|
||||||
|
|
||||||
|
.. index:: Python
|
||||||
|
:name: py-index
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
.. rst:role:: index
|
.. rst:role:: index
|
||||||
|
|
||||||
While the :rst:dir:`index` directive is a block-level markup and links to the
|
While the :rst:dir:`index` directive is a block-level markup and links to the
|
||||||
@ -1017,7 +1070,7 @@ this reason, the following directive exists:
|
|||||||
cells.
|
cells.
|
||||||
|
|
||||||
Sphinx's merged cells interact well with ``p{width}``, ``\X{a}{b}``,
|
Sphinx's merged cells interact well with ``p{width}``, ``\X{a}{b}``,
|
||||||
``Y{f}`` and tabulary's columns.
|
``\Y{f}`` and tabulary's columns.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -1105,7 +1158,7 @@ derived forms), but provides enough to allow context-free grammars to be
|
|||||||
displayed in a way that causes uses of a symbol to be rendered as hyperlinks to
|
displayed in a way that causes uses of a symbol to be rendered as hyperlinks to
|
||||||
the definition of the symbol. There is this directive:
|
the definition of the symbol. There is this directive:
|
||||||
|
|
||||||
.. rst:directive:: .. productionlist:: [name]
|
.. rst:directive:: .. productionlist:: [productionGroup]
|
||||||
|
|
||||||
This directive is used to enclose a group of productions. Each production
|
This directive is used to enclose a group of productions. Each production
|
||||||
is given on a single line and consists of a name, separated by a colon from
|
is given on a single line and consists of a name, separated by a colon from
|
||||||
@ -1113,16 +1166,24 @@ the definition of the symbol. There is this directive:
|
|||||||
continuation line must begin with a colon placed at the same column as in
|
continuation line must begin with a colon placed at the same column as in
|
||||||
the first line.
|
the first line.
|
||||||
|
|
||||||
The argument to :rst:dir:`productionlist` serves to distinguish different
|
The *productionGroup* argument to :rst:dir:`productionlist` serves to
|
||||||
sets of production lists that belong to different grammars.
|
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.
|
Blank lines are not allowed within ``productionlist`` directive arguments.
|
||||||
|
|
||||||
The definition can contain token names which are marked as interpreted text
|
The definition can contain token names which are marked as interpreted text
|
||||||
(e.g. ``sum ::= `integer` "+" `integer```) -- this generates
|
(e.g. "``sum ::= `integer` "+" `integer```") -- this generates
|
||||||
cross-references to the productions of these tokens. Outside of the
|
cross-references to the productions of these tokens. Outside of the
|
||||||
production list, you can reference to token productions using
|
production list, you can reference to token productions using
|
||||||
:rst:role:`token`.
|
:rst:role:`token`.
|
||||||
|
However, if you have given a *productionGroup* argument you must prefix the
|
||||||
|
token name in the cross-reference with the group name and a colon,
|
||||||
|
e.g., "``myGroup:sum``" instead of just "``sum``".
|
||||||
|
If the group should not be shown in the title of the link either
|
||||||
|
an explicit title can be given (e.g., "``myTitle <myGroup:sum>``"),
|
||||||
|
or the target can be prefixed with a tilde (e.g., "``~myGroup:sum``").
|
||||||
|
|
||||||
Note that no further reST parsing is done in the production, so that you
|
Note that no further reST parsing is done in the production, so that you
|
||||||
don't have to escape ``*`` or ``|`` characters.
|
don't have to escape ``*`` or ``|`` characters.
|
||||||
|
@ -195,6 +195,18 @@ The following directives are provided for module and class contents:
|
|||||||
as "defined constants." Class and object attributes are not documented
|
as "defined constants." Class and object attributes are not documented
|
||||||
using this environment.
|
using this environment.
|
||||||
|
|
||||||
|
.. rubric:: options
|
||||||
|
|
||||||
|
.. rst:directive:option:: type: type of the variable
|
||||||
|
:type: text
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
|
.. rst:directive:option:: value: initial value of the variable
|
||||||
|
:type: text
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
.. rst:directive:: .. py:exception:: name
|
.. rst:directive:: .. py:exception:: name
|
||||||
|
|
||||||
Describes an exception class. The signature can, but need not include
|
Describes an exception class. The signature can, but need not include
|
||||||
@ -229,6 +241,18 @@ The following directives are provided for module and class contents:
|
|||||||
information about the type of the data to be expected and whether it may be
|
information about the type of the data to be expected and whether it may be
|
||||||
changed directly.
|
changed directly.
|
||||||
|
|
||||||
|
.. rubric:: options
|
||||||
|
|
||||||
|
.. rst:directive:option:: type: type of the attribute
|
||||||
|
:type: text
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
|
.. rst:directive:option:: value: initial value of the attribute
|
||||||
|
:type: text
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
.. rst:directive:: .. py:method:: name(parameters)
|
.. rst:directive:: .. py:method:: name(parameters)
|
||||||
|
|
||||||
Describes an object method. The parameters should not include the ``self``
|
Describes an object method. The parameters should not include the ``self``
|
||||||
@ -354,6 +378,9 @@ Info field lists
|
|||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. versionadded:: 0.4
|
.. versionadded:: 0.4
|
||||||
|
.. versionchanged:: 3.0
|
||||||
|
|
||||||
|
meta fields are added.
|
||||||
|
|
||||||
Inside Python object description directives, reST field lists with these fields
|
Inside Python object description directives, reST field lists with these fields
|
||||||
are recognized and formatted nicely:
|
are recognized and formatted nicely:
|
||||||
@ -367,6 +394,10 @@ are recognized and formatted nicely:
|
|||||||
* ``vartype``: Type of a variable. Creates a link if possible.
|
* ``vartype``: Type of a variable. Creates a link if possible.
|
||||||
* ``returns``, ``return``: Description of the return value.
|
* ``returns``, ``return``: Description of the return value.
|
||||||
* ``rtype``: Return type. Creates a link if possible.
|
* ``rtype``: Return type. Creates a link if possible.
|
||||||
|
* ``meta``: Add metadata to description of the python object. The metadata will
|
||||||
|
not be shown on output document. For example, ``:meta private:`` indicates
|
||||||
|
the python object is private member. It is used in
|
||||||
|
:py:mod:`sphinx.ext.autodoc` for filtering members.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -521,47 +552,62 @@ The C Domain
|
|||||||
|
|
||||||
The C domain (name **c**) is suited for documentation of C API.
|
The C domain (name **c**) is suited for documentation of C API.
|
||||||
|
|
||||||
|
.. rst:directive:: .. c:member:: declaration
|
||||||
|
.. c:var:: declaration
|
||||||
|
|
||||||
|
Describes a C struct member or variable. Example signature::
|
||||||
|
|
||||||
|
.. c:member:: PyObject *PyTypeObject.tp_bases
|
||||||
|
|
||||||
|
The difference between the two directives is only cosmetic.
|
||||||
|
|
||||||
.. rst:directive:: .. c:function:: function prototype
|
.. rst:directive:: .. c:function:: function prototype
|
||||||
|
|
||||||
Describes a C function. The signature should be given as in C, e.g.::
|
Describes a C function. The signature should be given as in C, e.g.::
|
||||||
|
|
||||||
.. c:function:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
|
.. c:function:: PyObject *PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
|
||||||
|
|
||||||
This is also used to describe function-like preprocessor macros. The names
|
|
||||||
of the arguments should be given so they may be used in the description.
|
|
||||||
|
|
||||||
Note that you don't have to backslash-escape asterisks in the signature, as
|
Note that you don't have to backslash-escape asterisks in the signature, as
|
||||||
it is not parsed by the reST inliner.
|
it is not parsed by the reST inliner.
|
||||||
|
|
||||||
.. rst:directive:: .. c:member:: declaration
|
|
||||||
|
|
||||||
Describes a C struct member. Example signature::
|
|
||||||
|
|
||||||
.. c:member:: PyObject* PyTypeObject.tp_bases
|
|
||||||
|
|
||||||
The text of the description should include the range of values allowed, how
|
|
||||||
the value should be interpreted, and whether the value can be changed.
|
|
||||||
References to structure members in text should use the ``member`` role.
|
|
||||||
|
|
||||||
.. rst:directive:: .. c:macro:: name
|
.. rst:directive:: .. c:macro:: name
|
||||||
|
.. c:macro:: name(arg list)
|
||||||
|
|
||||||
Describes a "simple" C macro. Simple macros are macros which are used for
|
Describes a C macro, i.e., a C-language ``#define``, without the replacement
|
||||||
code expansion, but which do not take arguments so cannot be described as
|
text.
|
||||||
functions. This is a simple C-language ``#define``. Examples of its use in
|
|
||||||
the Python documentation include :c:macro:`PyObject_HEAD` and
|
|
||||||
:c:macro:`Py_BEGIN_ALLOW_THREADS`.
|
|
||||||
|
|
||||||
.. rst:directive:: .. c:type:: name
|
.. versionadded:: 3.0
|
||||||
|
The function style variant.
|
||||||
|
|
||||||
Describes a C type (whether defined by a typedef or struct). The signature
|
.. rst:directive:: .. c:struct:: name
|
||||||
should just be the type name.
|
|
||||||
|
|
||||||
.. rst:directive:: .. c:var:: declaration
|
Describes a C struct.
|
||||||
|
|
||||||
Describes a global C variable. The signature should include the type, such
|
.. versionadded:: 3.0
|
||||||
as::
|
|
||||||
|
|
||||||
.. c:var:: PyObject* PyClass_Type
|
.. rst:directive:: .. c:union:: name
|
||||||
|
|
||||||
|
Describes a C union.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
.. rst:directive:: .. c:enum:: name
|
||||||
|
|
||||||
|
Describes a C enum.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
.. rst:directive:: .. c:enumerator:: name
|
||||||
|
|
||||||
|
Describes a C enumerator.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
.. rst:directive:: .. c:type:: typedef-like declaration
|
||||||
|
.. c:type:: name
|
||||||
|
|
||||||
|
Describes a C type, either as a typedef, or the alias for an unspecified
|
||||||
|
type.
|
||||||
|
|
||||||
.. _c-roles:
|
.. _c-roles:
|
||||||
|
|
||||||
@ -571,25 +617,164 @@ Cross-referencing C constructs
|
|||||||
The following roles create cross-references to C-language constructs if they
|
The following roles create cross-references to C-language constructs if they
|
||||||
are defined in the documentation:
|
are defined in the documentation:
|
||||||
|
|
||||||
.. rst:role:: c:func
|
|
||||||
|
|
||||||
Reference a C-language function. Should include trailing parentheses.
|
|
||||||
|
|
||||||
.. rst:role:: c:member
|
.. rst:role:: c:member
|
||||||
|
c:data
|
||||||
|
c:var
|
||||||
|
c:func
|
||||||
|
c:macro
|
||||||
|
c:struct
|
||||||
|
c:union
|
||||||
|
c:enum
|
||||||
|
c:enumerator
|
||||||
|
c:type
|
||||||
|
|
||||||
Reference a C-language member of a struct.
|
Reference a C declaration, as defined above.
|
||||||
|
Note that :rst:role:`c:member`, :rst:role:`c:data`, and
|
||||||
|
:rst:role:`c:var` are equivalent.
|
||||||
|
|
||||||
.. rst:role:: c:macro
|
.. versionadded:: 3.0
|
||||||
|
The var, struct, union, enum, and enumerator roles.
|
||||||
|
|
||||||
Reference a "simple" C macro, as defined above.
|
|
||||||
|
|
||||||
.. rst:role:: c:type
|
Anonymous Entities
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Reference a C-language type.
|
C supports anonymous structs, enums, and unions.
|
||||||
|
For the sake of documentation they must be given some name that starts with
|
||||||
|
``@``, e.g., ``@42`` or ``@data``.
|
||||||
|
These names can also be used in cross-references,
|
||||||
|
though nested symbols will be found even when omitted.
|
||||||
|
The ``@...`` name will always be rendered as **[anonymous]** (possibly as a
|
||||||
|
link).
|
||||||
|
|
||||||
.. rst:role:: c:data
|
Example::
|
||||||
|
|
||||||
Reference a C-language variable.
|
.. c:struct:: Data
|
||||||
|
|
||||||
|
.. c:union:: @data
|
||||||
|
|
||||||
|
.. c:var:: int a
|
||||||
|
|
||||||
|
.. c:var:: double b
|
||||||
|
|
||||||
|
Explicit ref: :c:var:`Data.@data.a`. Short-hand ref: :c:var:`Data.a`.
|
||||||
|
|
||||||
|
This will be rendered as:
|
||||||
|
|
||||||
|
.. c:struct:: Data
|
||||||
|
|
||||||
|
.. c:union:: @data
|
||||||
|
|
||||||
|
.. c:var:: int a
|
||||||
|
|
||||||
|
.. c:var:: double b
|
||||||
|
|
||||||
|
Explicit ref: :c:var:`Data.@data.a`. Short-hand ref: :c:var:`Data.a`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
|
||||||
|
Inline Expressions and Types
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. rst:role:: c:expr
|
||||||
|
c:texpr
|
||||||
|
|
||||||
|
Insert a C expression or type either as inline code (``cpp:expr``)
|
||||||
|
or inline text (``cpp:texpr``). For example::
|
||||||
|
|
||||||
|
.. c:var:: int a = 42
|
||||||
|
|
||||||
|
.. c:function:: int f(int i)
|
||||||
|
|
||||||
|
An expression: :c:expr:`a * f(a)` (or as text: :c:texpr:`a * f(a)`).
|
||||||
|
|
||||||
|
A type: :c:expr:`const Data*`
|
||||||
|
(or as text :c:texpr:`const Data*`).
|
||||||
|
|
||||||
|
will be rendered as follows:
|
||||||
|
|
||||||
|
.. c:var:: int a = 42
|
||||||
|
|
||||||
|
.. c:function:: int f(int i)
|
||||||
|
|
||||||
|
An expression: :c:expr:`a * f(a)` (or as text: :c:texpr:`a * f(a)`).
|
||||||
|
|
||||||
|
A type: :c:expr:`const Data*`
|
||||||
|
(or as text :c:texpr:`const Data*`).
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
|
||||||
|
Namespacing
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
The C language it self does not support namespacing, but it can sometimes be
|
||||||
|
useful to emulate it in documentation, e.g., to show alternate declarations.
|
||||||
|
The feature may also be used to document members of structs/unions/enums
|
||||||
|
separate from their parent declaration.
|
||||||
|
|
||||||
|
The current scope can be changed using three namespace directives. They manage
|
||||||
|
a stack declarations where ``c:namespace`` resets the stack and changes a given
|
||||||
|
scope.
|
||||||
|
|
||||||
|
The ``c:namespace-push`` directive changes the scope to a given inner scope
|
||||||
|
of the current one.
|
||||||
|
|
||||||
|
The ``c:namespace-pop`` directive undoes the most recent
|
||||||
|
``c:namespace-push`` directive.
|
||||||
|
|
||||||
|
.. rst:directive:: .. c:namespace:: scope specification
|
||||||
|
|
||||||
|
Changes the current scope for the subsequent objects to the given scope, and
|
||||||
|
resets the namespace directive stack. Note that nested scopes can be
|
||||||
|
specified by separating with a dot, e.g.::
|
||||||
|
|
||||||
|
.. c:namespace:: Namespace1.Namespace2.SomeStruct.AnInnerStruct
|
||||||
|
|
||||||
|
All subsequent objects will be defined as if their name were declared with
|
||||||
|
the scope prepended. The subsequent cross-references will be searched for
|
||||||
|
starting in the current scope.
|
||||||
|
|
||||||
|
Using ``NULL`` or ``0`` as the scope will change to global scope.
|
||||||
|
|
||||||
|
.. rst:directive:: .. c:namespace-push:: scope specification
|
||||||
|
|
||||||
|
Change the scope relatively to the current scope. For example, after::
|
||||||
|
|
||||||
|
.. c:namespace:: A.B
|
||||||
|
|
||||||
|
.. c:namespace-push:: C.D
|
||||||
|
|
||||||
|
the current scope will be ``A.B.C.D``.
|
||||||
|
|
||||||
|
.. rst:directive:: .. c:namespace-pop::
|
||||||
|
|
||||||
|
Undo the previous ``c:namespace-push`` directive (*not* just pop a scope).
|
||||||
|
For example, after::
|
||||||
|
|
||||||
|
.. c:namespace:: A.B
|
||||||
|
|
||||||
|
.. c:namespace-push:: C.D
|
||||||
|
|
||||||
|
.. c:namespace-pop::
|
||||||
|
|
||||||
|
the current scope will be ``A.B`` (*not* ``A.B.C``).
|
||||||
|
|
||||||
|
If no previous ``c:namespace-push`` directive has been used, but only a
|
||||||
|
``c:namespace`` directive, then the current scope will be reset to global
|
||||||
|
scope. That is, ``.. c:namespace:: A.B`` is equivalent to::
|
||||||
|
|
||||||
|
.. c:namespace:: NULL
|
||||||
|
|
||||||
|
.. c:namespace-push:: A.B
|
||||||
|
|
||||||
|
Configuration Variables
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
See :ref:`c-config`.
|
||||||
|
|
||||||
|
|
||||||
.. _cpp-domain:
|
.. _cpp-domain:
|
||||||
@ -1530,7 +1715,7 @@ These roles are provided to refer to the described objects:
|
|||||||
The Math Domain
|
The Math Domain
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
The math domain (name **math**) provides the following roles::
|
The math domain (name **math**) provides the following roles:
|
||||||
|
|
||||||
.. rst:role:: math:numref
|
.. rst:role:: math:numref
|
||||||
|
|
||||||
|
@ -30,6 +30,12 @@ At the moment, these metadata fields are recognized:
|
|||||||
|
|
||||||
:tocdepth: 2
|
:tocdepth: 2
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This metadata effects to the depth of local toctree. But it does not
|
||||||
|
effect to the depth of *global* toctree. So this would not be change
|
||||||
|
the sidebar of some themes which uses global one.
|
||||||
|
|
||||||
.. versionadded:: 0.4
|
.. versionadded:: 0.4
|
||||||
|
|
||||||
``nocomments``
|
``nocomments``
|
||||||
@ -45,3 +51,12 @@ At the moment, these metadata fields are recognized:
|
|||||||
:orphan:
|
:orphan:
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
.. versionadded:: 1.0
|
||||||
|
|
||||||
|
``nosearch``
|
||||||
|
If set, full text search for this file is disabled. ::
|
||||||
|
|
||||||
|
:nosearch:
|
||||||
|
|
||||||
|
.. note:: object search is still available even if `nosearch` option is set.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
@ -189,8 +189,8 @@ Referencing downloadable files
|
|||||||
|
|
||||||
When you use this role, the referenced file is automatically marked for
|
When you use this role, the referenced file is automatically marked for
|
||||||
inclusion in the output when building (obviously, for HTML output only).
|
inclusion in the output when building (obviously, for HTML output only).
|
||||||
All downloadable files are put into the ``_downloads`` subdirectory of the
|
All downloadable files are put into a ``_downloads/<unique hash>/``
|
||||||
output directory; duplicate filenames are handled.
|
subdirectory of the output directory; duplicate filenames are handled.
|
||||||
|
|
||||||
An example::
|
An example::
|
||||||
|
|
||||||
|
@ -151,6 +151,25 @@ These themes are:
|
|||||||
dimension string such as '70em' or '50%'. Use 'none' if you don't
|
dimension string such as '70em' or '50%'. Use 'none' if you don't
|
||||||
want a width limit. Defaults may depend on the theme (often 800px).
|
want a width limit. Defaults may depend on the theme (often 800px).
|
||||||
|
|
||||||
|
- **navigation_with_keys** (true or false): Allow navigating to the
|
||||||
|
previous/next page using the keyboard's left and right arrows. Defaults to
|
||||||
|
``False``.
|
||||||
|
|
||||||
|
- **globaltoc_collapse** (true or false): Only expand subsections
|
||||||
|
of the current document in ``globaltoc.html``
|
||||||
|
(see :confval:`html_sidebars`).
|
||||||
|
Defaults to ``True``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
- **globaltoc_includehidden** (true or false): Show even those
|
||||||
|
subsections in ``globaltoc.html`` (see :confval:`html_sidebars`)
|
||||||
|
which have been included with the ``:hidden:`` flag of the
|
||||||
|
:rst:dir:`toctree` directive.
|
||||||
|
Defaults to ``False``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
**alabaster**
|
**alabaster**
|
||||||
`Alabaster theme`_ is a modified "Kr" Sphinx theme from @kennethreitz
|
`Alabaster theme`_ is a modified "Kr" Sphinx theme from @kennethreitz
|
||||||
(especially as used in his Requests project), which was itself originally
|
(especially as used in his Requests project), which was itself originally
|
||||||
@ -237,6 +256,8 @@ These themes are:
|
|||||||
- **documentwidth** (CSS length): Width of the document (without sidebar),
|
- **documentwidth** (CSS length): Width of the document (without sidebar),
|
||||||
default 50em.
|
default 50em.
|
||||||
- **sidebarwidth** (CSS length): Width of the sidebar, default 20em.
|
- **sidebarwidth** (CSS length): Width of the sidebar, default 20em.
|
||||||
|
- **rightsidebar** (true or false): Put the sidebar on the right side.
|
||||||
|
Defaults to ``True``.
|
||||||
- **bgcolor** (CSS color): Background color.
|
- **bgcolor** (CSS color): Background color.
|
||||||
- **headerbg** (CSS value for "background"): background for the header area,
|
- **headerbg** (CSS value for "background"): background for the header area,
|
||||||
default a grayish gradient.
|
default a grayish gradient.
|
||||||
|
2323
package-lock.json
generated
2323
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -11,10 +11,10 @@
|
|||||||
"url": "https://github.com/sphinx-doc/sphinx/issues"
|
"url": "https://github.com/sphinx-doc/sphinx/issues"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"jasmine-core": "^3.1.0",
|
"jasmine-core": "^3.4.0",
|
||||||
"karma": "^3.0.0",
|
"karma": "^4.0.0",
|
||||||
"karma-chrome-launcher": "^2.2.0",
|
"karma-chrome-launcher": "^3.0.0",
|
||||||
"karma-firefox-launcher": "^1.1.0",
|
"karma-firefox-launcher": "^1.1.0",
|
||||||
"karma-jasmine": "^1.1.2"
|
"karma-jasmine": "^2.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,8 @@ paths =
|
|||||||
.
|
.
|
||||||
|
|
||||||
[mypy]
|
[mypy]
|
||||||
|
python_version = 3.5
|
||||||
|
disallow_incomplete_defs = True
|
||||||
show_column_numbers = True
|
show_column_numbers = True
|
||||||
show_error_context = True
|
show_error_context = True
|
||||||
ignore_missing_imports = True
|
ignore_missing_imports = True
|
||||||
@ -57,9 +59,11 @@ markers =
|
|||||||
apidoc
|
apidoc
|
||||||
setup_command
|
setup_command
|
||||||
test_params
|
test_params
|
||||||
|
testpaths = tests
|
||||||
|
|
||||||
[coverage:run]
|
[coverage:run]
|
||||||
branch = True
|
branch = True
|
||||||
|
parallel = True
|
||||||
source = sphinx
|
source = sphinx
|
||||||
|
|
||||||
[coverage:report]
|
[coverage:report]
|
||||||
|
21
setup.py
21
setup.py
@ -25,7 +25,7 @@ install_requires = [
|
|||||||
'Pygments>=2.0',
|
'Pygments>=2.0',
|
||||||
'docutils>=0.12',
|
'docutils>=0.12',
|
||||||
'snowballstemmer>=1.1',
|
'snowballstemmer>=1.1',
|
||||||
'babel>=1.3,!=2.0',
|
'babel>=1.3',
|
||||||
'alabaster>=0.7,<0.8',
|
'alabaster>=0.7,<0.8',
|
||||||
'imagesize',
|
'imagesize',
|
||||||
'requests>=2.5.0',
|
'requests>=2.5.0',
|
||||||
@ -41,14 +41,18 @@ extras_require = {
|
|||||||
'docs': [
|
'docs': [
|
||||||
'sphinxcontrib-websupport',
|
'sphinxcontrib-websupport',
|
||||||
],
|
],
|
||||||
|
'lint': [
|
||||||
|
'flake8>=3.5.0',
|
||||||
|
'flake8-import-order',
|
||||||
|
'mypy>=0.770',
|
||||||
|
'docutils-stubs',
|
||||||
|
],
|
||||||
'test': [
|
'test': [
|
||||||
'pytest',
|
'pytest',
|
||||||
'pytest-cov',
|
'pytest-cov',
|
||||||
'html5lib',
|
'html5lib',
|
||||||
'flake8>=3.5.0',
|
'typed_ast', # for py35-37
|
||||||
'flake8-import-order',
|
'cython',
|
||||||
'mypy>=0.711',
|
|
||||||
'docutils-stubs',
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,6 +180,10 @@ setup(
|
|||||||
description='Python documentation generator',
|
description='Python documentation generator',
|
||||||
long_description=long_desc,
|
long_description=long_desc,
|
||||||
long_description_content_type='text/x-rst',
|
long_description_content_type='text/x-rst',
|
||||||
|
project_urls={
|
||||||
|
"Code": "https://github.com/sphinx-doc/sphinx",
|
||||||
|
"Issue tracker": "https://github.com/sphinx-doc/sphinx/issues",
|
||||||
|
},
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Development Status :: 5 - Production/Stable',
|
'Development Status :: 5 - Production/Stable',
|
||||||
@ -216,6 +224,9 @@ setup(
|
|||||||
],
|
],
|
||||||
platforms='any',
|
platforms='any',
|
||||||
packages=find_packages(exclude=['tests', 'utils']),
|
packages=find_packages(exclude=['tests', 'utils']),
|
||||||
|
package_data = {
|
||||||
|
'sphinx': ['py.typed'],
|
||||||
|
},
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
The Sphinx documentation toolchain.
|
The Sphinx documentation toolchain.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -32,8 +32,8 @@ if 'PYTHONWARNINGS' not in os.environ:
|
|||||||
warnings.filterwarnings('ignore', "'U' mode is deprecated",
|
warnings.filterwarnings('ignore', "'U' mode is deprecated",
|
||||||
DeprecationWarning, module='docutils.io')
|
DeprecationWarning, module='docutils.io')
|
||||||
|
|
||||||
__version__ = '3.0.0+'
|
__version__ = '3.1.0+'
|
||||||
__released__ = '3.0.0' # used when Sphinx builds its own docs
|
__released__ = '3.1.0' # used when Sphinx builds its own docs
|
||||||
|
|
||||||
#: Version info for better programmatic use.
|
#: Version info for better programmatic use.
|
||||||
#:
|
#:
|
||||||
@ -43,7 +43,7 @@ __released__ = '3.0.0' # used when Sphinx builds its own docs
|
|||||||
#:
|
#:
|
||||||
#: .. versionadded:: 1.2
|
#: .. versionadded:: 1.2
|
||||||
#: Before version 1.2, check the string ``sphinx.__version__``.
|
#: Before version 1.2, check the string ``sphinx.__version__``.
|
||||||
version_info = (3, 0, 0, 'beta', 0)
|
version_info = (3, 1, 0, 'beta', 0)
|
||||||
|
|
||||||
package_dir = path.abspath(path.dirname(__file__))
|
package_dir = path.abspath(path.dirname(__file__))
|
||||||
|
|
||||||
@ -56,8 +56,9 @@ if __version__.endswith('+'):
|
|||||||
__version__ = __version__[:-1] # remove '+' for PEP-440 version spec.
|
__version__ = __version__[:-1] # remove '+' for PEP-440 version spec.
|
||||||
try:
|
try:
|
||||||
ret = subprocess.run(['git', 'show', '-s', '--pretty=format:%h'],
|
ret = subprocess.run(['git', 'show', '-s', '--pretty=format:%h'],
|
||||||
stdout=PIPE, stderr=PIPE, encoding='ascii')
|
cwd=package_dir,
|
||||||
|
stdout=PIPE, stderr=PIPE)
|
||||||
if ret.stdout:
|
if ret.stdout:
|
||||||
__display_version__ += '/' + ret.stdout.strip()
|
__display_version__ += '/' + ret.stdout.decode('ascii').strip()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
The Sphinx documentation toolchain.
|
The Sphinx documentation toolchain.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -4,20 +4,21 @@
|
|||||||
|
|
||||||
Additional docutils nodes.
|
Additional docutils nodes.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Any, Dict, List, Sequence
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Element, Node
|
||||||
|
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, List, Sequence # NOQA
|
from sphinx.application import Sphinx
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
class translatable(nodes.Node):
|
class translatable(nodes.Node):
|
||||||
@ -34,18 +35,15 @@ class translatable(nodes.Node):
|
|||||||
Because they are used at final step; extraction.
|
Because they are used at final step; extraction.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def preserve_original_messages(self):
|
def preserve_original_messages(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Preserve original translatable messages."""
|
"""Preserve original translatable messages."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def apply_translated_message(self, original_message, translated_message):
|
def apply_translated_message(self, original_message: str, translated_message: str) -> None:
|
||||||
# type: (str, str) -> None
|
|
||||||
"""Apply translated message."""
|
"""Apply translated message."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def extract_original_messages(self):
|
def extract_original_messages(self) -> Sequence[str]:
|
||||||
# type: () -> Sequence[str]
|
|
||||||
"""Extract translation messages.
|
"""Extract translation messages.
|
||||||
|
|
||||||
:returns: list of extracted messages or messages generator
|
:returns: list of extracted messages or messages generator
|
||||||
@ -61,22 +59,37 @@ class not_smartquotable:
|
|||||||
class toctree(nodes.General, nodes.Element, translatable):
|
class toctree(nodes.General, nodes.Element, translatable):
|
||||||
"""Node for inserting a "TOC tree"."""
|
"""Node for inserting a "TOC tree"."""
|
||||||
|
|
||||||
def preserve_original_messages(self):
|
def preserve_original_messages(self) -> None:
|
||||||
# type: () -> None
|
# toctree entries
|
||||||
|
rawentries = self.setdefault('rawentries', [])
|
||||||
|
for title, docname in self['entries']:
|
||||||
|
if title:
|
||||||
|
rawentries.append(title)
|
||||||
|
|
||||||
|
# :caption: option
|
||||||
if self.get('caption'):
|
if self.get('caption'):
|
||||||
self['rawcaption'] = self['caption']
|
self['rawcaption'] = self['caption']
|
||||||
|
|
||||||
def apply_translated_message(self, original_message, translated_message):
|
def apply_translated_message(self, original_message: str, translated_message: str) -> None:
|
||||||
# type: (str, str) -> None
|
# toctree entries
|
||||||
|
for i, (title, docname) in enumerate(self['entries']):
|
||||||
|
if title == original_message:
|
||||||
|
self['entries'][i] = (translated_message, docname)
|
||||||
|
|
||||||
|
# :caption: option
|
||||||
if self.get('rawcaption') == original_message:
|
if self.get('rawcaption') == original_message:
|
||||||
self['caption'] = translated_message
|
self['caption'] = translated_message
|
||||||
|
|
||||||
def extract_original_messages(self):
|
def extract_original_messages(self) -> List[str]:
|
||||||
# type: () -> List[str]
|
messages = [] # type: List[str]
|
||||||
|
|
||||||
|
# toctree entries
|
||||||
|
messages.extend(self.get('rawentries', []))
|
||||||
|
|
||||||
|
# :caption: option
|
||||||
if 'rawcaption' in self:
|
if 'rawcaption' in self:
|
||||||
return [self['rawcaption']]
|
messages.append(self['rawcaption'])
|
||||||
else:
|
return messages
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
# domain-specific object descriptions (class, function etc.)
|
# domain-specific object descriptions (class, function etc.)
|
||||||
@ -106,7 +119,7 @@ class desc_signature_line(nodes.Part, nodes.Inline, nodes.FixedTextElement):
|
|||||||
It should only be used in a ``desc_signature`` with ``is_multiline`` set.
|
It should only be used in a ``desc_signature`` with ``is_multiline`` set.
|
||||||
Set ``add_permalink = True`` for the line that should get the permalink.
|
Set ``add_permalink = True`` for the line that should get the permalink.
|
||||||
"""
|
"""
|
||||||
sphinx_cpp_tagname = ''
|
sphinx_line_type = ''
|
||||||
|
|
||||||
|
|
||||||
# nodes to use within a desc_signature or desc_signature_line
|
# nodes to use within a desc_signature or desc_signature_line
|
||||||
@ -125,8 +138,7 @@ class desc_type(nodes.Part, nodes.Inline, nodes.FixedTextElement):
|
|||||||
|
|
||||||
class desc_returns(desc_type):
|
class desc_returns(desc_type):
|
||||||
"""Node for a "returns" annotation (a la -> in Python)."""
|
"""Node for a "returns" annotation (a la -> in Python)."""
|
||||||
def astext(self):
|
def astext(self) -> str:
|
||||||
# type: () -> str
|
|
||||||
return ' -> ' + super().astext()
|
return ' -> ' + super().astext()
|
||||||
|
|
||||||
|
|
||||||
@ -147,8 +159,7 @@ class desc_optional(nodes.Part, nodes.Inline, nodes.FixedTextElement):
|
|||||||
"""Node for marking optional parts of the parameter list."""
|
"""Node for marking optional parts of the parameter list."""
|
||||||
child_text_separator = ', '
|
child_text_separator = ', '
|
||||||
|
|
||||||
def astext(self):
|
def astext(self) -> str:
|
||||||
# type: () -> str
|
|
||||||
return '[' + super().astext() + ']'
|
return '[' + super().astext() + ']'
|
||||||
|
|
||||||
|
|
||||||
@ -163,6 +174,31 @@ class desc_content(nodes.General, nodes.Element):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class desc_sig_element(nodes.inline):
|
||||||
|
"""Common parent class of nodes for inline text of a signature."""
|
||||||
|
classes = [] # type: List[str]
|
||||||
|
|
||||||
|
def __init__(self, rawsource: str = '', text: str = '',
|
||||||
|
*children: Element, **attributes: Any) -> None:
|
||||||
|
super().__init__(rawsource, text, *children, **attributes)
|
||||||
|
self['classes'].extend(self.classes)
|
||||||
|
|
||||||
|
|
||||||
|
class desc_sig_name(desc_sig_element):
|
||||||
|
"""Node for a name in a signature."""
|
||||||
|
classes = ["n"]
|
||||||
|
|
||||||
|
|
||||||
|
class desc_sig_operator(desc_sig_element):
|
||||||
|
"""Node for an operator in a signature."""
|
||||||
|
classes = ["o"]
|
||||||
|
|
||||||
|
|
||||||
|
class desc_sig_punctuation(desc_sig_element):
|
||||||
|
"""Node for a punctuation in a signature."""
|
||||||
|
classes = ["p"]
|
||||||
|
|
||||||
|
|
||||||
# new admonition-like constructs
|
# new admonition-like constructs
|
||||||
|
|
||||||
class versionmodified(nodes.Admonition, nodes.TextElement):
|
class versionmodified(nodes.Admonition, nodes.TextElement):
|
||||||
@ -295,8 +331,8 @@ class abbreviation(nodes.abbreviation):
|
|||||||
.. deprecated:: 2.0
|
.. deprecated:: 2.0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, rawsource='', text='', *children, **attributes):
|
def __init__(self, rawsource: str = '', text: str = '',
|
||||||
# type: (str, str, *nodes.Node, **Any) -> None
|
*children: Node, **attributes: Any) -> None:
|
||||||
warnings.warn("abbrevition node for Sphinx was replaced by docutils'.",
|
warnings.warn("abbrevition node for Sphinx was replaced by docutils'.",
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
|
||||||
@ -307,8 +343,7 @@ class manpage(nodes.Inline, nodes.FixedTextElement):
|
|||||||
"""Node for references to manpages."""
|
"""Node for references to manpages."""
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_node(toctree)
|
app.add_node(toctree)
|
||||||
app.add_node(desc)
|
app.add_node(desc)
|
||||||
app.add_node(desc_signature)
|
app.add_node(desc_signature)
|
||||||
@ -322,6 +357,9 @@ def setup(app):
|
|||||||
app.add_node(desc_optional)
|
app.add_node(desc_optional)
|
||||||
app.add_node(desc_annotation)
|
app.add_node(desc_annotation)
|
||||||
app.add_node(desc_content)
|
app.add_node(desc_content)
|
||||||
|
app.add_node(desc_sig_name)
|
||||||
|
app.add_node(desc_sig_operator)
|
||||||
|
app.add_node(desc_sig_punctuation)
|
||||||
app.add_node(versionmodified)
|
app.add_node(versionmodified)
|
||||||
app.add_node(seealso)
|
app.add_node(seealso)
|
||||||
app.add_node(productionlist)
|
app.add_node(productionlist)
|
||||||
|
@ -6,32 +6,42 @@
|
|||||||
|
|
||||||
Gracefully adapted from the TextPress system by Armin.
|
Gracefully adapted from the TextPress system by Armin.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
|
import platform
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Callable, Dict, IO, List, Tuple, Union
|
||||||
|
|
||||||
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Element, TextElement
|
||||||
from docutils.parsers.rst import Directive, roles
|
from docutils.parsers.rst import Directive, roles
|
||||||
|
from docutils.transforms import Transform
|
||||||
from pygments.lexer import Lexer
|
from pygments.lexer import Lexer
|
||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
from sphinx import package_dir, locale
|
from sphinx import package_dir, locale
|
||||||
from sphinx.config import Config
|
from sphinx.config import Config
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
|
from sphinx.domains import Domain, Index
|
||||||
from sphinx.environment import BuildEnvironment
|
from sphinx.environment import BuildEnvironment
|
||||||
|
from sphinx.environment.collectors import EnvironmentCollector
|
||||||
from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError
|
from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError
|
||||||
from sphinx.events import EventManager
|
from sphinx.events import EventManager
|
||||||
|
from sphinx.extension import Extension
|
||||||
from sphinx.highlighting import lexer_classes, lexers
|
from sphinx.highlighting import lexer_classes, lexers
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.project import Project
|
from sphinx.project import Project
|
||||||
from sphinx.registry import SphinxComponentRegistry
|
from sphinx.registry import SphinxComponentRegistry
|
||||||
|
from sphinx.roles import XRefRole
|
||||||
|
from sphinx.theming import Theme
|
||||||
from sphinx.util import docutils
|
from sphinx.util import docutils
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util import progress_message
|
from sphinx.util import progress_message
|
||||||
@ -41,20 +51,14 @@ from sphinx.util.i18n import CatalogRepository
|
|||||||
from sphinx.util.logging import prefixed_warnings
|
from sphinx.util.logging import prefixed_warnings
|
||||||
from sphinx.util.osutil import abspath, ensuredir, relpath
|
from sphinx.util.osutil import abspath, ensuredir, relpath
|
||||||
from sphinx.util.tags import Tags
|
from sphinx.util.tags import Tags
|
||||||
|
from sphinx.util.typing import RoleFunction, TitleGetter
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Callable, Dict, IO, Iterable, Iterator, List, Tuple, Type, Union # NOQA
|
from docutils.nodes import Node # NOQA
|
||||||
from docutils import nodes # NOQA
|
from typing import Type # for python3.5.1
|
||||||
from docutils.parsers import Parser # NOQA
|
from sphinx.builders import Builder
|
||||||
from docutils.transforms import Transform # NOQA
|
|
||||||
from sphinx.builders import Builder # NOQA
|
|
||||||
from sphinx.domains import Domain, Index # NOQA
|
|
||||||
from sphinx.environment.collectors import EnvironmentCollector # NOQA
|
|
||||||
from sphinx.extension import Extension # NOQA
|
|
||||||
from sphinx.roles import XRefRole # NOQA
|
|
||||||
from sphinx.theming import Theme # NOQA
|
|
||||||
from sphinx.util.typing import RoleFunction, TitleGetter # NOQA
|
|
||||||
|
|
||||||
builtin_extensions = (
|
builtin_extensions = (
|
||||||
'sphinx.addnodes',
|
'sphinx.addnodes',
|
||||||
@ -76,6 +80,7 @@ builtin_extensions = (
|
|||||||
'sphinx.domains.changeset',
|
'sphinx.domains.changeset',
|
||||||
'sphinx.domains.citation',
|
'sphinx.domains.citation',
|
||||||
'sphinx.domains.cpp',
|
'sphinx.domains.cpp',
|
||||||
|
'sphinx.domains.index',
|
||||||
'sphinx.domains.javascript',
|
'sphinx.domains.javascript',
|
||||||
'sphinx.domains.math',
|
'sphinx.domains.math',
|
||||||
'sphinx.domains.python',
|
'sphinx.domains.python',
|
||||||
@ -104,7 +109,6 @@ builtin_extensions = (
|
|||||||
'sphinx.environment.collectors.metadata',
|
'sphinx.environment.collectors.metadata',
|
||||||
'sphinx.environment.collectors.title',
|
'sphinx.environment.collectors.title',
|
||||||
'sphinx.environment.collectors.toctree',
|
'sphinx.environment.collectors.toctree',
|
||||||
'sphinx.environment.collectors.indexentries',
|
|
||||||
# 1st party extensions
|
# 1st party extensions
|
||||||
'sphinxcontrib.applehelp',
|
'sphinxcontrib.applehelp',
|
||||||
'sphinxcontrib.devhelp',
|
'sphinxcontrib.devhelp',
|
||||||
@ -130,11 +134,11 @@ class Sphinx:
|
|||||||
:ivar outdir: Directory for storing build documents.
|
:ivar outdir: Directory for storing build documents.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, srcdir, confdir, outdir, doctreedir, buildername,
|
def __init__(self, srcdir: str, confdir: str, outdir: str, doctreedir: str,
|
||||||
confoverrides=None, status=sys.stdout, warning=sys.stderr,
|
buildername: str, confoverrides: Dict = None,
|
||||||
freshenv=False, warningiserror=False, tags=None, verbosity=0,
|
status: IO = sys.stdout, warning: IO = sys.stderr,
|
||||||
parallel=0, keep_going=False):
|
freshenv: bool = False, warningiserror: bool = False, tags: List[str] = None,
|
||||||
# type: (str, str, str, str, str, Dict, IO, IO, bool, bool, List[str], int, int, bool) -> None # NOQA
|
verbosity: int = 0, parallel: int = 0, keep_going: bool = False) -> None:
|
||||||
self.phase = BuildPhase.INITIALIZATION
|
self.phase = BuildPhase.INITIALIZATION
|
||||||
self.verbosity = verbosity
|
self.verbosity = verbosity
|
||||||
self.extensions = {} # type: Dict[str, Extension]
|
self.extensions = {} # type: Dict[str, Extension]
|
||||||
@ -159,6 +163,10 @@ class Sphinx:
|
|||||||
raise ApplicationError(__('Cannot find source directory (%s)') %
|
raise ApplicationError(__('Cannot find source directory (%s)') %
|
||||||
self.srcdir)
|
self.srcdir)
|
||||||
|
|
||||||
|
if path.exists(self.outdir) and not path.isdir(self.outdir):
|
||||||
|
raise ApplicationError(__('Output directory (%s) is not a directory') %
|
||||||
|
self.srcdir)
|
||||||
|
|
||||||
if self.srcdir == self.outdir:
|
if self.srcdir == self.outdir:
|
||||||
raise ApplicationError(__('Source directory and destination '
|
raise ApplicationError(__('Source directory and destination '
|
||||||
'directory cannot be identical'))
|
'directory cannot be identical'))
|
||||||
@ -193,6 +201,12 @@ class Sphinx:
|
|||||||
# say hello to the world
|
# say hello to the world
|
||||||
logger.info(bold(__('Running Sphinx v%s') % sphinx.__display_version__))
|
logger.info(bold(__('Running Sphinx v%s') % sphinx.__display_version__))
|
||||||
|
|
||||||
|
# notice for parallel build on macOS and py38+
|
||||||
|
if sys.version_info > (3, 8) and platform.system() == 'Darwin' and parallel > 1:
|
||||||
|
logger.info(bold(__("For security reason, parallel mode is disabled on macOS and "
|
||||||
|
"python3.8 and above. For more details, please read "
|
||||||
|
"https://github.com/sphinx-doc/sphinx/issues/6803")))
|
||||||
|
|
||||||
# status code for command-line application
|
# status code for command-line application
|
||||||
self.statuscode = 0
|
self.statuscode = 0
|
||||||
|
|
||||||
@ -262,8 +276,7 @@ class Sphinx:
|
|||||||
# set up the builder
|
# set up the builder
|
||||||
self._init_builder()
|
self._init_builder()
|
||||||
|
|
||||||
def _init_i18n(self):
|
def _init_i18n(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Load translated strings from the configured localedirs if enabled in
|
"""Load translated strings from the configured localedirs if enabled in
|
||||||
the configuration.
|
the configuration.
|
||||||
"""
|
"""
|
||||||
@ -288,8 +301,7 @@ class Sphinx:
|
|||||||
else:
|
else:
|
||||||
logger.info(__('not available for built-in messages'))
|
logger.info(__('not available for built-in messages'))
|
||||||
|
|
||||||
def _init_env(self, freshenv):
|
def _init_env(self, freshenv: bool) -> None:
|
||||||
# type: (bool) -> None
|
|
||||||
filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
|
filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
|
||||||
if freshenv or not os.path.exists(filename):
|
if freshenv or not os.path.exists(filename):
|
||||||
self.env = BuildEnvironment()
|
self.env = BuildEnvironment()
|
||||||
@ -305,28 +317,24 @@ class Sphinx:
|
|||||||
logger.info(__('failed: %s'), err)
|
logger.info(__('failed: %s'), err)
|
||||||
self._init_env(freshenv=True)
|
self._init_env(freshenv=True)
|
||||||
|
|
||||||
def preload_builder(self, name):
|
def preload_builder(self, name: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
self.registry.preload_builder(self, name)
|
self.registry.preload_builder(self, name)
|
||||||
|
|
||||||
def create_builder(self, name):
|
def create_builder(self, name: str) -> "Builder":
|
||||||
# type: (str) -> Builder
|
|
||||||
if name is None:
|
if name is None:
|
||||||
logger.info(__('No builder selected, using default: html'))
|
logger.info(__('No builder selected, using default: html'))
|
||||||
name = 'html'
|
name = 'html'
|
||||||
|
|
||||||
return self.registry.create_builder(self, name)
|
return self.registry.create_builder(self, name)
|
||||||
|
|
||||||
def _init_builder(self):
|
def _init_builder(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.builder.set_environment(self.env)
|
self.builder.set_environment(self.env)
|
||||||
self.builder.init()
|
self.builder.init()
|
||||||
self.events.emit('builder-inited')
|
self.events.emit('builder-inited')
|
||||||
|
|
||||||
# ---- main "build" method -------------------------------------------------
|
# ---- main "build" method -------------------------------------------------
|
||||||
|
|
||||||
def build(self, force_all=False, filenames=None):
|
def build(self, force_all: bool = False, filenames: List[str] = None) -> None:
|
||||||
# type: (bool, List[str]) -> None
|
|
||||||
self.phase = BuildPhase.READING
|
self.phase = BuildPhase.READING
|
||||||
try:
|
try:
|
||||||
if force_all:
|
if force_all:
|
||||||
@ -342,17 +350,19 @@ class Sphinx:
|
|||||||
if self._warncount and self.keep_going:
|
if self._warncount and self.keep_going:
|
||||||
self.statuscode = 1
|
self.statuscode = 1
|
||||||
|
|
||||||
status = (self.statuscode == 0 and
|
status = (__('succeeded') if self.statuscode == 0
|
||||||
__('succeeded') or __('finished with problems'))
|
else __('finished with problems'))
|
||||||
if self._warncount:
|
if self._warncount:
|
||||||
if self.warningiserror:
|
if self.warningiserror:
|
||||||
msg = __('build %s, %s warning (with warnings treated as errors).',
|
if self._warncount == 1:
|
||||||
'build %s, %s warnings (with warnings treated as errors).',
|
msg = __('build %s, %s warning (with warnings treated as errors).')
|
||||||
self._warncount)
|
else:
|
||||||
|
msg = __('build %s, %s warnings (with warnings treated as errors).')
|
||||||
else:
|
else:
|
||||||
msg = __('build %s, %s warning.',
|
if self._warncount == 1:
|
||||||
'build %s, %s warnings.',
|
msg = __('build %s, %s warning.')
|
||||||
self._warncount)
|
else:
|
||||||
|
msg = __('build %s, %s warnings.')
|
||||||
|
|
||||||
logger.info(bold(msg % (status, self._warncount)))
|
logger.info(bold(msg % (status, self._warncount)))
|
||||||
else:
|
else:
|
||||||
@ -377,8 +387,7 @@ class Sphinx:
|
|||||||
|
|
||||||
# ---- general extensibility interface -------------------------------------
|
# ---- general extensibility interface -------------------------------------
|
||||||
|
|
||||||
def setup_extension(self, extname):
|
def setup_extension(self, extname: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
"""Import and setup a Sphinx extension module.
|
"""Import and setup a Sphinx extension module.
|
||||||
|
|
||||||
Load the extension given by the module *name*. Use this if your
|
Load the extension given by the module *name*. Use this if your
|
||||||
@ -388,8 +397,7 @@ class Sphinx:
|
|||||||
logger.debug('[app] setting up extension: %r', extname)
|
logger.debug('[app] setting up extension: %r', extname)
|
||||||
self.registry.load_extension(self, extname)
|
self.registry.load_extension(self, extname)
|
||||||
|
|
||||||
def require_sphinx(self, version):
|
def require_sphinx(self, version: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
"""Check the Sphinx version if requested.
|
"""Check the Sphinx version if requested.
|
||||||
|
|
||||||
Compare *version* (which must be a ``major.minor`` version string, e.g.
|
Compare *version* (which must be a ``major.minor`` version string, e.g.
|
||||||
@ -402,28 +410,33 @@ class Sphinx:
|
|||||||
raise VersionRequirementError(version)
|
raise VersionRequirementError(version)
|
||||||
|
|
||||||
# event interface
|
# event interface
|
||||||
def connect(self, event, callback):
|
def connect(self, event: str, callback: Callable, priority: int = 500) -> int:
|
||||||
# type: (str, Callable) -> int
|
|
||||||
"""Register *callback* to be called when *event* is emitted.
|
"""Register *callback* to be called when *event* is emitted.
|
||||||
|
|
||||||
For details on available core events and the arguments of callback
|
For details on available core events and the arguments of callback
|
||||||
functions, please see :ref:`events`.
|
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
|
The method returns a "listener ID" that can be used as an argument to
|
||||||
:meth:`disconnect`.
|
:meth:`disconnect`.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.0
|
||||||
|
|
||||||
|
Support *priority*
|
||||||
"""
|
"""
|
||||||
listener_id = self.events.connect(event, callback)
|
listener_id = self.events.connect(event, callback, priority)
|
||||||
logger.debug('[app] connecting event %r: %r [id=%s]', event, callback, listener_id)
|
logger.debug('[app] connecting event %r (%d): %r [id=%s]',
|
||||||
|
event, priority, callback, listener_id)
|
||||||
return listener_id
|
return listener_id
|
||||||
|
|
||||||
def disconnect(self, listener_id):
|
def disconnect(self, listener_id: int) -> None:
|
||||||
# type: (int) -> None
|
|
||||||
"""Unregister callback by *listener_id*."""
|
"""Unregister callback by *listener_id*."""
|
||||||
logger.debug('[app] disconnecting event: [id=%s]', listener_id)
|
logger.debug('[app] disconnecting event: [id=%s]', listener_id)
|
||||||
self.events.disconnect(listener_id)
|
self.events.disconnect(listener_id)
|
||||||
|
|
||||||
def emit(self, event, *args):
|
def emit(self, event: str, *args: Any) -> List:
|
||||||
# type: (str, Any) -> List
|
|
||||||
"""Emit *event* and pass *arguments* to the callback functions.
|
"""Emit *event* and pass *arguments* to the callback functions.
|
||||||
|
|
||||||
Return the return values of all callbacks as a list. Do not emit core
|
Return the return values of all callbacks as a list. Do not emit core
|
||||||
@ -431,8 +444,7 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
return self.events.emit(event, *args)
|
return self.events.emit(event, *args)
|
||||||
|
|
||||||
def emit_firstresult(self, event, *args):
|
def emit_firstresult(self, event: str, *args: Any) -> Any:
|
||||||
# type: (str, Any) -> Any
|
|
||||||
"""Emit *event* and pass *arguments* to the callback functions.
|
"""Emit *event* and pass *arguments* to the callback functions.
|
||||||
|
|
||||||
Return the result of the first callback that doesn't return ``None``.
|
Return the result of the first callback that doesn't return ``None``.
|
||||||
@ -443,8 +455,7 @@ class Sphinx:
|
|||||||
|
|
||||||
# registering addon parts
|
# registering addon parts
|
||||||
|
|
||||||
def add_builder(self, builder, override=False):
|
def add_builder(self, builder: "Type[Builder]", override: bool = False) -> None:
|
||||||
# type: (Type[Builder], bool) -> None
|
|
||||||
"""Register a new builder.
|
"""Register a new builder.
|
||||||
|
|
||||||
*builder* must be a class that inherits from
|
*builder* must be a class that inherits from
|
||||||
@ -456,8 +467,8 @@ class Sphinx:
|
|||||||
self.registry.add_builder(builder, override=override)
|
self.registry.add_builder(builder, override=override)
|
||||||
|
|
||||||
# TODO(stephenfin): Describe 'types' parameter
|
# TODO(stephenfin): Describe 'types' parameter
|
||||||
def add_config_value(self, name, default, rebuild, types=()):
|
def add_config_value(self, name: str, default: Any, rebuild: Union[bool, str],
|
||||||
# type: (str, Any, Union[bool, str], Any) -> None
|
types: Any = ()) -> None:
|
||||||
"""Register a configuration value.
|
"""Register a configuration value.
|
||||||
|
|
||||||
This is necessary for Sphinx to recognize new values and set default
|
This is necessary for Sphinx to recognize new values and set default
|
||||||
@ -484,13 +495,12 @@ class Sphinx:
|
|||||||
other values.
|
other values.
|
||||||
"""
|
"""
|
||||||
logger.debug('[app] adding config value: %r',
|
logger.debug('[app] adding config value: %r',
|
||||||
(name, default, rebuild) + ((types,) if types else ())) # type: ignore
|
(name, default, rebuild) + ((types,) if types else ()))
|
||||||
if rebuild in (False, True):
|
if rebuild in (False, True):
|
||||||
rebuild = rebuild and 'env' or ''
|
rebuild = 'env' if rebuild else ''
|
||||||
self.config.add(name, default, rebuild, types)
|
self.config.add(name, default, rebuild, types)
|
||||||
|
|
||||||
def add_event(self, name):
|
def add_event(self, name: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
"""Register an event called *name*.
|
"""Register an event called *name*.
|
||||||
|
|
||||||
This is needed to be able to emit it.
|
This is needed to be able to emit it.
|
||||||
@ -498,8 +508,8 @@ class Sphinx:
|
|||||||
logger.debug('[app] adding event: %r', name)
|
logger.debug('[app] adding event: %r', name)
|
||||||
self.events.add(name)
|
self.events.add(name)
|
||||||
|
|
||||||
def set_translator(self, name, translator_class, override=False):
|
def set_translator(self, name: str, translator_class: "Type[nodes.NodeVisitor]",
|
||||||
# type: (str, Type[nodes.NodeVisitor], bool) -> None
|
override: bool = False) -> None:
|
||||||
"""Register or override a Docutils translator class.
|
"""Register or override a Docutils translator class.
|
||||||
|
|
||||||
This is used to register a custom output translator or to replace a
|
This is used to register a custom output translator or to replace a
|
||||||
@ -512,8 +522,8 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_translator(name, translator_class, override=override)
|
self.registry.add_translator(name, translator_class, override=override)
|
||||||
|
|
||||||
def add_node(self, node, override=False, **kwds):
|
def add_node(self, node: "Type[Element]", override: bool = False,
|
||||||
# type: (Type[nodes.Element], bool, Any) -> None
|
**kwargs: Tuple[Callable, Callable]) -> None:
|
||||||
"""Register a Docutils node class.
|
"""Register a Docutils node class.
|
||||||
|
|
||||||
This is necessary for Docutils internals. It may also be used in the
|
This is necessary for Docutils internals. It may also be used in the
|
||||||
@ -543,16 +553,17 @@ class Sphinx:
|
|||||||
.. versionchanged:: 0.5
|
.. versionchanged:: 0.5
|
||||||
Added the support for keyword arguments giving visit functions.
|
Added the support for keyword arguments giving visit functions.
|
||||||
"""
|
"""
|
||||||
logger.debug('[app] adding node: %r', (node, kwds))
|
logger.debug('[app] adding node: %r', (node, kwargs))
|
||||||
if not override and docutils.is_node_registered(node):
|
if not override and docutils.is_node_registered(node):
|
||||||
logger.warning(__('node class %r is already registered, '
|
logger.warning(__('node class %r is already registered, '
|
||||||
'its visitors will be overridden'),
|
'its visitors will be overridden'),
|
||||||
node.__name__, type='app', subtype='add_node')
|
node.__name__, type='app', subtype='add_node')
|
||||||
docutils.register_node(node)
|
docutils.register_node(node)
|
||||||
self.registry.add_translation_handlers(node, **kwds)
|
self.registry.add_translation_handlers(node, **kwargs)
|
||||||
|
|
||||||
def add_enumerable_node(self, node, figtype, title_getter=None, override=False, **kwds):
|
def add_enumerable_node(self, node: "Type[Element]", figtype: str,
|
||||||
# type: (Type[nodes.Element], str, TitleGetter, bool, Any) -> None
|
title_getter: TitleGetter = None, override: bool = False,
|
||||||
|
**kwargs: Tuple[Callable, Callable]) -> None:
|
||||||
"""Register a Docutils node class as a numfig target.
|
"""Register a Docutils node class as a numfig target.
|
||||||
|
|
||||||
Sphinx numbers the node automatically. And then the users can refer it
|
Sphinx numbers the node automatically. And then the users can refer it
|
||||||
@ -577,10 +588,9 @@ class Sphinx:
|
|||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
"""
|
"""
|
||||||
self.registry.add_enumerable_node(node, figtype, title_getter, override=override)
|
self.registry.add_enumerable_node(node, figtype, title_getter, override=override)
|
||||||
self.add_node(node, override=override, **kwds)
|
self.add_node(node, override=override, **kwargs)
|
||||||
|
|
||||||
def add_directive(self, name, cls, override=False):
|
def add_directive(self, name: str, cls: "Type[Directive]", override: bool = False) -> None:
|
||||||
# type: (str, Type[Directive], bool) -> None
|
|
||||||
"""Register a Docutils directive.
|
"""Register a Docutils directive.
|
||||||
|
|
||||||
*name* must be the prospective directive name. *cls* is a directive
|
*name* must be the prospective directive name. *cls* is a directive
|
||||||
@ -624,8 +634,7 @@ class Sphinx:
|
|||||||
|
|
||||||
docutils.register_directive(name, cls)
|
docutils.register_directive(name, cls)
|
||||||
|
|
||||||
def add_role(self, name, role, override=False):
|
def add_role(self, name: str, role: Any, override: bool = False) -> None:
|
||||||
# type: (str, Any, bool) -> None
|
|
||||||
"""Register a Docutils role.
|
"""Register a Docutils role.
|
||||||
|
|
||||||
*name* must be the role name that occurs in the source, *role* the role
|
*name* must be the role name that occurs in the source, *role* the role
|
||||||
@ -642,8 +651,7 @@ class Sphinx:
|
|||||||
name, type='app', subtype='add_role')
|
name, type='app', subtype='add_role')
|
||||||
docutils.register_role(name, role)
|
docutils.register_role(name, role)
|
||||||
|
|
||||||
def add_generic_role(self, name, nodeclass, override=False):
|
def add_generic_role(self, name: str, nodeclass: Any, override: bool = False) -> None:
|
||||||
# type: (str, Any, bool) -> None
|
|
||||||
"""Register a generic Docutils role.
|
"""Register a generic Docutils role.
|
||||||
|
|
||||||
Register a Docutils role that does nothing but wrap its contents in the
|
Register a Docutils role that does nothing but wrap its contents in the
|
||||||
@ -662,8 +670,7 @@ class Sphinx:
|
|||||||
role = roles.GenericRole(name, nodeclass)
|
role = roles.GenericRole(name, nodeclass)
|
||||||
docutils.register_role(name, role)
|
docutils.register_role(name, role)
|
||||||
|
|
||||||
def add_domain(self, domain, override=False):
|
def add_domain(self, domain: "Type[Domain]", override: bool = False) -> None:
|
||||||
# type: (Type[Domain], bool) -> None
|
|
||||||
"""Register a domain.
|
"""Register a domain.
|
||||||
|
|
||||||
Make the given *domain* (which must be a class; more precisely, a
|
Make the given *domain* (which must be a class; more precisely, a
|
||||||
@ -675,8 +682,8 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_domain(domain, override=override)
|
self.registry.add_domain(domain, override=override)
|
||||||
|
|
||||||
def add_directive_to_domain(self, domain, name, cls, override=False):
|
def add_directive_to_domain(self, domain: str, name: str,
|
||||||
# type: (str, str, Type[Directive], bool) -> None
|
cls: "Type[Directive]", override: bool = False) -> None:
|
||||||
"""Register a Docutils directive in a domain.
|
"""Register a Docutils directive in a domain.
|
||||||
|
|
||||||
Like :meth:`add_directive`, but the directive is added to the domain
|
Like :meth:`add_directive`, but the directive is added to the domain
|
||||||
@ -688,8 +695,8 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_directive_to_domain(domain, name, cls, override=override)
|
self.registry.add_directive_to_domain(domain, name, cls, override=override)
|
||||||
|
|
||||||
def add_role_to_domain(self, domain, name, role, override=False):
|
def add_role_to_domain(self, domain: str, name: str, role: Union[RoleFunction, XRefRole],
|
||||||
# type: (str, str, Union[RoleFunction, XRefRole], bool) -> None
|
override: bool = False) -> None:
|
||||||
"""Register a Docutils role in a domain.
|
"""Register a Docutils role in a domain.
|
||||||
|
|
||||||
Like :meth:`add_role`, but the role is added to the domain named
|
Like :meth:`add_role`, but the role is added to the domain named
|
||||||
@ -701,8 +708,8 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_role_to_domain(domain, name, role, override=override)
|
self.registry.add_role_to_domain(domain, name, role, override=override)
|
||||||
|
|
||||||
def add_index_to_domain(self, domain, index, override=False):
|
def add_index_to_domain(self, domain: str, index: "Type[Index]", override: bool = False
|
||||||
# type: (str, Type[Index], bool) -> None
|
) -> None:
|
||||||
"""Register a custom index for a domain.
|
"""Register a custom index for a domain.
|
||||||
|
|
||||||
Add a custom *index* class to the domain named *domain*. *index* must
|
Add a custom *index* class to the domain named *domain*. *index* must
|
||||||
@ -714,10 +721,10 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_index_to_domain(domain, index)
|
self.registry.add_index_to_domain(domain, index)
|
||||||
|
|
||||||
def add_object_type(self, directivename, rolename, indextemplate='',
|
def add_object_type(self, directivename: str, rolename: str, indextemplate: str = '',
|
||||||
parse_node=None, ref_nodeclass=None, objname='',
|
parse_node: Callable = None, ref_nodeclass: "Type[TextElement]" = None,
|
||||||
doc_field_types=[], override=False):
|
objname: str = '', doc_field_types: List = [], override: bool = False
|
||||||
# type: (str, str, str, Callable, Type[nodes.TextElement], str, List, bool) -> None
|
) -> None:
|
||||||
"""Register a new object type.
|
"""Register a new object type.
|
||||||
|
|
||||||
This method is a very convenient way to add a new :term:`object` type
|
This method is a very convenient way to add a new :term:`object` type
|
||||||
@ -778,9 +785,9 @@ class Sphinx:
|
|||||||
ref_nodeclass, objname, doc_field_types,
|
ref_nodeclass, objname, doc_field_types,
|
||||||
override=override)
|
override=override)
|
||||||
|
|
||||||
def add_crossref_type(self, directivename, rolename, indextemplate='',
|
def add_crossref_type(self, directivename: str, rolename: str, indextemplate: str = '',
|
||||||
ref_nodeclass=None, objname='', override=False):
|
ref_nodeclass: "Type[TextElement]" = None, objname: str = '',
|
||||||
# type: (str, str, str, Type[nodes.TextElement], str, bool) -> None
|
override: bool = False) -> None:
|
||||||
"""Register a new crossref object type.
|
"""Register a new crossref object type.
|
||||||
|
|
||||||
This method is very similar to :meth:`add_object_type` except that the
|
This method is very similar to :meth:`add_object_type` except that the
|
||||||
@ -814,8 +821,7 @@ class Sphinx:
|
|||||||
indextemplate, ref_nodeclass, objname,
|
indextemplate, ref_nodeclass, objname,
|
||||||
override=override)
|
override=override)
|
||||||
|
|
||||||
def add_transform(self, transform):
|
def add_transform(self, transform: "Type[Transform]") -> None:
|
||||||
# type: (Type[Transform]) -> None
|
|
||||||
"""Register a Docutils transform to be applied after parsing.
|
"""Register a Docutils transform to be applied after parsing.
|
||||||
|
|
||||||
Add the standard docutils :class:`Transform` subclass *transform* to
|
Add the standard docutils :class:`Transform` subclass *transform* to
|
||||||
@ -848,8 +854,7 @@ class Sphinx:
|
|||||||
""" # NOQA
|
""" # NOQA
|
||||||
self.registry.add_transform(transform)
|
self.registry.add_transform(transform)
|
||||||
|
|
||||||
def add_post_transform(self, transform):
|
def add_post_transform(self, transform: "Type[Transform]") -> None:
|
||||||
# type: (Type[Transform]) -> None
|
|
||||||
"""Register a Docutils transform to be applied before writing.
|
"""Register a Docutils transform to be applied before writing.
|
||||||
|
|
||||||
Add the standard docutils :class:`Transform` subclass *transform* to
|
Add the standard docutils :class:`Transform` subclass *transform* to
|
||||||
@ -858,22 +863,22 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_post_transform(transform)
|
self.registry.add_post_transform(transform)
|
||||||
|
|
||||||
def add_javascript(self, filename, **kwargs):
|
def add_javascript(self, filename: str, **kwargs: str) -> None:
|
||||||
# type: (str, **str) -> None
|
|
||||||
"""An alias of :meth:`add_js_file`."""
|
"""An alias of :meth:`add_js_file`."""
|
||||||
warnings.warn('The app.add_javascript() is deprecated. '
|
warnings.warn('The app.add_javascript() is deprecated. '
|
||||||
'Please use app.add_js_file() instead.',
|
'Please use app.add_js_file() instead.',
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
self.add_js_file(filename, **kwargs)
|
self.add_js_file(filename, **kwargs)
|
||||||
|
|
||||||
def add_js_file(self, filename, **kwargs):
|
def add_js_file(self, filename: str, **kwargs: str) -> None:
|
||||||
# type: (str, **str) -> None
|
|
||||||
"""Register a JavaScript file to include in the HTML output.
|
"""Register a JavaScript file to include in the HTML output.
|
||||||
|
|
||||||
Add *filename* to the list of JavaScript files that the default HTML
|
Add *filename* to the list of JavaScript files that the default HTML
|
||||||
template will include. The filename must be relative to the HTML
|
template will include. The filename must be relative to the HTML
|
||||||
static path , or a full URI with scheme. The keyword arguments are
|
static path , or a full URI with scheme. If the keyword argument
|
||||||
also accepted for attributes of ``<script>`` tag.
|
``body`` is given, its value will be added between the
|
||||||
|
``<script>`` tags. Extra keyword arguments are included as
|
||||||
|
attributes of the ``<script>`` tag.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
@ -883,6 +888,9 @@ class Sphinx:
|
|||||||
app.add_js_file('example.js', async="async")
|
app.add_js_file('example.js', async="async")
|
||||||
# => <script src="_static/example.js" async="async"></script>
|
# => <script src="_static/example.js" async="async"></script>
|
||||||
|
|
||||||
|
app.add_js_file(None, body="var myVariable = 'foo';")
|
||||||
|
# => <script>var myVariable = 'foo';</script>
|
||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
|
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
@ -893,8 +901,7 @@ class Sphinx:
|
|||||||
if hasattr(self.builder, 'add_js_file'):
|
if hasattr(self.builder, 'add_js_file'):
|
||||||
self.builder.add_js_file(filename, **kwargs) # type: ignore
|
self.builder.add_js_file(filename, **kwargs) # type: ignore
|
||||||
|
|
||||||
def add_css_file(self, filename, **kwargs):
|
def add_css_file(self, filename: str, **kwargs: str) -> None:
|
||||||
# type: (str, **str) -> None
|
|
||||||
"""Register a stylesheet to include in the HTML output.
|
"""Register a stylesheet to include in the HTML output.
|
||||||
|
|
||||||
Add *filename* to the list of CSS files that the default HTML template
|
Add *filename* to the list of CSS files that the default HTML template
|
||||||
@ -933,8 +940,8 @@ class Sphinx:
|
|||||||
if hasattr(self.builder, 'add_css_file'):
|
if hasattr(self.builder, 'add_css_file'):
|
||||||
self.builder.add_css_file(filename, **kwargs) # type: ignore
|
self.builder.add_css_file(filename, **kwargs) # type: ignore
|
||||||
|
|
||||||
def add_stylesheet(self, filename, alternate=False, title=None):
|
def add_stylesheet(self, filename: str, alternate: bool = False, title: str = None
|
||||||
# type: (str, bool, str) -> None
|
) -> None:
|
||||||
"""An alias of :meth:`add_css_file`."""
|
"""An alias of :meth:`add_css_file`."""
|
||||||
warnings.warn('The app.add_stylesheet() is deprecated. '
|
warnings.warn('The app.add_stylesheet() is deprecated. '
|
||||||
'Please use app.add_css_file() instead.',
|
'Please use app.add_css_file() instead.',
|
||||||
@ -951,8 +958,7 @@ class Sphinx:
|
|||||||
|
|
||||||
self.add_css_file(filename, **attributes)
|
self.add_css_file(filename, **attributes)
|
||||||
|
|
||||||
def add_latex_package(self, packagename, options=None):
|
def add_latex_package(self, packagename: str, options: str = None) -> None:
|
||||||
# type: (str, str) -> None
|
|
||||||
r"""Register a package to include in the LaTeX source code.
|
r"""Register a package to include in the LaTeX source code.
|
||||||
|
|
||||||
Add *packagename* to the list of packages that LaTeX source code will
|
Add *packagename* to the list of packages that LaTeX source code will
|
||||||
@ -970,8 +976,7 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_latex_package(packagename, options)
|
self.registry.add_latex_package(packagename, options)
|
||||||
|
|
||||||
def add_lexer(self, alias, lexer):
|
def add_lexer(self, alias: str, lexer: Union[Lexer, "Type[Lexer]"]) -> None:
|
||||||
# type: (str, Union[Lexer, Type[Lexer]]) -> None
|
|
||||||
"""Register a new lexer for source code.
|
"""Register a new lexer for source code.
|
||||||
|
|
||||||
Use *lexer* to highlight code blocks with the given language *alias*.
|
Use *lexer* to highlight code blocks with the given language *alias*.
|
||||||
@ -990,8 +995,7 @@ class Sphinx:
|
|||||||
else:
|
else:
|
||||||
lexer_classes[alias] = lexer
|
lexer_classes[alias] = lexer
|
||||||
|
|
||||||
def add_autodocumenter(self, cls, override=False):
|
def add_autodocumenter(self, cls: Any, override: bool = False) -> None:
|
||||||
# type: (Any, bool) -> None
|
|
||||||
"""Register a new documenter class for the autodoc extension.
|
"""Register a new documenter class for the autodoc extension.
|
||||||
|
|
||||||
Add *cls* as a new documenter class for the :mod:`sphinx.ext.autodoc`
|
Add *cls* as a new documenter class for the :mod:`sphinx.ext.autodoc`
|
||||||
@ -1011,8 +1015,8 @@ class Sphinx:
|
|||||||
self.registry.add_documenter(cls.objtype, cls)
|
self.registry.add_documenter(cls.objtype, cls)
|
||||||
self.add_directive('auto' + cls.objtype, AutodocDirective, override=override)
|
self.add_directive('auto' + cls.objtype, AutodocDirective, override=override)
|
||||||
|
|
||||||
def add_autodoc_attrgetter(self, typ, getter):
|
def add_autodoc_attrgetter(self, typ: "Type", getter: Callable[[Any, str, Any], Any]
|
||||||
# type: (Type, Callable[[Any, str, Any], Any]) -> None
|
) -> None:
|
||||||
"""Register a new ``getattr``-like function for the autodoc extension.
|
"""Register a new ``getattr``-like function for the autodoc extension.
|
||||||
|
|
||||||
Add *getter*, which must be a function with an interface compatible to
|
Add *getter*, which must be a function with an interface compatible to
|
||||||
@ -1026,8 +1030,7 @@ class Sphinx:
|
|||||||
logger.debug('[app] adding autodoc attrgetter: %r', (typ, getter))
|
logger.debug('[app] adding autodoc attrgetter: %r', (typ, getter))
|
||||||
self.registry.add_autodoc_attrgetter(typ, getter)
|
self.registry.add_autodoc_attrgetter(typ, getter)
|
||||||
|
|
||||||
def add_search_language(self, cls):
|
def add_search_language(self, cls: Any) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
"""Register a new language for the HTML search index.
|
"""Register a new language for the HTML search index.
|
||||||
|
|
||||||
Add *cls*, which must be a subclass of
|
Add *cls*, which must be a subclass of
|
||||||
@ -1043,8 +1046,7 @@ class Sphinx:
|
|||||||
assert issubclass(cls, SearchLanguage)
|
assert issubclass(cls, SearchLanguage)
|
||||||
languages[cls.lang] = cls
|
languages[cls.lang] = cls
|
||||||
|
|
||||||
def add_source_suffix(self, suffix, filetype, override=False):
|
def add_source_suffix(self, suffix: str, filetype: str, override: bool = False) -> None:
|
||||||
# type: (str, str, bool) -> None
|
|
||||||
"""Register a suffix of source files.
|
"""Register a suffix of source files.
|
||||||
|
|
||||||
Same as :confval:`source_suffix`. The users can override this
|
Same as :confval:`source_suffix`. The users can override this
|
||||||
@ -1054,8 +1056,7 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_source_suffix(suffix, filetype, override=override)
|
self.registry.add_source_suffix(suffix, filetype, override=override)
|
||||||
|
|
||||||
def add_source_parser(self, *args, **kwargs):
|
def add_source_parser(self, *args: Any, **kwargs: Any) -> None:
|
||||||
# type: (Any, Any) -> None
|
|
||||||
"""Register a parser class.
|
"""Register a parser class.
|
||||||
|
|
||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
@ -1067,8 +1068,7 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_source_parser(*args, **kwargs)
|
self.registry.add_source_parser(*args, **kwargs)
|
||||||
|
|
||||||
def add_env_collector(self, collector):
|
def add_env_collector(self, collector: "Type[EnvironmentCollector]") -> None:
|
||||||
# type: (Type[EnvironmentCollector]) -> None
|
|
||||||
"""Register an environment collector class.
|
"""Register an environment collector class.
|
||||||
|
|
||||||
Refer to :ref:`collector-api`.
|
Refer to :ref:`collector-api`.
|
||||||
@ -1078,8 +1078,7 @@ class Sphinx:
|
|||||||
logger.debug('[app] adding environment collector: %r', collector)
|
logger.debug('[app] adding environment collector: %r', collector)
|
||||||
collector().enable(self)
|
collector().enable(self)
|
||||||
|
|
||||||
def add_html_theme(self, name, theme_path):
|
def add_html_theme(self, name: str, theme_path: str) -> None:
|
||||||
# type: (str, str) -> None
|
|
||||||
"""Register a HTML Theme.
|
"""Register a HTML Theme.
|
||||||
|
|
||||||
The *name* is a name of theme, and *path* is a full path to the theme
|
The *name* is a name of theme, and *path* is a full path to the theme
|
||||||
@ -1090,8 +1089,9 @@ class Sphinx:
|
|||||||
logger.debug('[app] adding HTML theme: %r, %r', name, theme_path)
|
logger.debug('[app] adding HTML theme: %r, %r', name, theme_path)
|
||||||
self.html_themes[name] = theme_path
|
self.html_themes[name] = theme_path
|
||||||
|
|
||||||
def add_html_math_renderer(self, name, inline_renderers=None, block_renderers=None):
|
def add_html_math_renderer(self, name: str,
|
||||||
# type: (str, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
|
inline_renderers: Tuple[Callable, Callable] = None,
|
||||||
|
block_renderers: Tuple[Callable, Callable] = None) -> None:
|
||||||
"""Register a math renderer for HTML.
|
"""Register a math renderer for HTML.
|
||||||
|
|
||||||
The *name* is a name of math renderer. Both *inline_renderers* and
|
The *name* is a name of math renderer. Both *inline_renderers* and
|
||||||
@ -1105,8 +1105,7 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_html_math_renderer(name, inline_renderers, block_renderers)
|
self.registry.add_html_math_renderer(name, inline_renderers, block_renderers)
|
||||||
|
|
||||||
def add_message_catalog(self, catalog, locale_dir):
|
def add_message_catalog(self, catalog: str, locale_dir: str) -> None:
|
||||||
# type: (str, str) -> None
|
|
||||||
"""Register a message catalog.
|
"""Register a message catalog.
|
||||||
|
|
||||||
The *catalog* is a name of catalog, and *locale_dir* is a base path
|
The *catalog* is a name of catalog, and *locale_dir* is a base path
|
||||||
@ -1119,34 +1118,37 @@ class Sphinx:
|
|||||||
locale.init_console(locale_dir, catalog)
|
locale.init_console(locale_dir, catalog)
|
||||||
|
|
||||||
# ---- other methods -------------------------------------------------
|
# ---- other methods -------------------------------------------------
|
||||||
def is_parallel_allowed(self, typ):
|
def is_parallel_allowed(self, typ: str) -> bool:
|
||||||
# type: (str) -> bool
|
|
||||||
"""Check parallel processing is allowed or not.
|
"""Check parallel processing is allowed or not.
|
||||||
|
|
||||||
``typ`` is a type of processing; ``'read'`` or ``'write'``.
|
``typ`` is a type of processing; ``'read'`` or ``'write'``.
|
||||||
"""
|
"""
|
||||||
if typ == 'read':
|
if typ == 'read':
|
||||||
attrname = 'parallel_read_safe'
|
attrname = 'parallel_read_safe'
|
||||||
message = __("the %s extension does not declare if it is safe "
|
message_not_declared = __("the %s extension does not declare if it "
|
||||||
"for parallel reading, assuming it isn't - please "
|
"is safe for parallel reading, assuming "
|
||||||
"ask the extension author to check and make it "
|
"it isn't - please ask the extension author "
|
||||||
"explicit")
|
"to check and make it explicit")
|
||||||
|
message_not_safe = __("the %s extension is not safe for parallel reading")
|
||||||
elif typ == 'write':
|
elif typ == 'write':
|
||||||
attrname = 'parallel_write_safe'
|
attrname = 'parallel_write_safe'
|
||||||
message = __("the %s extension does not declare if it is safe "
|
message_not_declared = __("the %s extension does not declare if it "
|
||||||
"for parallel writing, assuming it isn't - please "
|
"is safe for parallel writing, assuming "
|
||||||
"ask the extension author to check and make it "
|
"it isn't - please ask the extension author "
|
||||||
"explicit")
|
"to check and make it explicit")
|
||||||
|
message_not_safe = __("the %s extension is not safe for parallel writing")
|
||||||
else:
|
else:
|
||||||
raise ValueError('parallel type %s is not supported' % typ)
|
raise ValueError('parallel type %s is not supported' % typ)
|
||||||
|
|
||||||
for ext in self.extensions.values():
|
for ext in self.extensions.values():
|
||||||
allowed = getattr(ext, attrname, None)
|
allowed = getattr(ext, attrname, None)
|
||||||
if allowed is None:
|
if allowed is None:
|
||||||
logger.warning(message, ext.name)
|
logger.warning(message_not_declared, ext.name)
|
||||||
logger.warning(__('doing serial %s'), typ)
|
logger.warning(__('doing serial %s'), typ)
|
||||||
return False
|
return False
|
||||||
elif not allowed:
|
elif not allowed:
|
||||||
|
logger.warning(message_not_safe, ext.name)
|
||||||
|
logger.warning(__('doing serial %s'), typ)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@ -1158,8 +1160,7 @@ class TemplateBridge:
|
|||||||
that renders templates given a template name and a context.
|
that renders templates given a template name and a context.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def init(self, builder, theme=None, dirs=None):
|
def init(self, builder: "Builder", theme: Theme = None, dirs: List[str] = None) -> None:
|
||||||
# type: (Builder, Theme, List[str]) -> None
|
|
||||||
"""Called by the builder to initialize the template system.
|
"""Called by the builder to initialize the template system.
|
||||||
|
|
||||||
*builder* is the builder object; you'll probably want to look at the
|
*builder* is the builder object; you'll probably want to look at the
|
||||||
@ -1170,23 +1171,20 @@ class TemplateBridge:
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError('must be implemented in subclasses')
|
raise NotImplementedError('must be implemented in subclasses')
|
||||||
|
|
||||||
def newest_template_mtime(self):
|
def newest_template_mtime(self) -> float:
|
||||||
# type: () -> float
|
|
||||||
"""Called by the builder to determine if output files are outdated
|
"""Called by the builder to determine if output files are outdated
|
||||||
because of template changes. Return the mtime of the newest template
|
because of template changes. Return the mtime of the newest template
|
||||||
file that was changed. The default implementation returns ``0``.
|
file that was changed. The default implementation returns ``0``.
|
||||||
"""
|
"""
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def render(self, template, context):
|
def render(self, template: str, context: Dict) -> None:
|
||||||
# type: (str, Dict) -> None
|
|
||||||
"""Called by the builder to render a template given as a filename with
|
"""Called by the builder to render a template given as a filename with
|
||||||
a specified context (a Python dictionary).
|
a specified context (a Python dictionary).
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('must be implemented in subclasses')
|
raise NotImplementedError('must be implemented in subclasses')
|
||||||
|
|
||||||
def render_string(self, template, context):
|
def render_string(self, template: str, context: Dict) -> str:
|
||||||
# type: (str, Dict) -> str
|
|
||||||
"""Called by the builder to render a template given as a string with a
|
"""Called by the builder to render a template given as a string with a
|
||||||
specified context (a Python dictionary).
|
specified context (a Python dictionary).
|
||||||
"""
|
"""
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
Builder superclass for all builders.
|
Builder superclass for all builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pickle
|
import pickle
|
||||||
import time
|
import time
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, Iterable, List, Sequence, Set, Tuple, Type, Union
|
from typing import Any, Dict, Iterable, List, Sequence, Set, Tuple, Union
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Node
|
from docutils.nodes import Node
|
||||||
@ -44,6 +44,7 @@ except ImportError:
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
|
from typing import Type # for python3.5.1
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
|
|
||||||
|
|
||||||
@ -117,11 +118,11 @@ class Builder:
|
|||||||
self.env.set_versioning_method(self.versioning_method,
|
self.env.set_versioning_method(self.versioning_method,
|
||||||
self.versioning_compare)
|
self.versioning_compare)
|
||||||
|
|
||||||
def get_translator_class(self, *args) -> Type[nodes.NodeVisitor]:
|
def get_translator_class(self, *args: Any) -> "Type[nodes.NodeVisitor]":
|
||||||
"""Return a class of translator."""
|
"""Return a class of translator."""
|
||||||
return self.app.registry.get_translator_class(self)
|
return self.app.registry.get_translator_class(self)
|
||||||
|
|
||||||
def create_translator(self, *args) -> nodes.NodeVisitor:
|
def create_translator(self, *args: Any) -> nodes.NodeVisitor:
|
||||||
"""Return an instance of translator.
|
"""Return an instance of translator.
|
||||||
|
|
||||||
This method returns an instance of ``default_translator_class`` by default.
|
This method returns an instance of ``default_translator_class`` by default.
|
||||||
@ -303,7 +304,7 @@ class Builder:
|
|||||||
First updates the environment, and then calls :meth:`write`.
|
First updates the environment, and then calls :meth:`write`.
|
||||||
"""
|
"""
|
||||||
if summary:
|
if summary:
|
||||||
logger.info(bold(__('building [%s]') % self.name) + ': ' + summary)
|
logger.info(bold(__('building [%s]: ') % self.name) + summary)
|
||||||
|
|
||||||
# while reading, collect all warnings from docutils
|
# while reading, collect all warnings from docutils
|
||||||
with logging.pending_warnings():
|
with logging.pending_warnings():
|
||||||
@ -378,7 +379,7 @@ class Builder:
|
|||||||
added, changed, removed = self.env.get_outdated_files(updated)
|
added, changed, removed = self.env.get_outdated_files(updated)
|
||||||
|
|
||||||
# allow user intervention as well
|
# allow user intervention as well
|
||||||
for docs in self.events.emit('env-get-outdated', self, added, changed, removed):
|
for docs in self.events.emit('env-get-outdated', self.env, added, changed, removed):
|
||||||
changed.update(set(docs) & self.env.found_docs)
|
changed.update(set(docs) & self.env.found_docs)
|
||||||
|
|
||||||
# if files were added or removed, all documents with globbed toctrees
|
# if files were added or removed, all documents with globbed toctrees
|
||||||
@ -387,9 +388,11 @@ class Builder:
|
|||||||
# ... but not those that already were removed
|
# ... but not those that already were removed
|
||||||
changed.update(self.env.glob_toctrees & self.env.found_docs)
|
changed.update(self.env.glob_toctrees & self.env.found_docs)
|
||||||
|
|
||||||
if changed:
|
if updated: # explain the change iff build config status was not ok
|
||||||
reason = CONFIG_CHANGED_REASON.get(self.env.config_status, '')
|
reason = (CONFIG_CHANGED_REASON.get(self.env.config_status, '') +
|
||||||
|
(self.env.config_status_extra or ''))
|
||||||
logger.info('[%s] ', reason, nonl=True)
|
logger.info('[%s] ', reason, nonl=True)
|
||||||
|
|
||||||
logger.info(__('%s added, %s changed, %s removed'),
|
logger.info(__('%s added, %s changed, %s removed'),
|
||||||
len(added), len(changed), len(removed))
|
len(added), len(changed), len(removed))
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Base class of epub2/epub3 builders.
|
Base class of epub2/epub3 builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -259,6 +259,15 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
Some readers crash because they interpret the part as a
|
Some readers crash because they interpret the part as a
|
||||||
transport protocol specification.
|
transport protocol specification.
|
||||||
"""
|
"""
|
||||||
|
def update_node_id(node: Element) -> None:
|
||||||
|
"""Update IDs of given *node*."""
|
||||||
|
new_ids = []
|
||||||
|
for node_id in node['ids']:
|
||||||
|
new_id = self.fix_fragment('', node_id)
|
||||||
|
if new_id not in new_ids:
|
||||||
|
new_ids.append(new_id)
|
||||||
|
node['ids'] = new_ids
|
||||||
|
|
||||||
for reference in tree.traverse(nodes.reference):
|
for reference in tree.traverse(nodes.reference):
|
||||||
if 'refuri' in reference:
|
if 'refuri' in reference:
|
||||||
m = self.refuri_re.match(reference['refuri'])
|
m = self.refuri_re.match(reference['refuri'])
|
||||||
@ -268,22 +277,14 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
reference['refid'] = self.fix_fragment('', reference['refid'])
|
reference['refid'] = self.fix_fragment('', reference['refid'])
|
||||||
|
|
||||||
for target in tree.traverse(nodes.target):
|
for target in tree.traverse(nodes.target):
|
||||||
for i, node_id in enumerate(target['ids']):
|
update_node_id(target)
|
||||||
if ':' in node_id:
|
|
||||||
target['ids'][i] = self.fix_fragment('', node_id)
|
|
||||||
|
|
||||||
next_node = target.next_node(siblings=True) # type: Node
|
next_node = target.next_node(ascend=True) # type: Node
|
||||||
if isinstance(next_node, nodes.Element):
|
if isinstance(next_node, nodes.Element):
|
||||||
for i, node_id in enumerate(next_node['ids']):
|
update_node_id(next_node)
|
||||||
if ':' in node_id:
|
|
||||||
next_node['ids'][i] = self.fix_fragment('', node_id)
|
|
||||||
|
|
||||||
for desc_signature in tree.traverse(addnodes.desc_signature):
|
for desc_signature in tree.traverse(addnodes.desc_signature):
|
||||||
ids = desc_signature.attributes['ids']
|
update_node_id(desc_signature)
|
||||||
newids = []
|
|
||||||
for id in ids:
|
|
||||||
newids.append(self.fix_fragment('', id))
|
|
||||||
desc_signature.attributes['ids'] = newids
|
|
||||||
|
|
||||||
def add_visible_links(self, tree: nodes.document, show_urls: str = 'inline') -> None:
|
def add_visible_links(self, tree: nodes.document, show_urls: str = 'inline') -> None:
|
||||||
"""Add visible link targets for external links"""
|
"""Add visible link targets for external links"""
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Build Apple help books.
|
Build Apple help books.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Changelog builder.
|
Changelog builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ class ChangesBuilder(Builder):
|
|||||||
'deprecated': 'deprecated',
|
'deprecated': 'deprecated',
|
||||||
}
|
}
|
||||||
|
|
||||||
def write(self, *ignored) -> None:
|
def write(self, *ignored: Any) -> None:
|
||||||
version = self.config.version
|
version = self.config.version
|
||||||
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
|
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
|
||||||
libchanges = {} # type: Dict[str, List[Tuple[str, str, int]]]
|
libchanges = {} # type: Dict[str, List[Tuple[str, str, int]]]
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
.. _Devhelp: https://wiki.gnome.org/Apps/Devhelp
|
.. _Devhelp: https://wiki.gnome.org/Apps/Devhelp
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
Directory HTML builders.
|
Directory HTML builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, Set
|
from typing import Any, Dict
|
||||||
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
@ -45,10 +45,6 @@ class DirectoryHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
return outfilename
|
return outfilename
|
||||||
|
|
||||||
def prepare_writing(self, docnames: Set[str]) -> None:
|
|
||||||
super().prepare_writing(docnames)
|
|
||||||
self.globalcontext['no_search_suffix'] = True
|
|
||||||
|
|
||||||
|
|
||||||
# for compatibility
|
# for compatibility
|
||||||
deprecated_alias('sphinx.builders.html',
|
deprecated_alias('sphinx.builders.html',
|
||||||
|
@ -282,7 +282,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
ENUM('horizontal', 'vertical'))
|
ENUM('horizontal', 'vertical'))
|
||||||
|
|
||||||
# event handlers
|
# event handlers
|
||||||
app.connect('config-inited', convert_epub_css_files)
|
app.connect('config-inited', convert_epub_css_files, priority=800)
|
||||||
app.connect('builder-inited', validate_config_values)
|
app.connect('builder-inited', validate_config_values)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -4,23 +4,23 @@
|
|||||||
|
|
||||||
The MessageCatalogBuilder class.
|
The MessageCatalogBuilder class.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from codecs import open
|
from codecs import open
|
||||||
from collections import defaultdict, OrderedDict
|
from collections import defaultdict, OrderedDict
|
||||||
from datetime import datetime, tzinfo, timedelta
|
from datetime import datetime, tzinfo, timedelta
|
||||||
from io import StringIO
|
|
||||||
from os import path, walk, getenv
|
from os import path, walk, getenv
|
||||||
from time import time
|
from time import time
|
||||||
from typing import Any, DefaultDict, Dict, Iterable, List, Set, Tuple, Union
|
from typing import Any, Dict, Iterable, Generator, List, Set, Tuple, Union
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Element
|
from docutils.nodes import Element
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx import package_dir
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.domains.python import pairindextypes
|
from sphinx.domains.python import pairindextypes
|
||||||
@ -30,9 +30,13 @@ from sphinx.util import split_index_msg, logging, status_iterator
|
|||||||
from sphinx.util.console import bold # type: ignore
|
from sphinx.util.console import bold # type: ignore
|
||||||
from sphinx.util.i18n import CatalogInfo, docname_to_domain
|
from sphinx.util.i18n import CatalogInfo, docname_to_domain
|
||||||
from sphinx.util.nodes import extract_messages, traverse_translatable_index
|
from sphinx.util.nodes import extract_messages, traverse_translatable_index
|
||||||
from sphinx.util.osutil import relpath, ensuredir, canon_path
|
from sphinx.util.osutil import ensuredir, canon_path, relpath
|
||||||
from sphinx.util.tags import Tags
|
from sphinx.util.tags import Tags
|
||||||
|
from sphinx.util.template import SphinxRenderer
|
||||||
|
|
||||||
|
if False:
|
||||||
|
# For type annotation
|
||||||
|
from typing import DefaultDict # for python3.5.1
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -55,7 +59,15 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
"""[1:]
|
"""[1:] # RemovedInSphinx40Warning
|
||||||
|
|
||||||
|
|
||||||
|
class Message:
|
||||||
|
"""An entry of translatable message."""
|
||||||
|
def __init__(self, text: str, locations: List[Tuple[str, int]], uuids: List[str]):
|
||||||
|
self.text = text
|
||||||
|
self.locations = locations
|
||||||
|
self.uuids = uuids
|
||||||
|
|
||||||
|
|
||||||
class Catalog:
|
class Catalog:
|
||||||
@ -77,6 +89,12 @@ class Catalog:
|
|||||||
self.metadata[msg] = []
|
self.metadata[msg] = []
|
||||||
self.metadata[msg].append((origin.source, origin.line, origin.uid)) # type: ignore
|
self.metadata[msg].append((origin.source, origin.line, origin.uid)) # type: ignore
|
||||||
|
|
||||||
|
def __iter__(self) -> Generator[Message, None, None]:
|
||||||
|
for message in self.messages:
|
||||||
|
positions = [(source, line) for source, line, uuid in self.metadata[message]]
|
||||||
|
uuids = [uuid for source, line, uuid in self.metadata[message]]
|
||||||
|
yield Message(message, positions, uuids)
|
||||||
|
|
||||||
|
|
||||||
class MsgOrigin:
|
class MsgOrigin:
|
||||||
"""
|
"""
|
||||||
@ -89,6 +107,30 @@ class MsgOrigin:
|
|||||||
self.uid = uuid4().hex
|
self.uid = uuid4().hex
|
||||||
|
|
||||||
|
|
||||||
|
class GettextRenderer(SphinxRenderer):
|
||||||
|
def __init__(self, template_path: str = None, outdir: str = None) -> None:
|
||||||
|
self.outdir = outdir
|
||||||
|
if template_path is None:
|
||||||
|
template_path = path.join(package_dir, 'templates', 'gettext')
|
||||||
|
super().__init__(template_path)
|
||||||
|
|
||||||
|
def escape(s: str) -> str:
|
||||||
|
s = s.replace('\\', r'\\')
|
||||||
|
s = s.replace('"', r'\"')
|
||||||
|
return s.replace('\n', '\\n"\n"')
|
||||||
|
|
||||||
|
# use texescape as escape filter
|
||||||
|
self.env.filters['e'] = escape
|
||||||
|
self.env.filters['escape'] = escape
|
||||||
|
|
||||||
|
def render(self, filename: str, context: Dict) -> str:
|
||||||
|
def _relpath(s: str) -> str:
|
||||||
|
return canon_path(relpath(s, self.outdir))
|
||||||
|
|
||||||
|
context['relpath'] = _relpath
|
||||||
|
return super().render(filename, context)
|
||||||
|
|
||||||
|
|
||||||
class I18nTags(Tags):
|
class I18nTags(Tags):
|
||||||
"""Dummy tags module for I18nBuilder.
|
"""Dummy tags module for I18nBuilder.
|
||||||
|
|
||||||
@ -164,8 +206,8 @@ if source_date_epoch is not None:
|
|||||||
|
|
||||||
|
|
||||||
class LocalTimeZone(tzinfo):
|
class LocalTimeZone(tzinfo):
|
||||||
def __init__(self, *args, **kw) -> None:
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||||
super().__init__(*args, **kw) # type: ignore
|
super().__init__(*args, **kwargs) # type: ignore
|
||||||
self.tzdelta = tzdelta
|
self.tzdelta = tzdelta
|
||||||
|
|
||||||
def utcoffset(self, dt: datetime) -> timedelta:
|
def utcoffset(self, dt: datetime) -> timedelta:
|
||||||
@ -178,7 +220,7 @@ class LocalTimeZone(tzinfo):
|
|||||||
ltz = LocalTimeZone()
|
ltz = LocalTimeZone()
|
||||||
|
|
||||||
|
|
||||||
def should_write(filepath: str, new_content: str):
|
def should_write(filepath: str, new_content: str) -> bool:
|
||||||
if not path.exists(filepath):
|
if not path.exists(filepath):
|
||||||
return True
|
return True
|
||||||
try:
|
try:
|
||||||
@ -244,12 +286,15 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
|
|
||||||
def finish(self) -> None:
|
def finish(self) -> None:
|
||||||
super().finish()
|
super().finish()
|
||||||
data = {
|
context = {
|
||||||
'version': self.config.version,
|
'version': self.config.version,
|
||||||
'copyright': self.config.copyright,
|
'copyright': self.config.copyright,
|
||||||
'project': self.config.project,
|
'project': self.config.project,
|
||||||
'ctime': datetime.fromtimestamp(
|
'last_translator': self.config.gettext_last_translator,
|
||||||
timestamp, ltz).strftime('%Y-%m-%d %H:%M%z'),
|
'language_team': self.config.gettext_language_team,
|
||||||
|
'ctime': datetime.fromtimestamp(timestamp, ltz).strftime('%Y-%m-%d %H:%M%z'),
|
||||||
|
'display_location': self.config.gettext_location,
|
||||||
|
'display_uuid': self.config.gettext_uuid,
|
||||||
}
|
}
|
||||||
for textdomain, catalog in status_iterator(self.catalogs.items(),
|
for textdomain, catalog in status_iterator(self.catalogs.items(),
|
||||||
__("writing message catalogs... "),
|
__("writing message catalogs... "),
|
||||||
@ -259,30 +304,10 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
# noop if config.gettext_compact is set
|
# noop if config.gettext_compact is set
|
||||||
ensuredir(path.join(self.outdir, path.dirname(textdomain)))
|
ensuredir(path.join(self.outdir, path.dirname(textdomain)))
|
||||||
|
|
||||||
|
context['messages'] = list(catalog)
|
||||||
|
content = GettextRenderer(outdir=self.outdir).render('message.pot_t', context)
|
||||||
|
|
||||||
pofn = path.join(self.outdir, textdomain + '.pot')
|
pofn = path.join(self.outdir, textdomain + '.pot')
|
||||||
output = StringIO()
|
|
||||||
output.write(POHEADER % data)
|
|
||||||
|
|
||||||
for message in catalog.messages:
|
|
||||||
positions = catalog.metadata[message]
|
|
||||||
|
|
||||||
if self.config.gettext_location:
|
|
||||||
# generate "#: file1:line1\n#: file2:line2 ..."
|
|
||||||
output.write("#: %s\n" % "\n#: ".join(
|
|
||||||
"%s:%s" % (canon_path(relpath(source, self.outdir)), line)
|
|
||||||
for source, line, _ in positions))
|
|
||||||
if self.config.gettext_uuid:
|
|
||||||
# generate "# uuid1\n# uuid2\n ..."
|
|
||||||
output.write("# %s\n" % "\n# ".join(uid for _, _, uid in positions))
|
|
||||||
|
|
||||||
# message contains *one* line of text ready for translation
|
|
||||||
message = message.replace('\\', r'\\'). \
|
|
||||||
replace('"', r'\"'). \
|
|
||||||
replace('\n', '\\n"\n"')
|
|
||||||
output.write('msgid "%s"\nmsgstr ""\n\n' % message)
|
|
||||||
|
|
||||||
content = output.getvalue()
|
|
||||||
|
|
||||||
if should_write(pofn, content):
|
if should_write(pofn, content):
|
||||||
with open(pofn, 'w', encoding='utf-8') as pofile:
|
with open(pofn, 'w', encoding='utf-8') as pofile:
|
||||||
pofile.write(content)
|
pofile.write(content)
|
||||||
@ -296,6 +321,8 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_config_value('gettext_uuid', False, 'gettext')
|
app.add_config_value('gettext_uuid', False, 'gettext')
|
||||||
app.add_config_value('gettext_auto_build', True, 'env')
|
app.add_config_value('gettext_auto_build', True, 'env')
|
||||||
app.add_config_value('gettext_additional_targets', [], 'env')
|
app.add_config_value('gettext_additional_targets', [], 'env')
|
||||||
|
app.add_config_value('gettext_last_translator', 'FULL NAME <EMAIL@ADDRESS>', 'gettext')
|
||||||
|
app.add_config_value('gettext_language_team', 'LANGUAGE <LL@li.org>', 'gettext')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Several HTML builders.
|
Several HTML builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ import sys
|
|||||||
import warnings
|
import warnings
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, IO, Iterable, Iterator, List, Set, Type, Tuple
|
from typing import Any, Dict, IO, Iterable, Iterator, List, Set, Tuple
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.core import publish_parts
|
from docutils.core import publish_parts
|
||||||
@ -48,6 +48,11 @@ from sphinx.util.osutil import os_path, relative_uri, ensuredir, movefile, copyf
|
|||||||
from sphinx.util.tags import Tags
|
from sphinx.util.tags import Tags
|
||||||
from sphinx.writers.html import HTMLWriter, HTMLTranslator
|
from sphinx.writers.html import HTMLWriter, HTMLTranslator
|
||||||
|
|
||||||
|
if False:
|
||||||
|
# For type annotation
|
||||||
|
from typing import Type # for python3.5.1
|
||||||
|
|
||||||
|
|
||||||
# HTML5 Writer is available or not
|
# HTML5 Writer is available or not
|
||||||
if is_html5_writer_available():
|
if is_html5_writer_available():
|
||||||
from sphinx.writers.html5 import HTML5Translator
|
from sphinx.writers.html5 import HTML5Translator
|
||||||
@ -85,7 +90,7 @@ class Stylesheet(str):
|
|||||||
attributes = None # type: Dict[str, str]
|
attributes = None # type: Dict[str, str]
|
||||||
filename = None # type: str
|
filename = None # type: str
|
||||||
|
|
||||||
def __new__(cls, filename: str, *args: str, **attributes: str) -> None:
|
def __new__(cls, filename: str, *args: str, **attributes: str) -> "Stylesheet":
|
||||||
self = str.__new__(cls, filename) # type: ignore
|
self = str.__new__(cls, filename) # type: ignore
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.attributes = attributes
|
self.attributes = attributes
|
||||||
@ -108,11 +113,10 @@ class JavaScript(str):
|
|||||||
attributes = None # type: Dict[str, str]
|
attributes = None # type: Dict[str, str]
|
||||||
filename = None # type: str
|
filename = None # type: str
|
||||||
|
|
||||||
def __new__(cls, filename: str, **attributes: str) -> None:
|
def __new__(cls, filename: str, **attributes: str) -> "JavaScript":
|
||||||
self = str.__new__(cls, filename) # type: ignore
|
self = str.__new__(cls, filename) # type: ignore
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.attributes = attributes
|
self.attributes = attributes
|
||||||
self.attributes.setdefault('type', 'text/javascript')
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@ -267,6 +271,19 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
style = 'sphinx'
|
style = 'sphinx'
|
||||||
self.highlighter = PygmentsBridge('html', style)
|
self.highlighter = PygmentsBridge('html', style)
|
||||||
|
|
||||||
|
if self.theme:
|
||||||
|
dark_style = self.theme.get_config('theme', 'pygments_dark_style', None)
|
||||||
|
else:
|
||||||
|
dark_style = None
|
||||||
|
|
||||||
|
if dark_style is not None:
|
||||||
|
self.dark_highlighter = PygmentsBridge('html', dark_style)
|
||||||
|
self.add_css_file('pygments_dark.css',
|
||||||
|
media='(prefers-color-scheme: dark)',
|
||||||
|
id='pygments_dark_css')
|
||||||
|
else:
|
||||||
|
self.dark_highlighter = None
|
||||||
|
|
||||||
def init_css_files(self) -> None:
|
def init_css_files(self) -> None:
|
||||||
for filename, attrs in self.app.registry.css_files:
|
for filename, attrs in self.app.registry.css_files:
|
||||||
self.add_css_file(filename, **attrs)
|
self.add_css_file(filename, **attrs)
|
||||||
@ -302,7 +319,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
self.script_files.append(JavaScript(filename, **kwargs))
|
self.script_files.append(JavaScript(filename, **kwargs))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def default_translator_class(self) -> Type[nodes.NodeVisitor]: # type: ignore
|
def default_translator_class(self) -> "Type[nodes.NodeVisitor]": # type: ignore
|
||||||
if not html5_ready or self.config.html4_writer:
|
if not html5_ready or self.config.html4_writer:
|
||||||
return HTMLTranslator
|
return HTMLTranslator
|
||||||
else:
|
else:
|
||||||
@ -428,11 +445,8 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
else:
|
else:
|
||||||
self.last_updated = None
|
self.last_updated = None
|
||||||
|
|
||||||
logo = self.config.html_logo and \
|
logo = path.basename(self.config.html_logo) if self.config.html_logo else ''
|
||||||
path.basename(self.config.html_logo) or ''
|
favicon = path.basename(self.config.html_favicon) if self.config.html_favicon else ''
|
||||||
|
|
||||||
favicon = self.config.html_favicon and \
|
|
||||||
path.basename(self.config.html_favicon) or ''
|
|
||||||
|
|
||||||
if not isinstance(self.config.html_use_opensearch, str):
|
if not isinstance(self.config.html_use_opensearch, str):
|
||||||
logger.warning(__('html_use_opensearch config value must now be a string'))
|
logger.warning(__('html_use_opensearch config value must now be a string'))
|
||||||
@ -472,6 +486,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
'show_source': self.config.html_show_sourcelink,
|
'show_source': self.config.html_show_sourcelink,
|
||||||
'sourcelink_suffix': self.config.html_sourcelink_suffix,
|
'sourcelink_suffix': self.config.html_sourcelink_suffix,
|
||||||
'file_suffix': self.out_suffix,
|
'file_suffix': self.out_suffix,
|
||||||
|
'link_suffix': self.link_suffix,
|
||||||
'script_files': self.script_files,
|
'script_files': self.script_files,
|
||||||
'language': self.config.language,
|
'language': self.config.language,
|
||||||
'css_files': self.css_files,
|
'css_files': self.css_files,
|
||||||
@ -482,7 +497,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
'parents': [],
|
'parents': [],
|
||||||
'logo': logo,
|
'logo': logo,
|
||||||
'favicon': favicon,
|
'favicon': favicon,
|
||||||
'html5_doctype': html5_ready and not self.config.html4_writer
|
'html5_doctype': html5_ready and not self.config.html4_writer,
|
||||||
}
|
}
|
||||||
if self.theme:
|
if self.theme:
|
||||||
self.globalcontext.update(
|
self.globalcontext.update(
|
||||||
@ -534,10 +549,10 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
|
|
||||||
# title rendered as HTML
|
# title rendered as HTML
|
||||||
title_node = self.env.longtitles.get(docname)
|
title_node = self.env.longtitles.get(docname)
|
||||||
title = title_node and self.render_partial(title_node)['title'] or ''
|
title = self.render_partial(title_node)['title'] if title_node else ''
|
||||||
|
|
||||||
# Suffix for the document
|
# Suffix for the document
|
||||||
source_suffix = path.splitext(self.env.doc2path(docname))[1]
|
source_suffix = self.env.doc2path(docname, False)[len(docname):]
|
||||||
|
|
||||||
# the name for the copied source
|
# the name for the copied source
|
||||||
if self.config.html_copy_source:
|
if self.config.html_copy_source:
|
||||||
@ -591,7 +606,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
self.imgpath = relative_uri(self.get_target_uri(docname), self.imagedir)
|
self.imgpath = relative_uri(self.get_target_uri(docname), self.imagedir)
|
||||||
self.post_process_images(doctree)
|
self.post_process_images(doctree)
|
||||||
title_node = self.env.longtitles.get(docname)
|
title_node = self.env.longtitles.get(docname)
|
||||||
title = title_node and self.render_partial(title_node)['title'] or ''
|
title = self.render_partial(title_node)['title'] if title_node else ''
|
||||||
self.index_page(docname, doctree, title)
|
self.index_page(docname, doctree, title)
|
||||||
|
|
||||||
def finish(self) -> None:
|
def finish(self) -> None:
|
||||||
@ -717,6 +732,10 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f:
|
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f:
|
||||||
f.write(self.highlighter.get_stylesheet())
|
f.write(self.highlighter.get_stylesheet())
|
||||||
|
|
||||||
|
if self.dark_highlighter:
|
||||||
|
with open(path.join(self.outdir, '_static', 'pygments_dark.css'), 'w') as f:
|
||||||
|
f.write(self.dark_highlighter.get_stylesheet())
|
||||||
|
|
||||||
def copy_translation_js(self) -> None:
|
def copy_translation_js(self) -> None:
|
||||||
"""Copy a JavaScript file for translations."""
|
"""Copy a JavaScript file for translations."""
|
||||||
if self.config.language is not None:
|
if self.config.language is not None:
|
||||||
@ -806,13 +825,17 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
|
|
||||||
if self.config.html_scaled_image_link and self.html_scaled_image_link:
|
if self.config.html_scaled_image_link and self.html_scaled_image_link:
|
||||||
for node in doctree.traverse(nodes.image):
|
for node in doctree.traverse(nodes.image):
|
||||||
scale_keys = ('scale', 'width', 'height')
|
if not any((key in node) for key in ['scale', 'width', 'height']):
|
||||||
if not any((key in node) for key in scale_keys) or \
|
# resizing options are not given. scaled image link is available
|
||||||
isinstance(node.parent, nodes.reference):
|
# only for resized images.
|
||||||
# docutils does unfortunately not preserve the
|
|
||||||
# ``target`` attribute on images, so we need to check
|
|
||||||
# the parent node here.
|
|
||||||
continue
|
continue
|
||||||
|
elif isinstance(node.parent, nodes.reference):
|
||||||
|
# A image having hyperlink target
|
||||||
|
continue
|
||||||
|
elif 'no-scaled-link' in node['classes']:
|
||||||
|
# scaled image link is disabled for this node
|
||||||
|
continue
|
||||||
|
|
||||||
uri = node['uri']
|
uri = node['uri']
|
||||||
reference = nodes.reference('', '', internal=True)
|
reference = nodes.reference('', '', internal=True)
|
||||||
if uri in self.images:
|
if uri in self.images:
|
||||||
@ -846,7 +869,11 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
if self.indexer is not None and title:
|
if self.indexer is not None and title:
|
||||||
filename = self.env.doc2path(pagename, base=None)
|
filename = self.env.doc2path(pagename, base=None)
|
||||||
try:
|
try:
|
||||||
self.indexer.feed(pagename, filename, title, doctree)
|
metadata = self.env.metadata.get(pagename, {})
|
||||||
|
if 'nosearch' in metadata:
|
||||||
|
self.indexer.feed(pagename, filename, '', new_document(''))
|
||||||
|
else:
|
||||||
|
self.indexer.feed(pagename, filename, title, doctree)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# fallback for old search-adapters
|
# fallback for old search-adapters
|
||||||
self.indexer.feed(pagename, title, doctree) # type: ignore
|
self.indexer.feed(pagename, title, doctree) # type: ignore
|
||||||
@ -857,11 +884,11 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
indexer_name, indexer_name),
|
indexer_name, indexer_name),
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwds) -> str:
|
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str:
|
||||||
if 'includehidden' not in kwds:
|
if 'includehidden' not in kwargs:
|
||||||
kwds['includehidden'] = False
|
kwargs['includehidden'] = False
|
||||||
return self.render_partial(TocTree(self.env).get_toctree_for(
|
return self.render_partial(TocTree(self.env).get_toctree_for(
|
||||||
docname, self, collapse, **kwds))['fragment']
|
docname, self, collapse, **kwargs))['fragment']
|
||||||
|
|
||||||
def get_outfilename(self, pagename: str) -> str:
|
def get_outfilename(self, pagename: str) -> str:
|
||||||
return path.join(self.outdir, os_path(pagename) + self.out_suffix)
|
return path.join(self.outdir, os_path(pagename) + self.out_suffix)
|
||||||
@ -970,7 +997,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
return False
|
return False
|
||||||
ctx['hasdoc'] = hasdoc
|
ctx['hasdoc'] = hasdoc
|
||||||
|
|
||||||
ctx['toctree'] = lambda **kw: self._get_local_toctree(pagename, **kw)
|
ctx['toctree'] = lambda **kwargs: self._get_local_toctree(pagename, **kwargs)
|
||||||
self.add_sidebars(pagename, ctx)
|
self.add_sidebars(pagename, ctx)
|
||||||
ctx.update(addctx)
|
ctx.update(addctx)
|
||||||
|
|
||||||
@ -1093,7 +1120,6 @@ def setup_js_tag_helper(app: Sphinx, pagename: str, templatexname: str,
|
|||||||
attrs.append('src="%s"' % pathto(js.filename, resource=True))
|
attrs.append('src="%s"' % pathto(js.filename, resource=True))
|
||||||
else:
|
else:
|
||||||
# str value (old styled)
|
# str value (old styled)
|
||||||
attrs.append('type="text/javascript"')
|
|
||||||
attrs.append('src="%s"' % pathto(js, resource=True))
|
attrs.append('src="%s"' % pathto(js, resource=True))
|
||||||
return '<script %s>%s</script>' % (' '.join(attrs), body)
|
return '<script %s>%s</script>' % (' '.join(attrs), body)
|
||||||
|
|
||||||
@ -1119,7 +1145,8 @@ def validate_html_extra_path(app: Sphinx, config: Config) -> None:
|
|||||||
if not path.exists(extra_path):
|
if not path.exists(extra_path):
|
||||||
logger.warning(__('html_extra_path entry %r does not exist'), entry)
|
logger.warning(__('html_extra_path entry %r does not exist'), entry)
|
||||||
config.html_extra_path.remove(entry)
|
config.html_extra_path.remove(entry)
|
||||||
elif path.commonpath([app.outdir, extra_path]) == app.outdir:
|
elif (path.splitdrive(app.outdir)[0] == path.splitdrive(extra_path)[0] and
|
||||||
|
path.commonpath([app.outdir, extra_path]) == app.outdir):
|
||||||
logger.warning(__('html_extra_path entry %r is placed inside outdir'), entry)
|
logger.warning(__('html_extra_path entry %r is placed inside outdir'), entry)
|
||||||
config.html_extra_path.remove(entry)
|
config.html_extra_path.remove(entry)
|
||||||
|
|
||||||
@ -1131,7 +1158,8 @@ def validate_html_static_path(app: Sphinx, config: Config) -> None:
|
|||||||
if not path.exists(static_path):
|
if not path.exists(static_path):
|
||||||
logger.warning(__('html_static_path entry %r does not exist'), entry)
|
logger.warning(__('html_static_path entry %r does not exist'), entry)
|
||||||
config.html_static_path.remove(entry)
|
config.html_static_path.remove(entry)
|
||||||
elif path.commonpath([app.outdir, static_path]) == app.outdir:
|
elif (path.splitdrive(app.outdir)[0] == path.splitdrive(static_path)[0] and
|
||||||
|
path.commonpath([app.outdir, static_path]) == app.outdir):
|
||||||
logger.warning(__('html_static_path entry %r is placed inside outdir'), entry)
|
logger.warning(__('html_static_path entry %r is placed inside outdir'), entry)
|
||||||
config.html_static_path.remove(entry)
|
config.html_static_path.remove(entry)
|
||||||
|
|
||||||
@ -1203,12 +1231,12 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_config_value('html4_writer', False, 'html')
|
app.add_config_value('html4_writer', False, 'html')
|
||||||
|
|
||||||
# event handlers
|
# event handlers
|
||||||
app.connect('config-inited', convert_html_css_files)
|
app.connect('config-inited', convert_html_css_files, priority=800)
|
||||||
app.connect('config-inited', convert_html_js_files)
|
app.connect('config-inited', convert_html_js_files, priority=800)
|
||||||
app.connect('config-inited', validate_html_extra_path)
|
app.connect('config-inited', validate_html_extra_path, priority=800)
|
||||||
app.connect('config-inited', validate_html_static_path)
|
app.connect('config-inited', validate_html_static_path, priority=800)
|
||||||
app.connect('config-inited', validate_html_logo)
|
app.connect('config-inited', validate_html_logo, priority=800)
|
||||||
app.connect('config-inited', validate_html_favicon)
|
app.connect('config-inited', validate_html_favicon, priority=800)
|
||||||
app.connect('builder-inited', validate_math_renderer)
|
app.connect('builder-inited', validate_math_renderer)
|
||||||
app.connect('html-page-context', setup_js_tag_helper)
|
app.connect('html-page-context', setup_js_tag_helper)
|
||||||
|
|
@ -5,7 +5,7 @@
|
|||||||
Build HTML help support files.
|
Build HTML help support files.
|
||||||
Parts adapted from Python's Doc/tools/prechm.py.
|
Parts adapted from Python's Doc/tools/prechm.py.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
LaTeX builder.
|
LaTeX builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -20,6 +20,8 @@ import sphinx.builders.latex.nodes # NOQA # Workaround: import this before wri
|
|||||||
from sphinx import package_dir, addnodes, highlighting
|
from sphinx import package_dir, addnodes, highlighting
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
|
from sphinx.builders.latex.constants import ADDITIONAL_SETTINGS, DEFAULT_SETTINGS, SHORTHANDOFF
|
||||||
|
from sphinx.builders.latex.theming import Theme, ThemeFactory
|
||||||
from sphinx.builders.latex.util import ExtBabel
|
from sphinx.builders.latex.util import ExtBabel
|
||||||
from sphinx.config import Config, ENUM
|
from sphinx.config import Config, ENUM
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
@ -34,9 +36,7 @@ from sphinx.util.i18n import format_date
|
|||||||
from sphinx.util.nodes import inline_all_toctrees
|
from sphinx.util.nodes import inline_all_toctrees
|
||||||
from sphinx.util.osutil import SEP, make_filename_from_project
|
from sphinx.util.osutil import SEP, make_filename_from_project
|
||||||
from sphinx.util.template import LaTeXRenderer
|
from sphinx.util.template import LaTeXRenderer
|
||||||
from sphinx.writers.latex import (
|
from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
|
||||||
ADDITIONAL_SETTINGS, DEFAULT_SETTINGS, LaTeXWriter, LaTeXTranslator
|
|
||||||
)
|
|
||||||
|
|
||||||
# load docutils.nodes after loading sphinx.builders.latex.nodes
|
# load docutils.nodes after loading sphinx.builders.latex.nodes
|
||||||
from docutils import nodes # NOQA
|
from docutils import nodes # NOQA
|
||||||
@ -54,13 +54,13 @@ XINDY_LANG_OPTIONS = {
|
|||||||
'hr': '-L croatian -C utf8 ',
|
'hr': '-L croatian -C utf8 ',
|
||||||
'cs': '-L czech -C utf8 ',
|
'cs': '-L czech -C utf8 ',
|
||||||
'da': '-L danish -C utf8 ',
|
'da': '-L danish -C utf8 ',
|
||||||
'nl': '-L dutch -C ij-as-ij-utf8 ',
|
'nl': '-L dutch-ij-as-ij -C utf8 ',
|
||||||
'en': '-L english -C utf8 ',
|
'en': '-L english -C utf8 ',
|
||||||
'eo': '-L esperanto -C utf8 ',
|
'eo': '-L esperanto -C utf8 ',
|
||||||
'et': '-L estonian -C utf8 ',
|
'et': '-L estonian -C utf8 ',
|
||||||
'fi': '-L finnish -C utf8 ',
|
'fi': '-L finnish -C utf8 ',
|
||||||
'fr': '-L french -C utf8 ',
|
'fr': '-L french -C utf8 ',
|
||||||
'de': '-L german -C din5007-utf8 ',
|
'de': '-L german-din5007 -C utf8 ',
|
||||||
'is': '-L icelandic -C utf8 ',
|
'is': '-L icelandic -C utf8 ',
|
||||||
'it': '-L italian -C utf8 ',
|
'it': '-L italian -C utf8 ',
|
||||||
'la': '-L latin -C utf8 ',
|
'la': '-L latin -C utf8 ',
|
||||||
@ -73,9 +73,9 @@ XINDY_LANG_OPTIONS = {
|
|||||||
'pl': '-L polish -C utf8 ',
|
'pl': '-L polish -C utf8 ',
|
||||||
'pt': '-L portuguese -C utf8 ',
|
'pt': '-L portuguese -C utf8 ',
|
||||||
'ro': '-L romanian -C utf8 ',
|
'ro': '-L romanian -C utf8 ',
|
||||||
'sk': '-L slovak -C small-utf8 ', # there is also slovak-large
|
'sk': '-L slovak-small -C utf8 ', # there is also slovak-large
|
||||||
'sl': '-L slovenian -C utf8 ',
|
'sl': '-L slovenian -C utf8 ',
|
||||||
'es': '-L spanish -C modern-utf8 ', # there is also spanish-traditional
|
'es': '-L spanish-modern -C utf8 ', # there is also spanish-traditional
|
||||||
'sv': '-L swedish -C utf8 ',
|
'sv': '-L swedish -C utf8 ',
|
||||||
'tr': '-L turkish -C utf8 ',
|
'tr': '-L turkish -C utf8 ',
|
||||||
'hsb': '-L upper-sorbian -C utf8 ',
|
'hsb': '-L upper-sorbian -C utf8 ',
|
||||||
@ -86,7 +86,7 @@ XINDY_LANG_OPTIONS = {
|
|||||||
'be': '-L belarusian -C utf8 ',
|
'be': '-L belarusian -C utf8 ',
|
||||||
'bg': '-L bulgarian -C utf8 ',
|
'bg': '-L bulgarian -C utf8 ',
|
||||||
'mk': '-L macedonian -C utf8 ',
|
'mk': '-L macedonian -C utf8 ',
|
||||||
'mn': '-L mongolian -C cyrillic-utf8 ',
|
'mn': '-L mongolian-cyrillic -C utf8 ',
|
||||||
'ru': '-L russian -C utf8 ',
|
'ru': '-L russian -C utf8 ',
|
||||||
'sr': '-L serbian -C utf8 ',
|
'sr': '-L serbian -C utf8 ',
|
||||||
'sh-cyrl': '-L serbian -C utf8 ',
|
'sh-cyrl': '-L serbian -C utf8 ',
|
||||||
@ -96,7 +96,7 @@ XINDY_LANG_OPTIONS = {
|
|||||||
# can work only with xelatex/lualatex, not supported by texindy+pdflatex
|
# can work only with xelatex/lualatex, not supported by texindy+pdflatex
|
||||||
'el': '-L greek -C utf8 ',
|
'el': '-L greek -C utf8 ',
|
||||||
# FIXME, not compatible with [:2] slice but does Sphinx support Greek ?
|
# FIXME, not compatible with [:2] slice but does Sphinx support Greek ?
|
||||||
'el-polyton': '-L greek -C polytonic-utf8 ',
|
'el-polyton': '-L greek-polytonic -C utf8 ',
|
||||||
}
|
}
|
||||||
|
|
||||||
XINDY_CYRILLIC_SCRIPTS = [
|
XINDY_CYRILLIC_SCRIPTS = [
|
||||||
@ -127,18 +127,20 @@ class LaTeXBuilder(Builder):
|
|||||||
self.context = {} # type: Dict[str, Any]
|
self.context = {} # type: Dict[str, Any]
|
||||||
self.docnames = [] # type: Iterable[str]
|
self.docnames = [] # type: Iterable[str]
|
||||||
self.document_data = [] # type: List[Tuple[str, str, str, str, str, bool]]
|
self.document_data = [] # type: List[Tuple[str, str, str, str, str, bool]]
|
||||||
|
self.themes = ThemeFactory(self.app)
|
||||||
self.usepackages = self.app.registry.latex_packages
|
self.usepackages = self.app.registry.latex_packages
|
||||||
texescape.init()
|
texescape.init()
|
||||||
|
|
||||||
self.init_context()
|
self.init_context()
|
||||||
self.init_babel()
|
self.init_babel()
|
||||||
|
self.init_multilingual()
|
||||||
|
|
||||||
def get_outdated_docs(self) -> Union[str, List[str]]:
|
def get_outdated_docs(self) -> Union[str, List[str]]:
|
||||||
return 'all documents' # for now
|
return 'all documents' # for now
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
if docname not in self.docnames:
|
if docname not in self.docnames:
|
||||||
raise NoUri
|
raise NoUri(docname, typ)
|
||||||
else:
|
else:
|
||||||
return '%' + docname
|
return '%' + docname
|
||||||
|
|
||||||
@ -207,6 +209,41 @@ class LaTeXBuilder(Builder):
|
|||||||
logger.warning(__('no Babel option known for language %r'),
|
logger.warning(__('no Babel option known for language %r'),
|
||||||
self.config.language)
|
self.config.language)
|
||||||
|
|
||||||
|
def init_multilingual(self) -> None:
|
||||||
|
if self.context['latex_engine'] == 'pdflatex':
|
||||||
|
if not self.babel.uses_cyrillic():
|
||||||
|
if 'X2' in self.context['fontenc']:
|
||||||
|
self.context['substitutefont'] = '\\usepackage{substitutefont}'
|
||||||
|
self.context['textcyrillic'] = '\\usepackage[Xtwo]{sphinxcyrillic}'
|
||||||
|
elif 'T2A' in self.context['fontenc']:
|
||||||
|
self.context['substitutefont'] = '\\usepackage{substitutefont}'
|
||||||
|
self.context['textcyrillic'] = '\\usepackage[TtwoA]{sphinxcyrillic}'
|
||||||
|
if 'LGR' in self.context['fontenc']:
|
||||||
|
self.context['substitutefont'] = '\\usepackage{substitutefont}'
|
||||||
|
else:
|
||||||
|
self.context['textgreek'] = ''
|
||||||
|
|
||||||
|
# 'babel' key is public and user setting must be obeyed
|
||||||
|
if self.context['babel']:
|
||||||
|
self.context['classoptions'] += ',' + self.babel.get_language()
|
||||||
|
# this branch is not taken for xelatex/lualatex if default settings
|
||||||
|
self.context['multilingual'] = self.context['babel']
|
||||||
|
if self.config.language:
|
||||||
|
self.context['shorthandoff'] = SHORTHANDOFF
|
||||||
|
|
||||||
|
# Times fonts don't work with Cyrillic languages
|
||||||
|
if self.babel.uses_cyrillic() and 'fontpkg' not in self.config.latex_elements:
|
||||||
|
self.context['fontpkg'] = ''
|
||||||
|
elif self.context['polyglossia']:
|
||||||
|
self.context['classoptions'] += ',' + self.babel.get_language()
|
||||||
|
options = self.babel.get_mainlanguage_options()
|
||||||
|
if options:
|
||||||
|
language = r'\setmainlanguage[%s]{%s}' % (options, self.babel.get_language())
|
||||||
|
else:
|
||||||
|
language = r'\setmainlanguage{%s}' % self.babel.get_language()
|
||||||
|
|
||||||
|
self.context['multilingual'] = '%s\n%s' % (self.context['polyglossia'], language)
|
||||||
|
|
||||||
def write_stylesheet(self) -> None:
|
def write_stylesheet(self) -> None:
|
||||||
highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style)
|
highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style)
|
||||||
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
|
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
|
||||||
@ -216,47 +253,51 @@ class LaTeXBuilder(Builder):
|
|||||||
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
|
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
|
||||||
f.write(highlighter.get_stylesheet())
|
f.write(highlighter.get_stylesheet())
|
||||||
|
|
||||||
def write(self, *ignored) -> None:
|
def write(self, *ignored: Any) -> None:
|
||||||
docwriter = LaTeXWriter(self)
|
docwriter = LaTeXWriter(self)
|
||||||
docsettings = OptionParser(
|
docsettings = OptionParser(
|
||||||
defaults=self.env.settings,
|
defaults=self.env.settings,
|
||||||
components=(docwriter,),
|
components=(docwriter,),
|
||||||
read_config_files=True).get_default_values() # type: Any
|
read_config_files=True).get_default_values() # type: Any
|
||||||
|
patch_settings(docsettings)
|
||||||
|
|
||||||
self.init_document_data()
|
self.init_document_data()
|
||||||
self.write_stylesheet()
|
self.write_stylesheet()
|
||||||
|
|
||||||
for entry in self.document_data:
|
for entry in self.document_data:
|
||||||
docname, targetname, title, author, docclass = entry[:5]
|
docname, targetname, title, author, themename = entry[:5]
|
||||||
|
theme = self.themes.get(themename)
|
||||||
toctree_only = False
|
toctree_only = False
|
||||||
if len(entry) > 5:
|
if len(entry) > 5:
|
||||||
toctree_only = entry[5]
|
toctree_only = entry[5]
|
||||||
destination = SphinxFileOutput(destination_path=path.join(self.outdir, targetname),
|
destination = SphinxFileOutput(destination_path=path.join(self.outdir, targetname),
|
||||||
encoding='utf-8', overwrite_if_changed=True)
|
encoding='utf-8', overwrite_if_changed=True)
|
||||||
with progress_message(__("processing %s") % targetname):
|
with progress_message(__("processing %s") % targetname):
|
||||||
toctrees = self.env.get_doctree(docname).traverse(addnodes.toctree)
|
doctree = self.env.get_doctree(docname)
|
||||||
if toctrees:
|
toctree = next(iter(doctree.traverse(addnodes.toctree)), None)
|
||||||
if toctrees[0].get('maxdepth') > 0:
|
if toctree and toctree.get('maxdepth') > 0:
|
||||||
tocdepth = toctrees[0].get('maxdepth')
|
tocdepth = toctree.get('maxdepth')
|
||||||
else:
|
|
||||||
tocdepth = None
|
|
||||||
else:
|
else:
|
||||||
tocdepth = None
|
tocdepth = None
|
||||||
|
|
||||||
doctree = self.assemble_doctree(
|
doctree = self.assemble_doctree(
|
||||||
docname, toctree_only,
|
docname, toctree_only,
|
||||||
appendices=((docclass != 'howto') and self.config.latex_appendices or []))
|
appendices=(self.config.latex_appendices if theme.name != 'howto' else []))
|
||||||
|
doctree['docclass'] = theme.docclass
|
||||||
|
doctree['contentsname'] = self.get_contentsname(docname)
|
||||||
doctree['tocdepth'] = tocdepth
|
doctree['tocdepth'] = tocdepth
|
||||||
self.post_process_images(doctree)
|
self.post_process_images(doctree)
|
||||||
self.update_doc_context(title, author)
|
self.update_doc_context(title, author, theme)
|
||||||
|
|
||||||
with progress_message(__("writing")):
|
with progress_message(__("writing")):
|
||||||
docsettings.author = author
|
docsettings._author = author
|
||||||
docsettings.title = title
|
docsettings._title = title
|
||||||
docsettings.contentsname = self.get_contentsname(docname)
|
docsettings._contentsname = doctree['contentsname']
|
||||||
docsettings.docname = docname
|
docsettings._docname = docname
|
||||||
docsettings.docclass = docclass
|
docsettings._docclass = theme.name
|
||||||
|
|
||||||
doctree.settings = docsettings
|
doctree.settings = docsettings
|
||||||
|
docwriter.theme = theme
|
||||||
docwriter.write(doctree, destination)
|
docwriter.write(doctree, destination)
|
||||||
|
|
||||||
def get_contentsname(self, indexfile: str) -> str:
|
def get_contentsname(self, indexfile: str) -> str:
|
||||||
@ -269,9 +310,13 @@ class LaTeXBuilder(Builder):
|
|||||||
|
|
||||||
return contentsname
|
return contentsname
|
||||||
|
|
||||||
def update_doc_context(self, title: str, author: str) -> None:
|
def update_doc_context(self, title: str, author: str, theme: Theme) -> None:
|
||||||
self.context['title'] = title
|
self.context['title'] = title
|
||||||
self.context['author'] = author
|
self.context['author'] = author
|
||||||
|
self.context['docclass'] = theme.docclass
|
||||||
|
self.context['papersize'] = theme.papersize
|
||||||
|
self.context['pointsize'] = theme.pointsize
|
||||||
|
self.context['wrapperclass'] = theme.wrapperclass
|
||||||
|
|
||||||
def assemble_doctree(self, indexfile: str, toctree_only: bool, appendices: List[str]) -> nodes.document: # NOQA
|
def assemble_doctree(self, indexfile: str, toctree_only: bool, appendices: List[str]) -> nodes.document: # NOQA
|
||||||
self.docnames = set([indexfile] + appendices)
|
self.docnames = set([indexfile] + appendices)
|
||||||
@ -361,13 +406,6 @@ class LaTeXBuilder(Builder):
|
|||||||
copy_asset_file(path.join(staticdirname, 'Makefile_t'),
|
copy_asset_file(path.join(staticdirname, 'Makefile_t'),
|
||||||
self.outdir, context=context)
|
self.outdir, context=context)
|
||||||
|
|
||||||
# the logo is handled differently
|
|
||||||
if self.config.latex_logo:
|
|
||||||
if not path.isfile(path.join(self.confdir, self.config.latex_logo)):
|
|
||||||
raise SphinxError(__('logo file %r does not exist') % self.config.latex_logo)
|
|
||||||
else:
|
|
||||||
copy_asset_file(path.join(self.confdir, self.config.latex_logo), self.outdir)
|
|
||||||
|
|
||||||
@progress_message(__('copying additional files'))
|
@progress_message(__('copying additional files'))
|
||||||
def copy_latex_additional_files(self) -> None:
|
def copy_latex_additional_files(self) -> None:
|
||||||
for filename in self.config.latex_additional_files:
|
for filename in self.config.latex_additional_files:
|
||||||
@ -387,6 +425,11 @@ class LaTeXBuilder(Builder):
|
|||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.warning(__('cannot copy image file %r: %s'),
|
logger.warning(__('cannot copy image file %r: %s'),
|
||||||
path.join(self.srcdir, src), err)
|
path.join(self.srcdir, src), err)
|
||||||
|
if self.config.latex_logo:
|
||||||
|
if not path.isfile(path.join(self.confdir, self.config.latex_logo)):
|
||||||
|
raise SphinxError(__('logo file %r does not exist') % self.config.latex_logo)
|
||||||
|
else:
|
||||||
|
copy_asset_file(path.join(self.confdir, self.config.latex_logo), self.outdir)
|
||||||
|
|
||||||
def write_message_catalog(self) -> None:
|
def write_message_catalog(self) -> None:
|
||||||
formats = self.config.numfig_format
|
formats = self.config.numfig_format
|
||||||
@ -404,20 +447,68 @@ class LaTeXBuilder(Builder):
|
|||||||
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())
|
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())
|
||||||
|
|
||||||
|
|
||||||
|
def patch_settings(settings: Any) -> Any:
|
||||||
|
"""Make settings object to show deprecation messages."""
|
||||||
|
|
||||||
|
class Values(type(settings)): # type: ignore
|
||||||
|
@property
|
||||||
|
def author(self) -> str:
|
||||||
|
warnings.warn('settings.author is deprecated',
|
||||||
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
return self._author
|
||||||
|
|
||||||
|
@property
|
||||||
|
def title(self) -> str:
|
||||||
|
warnings.warn('settings.title is deprecated',
|
||||||
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
return self._title
|
||||||
|
|
||||||
|
@property
|
||||||
|
def contentsname(self) -> str:
|
||||||
|
warnings.warn('settings.contentsname is deprecated',
|
||||||
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
return self._contentsname
|
||||||
|
|
||||||
|
@property
|
||||||
|
def docname(self) -> str:
|
||||||
|
warnings.warn('settings.docname is deprecated',
|
||||||
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
return self._docname
|
||||||
|
|
||||||
|
@property
|
||||||
|
def docclass(self) -> str:
|
||||||
|
warnings.warn('settings.docclass is deprecated',
|
||||||
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
return self._docclass
|
||||||
|
|
||||||
|
# dynamic subclassing
|
||||||
|
settings.__class__ = Values
|
||||||
|
|
||||||
|
|
||||||
def validate_config_values(app: Sphinx, config: Config) -> None:
|
def validate_config_values(app: Sphinx, config: Config) -> None:
|
||||||
for key in list(config.latex_elements):
|
for key in list(config.latex_elements):
|
||||||
if key not in DEFAULT_SETTINGS:
|
if key not in DEFAULT_SETTINGS:
|
||||||
msg = __("Unknown configure key: latex_elements[%r]. ignored.")
|
msg = __("Unknown configure key: latex_elements[%r], ignored.")
|
||||||
logger.warning(msg % (key,))
|
logger.warning(msg % (key,))
|
||||||
config.latex_elements.pop(key)
|
config.latex_elements.pop(key)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_latex_theme_options(app: Sphinx, config: Config) -> None:
|
||||||
|
for key in list(config.latex_theme_options):
|
||||||
|
if key not in Theme.UPDATABLE_KEYS:
|
||||||
|
msg = __("Unknown theme option: latex_theme_options[%r], ignored.")
|
||||||
|
logger.warning(msg % (key,))
|
||||||
|
config.latex_theme_options.pop(key)
|
||||||
|
|
||||||
|
|
||||||
def default_latex_engine(config: Config) -> str:
|
def default_latex_engine(config: Config) -> str:
|
||||||
""" Better default latex_engine settings for specific languages. """
|
""" Better default latex_engine settings for specific languages. """
|
||||||
if config.language == 'ja':
|
if config.language == 'ja':
|
||||||
return 'platex'
|
return 'platex'
|
||||||
elif (config.language or '').startswith('zh'):
|
elif (config.language or '').startswith('zh'):
|
||||||
return 'xelatex'
|
return 'xelatex'
|
||||||
|
elif config.language == 'el':
|
||||||
|
return 'xelatex'
|
||||||
else:
|
else:
|
||||||
return 'pdflatex'
|
return 'pdflatex'
|
||||||
|
|
||||||
@ -425,8 +516,12 @@ def default_latex_engine(config: Config) -> str:
|
|||||||
def default_latex_docclass(config: Config) -> Dict[str, str]:
|
def default_latex_docclass(config: Config) -> Dict[str, str]:
|
||||||
""" Better default latex_docclass settings for specific languages. """
|
""" Better default latex_docclass settings for specific languages. """
|
||||||
if config.language == 'ja':
|
if config.language == 'ja':
|
||||||
return {'manual': 'jsbook',
|
if config.latex_engine == 'uplatex':
|
||||||
'howto': 'jreport'}
|
return {'manual': 'ujbook',
|
||||||
|
'howto': 'ujreport'}
|
||||||
|
else:
|
||||||
|
return {'manual': 'jsbook',
|
||||||
|
'howto': 'jreport'}
|
||||||
else:
|
else:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@ -438,26 +533,29 @@ def default_latex_use_xindy(config: Config) -> bool:
|
|||||||
|
|
||||||
def default_latex_documents(config: Config) -> List[Tuple[str, str, str, str, str]]:
|
def default_latex_documents(config: Config) -> List[Tuple[str, str, str, str, str]]:
|
||||||
""" Better default latex_documents settings. """
|
""" Better default latex_documents settings. """
|
||||||
|
project = texescape.escape(config.project, config.latex_engine)
|
||||||
|
author = texescape.escape(config.author, config.latex_engine)
|
||||||
return [(config.master_doc,
|
return [(config.master_doc,
|
||||||
make_filename_from_project(config.project) + '.tex',
|
make_filename_from_project(config.project) + '.tex',
|
||||||
texescape.escape_abbr(texescape.escape(config.project)),
|
texescape.escape_abbr(project),
|
||||||
texescape.escape_abbr(texescape.escape(config.author)),
|
texescape.escape_abbr(author),
|
||||||
'manual')]
|
config.latex_theme)]
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
app.setup_extension('sphinx.builders.latex.transforms')
|
app.setup_extension('sphinx.builders.latex.transforms')
|
||||||
|
|
||||||
app.add_builder(LaTeXBuilder)
|
app.add_builder(LaTeXBuilder)
|
||||||
app.connect('config-inited', validate_config_values)
|
app.connect('config-inited', validate_config_values, priority=800)
|
||||||
|
app.connect('config-inited', validate_latex_theme_options, priority=800)
|
||||||
|
|
||||||
app.add_config_value('latex_engine', default_latex_engine, None,
|
app.add_config_value('latex_engine', default_latex_engine, None,
|
||||||
ENUM('pdflatex', 'xelatex', 'lualatex', 'platex'))
|
ENUM('pdflatex', 'xelatex', 'lualatex', 'platex', 'uplatex'))
|
||||||
app.add_config_value('latex_documents', default_latex_documents, None)
|
app.add_config_value('latex_documents', default_latex_documents, None)
|
||||||
app.add_config_value('latex_logo', None, None, [str])
|
app.add_config_value('latex_logo', None, None, [str])
|
||||||
app.add_config_value('latex_appendices', [], None)
|
app.add_config_value('latex_appendices', [], None)
|
||||||
app.add_config_value('latex_use_latex_multicolumn', False, None)
|
app.add_config_value('latex_use_latex_multicolumn', False, None)
|
||||||
app.add_config_value('latex_use_xindy', default_latex_use_xindy, None)
|
app.add_config_value('latex_use_xindy', default_latex_use_xindy, None, [bool])
|
||||||
app.add_config_value('latex_toplevel_sectioning', None, None,
|
app.add_config_value('latex_toplevel_sectioning', None, None,
|
||||||
ENUM(None, 'part', 'chapter', 'section'))
|
ENUM(None, 'part', 'chapter', 'section'))
|
||||||
app.add_config_value('latex_domain_indices', True, None, [list])
|
app.add_config_value('latex_domain_indices', True, None, [list])
|
||||||
@ -465,6 +563,9 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_config_value('latex_show_pagerefs', False, None)
|
app.add_config_value('latex_show_pagerefs', False, None)
|
||||||
app.add_config_value('latex_elements', {}, None)
|
app.add_config_value('latex_elements', {}, None)
|
||||||
app.add_config_value('latex_additional_files', [], None)
|
app.add_config_value('latex_additional_files', [], None)
|
||||||
|
app.add_config_value('latex_theme', 'manual', None, [str])
|
||||||
|
app.add_config_value('latex_theme_options', {}, None)
|
||||||
|
app.add_config_value('latex_theme_path', [], None, [list])
|
||||||
|
|
||||||
app.add_config_value('latex_docclass', default_latex_docclass, None)
|
app.add_config_value('latex_docclass', default_latex_docclass, None)
|
||||||
|
|
||||||
|
202
sphinx/builders/latex/constants.py
Normal file
202
sphinx/builders/latex/constants.py
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
"""
|
||||||
|
sphinx.builders.latex.constants
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
consntants for LaTeX builder.
|
||||||
|
|
||||||
|
:copyright: Copyright 2007-2020 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
|
||||||
|
\else
|
||||||
|
% LGR was declared as font encoding
|
||||||
|
\substitutefont{LGR}{\rmdefault}{cmr}
|
||||||
|
\substitutefont{LGR}{\sfdefault}{cmss}
|
||||||
|
\substitutefont{LGR}{\ttdefault}{cmtt}
|
||||||
|
\fi
|
||||||
|
\expandafter\ifx\csname T@X2\endcsname\relax
|
||||||
|
\expandafter\ifx\csname T@T2A\endcsname\relax
|
||||||
|
\else
|
||||||
|
% T2A was declared as font encoding
|
||||||
|
\substitutefont{T2A}{\rmdefault}{cmr}
|
||||||
|
\substitutefont{T2A}{\sfdefault}{cmss}
|
||||||
|
\substitutefont{T2A}{\ttdefault}{cmtt}
|
||||||
|
\fi
|
||||||
|
\else
|
||||||
|
% X2 was declared as font encoding
|
||||||
|
\substitutefont{X2}{\rmdefault}{cmr}
|
||||||
|
\substitutefont{X2}{\sfdefault}{cmss}
|
||||||
|
\substitutefont{X2}{\ttdefault}{cmtt}
|
||||||
|
\fi
|
||||||
|
'''
|
||||||
|
|
||||||
|
XELATEX_DEFAULT_FONTPKG = r'''
|
||||||
|
\setmainfont{FreeSerif}[
|
||||||
|
Extension = .otf,
|
||||||
|
UprightFont = *,
|
||||||
|
ItalicFont = *Italic,
|
||||||
|
BoldFont = *Bold,
|
||||||
|
BoldItalicFont = *BoldItalic
|
||||||
|
]
|
||||||
|
\setsansfont{FreeSans}[
|
||||||
|
Extension = .otf,
|
||||||
|
UprightFont = *,
|
||||||
|
ItalicFont = *Oblique,
|
||||||
|
BoldFont = *Bold,
|
||||||
|
BoldItalicFont = *BoldOblique,
|
||||||
|
]
|
||||||
|
\setmonofont{FreeMono}[
|
||||||
|
Extension = .otf,
|
||||||
|
UprightFont = *,
|
||||||
|
ItalicFont = *Oblique,
|
||||||
|
BoldFont = *Bold,
|
||||||
|
BoldItalicFont = *BoldOblique,
|
||||||
|
]
|
||||||
|
'''
|
||||||
|
|
||||||
|
XELATEX_GREEK_DEFAULT_FONTPKG = (XELATEX_DEFAULT_FONTPKG +
|
||||||
|
'\n\\newfontfamily\\greekfont{FreeSerif}' +
|
||||||
|
'\n\\newfontfamily\\greekfontsf{FreeSans}' +
|
||||||
|
'\n\\newfontfamily\\greekfonttt{FreeMono}')
|
||||||
|
|
||||||
|
LUALATEX_DEFAULT_FONTPKG = XELATEX_DEFAULT_FONTPKG
|
||||||
|
|
||||||
|
DEFAULT_SETTINGS = {
|
||||||
|
'latex_engine': 'pdflatex',
|
||||||
|
'papersize': '',
|
||||||
|
'pointsize': '',
|
||||||
|
'pxunit': '.75bp',
|
||||||
|
'classoptions': '',
|
||||||
|
'extraclassoptions': '',
|
||||||
|
'maxlistdepth': '',
|
||||||
|
'sphinxpkgoptions': '',
|
||||||
|
'sphinxsetup': '',
|
||||||
|
'fvset': '\\fvset{fontsize=\\small}',
|
||||||
|
'passoptionstopackages': '',
|
||||||
|
'geometry': '\\usepackage{geometry}',
|
||||||
|
'inputenc': '',
|
||||||
|
'utf8extra': '',
|
||||||
|
'cmappkg': '\\usepackage{cmap}',
|
||||||
|
'fontenc': '\\usepackage[T1]{fontenc}',
|
||||||
|
'amsmath': '\\usepackage{amsmath,amssymb,amstext}',
|
||||||
|
'multilingual': '',
|
||||||
|
'babel': '\\usepackage{babel}',
|
||||||
|
'polyglossia': '',
|
||||||
|
'fontpkg': PDFLATEX_DEFAULT_FONTPKG,
|
||||||
|
'substitutefont': '',
|
||||||
|
'textcyrillic': '',
|
||||||
|
'textgreek': '\\usepackage{textalpha}',
|
||||||
|
'fncychap': '\\usepackage[Bjarne]{fncychap}',
|
||||||
|
'hyperref': ('% Include hyperref last.\n'
|
||||||
|
'\\usepackage{hyperref}\n'
|
||||||
|
'% Fix anchor placement for figures with captions.\n'
|
||||||
|
'\\usepackage{hypcap}% it must be loaded after hyperref.\n'
|
||||||
|
'% Set up styles of URL: it should be placed after hyperref.\n'
|
||||||
|
'\\urlstyle{same}'),
|
||||||
|
'contentsname': '',
|
||||||
|
'extrapackages': '',
|
||||||
|
'preamble': '',
|
||||||
|
'title': '',
|
||||||
|
'release': '',
|
||||||
|
'author': '',
|
||||||
|
'releasename': '',
|
||||||
|
'makeindex': '\\makeindex',
|
||||||
|
'shorthandoff': '',
|
||||||
|
'maketitle': '\\sphinxmaketitle',
|
||||||
|
'tableofcontents': '\\sphinxtableofcontents',
|
||||||
|
'atendofbody': '',
|
||||||
|
'printindex': '\\printindex',
|
||||||
|
'transition': '\n\n\\bigskip\\hrule\\bigskip\n\n',
|
||||||
|
'figure_align': 'htbp',
|
||||||
|
'tocdepth': '',
|
||||||
|
'secnumdepth': '',
|
||||||
|
} # type: Dict[str, Any]
|
||||||
|
|
||||||
|
ADDITIONAL_SETTINGS = {
|
||||||
|
'pdflatex': {
|
||||||
|
'inputenc': '\\usepackage[utf8]{inputenc}',
|
||||||
|
'utf8extra': ('\\ifdefined\\DeclareUnicodeCharacter\n'
|
||||||
|
'% support both utf8 and utf8x syntaxes\n'
|
||||||
|
' \\ifdefined\\DeclareUnicodeCharacterAsOptional\n'
|
||||||
|
' \\def\\sphinxDUC#1{\\DeclareUnicodeCharacter{"#1}}\n'
|
||||||
|
' \\else\n'
|
||||||
|
' \\let\\sphinxDUC\\DeclareUnicodeCharacter\n'
|
||||||
|
' \\fi\n'
|
||||||
|
' \\sphinxDUC{00A0}{\\nobreakspace}\n'
|
||||||
|
' \\sphinxDUC{2500}{\\sphinxunichar{2500}}\n'
|
||||||
|
' \\sphinxDUC{2502}{\\sphinxunichar{2502}}\n'
|
||||||
|
' \\sphinxDUC{2514}{\\sphinxunichar{2514}}\n'
|
||||||
|
' \\sphinxDUC{251C}{\\sphinxunichar{251C}}\n'
|
||||||
|
' \\sphinxDUC{2572}{\\textbackslash}\n'
|
||||||
|
'\\fi'),
|
||||||
|
},
|
||||||
|
'xelatex': {
|
||||||
|
'latex_engine': 'xelatex',
|
||||||
|
'polyglossia': '\\usepackage{polyglossia}',
|
||||||
|
'babel': '',
|
||||||
|
'fontenc': ('\\usepackage{fontspec}\n'
|
||||||
|
'\\defaultfontfeatures[\\rmfamily,\\sffamily,\\ttfamily]{}'),
|
||||||
|
'fontpkg': XELATEX_DEFAULT_FONTPKG,
|
||||||
|
'textgreek': '',
|
||||||
|
'utf8extra': ('\\catcode`^^^^00a0\\active\\protected\\def^^^^00a0'
|
||||||
|
'{\\leavevmode\\nobreak\\ }'),
|
||||||
|
},
|
||||||
|
'lualatex': {
|
||||||
|
'latex_engine': 'lualatex',
|
||||||
|
'polyglossia': '\\usepackage{polyglossia}',
|
||||||
|
'babel': '',
|
||||||
|
'fontenc': ('\\usepackage{fontspec}\n'
|
||||||
|
'\\defaultfontfeatures[\\rmfamily,\\sffamily,\\ttfamily]{}'),
|
||||||
|
'fontpkg': LUALATEX_DEFAULT_FONTPKG,
|
||||||
|
'textgreek': '',
|
||||||
|
'utf8extra': ('\\catcode`^^^^00a0\\active\\protected\\def^^^^00a0'
|
||||||
|
'{\\leavevmode\\nobreak\\ }'),
|
||||||
|
},
|
||||||
|
'platex': {
|
||||||
|
'latex_engine': 'platex',
|
||||||
|
'babel': '',
|
||||||
|
'classoptions': ',dvipdfmx',
|
||||||
|
'fontpkg': '\\usepackage{times}',
|
||||||
|
'textgreek': '',
|
||||||
|
'fncychap': '',
|
||||||
|
'geometry': '\\usepackage[dvipdfm]{geometry}',
|
||||||
|
},
|
||||||
|
'uplatex': {
|
||||||
|
'latex_engine': 'uplatex',
|
||||||
|
'babel': '',
|
||||||
|
'classoptions': ',dvipdfmx',
|
||||||
|
'fontpkg': '\\usepackage{times}',
|
||||||
|
'textgreek': '',
|
||||||
|
'fncychap': '',
|
||||||
|
'geometry': '\\usepackage[dvipdfm]{geometry}',
|
||||||
|
},
|
||||||
|
|
||||||
|
# special settings for latex_engine + language_code
|
||||||
|
('xelatex', 'fr'): {
|
||||||
|
# use babel instead of polyglossia by default
|
||||||
|
'polyglossia': '',
|
||||||
|
'babel': '\\usepackage{babel}',
|
||||||
|
},
|
||||||
|
('xelatex', 'zh'): {
|
||||||
|
'polyglossia': '',
|
||||||
|
'babel': '\\usepackage{babel}',
|
||||||
|
'fontenc': '\\usepackage{xeCJK}',
|
||||||
|
},
|
||||||
|
('xelatex', 'el'): {
|
||||||
|
'fontpkg': XELATEX_GREEK_DEFAULT_FONTPKG,
|
||||||
|
},
|
||||||
|
} # type: Dict[Any, Dict[str, Any]]
|
||||||
|
|
||||||
|
|
||||||
|
SHORTHANDOFF = r'''
|
||||||
|
\ifdefined\shorthandoff
|
||||||
|
\ifnum\catcode`\=\string=\active\shorthandoff{=}\fi
|
||||||
|
\ifnum\catcode`\"=\active\shorthandoff{"}\fi
|
||||||
|
\fi
|
||||||
|
'''
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Additional nodes for LaTeX writer.
|
Additional nodes for LaTeX writer.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
139
sphinx/builders/latex/theming.py
Normal file
139
sphinx/builders/latex/theming.py
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
"""
|
||||||
|
sphinx.builders.latex.theming
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Theming support for LaTeX builder.
|
||||||
|
|
||||||
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
|
:license: BSD, see LICENSE for details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import configparser
|
||||||
|
from os import path
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
|
from sphinx.config import Config
|
||||||
|
from sphinx.errors import ThemeError
|
||||||
|
from sphinx.locale import __
|
||||||
|
from sphinx.util import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Theme:
|
||||||
|
"""A set of LaTeX configurations."""
|
||||||
|
|
||||||
|
LATEX_ELEMENTS_KEYS = ['papersize', 'pointsize']
|
||||||
|
UPDATABLE_KEYS = ['papersize', 'pointsize']
|
||||||
|
|
||||||
|
def __init__(self, name: str) -> None:
|
||||||
|
self.name = name
|
||||||
|
self.docclass = name
|
||||||
|
self.wrapperclass = name
|
||||||
|
self.papersize = 'letterpaper'
|
||||||
|
self.pointsize = '10pt'
|
||||||
|
self.toplevel_sectioning = 'chapter'
|
||||||
|
|
||||||
|
def update(self, config: Config) -> None:
|
||||||
|
"""Override theme settings by user's configuration."""
|
||||||
|
for key in self.LATEX_ELEMENTS_KEYS:
|
||||||
|
if config.latex_elements.get(key):
|
||||||
|
value = config.latex_elements[key]
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
for key in self.UPDATABLE_KEYS:
|
||||||
|
if key in config.latex_theme_options:
|
||||||
|
value = config.latex_theme_options[key]
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
|
||||||
|
class BuiltInTheme(Theme):
|
||||||
|
"""A built-in LaTeX theme."""
|
||||||
|
|
||||||
|
def __init__(self, name: str, config: Config) -> None:
|
||||||
|
super().__init__(name)
|
||||||
|
|
||||||
|
if name == 'howto':
|
||||||
|
self.docclass = config.latex_docclass.get('howto', 'article')
|
||||||
|
else:
|
||||||
|
self.docclass = config.latex_docclass.get('manual', 'report')
|
||||||
|
|
||||||
|
if name in ('manual', 'howto'):
|
||||||
|
self.wrapperclass = 'sphinx' + name
|
||||||
|
else:
|
||||||
|
self.wrapperclass = name
|
||||||
|
|
||||||
|
# we assume LaTeX class provides \chapter command except in case
|
||||||
|
# of non-Japanese 'howto' case
|
||||||
|
if name == 'howto' and not self.docclass.startswith('j'):
|
||||||
|
self.toplevel_sectioning = 'section'
|
||||||
|
else:
|
||||||
|
self.toplevel_sectioning = 'chapter'
|
||||||
|
|
||||||
|
|
||||||
|
class UserTheme(Theme):
|
||||||
|
"""A user defined LaTeX theme."""
|
||||||
|
|
||||||
|
REQUIRED_CONFIG_KEYS = ['docclass', 'wrapperclass']
|
||||||
|
OPTIONAL_CONFIG_KEYS = ['papersize', 'pointsize', 'toplevel_sectioning']
|
||||||
|
|
||||||
|
def __init__(self, name: str, filename: str) -> None:
|
||||||
|
super().__init__(name)
|
||||||
|
self.config = configparser.RawConfigParser()
|
||||||
|
self.config.read(path.join(filename))
|
||||||
|
|
||||||
|
for key in self.REQUIRED_CONFIG_KEYS:
|
||||||
|
try:
|
||||||
|
value = self.config.get('theme', key)
|
||||||
|
setattr(self, key, value)
|
||||||
|
except configparser.NoSectionError:
|
||||||
|
raise ThemeError(__('%r doesn\'t have "theme" setting') % filename)
|
||||||
|
except configparser.NoOptionError as exc:
|
||||||
|
raise ThemeError(__('%r doesn\'t have "%s" setting') % (filename, exc.args[0]))
|
||||||
|
|
||||||
|
for key in self.OPTIONAL_CONFIG_KEYS:
|
||||||
|
try:
|
||||||
|
value = self.config.get('theme', key)
|
||||||
|
setattr(self, key, value)
|
||||||
|
except configparser.NoOptionError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ThemeFactory:
|
||||||
|
"""A factory class for LaTeX Themes."""
|
||||||
|
|
||||||
|
def __init__(self, app: Sphinx) -> None:
|
||||||
|
self.themes = {} # type: Dict[str, Theme]
|
||||||
|
self.theme_paths = [path.join(app.srcdir, p) for p in app.config.latex_theme_path]
|
||||||
|
self.config = app.config
|
||||||
|
self.load_builtin_themes(app.config)
|
||||||
|
|
||||||
|
def load_builtin_themes(self, config: Config) -> None:
|
||||||
|
"""Load built-in themes."""
|
||||||
|
self.themes['manual'] = BuiltInTheme('manual', config)
|
||||||
|
self.themes['howto'] = BuiltInTheme('howto', config)
|
||||||
|
|
||||||
|
def get(self, name: str) -> Theme:
|
||||||
|
"""Get a theme for given *name*."""
|
||||||
|
if name in self.themes:
|
||||||
|
theme = self.themes[name]
|
||||||
|
else:
|
||||||
|
theme = self.find_user_theme(name)
|
||||||
|
if not theme:
|
||||||
|
theme = Theme(name)
|
||||||
|
|
||||||
|
theme.update(self.config)
|
||||||
|
return theme
|
||||||
|
|
||||||
|
def find_user_theme(self, name: str) -> Theme:
|
||||||
|
"""Find a theme named as *name* from latex_theme_path."""
|
||||||
|
for theme_path in self.theme_paths:
|
||||||
|
config_path = path.join(theme_path, name, 'theme.conf')
|
||||||
|
if path.isfile(config_path):
|
||||||
|
try:
|
||||||
|
return UserTheme(name, config_path)
|
||||||
|
except ThemeError as exc:
|
||||||
|
logger.warning(exc)
|
||||||
|
|
||||||
|
return None
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Transforms for LaTeX builder.
|
Transforms for LaTeX builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ class FootnoteDocnameUpdater(SphinxTransform):
|
|||||||
default_priority = 700
|
default_priority = 700
|
||||||
TARGET_NODES = (nodes.footnote, nodes.footnote_reference)
|
TARGET_NODES = (nodes.footnote, nodes.footnote_reference)
|
||||||
|
|
||||||
def apply(self, **kwargs) -> None:
|
def apply(self, **kwargs: Any) -> None:
|
||||||
matcher = NodeMatcher(*self.TARGET_NODES)
|
matcher = NodeMatcher(*self.TARGET_NODES)
|
||||||
for node in self.document.traverse(matcher): # type: nodes.Element
|
for node in self.document.traverse(matcher): # type: nodes.Element
|
||||||
node['docname'] = self.env.docname
|
node['docname'] = self.env.docname
|
||||||
@ -51,7 +51,7 @@ class ShowUrlsTransform(SphinxPostTransform):
|
|||||||
# references are expanded to footnotes (or not)
|
# references are expanded to footnotes (or not)
|
||||||
expanded = False
|
expanded = False
|
||||||
|
|
||||||
def run(self, **kwargs) -> None:
|
def run(self, **kwargs: Any) -> None:
|
||||||
try:
|
try:
|
||||||
# replace id_prefix temporarily
|
# replace id_prefix temporarily
|
||||||
settings = self.document.settings # type: Any
|
settings = self.document.settings # type: Any
|
||||||
@ -338,7 +338,7 @@ class LaTeXFootnoteTransform(SphinxPostTransform):
|
|||||||
default_priority = 600
|
default_priority = 600
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs) -> None:
|
def run(self, **kwargs: Any) -> None:
|
||||||
footnotes = list(self.document.traverse(nodes.footnote))
|
footnotes = list(self.document.traverse(nodes.footnote))
|
||||||
for node in footnotes:
|
for node in footnotes:
|
||||||
node.parent.remove(node)
|
node.parent.remove(node)
|
||||||
@ -490,7 +490,7 @@ class BibliographyTransform(SphinxPostTransform):
|
|||||||
default_priority = 750
|
default_priority = 750
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs) -> None:
|
def run(self, **kwargs: Any) -> None:
|
||||||
citations = thebibliography()
|
citations = thebibliography()
|
||||||
for node in self.document.traverse(nodes.citation):
|
for node in self.document.traverse(nodes.citation):
|
||||||
node.parent.remove(node)
|
node.parent.remove(node)
|
||||||
@ -509,7 +509,7 @@ class CitationReferenceTransform(SphinxPostTransform):
|
|||||||
default_priority = 5 # before ReferencesResolver
|
default_priority = 5 # before ReferencesResolver
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs) -> None:
|
def run(self, **kwargs: Any) -> None:
|
||||||
domain = cast(CitationDomain, self.env.get_domain('citation'))
|
domain = cast(CitationDomain, self.env.get_domain('citation'))
|
||||||
matcher = NodeMatcher(addnodes.pending_xref, refdomain='citation', reftype='ref')
|
matcher = NodeMatcher(addnodes.pending_xref, refdomain='citation', reftype='ref')
|
||||||
for node in self.document.traverse(matcher): # type: addnodes.pending_xref
|
for node in self.document.traverse(matcher): # type: addnodes.pending_xref
|
||||||
@ -529,7 +529,7 @@ class MathReferenceTransform(SphinxPostTransform):
|
|||||||
default_priority = 5 # before ReferencesResolver
|
default_priority = 5 # before ReferencesResolver
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs) -> None:
|
def run(self, **kwargs: Any) -> None:
|
||||||
equations = self.env.get_domain('math').data['objects']
|
equations = self.env.get_domain('math').data['objects']
|
||||||
for node in self.document.traverse(addnodes.pending_xref):
|
for node in self.document.traverse(addnodes.pending_xref):
|
||||||
if node['refdomain'] == 'math' and node['reftype'] in ('eq', 'numref'):
|
if node['refdomain'] == 'math' and node['reftype'] in ('eq', 'numref'):
|
||||||
@ -544,7 +544,7 @@ class LiteralBlockTransform(SphinxPostTransform):
|
|||||||
default_priority = 400
|
default_priority = 400
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs) -> None:
|
def run(self, **kwargs: Any) -> None:
|
||||||
matcher = NodeMatcher(nodes.container, literal_block=True)
|
matcher = NodeMatcher(nodes.container, literal_block=True)
|
||||||
for node in self.document.traverse(matcher): # type: nodes.container
|
for node in self.document.traverse(matcher): # type: nodes.container
|
||||||
newnode = captioned_literal_block('', *node.children, **node.attributes)
|
newnode = captioned_literal_block('', *node.children, **node.attributes)
|
||||||
@ -556,7 +556,7 @@ class DocumentTargetTransform(SphinxPostTransform):
|
|||||||
default_priority = 400
|
default_priority = 400
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs) -> None:
|
def run(self, **kwargs: Any) -> None:
|
||||||
for node in self.document.traverse(addnodes.start_of_file):
|
for node in self.document.traverse(addnodes.start_of_file):
|
||||||
section = node.next_node(nodes.section)
|
section = node.next_node(nodes.section)
|
||||||
if section:
|
if section:
|
||||||
@ -591,7 +591,7 @@ class IndexInSectionTitleTransform(SphinxTransform):
|
|||||||
"""
|
"""
|
||||||
default_priority = 400
|
default_priority = 400
|
||||||
|
|
||||||
def apply(self):
|
def apply(self, **kwargs: Any) -> None:
|
||||||
for node in self.document.traverse(nodes.title):
|
for node in self.document.traverse(nodes.title):
|
||||||
if isinstance(node.parent, nodes.section):
|
if isinstance(node.parent, nodes.section):
|
||||||
for i, index in enumerate(node.traverse(addnodes.index)):
|
for i, index in enumerate(node.traverse(addnodes.index)):
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from docutils.writers.latex2e import Babel
|
from docutils.writers.latex2e import Babel
|
||||||
|
|
||||||
|
|
||||||
@ -40,7 +42,7 @@ class ExtBabel(Babel):
|
|||||||
self.supported = False
|
self.supported = False
|
||||||
return 'english' # fallback to english
|
return 'english' # fallback to english
|
||||||
|
|
||||||
def get_mainlanguage_options(self) -> str:
|
def get_mainlanguage_options(self) -> Optional[str]:
|
||||||
"""Return options for polyglossia's ``\\setmainlanguage``."""
|
"""Return options for polyglossia's ``\\setmainlanguage``."""
|
||||||
if self.use_polyglossia is False:
|
if self.use_polyglossia is False:
|
||||||
return None
|
return None
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
|
|
||||||
The CheckExternalLinksBuilder class.
|
The CheckExternalLinksBuilder class.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
import queue
|
import queue
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
@ -26,7 +27,7 @@ from sphinx.builders import Builder
|
|||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import encode_uri, requests, logging
|
from sphinx.util import encode_uri, requests, logging
|
||||||
from sphinx.util.console import ( # type: ignore
|
from sphinx.util.console import ( # type: ignore
|
||||||
purple, red, darkgreen, darkgray, darkred, turquoise
|
purple, red, darkgreen, darkgray, turquoise
|
||||||
)
|
)
|
||||||
from sphinx.util.nodes import get_node_line
|
from sphinx.util.nodes import get_node_line
|
||||||
from sphinx.util.requests import is_ssl_error
|
from sphinx.util.requests import is_ssl_error
|
||||||
@ -59,6 +60,9 @@ def check_anchor(response: requests.requests.Response, anchor: str) -> bool:
|
|||||||
# Read file in chunks. If we find a matching anchor, we break
|
# Read file in chunks. If we find a matching anchor, we break
|
||||||
# the loop early in hopes not to have to download the whole thing.
|
# the loop early in hopes not to have to download the whole thing.
|
||||||
for chunk in response.iter_content(chunk_size=4096, decode_unicode=True):
|
for chunk in response.iter_content(chunk_size=4096, decode_unicode=True):
|
||||||
|
if isinstance(chunk, bytes): # requests failed to decode
|
||||||
|
chunk = chunk.decode() # manually try to decode it
|
||||||
|
|
||||||
parser.feed(chunk)
|
parser.feed(chunk)
|
||||||
if parser.found:
|
if parser.found:
|
||||||
break
|
break
|
||||||
@ -78,6 +82,8 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
|
self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
|
||||||
self.anchors_ignore = [re.compile(x)
|
self.anchors_ignore = [re.compile(x)
|
||||||
for x in self.app.config.linkcheck_anchors_ignore]
|
for x in self.app.config.linkcheck_anchors_ignore]
|
||||||
|
self.auth = [(re.compile(pattern), auth_info) for pattern, auth_info
|
||||||
|
in self.app.config.linkcheck_auth]
|
||||||
self.good = set() # type: Set[str]
|
self.good = set() # type: Set[str]
|
||||||
self.broken = {} # type: Dict[str, str]
|
self.broken = {} # type: Dict[str, str]
|
||||||
self.redirected = {} # type: Dict[str, Tuple[str, int]]
|
self.redirected = {} # type: Dict[str, Tuple[str, int]]
|
||||||
@ -85,6 +91,8 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
socket.setdefaulttimeout(5.0)
|
socket.setdefaulttimeout(5.0)
|
||||||
# create output file
|
# create output file
|
||||||
open(path.join(self.outdir, 'output.txt'), 'w').close()
|
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
|
# create queues and worker threads
|
||||||
self.wqueue = queue.Queue() # type: queue.Queue
|
self.wqueue = queue.Queue() # type: queue.Queue
|
||||||
@ -101,7 +109,6 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
'allow_redirects': True,
|
'allow_redirects': True,
|
||||||
'headers': {
|
'headers': {
|
||||||
'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8',
|
'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8',
|
||||||
'User-Agent': requests.useragent_header[0][1],
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if self.app.config.linkcheck_timeout:
|
if self.app.config.linkcheck_timeout:
|
||||||
@ -125,11 +132,18 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
except UnicodeError:
|
except UnicodeError:
|
||||||
req_url = encode_uri(req_url)
|
req_url = encode_uri(req_url)
|
||||||
|
|
||||||
|
# Get auth info, if any
|
||||||
|
for pattern, auth_info in self.auth:
|
||||||
|
if pattern.match(uri):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
auth_info = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if anchor and self.app.config.linkcheck_anchors:
|
if anchor and self.app.config.linkcheck_anchors:
|
||||||
# Read the whole document and see if #anchor exists
|
# Read the whole document and see if #anchor exists
|
||||||
response = requests.get(req_url, stream=True, config=self.app.config,
|
response = requests.get(req_url, stream=True, config=self.app.config,
|
||||||
**kwargs)
|
auth=auth_info, **kwargs)
|
||||||
found = check_anchor(response, unquote(anchor))
|
found = check_anchor(response, unquote(anchor))
|
||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
@ -138,13 +152,14 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
try:
|
try:
|
||||||
# try a HEAD request first, which should be easier on
|
# try a HEAD request first, which should be easier on
|
||||||
# the server and the network
|
# the server and the network
|
||||||
response = requests.head(req_url, config=self.app.config, **kwargs)
|
response = requests.head(req_url, config=self.app.config,
|
||||||
|
auth=auth_info, **kwargs)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except HTTPError:
|
except HTTPError:
|
||||||
# retry with GET request if that fails, some servers
|
# retry with GET request if that fails, some servers
|
||||||
# don't like HEAD requests.
|
# don't like HEAD requests.
|
||||||
response = requests.get(req_url, stream=True, config=self.app.config,
|
response = requests.get(req_url, stream=True, config=self.app.config,
|
||||||
**kwargs)
|
auth=auth_info, **kwargs)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except HTTPError as err:
|
except HTTPError as err:
|
||||||
if err.response.status_code == 401:
|
if err.response.status_code == 401:
|
||||||
@ -213,9 +228,16 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
|
|
||||||
def process_result(self, result: Tuple[str, str, int, str, str, int]) -> None:
|
def process_result(self, result: Tuple[str, str, int, str, str, int]) -> None:
|
||||||
uri, docname, lineno, status, info, code = result
|
uri, docname, lineno, status, info, code = result
|
||||||
|
|
||||||
|
filename = self.env.doc2path(docname, None)
|
||||||
|
linkstat = dict(filename=filename, lineno=lineno,
|
||||||
|
status=status, code=code, uri=uri,
|
||||||
|
info=info)
|
||||||
if status == 'unchecked':
|
if status == 'unchecked':
|
||||||
|
self.write_linkstat(linkstat)
|
||||||
return
|
return
|
||||||
if status == 'working' and info == 'old':
|
if status == 'working' and info == 'old':
|
||||||
|
self.write_linkstat(linkstat)
|
||||||
return
|
return
|
||||||
if lineno:
|
if lineno:
|
||||||
logger.info('(line %4d) ', lineno, nonl=True)
|
logger.info('(line %4d) ', lineno, nonl=True)
|
||||||
@ -224,29 +246,38 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
logger.info(darkgray('-ignored- ') + uri + ': ' + info)
|
logger.info(darkgray('-ignored- ') + uri + ': ' + info)
|
||||||
else:
|
else:
|
||||||
logger.info(darkgray('-ignored- ') + uri)
|
logger.info(darkgray('-ignored- ') + uri)
|
||||||
|
self.write_linkstat(linkstat)
|
||||||
elif status == 'local':
|
elif status == 'local':
|
||||||
logger.info(darkgray('-local- ') + uri)
|
logger.info(darkgray('-local- ') + uri)
|
||||||
self.write_entry('local', docname, lineno, uri)
|
self.write_entry('local', docname, filename, lineno, uri)
|
||||||
|
self.write_linkstat(linkstat)
|
||||||
elif status == 'working':
|
elif status == 'working':
|
||||||
logger.info(darkgreen('ok ') + uri + info)
|
logger.info(darkgreen('ok ') + uri + info)
|
||||||
|
self.write_linkstat(linkstat)
|
||||||
elif status == 'broken':
|
elif status == 'broken':
|
||||||
self.write_entry('broken', docname, lineno, uri + ': ' + info)
|
|
||||||
if self.app.quiet or self.app.warningiserror:
|
if self.app.quiet or self.app.warningiserror:
|
||||||
logger.warning(__('broken link: %s (%s)'), uri, info,
|
logger.warning(__('broken link: %s (%s)'), uri, info,
|
||||||
location=(self.env.doc2path(docname), lineno))
|
location=(filename, lineno))
|
||||||
else:
|
else:
|
||||||
logger.info(red('broken ') + uri + red(' - ' + info))
|
logger.info(red('broken ') + uri + red(' - ' + info))
|
||||||
|
self.write_entry('broken', docname, filename, lineno, uri + ': ' + info)
|
||||||
|
self.write_linkstat(linkstat)
|
||||||
elif status == 'redirected':
|
elif status == 'redirected':
|
||||||
text, color = {
|
try:
|
||||||
301: ('permanently', darkred),
|
text, color = {
|
||||||
302: ('with Found', purple),
|
301: ('permanently', purple),
|
||||||
303: ('with See Other', purple),
|
302: ('with Found', purple),
|
||||||
307: ('temporarily', turquoise),
|
303: ('with See Other', purple),
|
||||||
0: ('with unknown code', purple),
|
307: ('temporarily', turquoise),
|
||||||
}[code]
|
308: ('permanently', purple),
|
||||||
self.write_entry('redirected ' + text, docname, lineno,
|
}[code]
|
||||||
uri + ' to ' + info)
|
except KeyError:
|
||||||
|
text, color = ('with unknown code', purple)
|
||||||
|
linkstat['text'] = text
|
||||||
logger.info(color('redirect ') + uri + color(' - ' + text + ' to ' + info))
|
logger.info(color('redirect ') + uri + color(' - ' + text + ' to ' + info))
|
||||||
|
self.write_entry('redirected ' + text, docname, filename,
|
||||||
|
lineno, uri + ' to ' + info)
|
||||||
|
self.write_linkstat(linkstat)
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
return ''
|
return ''
|
||||||
@ -286,10 +317,15 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
if self.broken:
|
if self.broken:
|
||||||
self.app.statuscode = 1
|
self.app.statuscode = 1
|
||||||
|
|
||||||
def write_entry(self, what: str, docname: str, line: int, uri: str) -> None:
|
def write_entry(self, what: str, docname: str, filename: str, line: int,
|
||||||
with open(path.join(self.outdir, 'output.txt'), 'a', encoding='utf-8') as output:
|
uri: str) -> None:
|
||||||
output.write("%s:%s: [%s] %s\n" % (self.env.doc2path(docname, None),
|
with open(path.join(self.outdir, 'output.txt'), 'a') as output:
|
||||||
line, what, uri))
|
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:
|
def finish(self) -> None:
|
||||||
for worker in self.workers:
|
for worker in self.workers:
|
||||||
@ -300,6 +336,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_builder(CheckExternalLinksBuilder)
|
app.add_builder(CheckExternalLinksBuilder)
|
||||||
|
|
||||||
app.add_config_value('linkcheck_ignore', [], None)
|
app.add_config_value('linkcheck_ignore', [], None)
|
||||||
|
app.add_config_value('linkcheck_auth', [], None)
|
||||||
app.add_config_value('linkcheck_retries', 1, None)
|
app.add_config_value('linkcheck_retries', 1, None)
|
||||||
app.add_config_value('linkcheck_timeout', None, None, [int])
|
app.add_config_value('linkcheck_timeout', None, None, [int])
|
||||||
app.add_config_value('linkcheck_workers', 5, None)
|
app.add_config_value('linkcheck_workers', 5, None)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Manual pages builder.
|
Manual pages builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -53,10 +53,10 @@ class ManualPageBuilder(Builder):
|
|||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
if typ == 'token':
|
if typ == 'token':
|
||||||
return ''
|
return ''
|
||||||
raise NoUri
|
raise NoUri(docname, typ)
|
||||||
|
|
||||||
@progress_message(__('writing'))
|
@progress_message(__('writing'))
|
||||||
def write(self, *ignored) -> None:
|
def write(self, *ignored: Any) -> None:
|
||||||
docwriter = ManualPageWriter(self)
|
docwriter = ManualPageWriter(self)
|
||||||
docsettings = OptionParser(
|
docsettings = OptionParser(
|
||||||
defaults=self.env.settings,
|
defaults=self.env.settings,
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Build input files for the Qt collection generator.
|
Build input files for the Qt collection generator.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Single HTML builders.
|
Single HTML builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -67,10 +67,10 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
if hashindex >= 0:
|
if hashindex >= 0:
|
||||||
refnode['refuri'] = fname + refuri[hashindex:]
|
refnode['refuri'] = fname + refuri[hashindex:]
|
||||||
|
|
||||||
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwds) -> str:
|
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str:
|
||||||
if 'includehidden' not in kwds:
|
if 'includehidden' not in kwargs:
|
||||||
kwds['includehidden'] = False
|
kwargs['includehidden'] = False
|
||||||
toctree = TocTree(self.env).get_toctree_for(docname, self, collapse, **kwds)
|
toctree = TocTree(self.env).get_toctree_for(docname, self, collapse, **kwargs)
|
||||||
if toctree is not None:
|
if toctree is not None:
|
||||||
self.fix_refuris(toctree)
|
self.fix_refuris(toctree)
|
||||||
return self.render_partial(toctree)['fragment']
|
return self.render_partial(toctree)['fragment']
|
||||||
@ -149,7 +149,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
'display_toc': display_toc,
|
'display_toc': display_toc,
|
||||||
}
|
}
|
||||||
|
|
||||||
def write(self, *ignored) -> None:
|
def write(self, *ignored: Any) -> None:
|
||||||
docnames = self.env.all_docs
|
docnames = self.env.all_docs
|
||||||
|
|
||||||
with progress_message(__('preparing documents')):
|
with progress_message(__('preparing documents')):
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Texinfo builder.
|
Texinfo builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ class TexinfoBuilder(Builder):
|
|||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
if docname not in self.docnames:
|
if docname not in self.docnames:
|
||||||
raise NoUri
|
raise NoUri(docname, typ)
|
||||||
else:
|
else:
|
||||||
return '%' + docname
|
return '%' + docname
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ class TexinfoBuilder(Builder):
|
|||||||
docname = docname[:-5]
|
docname = docname[:-5]
|
||||||
self.titles.append((docname, entry[2]))
|
self.titles.append((docname, entry[2]))
|
||||||
|
|
||||||
def write(self, *ignored) -> None:
|
def write(self, *ignored: Any) -> None:
|
||||||
self.init_document_data()
|
self.init_document_data()
|
||||||
for entry in self.document_data:
|
for entry in self.document_data:
|
||||||
docname, targetname, title, author = entry[:4]
|
docname, targetname, title, author = entry[:4]
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Plain-text Sphinx builder.
|
Plain-text Sphinx builder.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
Docutils-native XML and pseudo-XML builders.
|
Docutils-native XML and pseudo-XML builders.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, Iterator, Set, Type, Union
|
from typing import Any, Dict, Iterator, Set, Union
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.io import StringOutput
|
from docutils.io import StringOutput
|
||||||
@ -23,6 +23,11 @@ from sphinx.util import logging
|
|||||||
from sphinx.util.osutil import ensuredir, os_path
|
from sphinx.util.osutil import ensuredir, os_path
|
||||||
from sphinx.writers.xml import XMLWriter, PseudoXMLWriter
|
from sphinx.writers.xml import XMLWriter, PseudoXMLWriter
|
||||||
|
|
||||||
|
if False:
|
||||||
|
# For type annotation
|
||||||
|
from typing import Type # for python3.5.1
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
Modules for command line executables.
|
Modules for command line executables.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
@ -4,14 +4,16 @@
|
|||||||
|
|
||||||
Build documentation from a provided source.
|
Build documentation from a provided source.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import bdb
|
||||||
import locale
|
import locale
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import os
|
import os
|
||||||
|
import pdb
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
from typing import Any, IO, List
|
from typing import Any, IO, List
|
||||||
@ -29,8 +31,10 @@ from sphinx.util.docutils import docutils_namespace, patch_docutils
|
|||||||
|
|
||||||
|
|
||||||
def handle_exception(app: Sphinx, args: Any, exception: BaseException, stderr: IO = sys.stderr) -> None: # NOQA
|
def handle_exception(app: Sphinx, args: Any, exception: BaseException, stderr: IO = sys.stderr) -> None: # NOQA
|
||||||
|
if isinstance(exception, bdb.BdbQuit):
|
||||||
|
return
|
||||||
|
|
||||||
if args.pdb:
|
if args.pdb:
|
||||||
import pdb
|
|
||||||
print(red(__('Exception occurred while building, starting debugger:')),
|
print(red(__('Exception occurred while building, starting debugger:')),
|
||||||
file=stderr)
|
file=stderr)
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@ -47,7 +51,7 @@ def handle_exception(app: Sphinx, args: Any, exception: BaseException, stderr: I
|
|||||||
print(terminal_safe(exception.args[0]), file=stderr)
|
print(terminal_safe(exception.args[0]), file=stderr)
|
||||||
elif isinstance(exception, SphinxError):
|
elif isinstance(exception, SphinxError):
|
||||||
print(red('%s:' % exception.category), file=stderr)
|
print(red('%s:' % exception.category), file=stderr)
|
||||||
print(terminal_safe(str(exception)), file=stderr)
|
print(str(exception), file=stderr)
|
||||||
elif isinstance(exception, UnicodeError):
|
elif isinstance(exception, UnicodeError):
|
||||||
print(red(__('Encoding error:')), file=stderr)
|
print(red(__('Encoding error:')), file=stderr)
|
||||||
print(terminal_safe(str(exception)), file=stderr)
|
print(terminal_safe(str(exception)), file=stderr)
|
||||||
@ -180,7 +184,7 @@ files can be built by specifying individual filenames.
|
|||||||
group.add_argument('-W', action='store_true', dest='warningiserror',
|
group.add_argument('-W', action='store_true', dest='warningiserror',
|
||||||
help=__('turn warnings into errors'))
|
help=__('turn warnings into errors'))
|
||||||
group.add_argument('--keep-going', action='store_true', dest='keep_going',
|
group.add_argument('--keep-going', action='store_true', dest='keep_going',
|
||||||
help=__("With -W, keep going when getting warnings"))
|
help=__("with -W, keep going when getting warnings"))
|
||||||
group.add_argument('-T', action='store_true', dest='traceback',
|
group.add_argument('-T', action='store_true', dest='traceback',
|
||||||
help=__('show full traceback on exception'))
|
help=__('show full traceback on exception'))
|
||||||
group.add_argument('-P', action='store_true', dest='pdb',
|
group.add_argument('-P', action='store_true', dest='pdb',
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
This is in its own module so that importing it is fast. It should not
|
This is in its own module so that importing it is fast. It should not
|
||||||
import the main Sphinx modules (like sphinx.applications, sphinx.builders).
|
import the main Sphinx modules (like sphinx.applications, sphinx.builders).
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ class Make:
|
|||||||
nocolor()
|
nocolor()
|
||||||
|
|
||||||
print(bold("Sphinx v%s" % sphinx.__display_version__))
|
print(bold("Sphinx v%s" % sphinx.__display_version__))
|
||||||
print("Please use `make %s' where %s is one of" % ((blue('target'),) * 2)) # type: ignore # NOQA
|
print("Please use `make %s' where %s is one of" % ((blue('target'),) * 2))
|
||||||
for osname, bname, description in BUILDERS:
|
for osname, bname, description in BUILDERS:
|
||||||
if not osname or os.name == osname:
|
if not osname or os.name == osname:
|
||||||
print(' %s %s' % (blue(bname.ljust(10)), description))
|
print(' %s %s' % (blue(bname.ljust(10)), description))
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Quickly setup documentation source to work with Sphinx.
|
Quickly setup documentation source to work with Sphinx.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ def generate(d: Dict, overwrite: bool = True, silent: bool = False, templatedir:
|
|||||||
|
|
||||||
ensuredir(d['path'])
|
ensuredir(d['path'])
|
||||||
|
|
||||||
srcdir = d['sep'] and path.join(d['path'], 'source') or d['path']
|
srcdir = path.join(d['path'], 'source') if d['sep'] else d['path']
|
||||||
|
|
||||||
ensuredir(srcdir)
|
ensuredir(srcdir)
|
||||||
if d['sep']:
|
if d['sep']:
|
||||||
@ -405,15 +405,15 @@ def generate(d: Dict, overwrite: bool = True, silent: bool = False, templatedir:
|
|||||||
batchfile_template = 'quickstart/make.bat_t'
|
batchfile_template = 'quickstart/make.bat_t'
|
||||||
|
|
||||||
if d['makefile'] is True:
|
if d['makefile'] is True:
|
||||||
d['rsrcdir'] = d['sep'] and 'source' or '.'
|
d['rsrcdir'] = 'source' if d['sep'] else '.'
|
||||||
d['rbuilddir'] = d['sep'] and 'build' or d['dot'] + 'build'
|
d['rbuilddir'] = 'build' if d['sep'] else d['dot'] + 'build'
|
||||||
# use binary mode, to avoid writing \r\n on Windows
|
# use binary mode, to avoid writing \r\n on Windows
|
||||||
write_file(path.join(d['path'], 'Makefile'),
|
write_file(path.join(d['path'], 'Makefile'),
|
||||||
template.render(makefile_template, d), '\n')
|
template.render(makefile_template, d), '\n')
|
||||||
|
|
||||||
if d['batchfile'] is True:
|
if d['batchfile'] is True:
|
||||||
d['rsrcdir'] = d['sep'] and 'source' or '.'
|
d['rsrcdir'] = 'source' if d['sep'] else '.'
|
||||||
d['rbuilddir'] = d['sep'] and 'build' or d['dot'] + 'build'
|
d['rbuilddir'] = 'build' if d['sep'] else d['dot'] + 'build'
|
||||||
write_file(path.join(d['path'], 'make.bat'),
|
write_file(path.join(d['path'], 'make.bat'),
|
||||||
template.render(batchfile_template, d), '\r\n')
|
template.render(batchfile_template, d), '\r\n')
|
||||||
|
|
||||||
|
125
sphinx/config.py
125
sphinx/config.py
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Build configuration file handling.
|
Build configuration file handling.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -14,7 +14,9 @@ import types
|
|||||||
import warnings
|
import warnings
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from os import path, getenv
|
from os import path, getenv
|
||||||
from typing import Any, NamedTuple, Union
|
from typing import (
|
||||||
|
Any, Callable, Dict, Generator, Iterator, List, NamedTuple, Set, Tuple, Union
|
||||||
|
)
|
||||||
|
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.errors import ConfigError, ExtensionError
|
from sphinx.errors import ConfigError, ExtensionError
|
||||||
@ -23,14 +25,13 @@ from sphinx.util import logging
|
|||||||
from sphinx.util.i18n import format_date
|
from sphinx.util.i18n import format_date
|
||||||
from sphinx.util.osutil import cd
|
from sphinx.util.osutil import cd
|
||||||
from sphinx.util.pycompat import execfile_
|
from sphinx.util.pycompat import execfile_
|
||||||
|
from sphinx.util.tags import Tags
|
||||||
from sphinx.util.typing import NoneType
|
from sphinx.util.typing import NoneType
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Callable, Dict, Generator, Iterator, List, Set, Tuple # NOQA
|
from sphinx.application import Sphinx
|
||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.environment import BuildEnvironment
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
|
||||||
from sphinx.util.tags import Tags # NOQA
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -43,8 +44,7 @@ ConfigValue = NamedTuple('ConfigValue', [('name', str),
|
|||||||
('rebuild', Union[bool, str])])
|
('rebuild', Union[bool, str])])
|
||||||
|
|
||||||
|
|
||||||
def is_serializable(obj):
|
def is_serializable(obj: Any) -> bool:
|
||||||
# type: (Any) -> bool
|
|
||||||
"""Check if object is serializable or not."""
|
"""Check if object is serializable or not."""
|
||||||
if isinstance(obj, UNSERIALIZABLE_TYPES):
|
if isinstance(obj, UNSERIALIZABLE_TYPES):
|
||||||
return False
|
return False
|
||||||
@ -64,12 +64,10 @@ class ENUM:
|
|||||||
Example:
|
Example:
|
||||||
app.add_config_value('latex_show_urls', 'no', None, ENUM('no', 'footnote', 'inline'))
|
app.add_config_value('latex_show_urls', 'no', None, ENUM('no', 'footnote', 'inline'))
|
||||||
"""
|
"""
|
||||||
def __init__(self, *candidates):
|
def __init__(self, *candidates: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
self.candidates = candidates
|
self.candidates = candidates
|
||||||
|
|
||||||
def match(self, value):
|
def match(self, value: Union[str, List, Tuple]) -> bool:
|
||||||
# type: (Union[str, List, Tuple]) -> bool
|
|
||||||
if isinstance(value, (list, tuple)):
|
if isinstance(value, (list, tuple)):
|
||||||
return all(item in self.candidates for item in value)
|
return all(item in self.candidates for item in value)
|
||||||
else:
|
else:
|
||||||
@ -148,6 +146,7 @@ class Config:
|
|||||||
'math_numfig': (True, 'env', []),
|
'math_numfig': (True, 'env', []),
|
||||||
'tls_verify': (True, 'env', []),
|
'tls_verify': (True, 'env', []),
|
||||||
'tls_cacerts': (None, 'env', []),
|
'tls_cacerts': (None, 'env', []),
|
||||||
|
'user_agent': (None, 'env', [str]),
|
||||||
'smartquotes': (True, 'env', []),
|
'smartquotes': (True, 'env', []),
|
||||||
'smartquotes_action': ('qDe', 'env', []),
|
'smartquotes_action': ('qDe', 'env', []),
|
||||||
'smartquotes_excludes': ({'languages': ['ja'],
|
'smartquotes_excludes': ({'languages': ['ja'],
|
||||||
@ -155,36 +154,39 @@ class Config:
|
|||||||
'env', []),
|
'env', []),
|
||||||
} # type: Dict[str, Tuple]
|
} # type: Dict[str, Tuple]
|
||||||
|
|
||||||
def __init__(self, config={}, overrides={}):
|
def __init__(self, config: Dict[str, Any] = {}, overrides: Dict[str, Any] = {}) -> None:
|
||||||
# type: (Dict[str, Any], Dict[str, Any]) -> None
|
self.overrides = dict(overrides)
|
||||||
self.overrides = overrides
|
|
||||||
self.values = Config.config_values.copy()
|
self.values = Config.config_values.copy()
|
||||||
self._raw_config = config
|
self._raw_config = config
|
||||||
self.setup = config.get('setup', None) # type: Callable
|
self.setup = config.get('setup', None) # type: Callable
|
||||||
|
|
||||||
if 'extensions' in overrides:
|
if 'extensions' in self.overrides:
|
||||||
if isinstance(overrides['extensions'], str):
|
if isinstance(self.overrides['extensions'], str):
|
||||||
config['extensions'] = overrides.pop('extensions').split(',')
|
config['extensions'] = self.overrides.pop('extensions').split(',')
|
||||||
else:
|
else:
|
||||||
config['extensions'] = overrides.pop('extensions')
|
config['extensions'] = self.overrides.pop('extensions')
|
||||||
self.extensions = config.get('extensions', []) # type: List[str]
|
self.extensions = config.get('extensions', []) # type: List[str]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def read(cls, confdir, overrides=None, tags=None):
|
def read(cls, confdir: str, overrides: Dict = None, tags: Tags = None) -> "Config":
|
||||||
# type: (str, Dict, Tags) -> Config
|
|
||||||
"""Create a Config object from configuration file."""
|
"""Create a Config object from configuration file."""
|
||||||
filename = path.join(confdir, CONFIG_FILENAME)
|
filename = path.join(confdir, CONFIG_FILENAME)
|
||||||
namespace = eval_config_file(filename, tags)
|
namespace = eval_config_file(filename, tags)
|
||||||
return cls(namespace, overrides or {})
|
return cls(namespace, overrides or {})
|
||||||
|
|
||||||
def convert_overrides(self, name, value):
|
def convert_overrides(self, name: str, value: Any) -> Any:
|
||||||
# type: (str, Any) -> Any
|
|
||||||
if not isinstance(value, str):
|
if not isinstance(value, str):
|
||||||
return value
|
return value
|
||||||
else:
|
else:
|
||||||
defvalue = self.values[name][0]
|
defvalue = self.values[name][0]
|
||||||
if self.values[name][2] == Any:
|
if self.values[name][2] == Any:
|
||||||
return value
|
return value
|
||||||
|
elif type(defvalue) is bool or self.values[name][2] == [bool]:
|
||||||
|
if value == '0':
|
||||||
|
# given falsy string from command line option
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return bool(value)
|
||||||
elif isinstance(defvalue, dict):
|
elif isinstance(defvalue, dict):
|
||||||
raise ValueError(__('cannot override dictionary config setting %r, '
|
raise ValueError(__('cannot override dictionary config setting %r, '
|
||||||
'ignoring (use %r to set individual elements)') %
|
'ignoring (use %r to set individual elements)') %
|
||||||
@ -205,8 +207,7 @@ class Config:
|
|||||||
else:
|
else:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def pre_init_values(self):
|
def pre_init_values(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""
|
"""
|
||||||
Initialize some limited config variables before initialize i18n and loading extensions
|
Initialize some limited config variables before initialize i18n and loading extensions
|
||||||
"""
|
"""
|
||||||
@ -220,8 +221,7 @@ class Config:
|
|||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
logger.warning("%s", exc)
|
logger.warning("%s", exc)
|
||||||
|
|
||||||
def init_values(self):
|
def init_values(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
config = self._raw_config
|
config = self._raw_config
|
||||||
for valname, value in self.overrides.items():
|
for valname, value in self.overrides.items():
|
||||||
try:
|
try:
|
||||||
@ -243,8 +243,7 @@ class Config:
|
|||||||
if name in self.values:
|
if name in self.values:
|
||||||
self.__dict__[name] = config[name]
|
self.__dict__[name] = config[name]
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name: str) -> Any:
|
||||||
# type: (str) -> Any
|
|
||||||
if name.startswith('_'):
|
if name.startswith('_'):
|
||||||
raise AttributeError(name)
|
raise AttributeError(name)
|
||||||
if name not in self.values:
|
if name not in self.values:
|
||||||
@ -254,42 +253,34 @@ class Config:
|
|||||||
return default(self)
|
return default(self)
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def __getitem__(self, name):
|
def __getitem__(self, name: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
return getattr(self, name)
|
return getattr(self, name)
|
||||||
|
|
||||||
def __setitem__(self, name, value):
|
def __setitem__(self, name: str, value: Any) -> None:
|
||||||
# type: (str, Any) -> None
|
|
||||||
setattr(self, name, value)
|
setattr(self, name, value)
|
||||||
|
|
||||||
def __delitem__(self, name):
|
def __delitem__(self, name: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
delattr(self, name)
|
delattr(self, name)
|
||||||
|
|
||||||
def __contains__(self, name):
|
def __contains__(self, name: str) -> bool:
|
||||||
# type: (str) -> bool
|
|
||||||
return name in self.values
|
return name in self.values
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self) -> Generator[ConfigValue, None, None]:
|
||||||
# type: () -> Generator[ConfigValue, None, None]
|
|
||||||
for name, value in self.values.items():
|
for name, value in self.values.items():
|
||||||
yield ConfigValue(name, getattr(self, name), value[1])
|
yield ConfigValue(name, getattr(self, name), value[1])
|
||||||
|
|
||||||
def add(self, name, default, rebuild, types):
|
def add(self, name: str, default: Any, rebuild: Union[bool, str], types: Any) -> None:
|
||||||
# type: (str, Any, Union[bool, str], Any) -> None
|
|
||||||
if name in self.values:
|
if name in self.values:
|
||||||
raise ExtensionError(__('Config value %r already present') % name)
|
raise ExtensionError(__('Config value %r already present') % name)
|
||||||
else:
|
else:
|
||||||
self.values[name] = (default, rebuild, types)
|
self.values[name] = (default, rebuild, types)
|
||||||
|
|
||||||
def filter(self, rebuild):
|
def filter(self, rebuild: Union[str, List[str]]) -> Iterator[ConfigValue]:
|
||||||
# type: (Union[str, List[str]]) -> Iterator[ConfigValue]
|
|
||||||
if isinstance(rebuild, str):
|
if isinstance(rebuild, str):
|
||||||
rebuild = [rebuild]
|
rebuild = [rebuild]
|
||||||
return (value for value in self if value.rebuild in rebuild)
|
return (value for value in self if value.rebuild in rebuild)
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self) -> Dict:
|
||||||
# type: () -> Dict
|
|
||||||
"""Obtains serializable data for pickling."""
|
"""Obtains serializable data for pickling."""
|
||||||
# remove potentially pickling-problematic values from config
|
# remove potentially pickling-problematic values from config
|
||||||
__dict__ = {}
|
__dict__ = {}
|
||||||
@ -312,13 +303,11 @@ class Config:
|
|||||||
|
|
||||||
return __dict__
|
return __dict__
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state: Dict) -> None:
|
||||||
# type: (Dict) -> None
|
|
||||||
self.__dict__.update(state)
|
self.__dict__.update(state)
|
||||||
|
|
||||||
|
|
||||||
def eval_config_file(filename, tags):
|
def eval_config_file(filename: str, tags: Tags) -> Dict[str, Any]:
|
||||||
# type: (str, Tags) -> Dict[str, Any]
|
|
||||||
"""Evaluate a config file."""
|
"""Evaluate a config file."""
|
||||||
namespace = {} # type: Dict[str, Any]
|
namespace = {} # type: Dict[str, Any]
|
||||||
namespace['__file__'] = filename
|
namespace['__file__'] = filename
|
||||||
@ -335,6 +324,9 @@ def eval_config_file(filename, tags):
|
|||||||
msg = __("The configuration file (or one of the modules it imports) "
|
msg = __("The configuration file (or one of the modules it imports) "
|
||||||
"called sys.exit()")
|
"called sys.exit()")
|
||||||
raise ConfigError(msg)
|
raise ConfigError(msg)
|
||||||
|
except ConfigError:
|
||||||
|
# pass through ConfigError from conf.py as is. It will be shown in console.
|
||||||
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
msg = __("There is a programmable error in your configuration file:\n\n%s")
|
msg = __("There is a programmable error in your configuration file:\n\n%s")
|
||||||
raise ConfigError(msg % traceback.format_exc())
|
raise ConfigError(msg % traceback.format_exc())
|
||||||
@ -342,8 +334,7 @@ def eval_config_file(filename, tags):
|
|||||||
return namespace
|
return namespace
|
||||||
|
|
||||||
|
|
||||||
def convert_source_suffix(app, config):
|
def convert_source_suffix(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""This converts old styled source_suffix to new styled one.
|
"""This converts old styled source_suffix to new styled one.
|
||||||
|
|
||||||
* old style: str or list
|
* old style: str or list
|
||||||
@ -368,8 +359,7 @@ def convert_source_suffix(app, config):
|
|||||||
"But `%r' is given." % source_suffix))
|
"But `%r' is given." % source_suffix))
|
||||||
|
|
||||||
|
|
||||||
def init_numfig_format(app, config):
|
def init_numfig_format(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""Initialize :confval:`numfig_format`."""
|
"""Initialize :confval:`numfig_format`."""
|
||||||
numfig_format = {'section': _('Section %s'),
|
numfig_format = {'section': _('Section %s'),
|
||||||
'figure': _('Fig. %s'),
|
'figure': _('Fig. %s'),
|
||||||
@ -381,8 +371,7 @@ def init_numfig_format(app, config):
|
|||||||
config.numfig_format = numfig_format # type: ignore
|
config.numfig_format = numfig_format # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def correct_copyright_year(app, config):
|
def correct_copyright_year(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""correct values of copyright year that are not coherent with
|
"""correct values of copyright year that are not coherent with
|
||||||
the SOURCE_DATE_EPOCH environment variable (if set)
|
the SOURCE_DATE_EPOCH environment variable (if set)
|
||||||
|
|
||||||
@ -395,8 +384,7 @@ def correct_copyright_year(app, config):
|
|||||||
config[k] = copyright_year_re.sub(replace, config[k])
|
config[k] = copyright_year_re.sub(replace, config[k])
|
||||||
|
|
||||||
|
|
||||||
def check_confval_types(app, config):
|
def check_confval_types(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""check all values for deviation from the default value's type, since
|
"""check all values for deviation from the default value's type, since
|
||||||
that can result in TypeErrors all over the place NB.
|
that can result in TypeErrors all over the place NB.
|
||||||
"""
|
"""
|
||||||
@ -451,8 +439,7 @@ def check_confval_types(app, config):
|
|||||||
default=type(default)))
|
default=type(default)))
|
||||||
|
|
||||||
|
|
||||||
def check_unicode(config):
|
def check_unicode(config: Config) -> None:
|
||||||
# type: (Config) -> None
|
|
||||||
"""check all string values for non-ASCII characters in bytestrings,
|
"""check all string values for non-ASCII characters in bytestrings,
|
||||||
since that can result in UnicodeErrors all over the place
|
since that can result in UnicodeErrors all over the place
|
||||||
"""
|
"""
|
||||||
@ -468,16 +455,15 @@ def check_unicode(config):
|
|||||||
'Please use Unicode strings, e.g. %r.'), name, 'Content')
|
'Please use Unicode strings, e.g. %r.'), name, 'Content')
|
||||||
|
|
||||||
|
|
||||||
def check_primary_domain(app, config):
|
def check_primary_domain(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
primary_domain = config.primary_domain
|
primary_domain = config.primary_domain
|
||||||
if primary_domain and not app.registry.has_domain(primary_domain):
|
if primary_domain and not app.registry.has_domain(primary_domain):
|
||||||
logger.warning(__('primary_domain %r not found, ignored.'), primary_domain)
|
logger.warning(__('primary_domain %r not found, ignored.'), primary_domain)
|
||||||
config.primary_domain = None # type: ignore
|
config.primary_domain = None # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def check_master_doc(app, env, added, changed, removed):
|
def check_master_doc(app: "Sphinx", env: "BuildEnvironment", added: Set[str],
|
||||||
# type: (Sphinx, BuildEnvironment, Set[str], Set[str], Set[str]) -> Set[str]
|
changed: Set[str], removed: Set[str]) -> Set[str]:
|
||||||
"""Adjust master_doc to 'contents' to support an old project which does not have
|
"""Adjust master_doc to 'contents' to support an old project which does not have
|
||||||
no master_doc setting.
|
no master_doc setting.
|
||||||
"""
|
"""
|
||||||
@ -491,13 +477,12 @@ def check_master_doc(app, env, added, changed, removed):
|
|||||||
return changed
|
return changed
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
app.connect('config-inited', convert_source_suffix, priority=800)
|
||||||
app.connect('config-inited', convert_source_suffix)
|
app.connect('config-inited', init_numfig_format, priority=800)
|
||||||
app.connect('config-inited', init_numfig_format)
|
app.connect('config-inited', correct_copyright_year, priority=800)
|
||||||
app.connect('config-inited', correct_copyright_year)
|
app.connect('config-inited', check_confval_types, priority=800)
|
||||||
app.connect('config-inited', check_confval_types)
|
app.connect('config-inited', check_primary_domain, priority=800)
|
||||||
app.connect('config-inited', check_primary_domain)
|
|
||||||
app.connect('env-get-outdated', check_master_doc)
|
app.connect('env-get-outdated', check_master_doc)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -4,17 +4,18 @@
|
|||||||
|
|
||||||
Sphinx deprecation classes and utilities.
|
Sphinx deprecation classes and utilities.
|
||||||
|
|
||||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, Type # NOQA
|
from typing import Type # for python3.5.1
|
||||||
|
|
||||||
|
|
||||||
class RemovedInSphinx40Warning(DeprecationWarning):
|
class RemovedInSphinx40Warning(DeprecationWarning):
|
||||||
@ -28,25 +29,20 @@ class RemovedInSphinx50Warning(PendingDeprecationWarning):
|
|||||||
RemovedInNextVersionWarning = RemovedInSphinx40Warning
|
RemovedInNextVersionWarning = RemovedInSphinx40Warning
|
||||||
|
|
||||||
|
|
||||||
def deprecated_alias(modname, objects, warning):
|
def deprecated_alias(modname: str, objects: Dict, warning: "Type[Warning]") -> None:
|
||||||
# type: (str, Dict, Type[Warning]) -> None
|
module = import_module(modname)
|
||||||
module = sys.modules.get(modname)
|
|
||||||
if module is None:
|
|
||||||
module = import_module(modname)
|
|
||||||
|
|
||||||
sys.modules[modname] = _ModuleWrapper(module, modname, objects, warning) # type: ignore
|
sys.modules[modname] = _ModuleWrapper(module, modname, objects, warning) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class _ModuleWrapper:
|
class _ModuleWrapper:
|
||||||
def __init__(self, module, modname, objects, warning):
|
def __init__(self, module: Any, modname: str, objects: Dict, warning: "Type[Warning]"
|
||||||
# type: (Any, str, Dict, Type[Warning]) -> None
|
) -> None:
|
||||||
self._module = module
|
self._module = module
|
||||||
self._modname = modname
|
self._modname = modname
|
||||||
self._objects = objects
|
self._objects = objects
|
||||||
self._warning = warning
|
self._warning = warning
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name: str) -> Any:
|
||||||
# type: (str) -> Any
|
|
||||||
if name in self._objects:
|
if name in self._objects:
|
||||||
warnings.warn("%s.%s is deprecated. Check CHANGES for Sphinx "
|
warnings.warn("%s.%s is deprecated. Check CHANGES for Sphinx "
|
||||||
"API modifications." % (self._modname, name),
|
"API modifications." % (self._modname, name),
|
||||||
@ -59,33 +55,27 @@ class _ModuleWrapper:
|
|||||||
class DeprecatedDict(dict):
|
class DeprecatedDict(dict):
|
||||||
"""A deprecated dict which warns on each access."""
|
"""A deprecated dict which warns on each access."""
|
||||||
|
|
||||||
def __init__(self, data, message, warning):
|
def __init__(self, data: Dict, message: str, warning: "Type[Warning]") -> None:
|
||||||
# type: (Dict, str, Type[Warning]) -> None
|
|
||||||
self.message = message
|
self.message = message
|
||||||
self.warning = warning
|
self.warning = warning
|
||||||
super().__init__(data)
|
super().__init__(data)
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
# type: (str, Any) -> None
|
|
||||||
warnings.warn(self.message, self.warning, stacklevel=2)
|
warnings.warn(self.message, self.warning, stacklevel=2)
|
||||||
super().__setitem__(key, value)
|
super().__setitem__(key, value)
|
||||||
|
|
||||||
def setdefault(self, key, default=None):
|
def setdefault(self, key: str, default: Any = None) -> Any:
|
||||||
# type: (str, Any) -> None
|
|
||||||
warnings.warn(self.message, self.warning, stacklevel=2)
|
warnings.warn(self.message, self.warning, stacklevel=2)
|
||||||
return super().setdefault(key, default)
|
return super().setdefault(key, default)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
warnings.warn(self.message, self.warning, stacklevel=2)
|
warnings.warn(self.message, self.warning, stacklevel=2)
|
||||||
return super().__getitem__(key)
|
return super().__getitem__(key)
|
||||||
|
|
||||||
def get(self, key, default=None):
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
# type: (str, Any) -> None
|
|
||||||
warnings.warn(self.message, self.warning, stacklevel=2)
|
warnings.warn(self.message, self.warning, stacklevel=2)
|
||||||
return super().get(key, default)
|
return super().get(key, default)
|
||||||
|
|
||||||
def update(self, other=None): # type: ignore
|
def update(self, other: Dict) -> None: # type: ignore
|
||||||
# type: (Dict) -> None
|
|
||||||
warnings.warn(self.message, self.warning, stacklevel=2)
|
warnings.warn(self.message, self.warning, stacklevel=2)
|
||||||
super().update(other)
|
super().update(other)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user