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:
|
||||
- checkout
|
||||
- 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
|
||||
|
@ -1,3 +1,4 @@
|
||||
comment: false
|
||||
coverage:
|
||||
status:
|
||||
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>
|
||||
|
||||
<!--
|
||||
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
|
||||
<!-- please choose -->
|
||||
- Feature
|
||||
- Bugfix
|
||||
- Refactoring
|
||||
|
||||
### Purpose
|
||||
- <long purpose of this pull request>
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -23,6 +23,7 @@ distribute-*
|
||||
env/
|
||||
build/
|
||||
dist/
|
||||
docker/
|
||||
Sphinx.egg-info/
|
||||
doc/_build/
|
||||
doc/locale/
|
||||
|
17
.travis.yml
17
.travis.yml
@ -1,6 +1,6 @@
|
||||
language: python
|
||||
sudo: false
|
||||
os: linux
|
||||
dist: xenial
|
||||
language: python
|
||||
cache: pip
|
||||
|
||||
env:
|
||||
@ -9,7 +9,7 @@ env:
|
||||
- SKIP_LATEX_BUILD=1
|
||||
- IS_PYTHON=true
|
||||
|
||||
matrix:
|
||||
jobs:
|
||||
include:
|
||||
- python: '3.5'
|
||||
env:
|
||||
@ -19,10 +19,14 @@ matrix:
|
||||
- TOXENV=du13
|
||||
- python: '3.7'
|
||||
env:
|
||||
- TOXENV=py37
|
||||
- TOXENV=du14
|
||||
- python: '3.8'
|
||||
env:
|
||||
- TOXENV=du15
|
||||
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
|
||||
- python: 'nightly'
|
||||
env: TOXENV=py38
|
||||
env:
|
||||
- TOXENV=du16
|
||||
- python: '3.6'
|
||||
env: TOXENV=docs
|
||||
- python: '3.6'
|
||||
@ -33,8 +37,7 @@ matrix:
|
||||
env: TOXENV=flake8
|
||||
|
||||
- language: node_js
|
||||
node_js:
|
||||
- 10.7
|
||||
node_js: '10.7'
|
||||
env: IS_PYTHON=false
|
||||
services: xvfb
|
||||
|
||||
|
4
AUTHORS
4
AUTHORS
@ -25,6 +25,7 @@ Other contributors, listed alphabetically, are:
|
||||
* Henrique Bastos -- SVG support for graphviz extension
|
||||
* Daniel Bültmann -- todo extension
|
||||
* Marco Buttu -- doctest extension (pyversion option)
|
||||
* Nathan Damon -- bugfix in validation of static paths in html builders
|
||||
* Etienne Desautels -- apidoc module
|
||||
* Michael Droettboom -- inheritance_diagram extension
|
||||
* Charles Duffy -- original graphviz extension
|
||||
@ -35,7 +36,7 @@ Other contributors, listed alphabetically, are:
|
||||
* Hernan Grecco -- search improvements
|
||||
* Horst Gutmann -- internationalization support
|
||||
* Martin Hans -- autodoc improvements
|
||||
* Zac Hatfield-Dodds -- doctest reporting improvements
|
||||
* Zac Hatfield-Dodds -- doctest reporting improvements, intersphinx performance
|
||||
* Doug Hellmann -- graphviz improvements
|
||||
* Tim Hoffmann -- theme improvements
|
||||
* Antti Kaihola -- doctest extension (skipif option)
|
||||
@ -63,6 +64,7 @@ Other contributors, listed alphabetically, are:
|
||||
* \T. Powers -- HTML output improvements
|
||||
* Jeppe Pihl -- literalinclude improvements
|
||||
* Rob Ruana -- napoleon extension
|
||||
* Vince Salvino -- JavaScript search improvements
|
||||
* Stefan Seefeld -- toctree improvements
|
||||
* Gregory Szorc -- performance improvements
|
||||
* 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
|
||||
@ -7,18 +7,35 @@ Dependencies
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
* 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
|
||||
* #7477: imgconverter: Invoke "magick convert" command by default on Windows
|
||||
|
||||
Deprecated
|
||||
----------
|
||||
|
||||
* The ``module`` argument of ``sphinx.ext.autosummary.generate.
|
||||
find_autosummary_in_docstring()``
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
||||
* #247: autosummary: Add :confval:`autosummary_generate_overwrite` to overwrite
|
||||
old stub file
|
||||
* LaTeX: Make the ``toplevel_sectioning`` setting optional in LaTeX theme
|
||||
* 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
|
||||
----------
|
||||
@ -26,7 +43,7 @@ Bugs fixed
|
||||
Testing
|
||||
--------
|
||||
|
||||
Release 2.2.0 (in development)
|
||||
Release 3.0.3 (in development)
|
||||
==============================
|
||||
|
||||
Dependencies
|
||||
@ -35,7 +52,546 @@ Dependencies
|
||||
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``
|
||||
* html: Field lists will be styled by grid layout
|
||||
|
||||
Deprecated
|
||||
----------
|
||||
@ -60,7 +616,12 @@ Features added
|
||||
* #6514: html: Add a label to search input for accessability purposes
|
||||
* #5602: apidoc: Add ``--templatedir`` option
|
||||
* #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``
|
||||
* #6628: quickstart: Use ``https://docs.python.org/3/`` for default setting of
|
||||
:confval:`intersphinx_mapping`
|
||||
* #6419: sphinx-build: give reasons why rebuilded
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@ -72,6 +633,13 @@ Bugs fixed
|
||||
* #5502: linkcheck: Consider HTTP 503 response as not an error
|
||||
* #6439: Make generated download links reproducible
|
||||
* #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
|
||||
* #6507: autosummary: crashes without no autosummary_generate setting
|
||||
* #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
|
||||
* #5592: std domain: :rst:dir:`option` directive registers an index entry for
|
||||
each comma separated option
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
||||
Release 2.1.3 (in development)
|
||||
==============================
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
Deprecated
|
||||
----------
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
Testing
|
||||
--------
|
||||
* #6549: sphinx-build: Escaped characters in error messages
|
||||
* #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
|
||||
docutils-0.15
|
||||
* #6474: ``DocFieldTransformer`` raises AttributeError when given directive is
|
||||
not a subclass of ObjectDescription
|
||||
|
||||
Release 2.1.2 (released Jun 19, 2019)
|
||||
=====================================
|
||||
@ -212,8 +763,6 @@ Features added
|
||||
|
||||
* #6180: Support ``--keep-going`` with BuildDoc setup command
|
||||
* ``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
|
||||
* Enable override via environment of ``SPHINXOPTS`` and ``SPHINXBUILD`` Makefile
|
||||
variables (refs: #6232, #6303)
|
||||
@ -968,6 +1517,8 @@ Features added
|
||||
* #5029: autosummary: expose ``inherited_members`` to template
|
||||
* #3784: mathjax: Add :confval:`mathjax_options` to give options to script tag
|
||||
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
|
||||
* #1431: latex: Add alphanumeric enumerated list support
|
||||
* Add :confval:`latex_use_xindy` for UTF-8 savvy indexing, defaults to ``True``
|
||||
@ -1787,7 +2338,7 @@ Features removed
|
||||
|
||||
* ``termsep`` node
|
||||
* 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
|
||||
* sphinx.ext.pngmath extension
|
||||
* ``sphinx.util.compat.make_admonition()``
|
||||
@ -4591,7 +5142,7 @@ Features added
|
||||
|
||||
- Added a "nitpicky" mode that emits warnings for all missing
|
||||
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.
|
||||
|
||||
* 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
|
||||
free to email the *sphinx-dev* mailing list.
|
||||
#. 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`_).
|
||||
#. Write a test which shows that the bug was fixed or that the feature works
|
||||
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/ ).
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
#. 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.
|
||||
|
||||
|
||||
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
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
@ -228,39 +236,6 @@ The following are some general guidelines for core developers:
|
||||
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
|
||||
------------
|
||||
|
||||
@ -325,8 +300,8 @@ Versioning 2.0.0 (refs: https://semver.org/ ).
|
||||
All changes including incompatible behaviors and public API updates are
|
||||
allowed.
|
||||
|
||||
``X.Y``
|
||||
Where ``X.Y`` is the ``MAJOR.MINOR`` release. Used to maintain current
|
||||
``A.x`` (ex. ``2.x``)
|
||||
Where ``A.x`` is the ``MAJOR.MINOR`` release. Used to maintain current
|
||||
MINOR release. All changes are allowed if the change preserves
|
||||
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
|
||||
deleted and replaced by an equivalent tag.
|
||||
|
||||
``X.Y.Z``
|
||||
Where ``X.Y.Z`` is the ``MAJOR.MINOR.PATCH`` release. Only
|
||||
``A.B.x`` (ex. ``2.4.x``)
|
||||
Where ``A.B.x`` is the ``MAJOR.MINOR.PATCH`` release. Only
|
||||
backwards-compatible bug fixes are allowed. In Sphinx project, PATCH
|
||||
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
|
||||
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.
|
||||
|
||||
The warnings are displayed by default. You can turn off display of these
|
||||
warnings with:
|
||||
Deprecation warnings
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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)
|
||||
* ``export PYTHONWARNINGS=`` and do ``make html`` (Linux/Mac)
|
||||
* ``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
|
||||
------------
|
||||
|
||||
@ -426,3 +414,42 @@ and other ``test_*.py`` files under ``tests`` directory.
|
||||
|
||||
.. versionadded:: 1.8
|
||||
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)
|
||||
* `Dataiku DSS <https://doc.dataiku.com/>`__
|
||||
* `DNF <https://dnf.readthedocs.io/>`__
|
||||
* `Django-cas-ng <https://djangocas.dev/docs/>`__
|
||||
* `edX <https://docs.edx.org/>`__
|
||||
* `Electrum <http://docs.electrum.org/>`__
|
||||
* `Elemental <http://libelemental.org/documentation/dev/>`__
|
||||
@ -212,6 +213,7 @@ Documentation using sphinx_rtd_theme
|
||||
* `Lasagne <https://lasagne.readthedocs.io/>`__
|
||||
* `latexindent.pl <https://latexindentpl.readthedocs.io/>`__
|
||||
* `Learning Apache Spark with Python <https://runawayhorse001.github.io/LearningApacheSpark>`__
|
||||
* `LibCEED <https://libceed.readthedocs.io/>`__
|
||||
* `Linguistica <https://linguistica-uchicago.github.io/lxa5/>`__
|
||||
* `Linux kernel <https://www.kernel.org/doc/html/latest/index.html>`__
|
||||
* `Mailman <http://docs.list.org/>`__
|
||||
@ -242,6 +244,7 @@ Documentation using sphinx_rtd_theme
|
||||
* `PyPy <http://doc.pypy.org/>`__
|
||||
* `python-sqlparse <https://sqlparse.readthedocs.io/>`__
|
||||
* `PyVISA <https://pyvisa.readthedocs.io/>`__
|
||||
* `pyvista <https://docs.pyvista.org/>`__
|
||||
* `Read The Docs <https://docs.readthedocs.io/>`__
|
||||
* `Free your information from their silos (French) <http://redaction-technique.org/>`__ (customized)
|
||||
* `Releases Sphinx extension <https://releases.readthedocs.io/>`__
|
||||
@ -404,6 +407,7 @@ Books produced using Sphinx
|
||||
* `"Python Professional Programming" (in Japanese) <http://www.amazon.co.jp/dp/4798032948/>`__
|
||||
* `"Python Professional Programming 2nd Edition" (in Japanese) <https://www.amazon.co.jp/dp/479804315X/>`__
|
||||
* `"Python Professional Programming 3rd Edition" (in Japanese) <https://www.amazon.co.jp/dp/4798053821/>`__
|
||||
* `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/>`__
|
||||
* `"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>`__
|
||||
|
3
Makefile
3
Makefile
@ -31,6 +31,7 @@ clean-backupfiles:
|
||||
clean-generated:
|
||||
find . -name '.DS_Store' -exec rm -f {} +
|
||||
rm -rf Sphinx.egg-info/
|
||||
rm -rf dist/
|
||||
rm -rf doc/_build/
|
||||
rm -f sphinx/pycode/*.pickle
|
||||
rm -f utils/*3.py*
|
||||
@ -49,7 +50,7 @@ clean-buildfiles:
|
||||
|
||||
.PHONY: clean-mypyfiles
|
||||
clean-mypyfiles:
|
||||
rm -rf .mypy_cache/
|
||||
find . -name '.mypy_cache' -exec rm -rf {} +
|
||||
|
||||
.PHONY: style-check
|
||||
style-check:
|
||||
|
@ -26,6 +26,10 @@
|
||||
:target: https://codecov.io/gh/sphinx-doc/sphinx
|
||||
: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
|
||||
documentation for Python projects (or other documents consisting of multiple
|
||||
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
|
||||
.. _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
|
||||
=======
|
||||
|
||||
|
@ -5,7 +5,6 @@ PYTHON ?= python3
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = $(PYTHON) ../sphinx/cmd/build.py
|
||||
SPHINXPROJ = sphinx
|
||||
SOURCEDIR = .
|
||||
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
|
||||
developers.{%endtrans%}</p>
|
||||
|
||||
<p>{%trans%}There is a <a href="http://docs.sphinx-users.jp/">Japanese translation</a>
|
||||
of this documentation, thanks to the Japanese Sphinx user group.{%endtrans%}</p>
|
||||
<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 Sphinx document translators.{%endtrans%}</p>
|
||||
<p>{%trans%}A Japanese book about Sphinx has been published by O'Reilly:
|
||||
<a href="https://www.oreilly.co.jp/books/9784873116488/">Sphinxをはじめよう /
|
||||
Learning Sphinx</a>.{%endtrans%}</p>
|
||||
@ -120,4 +120,8 @@
|
||||
<li>{%trans path=pathto("authors")%}<a href="{{ path }}">Sphinx Authors</a></li>{%endtrans%}
|
||||
</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 %}
|
||||
|
7
doc/_themes/sphinx13/layout.html
vendored
7
doc/_themes/sphinx13/layout.html
vendored
@ -13,11 +13,6 @@
|
||||
{% block sidebar1 %}{{ sidebar() }}{% endblock %}
|
||||
{% block sidebar2 %}{% endblock %}
|
||||
|
||||
{% block linktags %}
|
||||
{{ super() }}
|
||||
<link rel="canonical" href="http://www.sphinx-doc.org/en/master/{{ pagename }}{{ file_suffix }}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block extrahead %}
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,700'
|
||||
rel='stylesheet' type='text/css' />
|
||||
@ -30,7 +25,7 @@
|
||||
.related { display: none; }
|
||||
{% endif %}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
// intelligent scrolling of the sidebar content
|
||||
$(window).scroll(function() {
|
||||
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;
|
||||
}
|
||||
|
||||
/* avoid font-size when :mod: role in headings */
|
||||
h1 code, h2 code, h3 code, h4 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
cite, code, tt {
|
||||
font-family: 'Consolas', 'DejaVu Sans Mono',
|
||||
'Bitstream Vera Sans Mono', monospace;
|
||||
|
@ -1,4 +1,4 @@
|
||||
:tocdepth: 2
|
||||
:tocdepth: 1
|
||||
|
||||
.. 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',
|
||||
'sphinx.ext.autosummary', 'sphinx.ext.extlinks',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.viewcode', 'sphinx.ext.inheritance_diagram']
|
||||
|
||||
master_doc = 'contents'
|
||||
@ -14,7 +15,7 @@ templates_path = ['_templates']
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
project = 'Sphinx'
|
||||
copyright = '2007-2019, Georg Brandl and the Sphinx team'
|
||||
copyright = '2007-2020, Georg Brandl and the Sphinx team'
|
||||
version = sphinx.__display_version__
|
||||
release = version
|
||||
show_authors = True
|
||||
@ -25,7 +26,8 @@ modindex_common_prefix = ['sphinx.']
|
||||
html_static_path = ['_static']
|
||||
html_sidebars = {'index': ['indexsidebar.html', 'searchbox.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'
|
||||
|
||||
@ -146,6 +148,9 @@ def setup(app):
|
||||
app.add_object_type('confval', 'confval',
|
||||
objname='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',
|
||||
names=['param'], can_collapse=True)
|
||||
app.add_object_type('event', 'event', 'pair: %s; event', parse_event,
|
||||
|
@ -34,6 +34,7 @@ Sphinx documentation contents
|
||||
changes
|
||||
examples
|
||||
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
|
||||
- autoanysrc: Gather reST documentation from any source files
|
||||
- autorun: Execute code in a ``runblock`` directive
|
||||
- beamer_: A builder for Beamer (LaTeX) output.
|
||||
- blockdiag: embed block diagrams by using blockdiag_
|
||||
- cacoo: embed diagram from Cacoo
|
||||
- cf3domain: a domain for CFEngine 3 policies
|
||||
@ -148,3 +149,4 @@ started with writing your own extensions.
|
||||
.. _domaintools: https://bitbucket.org/klorenz/sphinxcontrib-domaintools
|
||||
.. _restbuilder: https://pypi.org/project/sphinxcontrib-restbuilder/
|
||||
.. _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.
|
||||
env = app.builder.env
|
||||
|
||||
if not hasattr(env, 'todo_all_todos'):
|
||||
env.todo_all_todos = []
|
||||
|
||||
for node in doctree.traverse(todolist):
|
||||
if not app.config.todo_include_todos:
|
||||
node.replace_self([])
|
||||
|
@ -75,7 +75,7 @@ The first thing to examine is the ``RecipeDirective`` directive:
|
||||
.. literalinclude:: examples/recipe.py
|
||||
:language: python
|
||||
:linenos:
|
||||
:lines: 17-37
|
||||
:pyobject: RecipeDirective
|
||||
|
||||
Unlike :doc:`helloworld` and :doc:`todo`, this directive doesn't derive from
|
||||
:class:`docutils.parsers.rst.Directive` and doesn't define a ``run`` method.
|
||||
@ -103,7 +103,12 @@ reStructuredText in the body.
|
||||
.. literalinclude:: examples/recipe.py
|
||||
:language: python
|
||||
:linenos:
|
||||
:lines: 40-102
|
||||
:pyobject: IngredientIndex
|
||||
|
||||
.. literalinclude:: examples/recipe.py
|
||||
:language: python
|
||||
:linenos:
|
||||
:pyobject: RecipeIndex
|
||||
|
||||
Both ``IngredientIndex`` and ``RecipeIndex`` are derived from :class:`Index`.
|
||||
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
|
||||
</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
|
||||
|
||||
A Sphinx domain is a specialized container that ties together roles,
|
||||
@ -126,7 +135,7 @@ creating here.
|
||||
.. literalinclude:: examples/recipe.py
|
||||
:language: python
|
||||
:linenos:
|
||||
:lines: 105-155
|
||||
:pyobject: RecipeDomain
|
||||
|
||||
There are some interesting things to note about this ``recipe`` domain and domains
|
||||
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
|
||||
:language: python
|
||||
:linenos:
|
||||
:lines: 158-
|
||||
:pyobject: setup
|
||||
|
||||
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
|
||||
|
@ -107,6 +107,20 @@ is just a "general" node.
|
||||
<http://docutils.sourceforge.net/docs/ref/doctree.html>`__ and :ref:`Sphinx
|
||||
<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
|
||||
|
||||
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)
|
||||
|
||||
.. method:: Sphinx.add_directive(name, func, content, arguments, \*\*options)
|
||||
.. automethod:: Sphinx.add_directive(name, directiveclass)
|
||||
|
||||
.. automethod:: Sphinx.add_role(name, role)
|
||||
@ -54,7 +53,6 @@ package.
|
||||
|
||||
.. 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_role_to_domain(domain, name, role)
|
||||
@ -107,6 +105,7 @@ Emitting events
|
||||
---------------
|
||||
|
||||
.. class:: Sphinx
|
||||
:noindex:
|
||||
|
||||
.. automethod:: emit(event, \*arguments)
|
||||
|
||||
@ -216,6 +215,14 @@ connect handlers to the events. Example:
|
||||
|
||||
.. 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)
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
.. event:: env-updated (app, env)
|
||||
|
@ -26,6 +26,228 @@ The following is a list of deprecated interfaces.
|
||||
- (will be) Removed
|
||||
- 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()``
|
||||
- 2.2
|
||||
- 4.0
|
||||
|
@ -35,25 +35,25 @@ In practice, you have to:
|
||||
:func:`sphinx.locale.get_translation` function, usually renamed ``_()``,
|
||||
e.g.:
|
||||
|
||||
.. code-block:: python
|
||||
:caption: src/__init__.py
|
||||
.. code-block:: python
|
||||
:caption: src/__init__.py
|
||||
|
||||
from sphinx.locale import get_translation
|
||||
from sphinx.locale import get_translation
|
||||
|
||||
MESSAGE_CATALOG_NAME = 'myextension'
|
||||
_ = get_translation(MESSAGE_CATALOG_NAME)
|
||||
MESSAGE_CATALOG_NAME = 'myextension'
|
||||
_ = get_translation(MESSAGE_CATALOG_NAME)
|
||||
|
||||
translated_text = _('Hello Sphinx!')
|
||||
translated_text = _('Hello Sphinx!')
|
||||
|
||||
#. Set up your extension to be aware of its dedicated translations:
|
||||
|
||||
.. code-block:: python
|
||||
:caption: src/__init__.py
|
||||
.. code-block:: python
|
||||
:caption: src/__init__.py
|
||||
|
||||
def setup(app):
|
||||
package_dir = path.abspath(path.dirname(__file__))
|
||||
locale_dir = os.path.join(package_dir, 'locales')
|
||||
app.add_message_catalog(MESSAGE_CATALOG_NAME, locale_dir)
|
||||
def setup(app):
|
||||
package_dir = path.abspath(path.dirname(__file__))
|
||||
locale_dir = os.path.join(package_dir, 'locales')
|
||||
app.add_message_catalog(MESSAGE_CATALOG_NAME, locale_dir)
|
||||
|
||||
#. Generate message catalog template ``*.pot`` file, usually in ``locale/``
|
||||
source directory, for example via `Babel`_:
|
||||
|
@ -27,7 +27,7 @@ Discovery of builders by entry point
|
||||
|
||||
.. 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
|
||||
value.
|
||||
|
||||
|
@ -89,7 +89,7 @@ Google Analytics
|
||||
|
||||
{%- block extrahead %}
|
||||
{{ super() }}
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'XXX account number XXX']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
@ -101,7 +101,7 @@ Google Analytics
|
||||
<div class="footer">This page uses <a href="https://analytics.google.com/">
|
||||
Google Analytics</a> to collect statistics. You can disable it by blocking
|
||||
the JavaScript coming from www.google-analytics.com.
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.src = ('https:' == document.location.protocol ?
|
||||
@ -132,7 +132,6 @@ Google Search
|
||||
(function() {
|
||||
var cx = '......';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
|
@ -55,9 +55,9 @@ See the :ref:`pertinent section in the FAQ list <usingwith>`.
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Sphinx needs at least **Python 3.5** to run, as well as the docutils_ and
|
||||
Jinja2_ libraries. Sphinx should work with docutils version 0.12 or some (not
|
||||
broken) SVN trunk snapshot.
|
||||
Sphinx needs at least **Python 3.5** to run.
|
||||
It also depends on 3rd party libraries such as docutils_ and jinja2_, but they
|
||||
are automatically installed when sphinx is installed.
|
||||
|
||||
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
|
||||
.. _docutils: http://docutils.sourceforge.net/
|
||||
|
@ -226,6 +226,25 @@ into the generated ``.tex`` files. Its ``'sphinxsetup'`` key is described
|
||||
|
||||
.. 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'``
|
||||
Additional footer content (before the indices), default empty.
|
||||
|
||||
@ -289,6 +308,11 @@ into the generated ``.tex`` files. Its ``'sphinxsetup'`` key is described
|
||||
|
||||
.. 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
|
||||
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
|
||||
@ -310,12 +334,19 @@ into the generated ``.tex`` files. Its ``'sphinxsetup'`` key is described
|
||||
.. versionchanged:: 2.0
|
||||
``'lualatex'`` executes
|
||||
``\defaultfontfeatures[\rmfamily,\sffamily]{}`` to disable TeX
|
||||
ligatures.
|
||||
ligatures transforming `<<` and `>>` as escaping working with
|
||||
``pdflatex/xelatex`` failed with ``lualatex``.
|
||||
.. versionchanged:: 2.0
|
||||
Detection of ``LGR``, ``T2A``, ``X2`` to trigger support of
|
||||
occasional Greek or Cyrillic (``'pdflatex'`` only, as this support
|
||||
is provided natively by ``'platex'`` and only requires suitable
|
||||
font with ``'xelatex'/'lualatex'``).
|
||||
.. 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'``
|
||||
The default (``'pdflatex'`` only) is
|
||||
@ -595,12 +626,15 @@ macros may be significant.
|
||||
default ``true``. Allows linebreaks inside inline literals: but extra
|
||||
potential break-points (additionally to those allowed by LaTeX at spaces
|
||||
or for hyphenation) are currently inserted only after the characters
|
||||
``. , ; ? ! /``. Due to TeX internals, white space in the line will be
|
||||
stretched (or shrunk) in order to accomodate the linebreak.
|
||||
``. , ; ? ! /`` and ``\``. Due to TeX internals, white space in the line
|
||||
will be stretched (or shrunk) in order to accomodate the linebreak.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
set this option value to ``false`` to recover former behaviour.
|
||||
|
||||
.. versionchanged:: 2.3.0
|
||||
added potential breakpoint at ``\`` characters.
|
||||
|
||||
``verbatimvisiblespace``
|
||||
default ``\textcolor{red}{\textvisiblespace}``. When a long code line is
|
||||
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.
|
||||
.. versionadded:: 1.6.3
|
||||
``\sphinxstylecodecontinued`` and ``\sphinxstylecodecontinues``.
|
||||
.. versionadded:: 3.0
|
||||
``\sphinxkeyboard``
|
||||
- ``\sphinxtableofcontents``: it is a
|
||||
wrapper (defined differently in :file:`sphinxhowto.cls` and in
|
||||
:file:`sphinxmanual.cls`) of standard ``\tableofcontents``. The macro
|
||||
|
@ -7,7 +7,6 @@ if "%SPHINXBUILD%" == "" (
|
||||
)
|
||||
set SOURCEDIR=.
|
||||
set BUILDDIR=_build
|
||||
set SPHINXPROJ=sphinx-doc
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
|
@ -5,7 +5,7 @@ Synopsis
|
||||
--------
|
||||
|
||||
**sphinx-apidoc** [*OPTIONS*] -o <*OUTPUT_PATH*> <*MODULE_PATH*>
|
||||
[*EXCLUDE_PATTERN*, ...]
|
||||
[*EXCLUDE_PATTERN* ...]
|
||||
|
||||
Description
|
||||
-----------
|
||||
@ -39,6 +39,11 @@ Options
|
||||
|
||||
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
|
||||
|
||||
Force overwriting of any existing generated files.
|
||||
|
@ -73,7 +73,7 @@ If you run the following:
|
||||
|
||||
.. 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``::
|
||||
|
||||
|
@ -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
|
||||
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`
|
||||
A possible location for a sidebar. `sidebar1` appears before the document
|
||||
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.
|
||||
|
||||
.. function:: pathto(file, 1)
|
||||
:noindex:
|
||||
|
||||
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.
|
||||
@ -402,10 +414,6 @@ are in HTML form), these variables are also available:
|
||||
nonempty if the :confval:`html_copy_source` value is ``True``.
|
||||
This has empty value on creating automatically-generated files.
|
||||
|
||||
.. data:: title
|
||||
|
||||
The page title.
|
||||
|
||||
.. data:: toc
|
||||
|
||||
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
|
||||
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
|
||||
:confval:`pygments_style` config value.
|
||||
|
||||
* The **pygments_dark_style** setting gives the name of a Pygments style to use
|
||||
for highlighting when the CSS media query ``(prefers-color-scheme: dark)``
|
||||
evaluates to true. It is injected into the page using
|
||||
:meth:`~Sphinx.add_css_file()`.
|
||||
|
||||
* The **sidebars** setting gives the comma separated list of sidebar templates
|
||||
for constructing sidebars. This can be overridden by the user in the
|
||||
:confval:`html_sidebars` config value.
|
||||
|
@ -9,11 +9,11 @@ Complementary to translations provided for Sphinx-generated messages such as
|
||||
navigation bars, Sphinx provides mechanisms facilitating *document* translations
|
||||
in itself. See the :ref:`intl-options` for details on configuration.
|
||||
|
||||
.. figure:: /_static/translation.png
|
||||
.. figure:: /_static/translation.svg
|
||||
:width: 100%
|
||||
|
||||
Workflow visualization of translations in Sphinx. (The stick-figure is taken
|
||||
from an `XKCD comic <https://xkcd.com/779/>`_.)
|
||||
Workflow visualization of translations in Sphinx. (The figure is created by
|
||||
`plantuml <http://plantuml.com>`_.)
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
@ -90,9 +90,9 @@ section describe an easy way to translate with *sphinx-intl*.
|
||||
locale_dirs = ['locale/'] # path is example but recommended.
|
||||
gettext_compact = False # optional.
|
||||
|
||||
This case-study assumes that :confval:`locale_dirs` is set to ``locale/`` and
|
||||
:confval:`gettext_compact` is set to ``False`` (the Sphinx document is
|
||||
already configured as such).
|
||||
This case-study assumes that BUILDDIR is set to ``_build``,
|
||||
:confval:`locale_dirs` is set to ``locale/`` and :confval:`gettext_compact`
|
||||
is set to ``False`` (the Sphinx document is already configured as such).
|
||||
|
||||
#. 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
|
||||
----------------------------------
|
||||
|
||||
.. confval:: fresh-env
|
||||
.. setuptools-confval:: fresh-env
|
||||
|
||||
A boolean that determines whether the saved environment should be discarded
|
||||
on build. Default is false.
|
||||
@ -68,7 +68,7 @@ Options for setuptools integration
|
||||
|
||||
$ 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.
|
||||
Default is false.
|
||||
@ -79,7 +79,7 @@ Options for setuptools integration
|
||||
|
||||
$ 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
|
||||
``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
|
||||
|
||||
.. confval:: build-dir
|
||||
.. setuptools-confval:: build-dir
|
||||
|
||||
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``.
|
||||
|
||||
.. confval:: config-dir
|
||||
.. setuptools-confval:: config-dir
|
||||
|
||||
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
|
||||
@ -111,7 +111,7 @@ Options for setuptools integration
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
.. confval:: builder
|
||||
.. setuptools-confval:: builder
|
||||
|
||||
The builder or list of builders to use. Default is ``html``.
|
||||
|
||||
@ -124,7 +124,7 @@ Options for setuptools integration
|
||||
.. versionchanged:: 1.6
|
||||
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.
|
||||
Default is false.
|
||||
@ -137,32 +137,32 @@ Options for setuptools integration
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
.. confval:: project
|
||||
.. setuptools-confval:: project
|
||||
|
||||
The documented project's name. Default is ``''``.
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
.. confval:: version
|
||||
.. setuptools-confval:: version
|
||||
|
||||
The short X.Y version. Default is ``''``.
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
.. confval:: release
|
||||
.. setuptools-confval:: release
|
||||
|
||||
The full version, including alpha/beta/rc tags. Default is ``''``.
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
.. confval:: today
|
||||
.. setuptools-confval:: today
|
||||
|
||||
How to format the current date, used as the replacement for ``|today|``.
|
||||
Default is ``''``.
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
.. confval:: link-index
|
||||
.. setuptools-confval:: link-index
|
||||
|
||||
A boolean that ensures index.html will be linked to the master doc. Default
|
||||
is false.
|
||||
@ -175,13 +175,13 @@ Options for setuptools integration
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
.. confval:: copyright
|
||||
.. setuptools-confval:: copyright
|
||||
|
||||
The copyright string. Default is ``''``.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. confval:: nitpicky
|
||||
.. setuptools-confval:: nitpicky
|
||||
|
||||
Run in nit-picky mode. Currently, this generates warnings for all missing
|
||||
references. See the config value :confval:`nitpick_ignore` for a way to
|
||||
@ -189,7 +189,7 @@ Options for setuptools integration
|
||||
|
||||
.. versionadded:: 1.8
|
||||
|
||||
.. confval:: pdb
|
||||
.. setuptools-confval:: pdb
|
||||
|
||||
A boolean to configure ``pdb`` on exception. Default is false.
|
||||
|
||||
|
@ -313,6 +313,7 @@ General configuration
|
||||
* ``ref.doc``
|
||||
* ``ref.python``
|
||||
* ``misc.highlighting_failure``
|
||||
* ``toc.circular``
|
||||
* ``toc.secnum``
|
||||
* ``epub.unknown_project_files``
|
||||
* ``autosectionlabel.*``
|
||||
@ -510,6 +511,14 @@ General configuration
|
||||
|
||||
.. 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
|
||||
|
||||
If true, Sphinx verifies server certifications. Default is ``True``.
|
||||
@ -530,7 +539,7 @@ General configuration
|
||||
directory pointed ``REQUESTS_CA_BUNDLE`` environment
|
||||
variable if ``tls_cacerts`` not set.
|
||||
|
||||
.. _requests: http://docs.python-requests.org/en/master/
|
||||
.. _requests: https://requests.readthedocs.io/en/master/
|
||||
|
||||
.. confval:: today
|
||||
today_fmt
|
||||
@ -566,7 +575,7 @@ General configuration
|
||||
A dictionary of options that modify how the lexer specified by
|
||||
:confval:`highlight_language` generates highlighted source code. These are
|
||||
lexer-specific; for the options understood by each, see the
|
||||
`Pygments documentation <http://pygments.org/docs/lexers/>`_.
|
||||
`Pygments documentation <https://pygments.org/docs/lexers.html>`_.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
@ -626,6 +635,16 @@ General configuration
|
||||
.. versionchanged:: 1.1
|
||||
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:
|
||||
|
||||
@ -654,12 +673,18 @@ documentation on :ref:`intl` for details.
|
||||
|
||||
Currently supported languages by Sphinx are:
|
||||
|
||||
* ``ar`` -- Arabic
|
||||
* ``bg`` -- Bulgarian
|
||||
* ``bn`` -- Bengali
|
||||
* ``ca`` -- Catalan
|
||||
* ``cak`` -- Kaqchikel
|
||||
* ``cs`` -- Czech
|
||||
* ``cy`` -- Welsh
|
||||
* ``da`` -- Danish
|
||||
* ``de`` -- German
|
||||
* ``el`` -- Greek
|
||||
* ``en`` -- English
|
||||
* ``eo`` -- Esperanto
|
||||
* ``es`` -- Spanish
|
||||
* ``et`` -- Estonian
|
||||
* ``eu`` -- Basque
|
||||
@ -667,6 +692,8 @@ documentation on :ref:`intl` for details.
|
||||
* ``fi`` -- Finnish
|
||||
* ``fr`` -- French
|
||||
* ``he`` -- Hebrew
|
||||
* ``hi`` -- Hindi
|
||||
* ``hi_IN`` -- Hindi (India)
|
||||
* ``hr`` -- Croatian
|
||||
* ``hu`` -- Hungarian
|
||||
* ``id`` -- Indonesian
|
||||
@ -680,15 +707,24 @@ documentation on :ref:`intl` for details.
|
||||
* ``ne`` -- Nepali
|
||||
* ``nl`` -- Dutch
|
||||
* ``pl`` -- Polish
|
||||
* ``pt`` -- Portuguese
|
||||
* ``pt_BR`` -- Brazilian Portuguese
|
||||
* ``pt_PT`` -- European Portuguese
|
||||
* ``ro`` -- Romanian
|
||||
* ``ru`` -- Russian
|
||||
* ``si`` -- Sinhala
|
||||
* ``sk`` -- Slovak
|
||||
* ``sl`` -- Slovenian
|
||||
* ``sq`` -- Albanian
|
||||
* ``sr`` -- Serbian
|
||||
* ``sr@latin`` -- Serbian (Latin)
|
||||
* ``sr_RS`` -- Serbian (Cyrillic)
|
||||
* ``sv`` -- Swedish
|
||||
* ``ta`` -- Tamil
|
||||
* ``te`` -- Telugu
|
||||
* ``tr`` -- Turkish
|
||||
* ``uk_UA`` -- Ukrainian
|
||||
* ``ur`` -- Urdu
|
||||
* ``vi`` -- Vietnamese
|
||||
* ``zh_CN`` -- Simplified Chinese
|
||||
* ``zh_TW`` -- Traditional Chinese
|
||||
@ -762,7 +798,7 @@ documentation on :ref:`intl` for details.
|
||||
i18n additionally. You can specify below names:
|
||||
|
||||
:index: index terms
|
||||
:literal-block: literal blocks: ``::`` and ``code-block``.
|
||||
:literal-block: literal blocks (``::`` annotation and ``code-block`` directive)
|
||||
:doctest-block: doctest block
|
||||
:raw: raw content
|
||||
:image: image/figure uri and alt
|
||||
@ -930,7 +966,7 @@ that use Sphinx's HTMLWriter class.
|
||||
|
||||
Example::
|
||||
|
||||
html_css_files = ['custom.css'
|
||||
html_css_files = ['custom.css',
|
||||
'https://example.com/css/custom.css',
|
||||
('print.css', {'media': 'print'})]
|
||||
|
||||
@ -1338,8 +1374,21 @@ that use Sphinx's HTMLWriter class.
|
||||
'target' option or scale related options: 'scale', 'width', 'height'.
|
||||
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
|
||||
|
||||
.. versionchanged:: 2.4
|
||||
|
||||
It is disabled for images having ``no-scaled-link`` class
|
||||
|
||||
.. confval:: html_math_renderer
|
||||
|
||||
The name of math_renderer extension for HTML output. The default is
|
||||
@ -1828,6 +1877,7 @@ These options influence LaTeX output.
|
||||
* ``'xelatex'`` -- XeLaTeX
|
||||
* ``'lualatex'`` -- LuaLaTeX
|
||||
* ``'platex'`` -- pLaTeX (default if :confval:`language` is ``'ja'``)
|
||||
* ``'uplatex'`` -- upLaTeX (experimental)
|
||||
|
||||
``'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
|
||||
with wide-enough glyph coverage is often easier than trying to make
|
||||
``'pdflatex'`` work with the extra Unicode characters. Since Sphinx 2.0
|
||||
the default is the GNU FreeFont which covers well Latin, Cyrillic and Greek.
|
||||
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>`,
|
||||
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.
|
||||
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*
|
||||
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:
|
||||
``'John \\and Sarah'`` (backslashes must be Python-escaped to reach LaTeX).
|
||||
|
||||
*documentclass*
|
||||
Normally, one of ``'manual'`` or ``'howto'`` (provided by Sphinx and based
|
||||
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.
|
||||
*theme*
|
||||
LaTeX theme. See :confval:`latex_theme`.
|
||||
|
||||
*toctree_only*
|
||||
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
|
||||
``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:
|
||||
|
||||
@ -2346,6 +2439,34 @@ Options for the linkcheck builder
|
||||
|
||||
.. 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
|
||||
---------------------------
|
||||
@ -2365,6 +2486,30 @@ Options for the XML builder
|
||||
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:
|
||||
|
||||
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
|
||||
|
||||
* 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
|
||||
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
|
||||
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
|
||||
: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
|
||||
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
|
||||
module whose docstrings are not reST formatted.
|
||||
|
||||
.. 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
|
||||
objects (functions, methods, classes) with the regular syntax that will
|
||||
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
|
||||
original ``__doc__`` to the new function.
|
||||
|
||||
From Python 2.5, :func:`functools.wraps` can be used to create
|
||||
well-behaved decorating functions.
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
@ -437,9 +466,13 @@ There are also config values that you can set:
|
||||
following values:
|
||||
|
||||
* ``'signature'`` -- Show typehints as its signature (default)
|
||||
* ``'description'`` -- Show typehints as content of function or method
|
||||
* ``'none'`` -- Do not show typehints
|
||||
|
||||
.. versionadded: 2.1
|
||||
.. versionadded:: 2.1
|
||||
.. versionadded:: 3.0
|
||||
|
||||
New option ``'description'`` is added.
|
||||
|
||||
.. confval:: autodoc_warningiserror
|
||||
|
||||
@ -494,6 +527,17 @@ autodoc provides the following additional events:
|
||||
auto directive
|
||||
: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)
|
||||
|
||||
.. 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
|
||||
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
|
||||
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
|
||||
``:toctree:`` options of the directives.
|
||||
|
||||
.. versionchanged:: 2.3
|
||||
|
||||
Emits :event:`autodoc-skip-member` event as :mod:`~sphinx.ext.autodoc`
|
||||
does.
|
||||
|
||||
.. confval:: autosummary_generate_overwrite
|
||||
|
||||
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.
|
||||
|
||||
.. function:: underline(s, line='=')
|
||||
:noindex:
|
||||
|
||||
Add a title underline to a piece of text.
|
||||
|
||||
|
@ -11,11 +11,15 @@
|
||||
pair: testing; snippets
|
||||
|
||||
|
||||
This extension allows you to test snippets in the documentation in a natural
|
||||
way. It works by collecting specially-marked up code blocks and running them as
|
||||
doctest tests.
|
||||
It is often helpful to include snippets of code in your documentation and
|
||||
demonstrate the results of executing them. But it is important to ensure that
|
||||
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:
|
||||
|
||||
* 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
|
||||
|
||||
.. 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
|
||||
|
||||
@ -131,6 +138,13 @@ It adds these directives:
|
||||
|
||||
.. 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
|
||||
|
||||
@ -176,6 +190,13 @@ It adds these directives:
|
||||
|
||||
.. 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:
|
||||
|
||||
|
@ -34,7 +34,19 @@ Configuration
|
||||
A path to :command:`convert` command. By default, the imgconverter uses
|
||||
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
|
||||
|
||||
Additional command-line arguments to give to :command:`convert`, as a 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
|
||||
coverage
|
||||
doctest
|
||||
duration
|
||||
extlinks
|
||||
githubpages
|
||||
graphviz
|
||||
|
@ -148,3 +148,13 @@ project. The following example prints the Intersphinx mapping of the Python 3
|
||||
documentation::
|
||||
|
||||
$ 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
|
||||
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`.
|
||||
|
||||
@ -80,6 +80,14 @@ are built:
|
||||
This value should only contain the path to the latex executable, not further
|
||||
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
|
||||
|
||||
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 (``{}``).
|
||||
|
||||
.. versionadded:: 1.8
|
||||
|
||||
.. confval:: mathjax_config
|
||||
|
||||
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).
|
||||
|
||||
.. versionadded:: 1.8
|
||||
|
||||
.. _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
|
||||
|
@ -56,7 +56,7 @@ source code files.
|
||||
.. _Google:
|
||||
https://google.github.io/styleguide/pyguide.html#Comments
|
||||
.. _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:
|
||||
https://github.com/Khan/style-guides/blob/master/style/python.md#docstrings
|
||||
|
||||
|
@ -23,8 +23,7 @@ Linux
|
||||
Debian/Ubuntu
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Install either ``python3-sphinx`` (Python 3) or ``python-sphinx`` (Python 2)
|
||||
using :command:`apt-get`:
|
||||
Install either ``python3-sphinx`` using :command:`apt-get`:
|
||||
|
||||
::
|
||||
|
||||
@ -77,23 +76,22 @@ __ https://formulae.brew.sh/formula/sphinx-doc
|
||||
MacPorts
|
||||
~~~~~~~~
|
||||
|
||||
Install either ``python36-sphinx`` (Python 3) or ``python27-sphinx`` (Python 2)
|
||||
using :command:`port`:
|
||||
Install either ``python3x-sphinx`` using :command:`port`:
|
||||
|
||||
::
|
||||
|
||||
$ sudo port install py36-sphinx
|
||||
$ sudo port install py38-sphinx
|
||||
|
||||
To set up the executable paths, use the ``port select`` command:
|
||||
|
||||
::
|
||||
|
||||
$ sudo port select --set python python36
|
||||
$ sudo port select --set sphinx py36-sphinx
|
||||
$ sudo port select --set python python38
|
||||
$ sudo port select --set sphinx py38-sphinx
|
||||
|
||||
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
|
||||
~~~~~~~~
|
||||
@ -161,6 +159,37 @@ the ``--pre`` flag.
|
||||
$ 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
|
||||
------------------------
|
||||
|
||||
|
@ -26,9 +26,6 @@ configuration values from a few questions it asks you. To use this, run:
|
||||
|
||||
$ 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
|
||||
: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
|
||||
directory with :file:`conf.py` and a master document, :file:`index.rst` (if you
|
||||
accepted the defaults). The main function of the :term:`master document` is to
|
||||
serve as a welcome page, and to contain the root of the "table of contents
|
||||
tree" (or *toctree*). This is one of the main things that Sphinx adds to
|
||||
reStructuredText, a way to connect multiple files to a single hierarchy of
|
||||
documents.
|
||||
directory with :file:`conf.py` and a master document, :file:`index.rst`. The
|
||||
main function of the :term:`master document` is to serve as a welcome page, and
|
||||
to contain the root of the "table of contents tree" (or *toctree*). This is one
|
||||
of the main things that Sphinx adds to reStructuredText, a way to connect
|
||||
multiple files to a single hierarchy of documents.
|
||||
|
||||
.. 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
|
||||
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
|
||||
value, you need to use Python Unicode strings (like ``project = u'Exposé'``).
|
||||
declaration in the first line.
|
||||
|
||||
|more| See :doc:`/usage/configuration` for documentation of all available
|
||||
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
|
||||
putting the string ``'sphinx.ext.autodoc'`` into the list assigned to the
|
||||
:confval:`extensions` config value. Then, you have a few additional directives
|
||||
at your disposal.
|
||||
:confval:`extensions` config value::
|
||||
|
||||
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::
|
||||
|
||||
.. autofunction:: io.open
|
||||
|
@ -372,7 +372,8 @@ Docutils supports the following directives:
|
||||
|
||||
* 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)
|
||||
|
||||
* Influencing markup:
|
||||
@ -538,6 +539,45 @@ You can indent text after a comment start to form multiline comments::
|
||||
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
|
||||
---------------
|
||||
|
||||
|
@ -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
|
||||
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)::
|
||||
|
||||
.. 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
|
||||
Pygments.
|
||||
|
||||
__ http://pygments.org/docs/lexers/
|
||||
__ http://pygments.org/docs/lexers
|
||||
|
||||
.. rst:directive:: .. highlight:: language
|
||||
|
||||
@ -453,21 +459,29 @@ __ http://pygments.org/docs/lexers/
|
||||
As discussed previously, *language* can be any lexer alias supported by
|
||||
Pygments.
|
||||
|
||||
**Additional options**
|
||||
.. rubric:: options
|
||||
|
||||
Pygments can generate line numbers for code blocks. To enable this, use the
|
||||
``linenothreshold`` option. ::
|
||||
.. rst:directive:option:: linenothreshold: threshold
|
||||
:type: number (optional)
|
||||
|
||||
.. highlight:: python
|
||||
:linenothreshold: 5
|
||||
Enable to generate line numbers for code blocks.
|
||||
|
||||
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]
|
||||
|
||||
@ -483,72 +497,98 @@ __ http://pygments.org/docs/lexers/
|
||||
:rst:dir:`highlight` directive will be used. If not set,
|
||||
: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
|
||||
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
|
||||
|
||||
@ -840,6 +880,19 @@ mainly contained in information units, such as the language reference.
|
||||
.. versionchanged:: 1.1
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
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::
|
||||
|
||||
@ -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
|
||||
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
|
||||
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
|
||||
the first line.
|
||||
|
||||
The argument to :rst:dir:`productionlist` serves to distinguish different
|
||||
sets of production lists that belong to different grammars.
|
||||
The *productionGroup* argument to :rst:dir:`productionlist` serves to
|
||||
distinguish different sets of production lists that belong to different
|
||||
grammars. Multiple production lists with the same *productionGroup* thus
|
||||
define rules in the same scope.
|
||||
|
||||
Blank lines are not allowed within ``productionlist`` directive arguments.
|
||||
|
||||
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
|
||||
production list, you can reference to token productions using
|
||||
:rst:role:`token`.
|
||||
However, if you have given a *productionGroup* argument you must prefix the
|
||||
token name in the cross-reference with the group name and a colon,
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
Describes an object method. The parameters should not include the ``self``
|
||||
@ -354,6 +378,9 @@ Info field lists
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 0.4
|
||||
.. versionchanged:: 3.0
|
||||
|
||||
meta fields are added.
|
||||
|
||||
Inside Python object description directives, reST field lists with these fields
|
||||
are recognized and formatted nicely:
|
||||
@ -367,6 +394,10 @@ are recognized and formatted nicely:
|
||||
* ``vartype``: Type of a variable. Creates a link if possible.
|
||||
* ``returns``, ``return``: Description of the return value.
|
||||
* ``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::
|
||||
|
||||
@ -521,47 +552,62 @@ The C Domain
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
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.
|
||||
.. c:function:: PyObject *PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
|
||||
|
||||
Note that you don't have to backslash-escape asterisks in the signature, as
|
||||
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
|
||||
.. c:macro:: name(arg list)
|
||||
|
||||
Describes a "simple" C macro. Simple macros are macros which are used for
|
||||
code expansion, but which do not take arguments so cannot be described as
|
||||
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`.
|
||||
Describes a C macro, i.e., a C-language ``#define``, without the replacement
|
||||
text.
|
||||
|
||||
.. 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
|
||||
should just be the type name.
|
||||
.. rst:directive:: .. c:struct:: name
|
||||
|
||||
.. rst:directive:: .. c:var:: declaration
|
||||
Describes a C struct.
|
||||
|
||||
Describes a global C variable. The signature should include the type, such
|
||||
as::
|
||||
.. versionadded:: 3.0
|
||||
|
||||
.. 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:
|
||||
|
||||
@ -571,25 +617,164 @@ Cross-referencing C constructs
|
||||
The following roles create cross-references to C-language constructs if they
|
||||
are defined in the documentation:
|
||||
|
||||
.. rst:role:: c:func
|
||||
|
||||
Reference a C-language function. Should include trailing parentheses.
|
||||
|
||||
.. 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:
|
||||
@ -1530,7 +1715,7 @@ These roles are provided to refer to the described objects:
|
||||
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
|
||||
|
||||
|
@ -30,6 +30,12 @@ At the moment, these metadata fields are recognized:
|
||||
|
||||
: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
|
||||
|
||||
``nocomments``
|
||||
@ -45,3 +51,12 @@ At the moment, these metadata fields are recognized:
|
||||
:orphan:
|
||||
|
||||
.. 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
|
||||
inclusion in the output when building (obviously, for HTML output only).
|
||||
All downloadable files are put into the ``_downloads`` subdirectory of the
|
||||
output directory; duplicate filenames are handled.
|
||||
All downloadable files are put into a ``_downloads/<unique hash>/``
|
||||
subdirectory of the output directory; duplicate filenames are handled.
|
||||
|
||||
An example::
|
||||
|
||||
|
@ -151,6 +151,25 @@ These themes are:
|
||||
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).
|
||||
|
||||
- **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 theme`_ is a modified "Kr" Sphinx theme from @kennethreitz
|
||||
(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),
|
||||
default 50em.
|
||||
- **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.
|
||||
- **headerbg** (CSS value for "background"): background for the header area,
|
||||
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"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jasmine-core": "^3.1.0",
|
||||
"karma": "^3.0.0",
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"jasmine-core": "^3.4.0",
|
||||
"karma": "^4.0.0",
|
||||
"karma-chrome-launcher": "^3.0.0",
|
||||
"karma-firefox-launcher": "^1.1.0",
|
||||
"karma-jasmine": "^1.1.2"
|
||||
"karma-jasmine": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ paths =
|
||||
.
|
||||
|
||||
[mypy]
|
||||
python_version = 3.5
|
||||
disallow_incomplete_defs = True
|
||||
show_column_numbers = True
|
||||
show_error_context = True
|
||||
ignore_missing_imports = True
|
||||
@ -57,9 +59,11 @@ markers =
|
||||
apidoc
|
||||
setup_command
|
||||
test_params
|
||||
testpaths = tests
|
||||
|
||||
[coverage:run]
|
||||
branch = True
|
||||
parallel = True
|
||||
source = sphinx
|
||||
|
||||
[coverage:report]
|
||||
|
21
setup.py
21
setup.py
@ -25,7 +25,7 @@ install_requires = [
|
||||
'Pygments>=2.0',
|
||||
'docutils>=0.12',
|
||||
'snowballstemmer>=1.1',
|
||||
'babel>=1.3,!=2.0',
|
||||
'babel>=1.3',
|
||||
'alabaster>=0.7,<0.8',
|
||||
'imagesize',
|
||||
'requests>=2.5.0',
|
||||
@ -41,14 +41,18 @@ extras_require = {
|
||||
'docs': [
|
||||
'sphinxcontrib-websupport',
|
||||
],
|
||||
'lint': [
|
||||
'flake8>=3.5.0',
|
||||
'flake8-import-order',
|
||||
'mypy>=0.770',
|
||||
'docutils-stubs',
|
||||
],
|
||||
'test': [
|
||||
'pytest',
|
||||
'pytest-cov',
|
||||
'html5lib',
|
||||
'flake8>=3.5.0',
|
||||
'flake8-import-order',
|
||||
'mypy>=0.711',
|
||||
'docutils-stubs',
|
||||
'typed_ast', # for py35-37
|
||||
'cython',
|
||||
],
|
||||
}
|
||||
|
||||
@ -176,6 +180,10 @@ setup(
|
||||
description='Python documentation generator',
|
||||
long_description=long_desc,
|
||||
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,
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
@ -216,6 +224,9 @@ setup(
|
||||
],
|
||||
platforms='any',
|
||||
packages=find_packages(exclude=['tests', 'utils']),
|
||||
package_data = {
|
||||
'sphinx': ['py.typed'],
|
||||
},
|
||||
include_package_data=True,
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -32,8 +32,8 @@ if 'PYTHONWARNINGS' not in os.environ:
|
||||
warnings.filterwarnings('ignore', "'U' mode is deprecated",
|
||||
DeprecationWarning, module='docutils.io')
|
||||
|
||||
__version__ = '3.0.0+'
|
||||
__released__ = '3.0.0' # used when Sphinx builds its own docs
|
||||
__version__ = '3.1.0+'
|
||||
__released__ = '3.1.0' # used when Sphinx builds its own docs
|
||||
|
||||
#: Version info for better programmatic use.
|
||||
#:
|
||||
@ -43,7 +43,7 @@ __released__ = '3.0.0' # used when Sphinx builds its own docs
|
||||
#:
|
||||
#: .. versionadded:: 1.2
|
||||
#: 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__))
|
||||
|
||||
@ -56,8 +56,9 @@ if __version__.endswith('+'):
|
||||
__version__ = __version__[:-1] # remove '+' for PEP-440 version spec.
|
||||
try:
|
||||
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:
|
||||
__display_version__ += '/' + ret.stdout.strip()
|
||||
__display_version__ += '/' + ret.stdout.decode('ascii').strip()
|
||||
except Exception:
|
||||
pass
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -4,20 +4,21 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import warnings
|
||||
from typing import Any, Dict, List, Sequence
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, List, Sequence # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.application import Sphinx
|
||||
|
||||
|
||||
class translatable(nodes.Node):
|
||||
@ -34,18 +35,15 @@ class translatable(nodes.Node):
|
||||
Because they are used at final step; extraction.
|
||||
"""
|
||||
|
||||
def preserve_original_messages(self):
|
||||
# type: () -> None
|
||||
def preserve_original_messages(self) -> None:
|
||||
"""Preserve original translatable messages."""
|
||||
raise NotImplementedError
|
||||
|
||||
def apply_translated_message(self, original_message, translated_message):
|
||||
# type: (str, str) -> None
|
||||
def apply_translated_message(self, original_message: str, translated_message: str) -> None:
|
||||
"""Apply translated message."""
|
||||
raise NotImplementedError
|
||||
|
||||
def extract_original_messages(self):
|
||||
# type: () -> Sequence[str]
|
||||
def extract_original_messages(self) -> Sequence[str]:
|
||||
"""Extract translation messages.
|
||||
|
||||
:returns: list of extracted messages or messages generator
|
||||
@ -61,22 +59,37 @@ class not_smartquotable:
|
||||
class toctree(nodes.General, nodes.Element, translatable):
|
||||
"""Node for inserting a "TOC tree"."""
|
||||
|
||||
def preserve_original_messages(self):
|
||||
# type: () -> None
|
||||
def preserve_original_messages(self) -> None:
|
||||
# toctree entries
|
||||
rawentries = self.setdefault('rawentries', [])
|
||||
for title, docname in self['entries']:
|
||||
if title:
|
||||
rawentries.append(title)
|
||||
|
||||
# :caption: option
|
||||
if self.get('caption'):
|
||||
self['rawcaption'] = self['caption']
|
||||
|
||||
def apply_translated_message(self, original_message, translated_message):
|
||||
# type: (str, str) -> None
|
||||
def apply_translated_message(self, original_message: str, translated_message: 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:
|
||||
self['caption'] = translated_message
|
||||
|
||||
def extract_original_messages(self):
|
||||
# type: () -> List[str]
|
||||
def extract_original_messages(self) -> List[str]:
|
||||
messages = [] # type: List[str]
|
||||
|
||||
# toctree entries
|
||||
messages.extend(self.get('rawentries', []))
|
||||
|
||||
# :caption: option
|
||||
if 'rawcaption' in self:
|
||||
return [self['rawcaption']]
|
||||
else:
|
||||
return []
|
||||
messages.append(self['rawcaption'])
|
||||
return messages
|
||||
|
||||
|
||||
# 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.
|
||||
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
|
||||
@ -125,8 +138,7 @@ class desc_type(nodes.Part, nodes.Inline, nodes.FixedTextElement):
|
||||
|
||||
class desc_returns(desc_type):
|
||||
"""Node for a "returns" annotation (a la -> in Python)."""
|
||||
def astext(self):
|
||||
# type: () -> str
|
||||
def astext(self) -> str:
|
||||
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."""
|
||||
child_text_separator = ', '
|
||||
|
||||
def astext(self):
|
||||
# type: () -> str
|
||||
def astext(self) -> str:
|
||||
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
|
||||
|
||||
class versionmodified(nodes.Admonition, nodes.TextElement):
|
||||
@ -295,8 +331,8 @@ class abbreviation(nodes.abbreviation):
|
||||
.. deprecated:: 2.0
|
||||
"""
|
||||
|
||||
def __init__(self, rawsource='', text='', *children, **attributes):
|
||||
# type: (str, str, *nodes.Node, **Any) -> None
|
||||
def __init__(self, rawsource: str = '', text: str = '',
|
||||
*children: Node, **attributes: Any) -> None:
|
||||
warnings.warn("abbrevition node for Sphinx was replaced by docutils'.",
|
||||
RemovedInSphinx40Warning, stacklevel=2)
|
||||
|
||||
@ -307,8 +343,7 @@ class manpage(nodes.Inline, nodes.FixedTextElement):
|
||||
"""Node for references to manpages."""
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||
app.add_node(toctree)
|
||||
app.add_node(desc)
|
||||
app.add_node(desc_signature)
|
||||
@ -322,6 +357,9 @@ def setup(app):
|
||||
app.add_node(desc_optional)
|
||||
app.add_node(desc_annotation)
|
||||
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(seealso)
|
||||
app.add_node(productionlist)
|
||||
|
@ -6,32 +6,42 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import os
|
||||
import pickle
|
||||
import platform
|
||||
import sys
|
||||
import warnings
|
||||
from collections import deque
|
||||
from io import StringIO
|
||||
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.transforms import Transform
|
||||
from pygments.lexer import Lexer
|
||||
|
||||
import sphinx
|
||||
from sphinx import package_dir, locale
|
||||
from sphinx.config import Config
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.domains import Domain, Index
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.environment.collectors import EnvironmentCollector
|
||||
from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError
|
||||
from sphinx.events import EventManager
|
||||
from sphinx.extension import Extension
|
||||
from sphinx.highlighting import lexer_classes, lexers
|
||||
from sphinx.locale import __
|
||||
from sphinx.project import Project
|
||||
from sphinx.registry import SphinxComponentRegistry
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.theming import Theme
|
||||
from sphinx.util import docutils
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import progress_message
|
||||
@ -41,20 +51,14 @@ from sphinx.util.i18n import CatalogRepository
|
||||
from sphinx.util.logging import prefixed_warnings
|
||||
from sphinx.util.osutil import abspath, ensuredir, relpath
|
||||
from sphinx.util.tags import Tags
|
||||
from sphinx.util.typing import RoleFunction, TitleGetter
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, Dict, IO, Iterable, Iterator, List, Tuple, Type, Union # NOQA
|
||||
from docutils import nodes # NOQA
|
||||
from docutils.parsers import Parser # NOQA
|
||||
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
|
||||
from docutils.nodes import Node # NOQA
|
||||
from typing import Type # for python3.5.1
|
||||
from sphinx.builders import Builder
|
||||
|
||||
|
||||
builtin_extensions = (
|
||||
'sphinx.addnodes',
|
||||
@ -76,6 +80,7 @@ builtin_extensions = (
|
||||
'sphinx.domains.changeset',
|
||||
'sphinx.domains.citation',
|
||||
'sphinx.domains.cpp',
|
||||
'sphinx.domains.index',
|
||||
'sphinx.domains.javascript',
|
||||
'sphinx.domains.math',
|
||||
'sphinx.domains.python',
|
||||
@ -104,7 +109,6 @@ builtin_extensions = (
|
||||
'sphinx.environment.collectors.metadata',
|
||||
'sphinx.environment.collectors.title',
|
||||
'sphinx.environment.collectors.toctree',
|
||||
'sphinx.environment.collectors.indexentries',
|
||||
# 1st party extensions
|
||||
'sphinxcontrib.applehelp',
|
||||
'sphinxcontrib.devhelp',
|
||||
@ -130,11 +134,11 @@ class Sphinx:
|
||||
:ivar outdir: Directory for storing build documents.
|
||||
"""
|
||||
|
||||
def __init__(self, srcdir, confdir, outdir, doctreedir, buildername,
|
||||
confoverrides=None, status=sys.stdout, warning=sys.stderr,
|
||||
freshenv=False, warningiserror=False, tags=None, verbosity=0,
|
||||
parallel=0, keep_going=False):
|
||||
# type: (str, str, str, str, str, Dict, IO, IO, bool, bool, List[str], int, int, bool) -> None # NOQA
|
||||
def __init__(self, srcdir: str, confdir: str, outdir: str, doctreedir: str,
|
||||
buildername: str, confoverrides: Dict = None,
|
||||
status: IO = sys.stdout, warning: IO = sys.stderr,
|
||||
freshenv: bool = False, warningiserror: bool = False, tags: List[str] = None,
|
||||
verbosity: int = 0, parallel: int = 0, keep_going: bool = False) -> None:
|
||||
self.phase = BuildPhase.INITIALIZATION
|
||||
self.verbosity = verbosity
|
||||
self.extensions = {} # type: Dict[str, Extension]
|
||||
@ -159,6 +163,10 @@ class Sphinx:
|
||||
raise ApplicationError(__('Cannot find source directory (%s)') %
|
||||
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:
|
||||
raise ApplicationError(__('Source directory and destination '
|
||||
'directory cannot be identical'))
|
||||
@ -193,6 +201,12 @@ class Sphinx:
|
||||
# say hello to the world
|
||||
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
|
||||
self.statuscode = 0
|
||||
|
||||
@ -262,8 +276,7 @@ class Sphinx:
|
||||
# set up the builder
|
||||
self._init_builder()
|
||||
|
||||
def _init_i18n(self):
|
||||
# type: () -> None
|
||||
def _init_i18n(self) -> None:
|
||||
"""Load translated strings from the configured localedirs if enabled in
|
||||
the configuration.
|
||||
"""
|
||||
@ -288,8 +301,7 @@ class Sphinx:
|
||||
else:
|
||||
logger.info(__('not available for built-in messages'))
|
||||
|
||||
def _init_env(self, freshenv):
|
||||
# type: (bool) -> None
|
||||
def _init_env(self, freshenv: bool) -> None:
|
||||
filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
|
||||
if freshenv or not os.path.exists(filename):
|
||||
self.env = BuildEnvironment()
|
||||
@ -305,28 +317,24 @@ class Sphinx:
|
||||
logger.info(__('failed: %s'), err)
|
||||
self._init_env(freshenv=True)
|
||||
|
||||
def preload_builder(self, name):
|
||||
# type: (str) -> None
|
||||
def preload_builder(self, name: str) -> None:
|
||||
self.registry.preload_builder(self, name)
|
||||
|
||||
def create_builder(self, name):
|
||||
# type: (str) -> Builder
|
||||
def create_builder(self, name: str) -> "Builder":
|
||||
if name is None:
|
||||
logger.info(__('No builder selected, using default: html'))
|
||||
name = 'html'
|
||||
|
||||
return self.registry.create_builder(self, name)
|
||||
|
||||
def _init_builder(self):
|
||||
# type: () -> None
|
||||
def _init_builder(self) -> None:
|
||||
self.builder.set_environment(self.env)
|
||||
self.builder.init()
|
||||
self.events.emit('builder-inited')
|
||||
|
||||
# ---- main "build" method -------------------------------------------------
|
||||
|
||||
def build(self, force_all=False, filenames=None):
|
||||
# type: (bool, List[str]) -> None
|
||||
def build(self, force_all: bool = False, filenames: List[str] = None) -> None:
|
||||
self.phase = BuildPhase.READING
|
||||
try:
|
||||
if force_all:
|
||||
@ -342,17 +350,19 @@ class Sphinx:
|
||||
if self._warncount and self.keep_going:
|
||||
self.statuscode = 1
|
||||
|
||||
status = (self.statuscode == 0 and
|
||||
__('succeeded') or __('finished with problems'))
|
||||
status = (__('succeeded') if self.statuscode == 0
|
||||
else __('finished with problems'))
|
||||
if self._warncount:
|
||||
if self.warningiserror:
|
||||
msg = __('build %s, %s warning (with warnings treated as errors).',
|
||||
'build %s, %s warnings (with warnings treated as errors).',
|
||||
self._warncount)
|
||||
if self._warncount == 1:
|
||||
msg = __('build %s, %s warning (with warnings treated as errors).')
|
||||
else:
|
||||
msg = __('build %s, %s warnings (with warnings treated as errors).')
|
||||
else:
|
||||
msg = __('build %s, %s warning.',
|
||||
'build %s, %s warnings.',
|
||||
self._warncount)
|
||||
if self._warncount == 1:
|
||||
msg = __('build %s, %s warning.')
|
||||
else:
|
||||
msg = __('build %s, %s warnings.')
|
||||
|
||||
logger.info(bold(msg % (status, self._warncount)))
|
||||
else:
|
||||
@ -377,8 +387,7 @@ class Sphinx:
|
||||
|
||||
# ---- general extensibility interface -------------------------------------
|
||||
|
||||
def setup_extension(self, extname):
|
||||
# type: (str) -> None
|
||||
def setup_extension(self, extname: str) -> None:
|
||||
"""Import and setup a Sphinx extension module.
|
||||
|
||||
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)
|
||||
self.registry.load_extension(self, extname)
|
||||
|
||||
def require_sphinx(self, version):
|
||||
# type: (str) -> None
|
||||
def require_sphinx(self, version: str) -> None:
|
||||
"""Check the Sphinx version if requested.
|
||||
|
||||
Compare *version* (which must be a ``major.minor`` version string, e.g.
|
||||
@ -402,28 +410,33 @@ class Sphinx:
|
||||
raise VersionRequirementError(version)
|
||||
|
||||
# event interface
|
||||
def connect(self, event, callback):
|
||||
# type: (str, Callable) -> int
|
||||
def connect(self, event: str, callback: Callable, priority: int = 500) -> int:
|
||||
"""Register *callback* to be called when *event* is emitted.
|
||||
|
||||
For details on available core events and the arguments of callback
|
||||
functions, please see :ref:`events`.
|
||||
|
||||
Registered callbacks will be invoked on event in the order of *priority* and
|
||||
registration. The priority is ascending order.
|
||||
|
||||
The method returns a "listener ID" that can be used as an argument to
|
||||
:meth:`disconnect`.
|
||||
|
||||
.. versionchanged:: 3.0
|
||||
|
||||
Support *priority*
|
||||
"""
|
||||
listener_id = self.events.connect(event, callback)
|
||||
logger.debug('[app] connecting event %r: %r [id=%s]', event, callback, listener_id)
|
||||
listener_id = self.events.connect(event, callback, priority)
|
||||
logger.debug('[app] connecting event %r (%d): %r [id=%s]',
|
||||
event, priority, callback, listener_id)
|
||||
return listener_id
|
||||
|
||||
def disconnect(self, listener_id):
|
||||
# type: (int) -> None
|
||||
def disconnect(self, listener_id: int) -> None:
|
||||
"""Unregister callback by *listener_id*."""
|
||||
logger.debug('[app] disconnecting event: [id=%s]', listener_id)
|
||||
self.events.disconnect(listener_id)
|
||||
|
||||
def emit(self, event, *args):
|
||||
# type: (str, Any) -> List
|
||||
def emit(self, event: str, *args: Any) -> List:
|
||||
"""Emit *event* and pass *arguments* to the callback functions.
|
||||
|
||||
Return the return values of all callbacks as a list. Do not emit core
|
||||
@ -431,8 +444,7 @@ class Sphinx:
|
||||
"""
|
||||
return self.events.emit(event, *args)
|
||||
|
||||
def emit_firstresult(self, event, *args):
|
||||
# type: (str, Any) -> Any
|
||||
def emit_firstresult(self, event: str, *args: Any) -> Any:
|
||||
"""Emit *event* and pass *arguments* to the callback functions.
|
||||
|
||||
Return the result of the first callback that doesn't return ``None``.
|
||||
@ -443,8 +455,7 @@ class Sphinx:
|
||||
|
||||
# registering addon parts
|
||||
|
||||
def add_builder(self, builder, override=False):
|
||||
# type: (Type[Builder], bool) -> None
|
||||
def add_builder(self, builder: "Type[Builder]", override: bool = False) -> None:
|
||||
"""Register a new builder.
|
||||
|
||||
*builder* must be a class that inherits from
|
||||
@ -456,8 +467,8 @@ class Sphinx:
|
||||
self.registry.add_builder(builder, override=override)
|
||||
|
||||
# TODO(stephenfin): Describe 'types' parameter
|
||||
def add_config_value(self, name, default, rebuild, types=()):
|
||||
# type: (str, Any, Union[bool, str], Any) -> None
|
||||
def add_config_value(self, name: str, default: Any, rebuild: Union[bool, str],
|
||||
types: Any = ()) -> None:
|
||||
"""Register a configuration value.
|
||||
|
||||
This is necessary for Sphinx to recognize new values and set default
|
||||
@ -484,13 +495,12 @@ class Sphinx:
|
||||
other values.
|
||||
"""
|
||||
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):
|
||||
rebuild = rebuild and 'env' or ''
|
||||
rebuild = 'env' if rebuild else ''
|
||||
self.config.add(name, default, rebuild, types)
|
||||
|
||||
def add_event(self, name):
|
||||
# type: (str) -> None
|
||||
def add_event(self, name: str) -> None:
|
||||
"""Register an event called *name*.
|
||||
|
||||
This is needed to be able to emit it.
|
||||
@ -498,8 +508,8 @@ class Sphinx:
|
||||
logger.debug('[app] adding event: %r', name)
|
||||
self.events.add(name)
|
||||
|
||||
def set_translator(self, name, translator_class, override=False):
|
||||
# type: (str, Type[nodes.NodeVisitor], bool) -> None
|
||||
def set_translator(self, name: str, translator_class: "Type[nodes.NodeVisitor]",
|
||||
override: bool = False) -> None:
|
||||
"""Register or override a Docutils translator class.
|
||||
|
||||
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)
|
||||
|
||||
def add_node(self, node, override=False, **kwds):
|
||||
# type: (Type[nodes.Element], bool, Any) -> None
|
||||
def add_node(self, node: "Type[Element]", override: bool = False,
|
||||
**kwargs: Tuple[Callable, Callable]) -> None:
|
||||
"""Register a Docutils node class.
|
||||
|
||||
This is necessary for Docutils internals. It may also be used in the
|
||||
@ -543,16 +553,17 @@ class Sphinx:
|
||||
.. versionchanged:: 0.5
|
||||
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):
|
||||
logger.warning(__('node class %r is already registered, '
|
||||
'its visitors will be overridden'),
|
||||
node.__name__, type='app', subtype='add_node')
|
||||
docutils.register_node(node)
|
||||
self.registry.add_translation_handlers(node, **kwds)
|
||||
self.registry.add_translation_handlers(node, **kwargs)
|
||||
|
||||
def add_enumerable_node(self, node, figtype, title_getter=None, override=False, **kwds):
|
||||
# type: (Type[nodes.Element], str, TitleGetter, bool, Any) -> None
|
||||
def add_enumerable_node(self, node: "Type[Element]", figtype: str,
|
||||
title_getter: TitleGetter = None, override: bool = False,
|
||||
**kwargs: Tuple[Callable, Callable]) -> None:
|
||||
"""Register a Docutils node class as a numfig target.
|
||||
|
||||
Sphinx numbers the node automatically. And then the users can refer it
|
||||
@ -577,10 +588,9 @@ class Sphinx:
|
||||
.. versionadded:: 1.4
|
||||
"""
|
||||
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):
|
||||
# type: (str, Type[Directive], bool) -> None
|
||||
def add_directive(self, name: str, cls: "Type[Directive]", override: bool = False) -> None:
|
||||
"""Register a Docutils directive.
|
||||
|
||||
*name* must be the prospective directive name. *cls* is a directive
|
||||
@ -624,8 +634,7 @@ class Sphinx:
|
||||
|
||||
docutils.register_directive(name, cls)
|
||||
|
||||
def add_role(self, name, role, override=False):
|
||||
# type: (str, Any, bool) -> None
|
||||
def add_role(self, name: str, role: Any, override: bool = False) -> None:
|
||||
"""Register a Docutils role.
|
||||
|
||||
*name* must be the role name that occurs in the source, *role* the role
|
||||
@ -642,8 +651,7 @@ class Sphinx:
|
||||
name, type='app', subtype='add_role')
|
||||
docutils.register_role(name, role)
|
||||
|
||||
def add_generic_role(self, name, nodeclass, override=False):
|
||||
# type: (str, Any, bool) -> None
|
||||
def add_generic_role(self, name: str, nodeclass: Any, override: bool = False) -> None:
|
||||
"""Register a generic Docutils role.
|
||||
|
||||
Register a Docutils role that does nothing but wrap its contents in the
|
||||
@ -662,8 +670,7 @@ class Sphinx:
|
||||
role = roles.GenericRole(name, nodeclass)
|
||||
docutils.register_role(name, role)
|
||||
|
||||
def add_domain(self, domain, override=False):
|
||||
# type: (Type[Domain], bool) -> None
|
||||
def add_domain(self, domain: "Type[Domain]", override: bool = False) -> None:
|
||||
"""Register a domain.
|
||||
|
||||
Make the given *domain* (which must be a class; more precisely, a
|
||||
@ -675,8 +682,8 @@ class Sphinx:
|
||||
"""
|
||||
self.registry.add_domain(domain, override=override)
|
||||
|
||||
def add_directive_to_domain(self, domain, name, cls, override=False):
|
||||
# type: (str, str, Type[Directive], bool) -> None
|
||||
def add_directive_to_domain(self, domain: str, name: str,
|
||||
cls: "Type[Directive]", override: bool = False) -> None:
|
||||
"""Register a Docutils directive in a 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)
|
||||
|
||||
def add_role_to_domain(self, domain, name, role, override=False):
|
||||
# type: (str, str, Union[RoleFunction, XRefRole], bool) -> None
|
||||
def add_role_to_domain(self, domain: str, name: str, role: Union[RoleFunction, XRefRole],
|
||||
override: bool = False) -> None:
|
||||
"""Register a Docutils role in a domain.
|
||||
|
||||
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)
|
||||
|
||||
def add_index_to_domain(self, domain, index, override=False):
|
||||
# type: (str, Type[Index], bool) -> None
|
||||
def add_index_to_domain(self, domain: str, index: "Type[Index]", override: bool = False
|
||||
) -> None:
|
||||
"""Register a custom index for a domain.
|
||||
|
||||
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)
|
||||
|
||||
def add_object_type(self, directivename, rolename, indextemplate='',
|
||||
parse_node=None, ref_nodeclass=None, objname='',
|
||||
doc_field_types=[], override=False):
|
||||
# type: (str, str, str, Callable, Type[nodes.TextElement], str, List, bool) -> None
|
||||
def add_object_type(self, directivename: str, rolename: str, indextemplate: str = '',
|
||||
parse_node: Callable = None, ref_nodeclass: "Type[TextElement]" = None,
|
||||
objname: str = '', doc_field_types: List = [], override: bool = False
|
||||
) -> None:
|
||||
"""Register a new 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,
|
||||
override=override)
|
||||
|
||||
def add_crossref_type(self, directivename, rolename, indextemplate='',
|
||||
ref_nodeclass=None, objname='', override=False):
|
||||
# type: (str, str, str, Type[nodes.TextElement], str, bool) -> None
|
||||
def add_crossref_type(self, directivename: str, rolename: str, indextemplate: str = '',
|
||||
ref_nodeclass: "Type[TextElement]" = None, objname: str = '',
|
||||
override: bool = False) -> None:
|
||||
"""Register a new crossref object type.
|
||||
|
||||
This method is very similar to :meth:`add_object_type` except that the
|
||||
@ -814,8 +821,7 @@ class Sphinx:
|
||||
indextemplate, ref_nodeclass, objname,
|
||||
override=override)
|
||||
|
||||
def add_transform(self, transform):
|
||||
# type: (Type[Transform]) -> None
|
||||
def add_transform(self, transform: "Type[Transform]") -> None:
|
||||
"""Register a Docutils transform to be applied after parsing.
|
||||
|
||||
Add the standard docutils :class:`Transform` subclass *transform* to
|
||||
@ -848,8 +854,7 @@ class Sphinx:
|
||||
""" # NOQA
|
||||
self.registry.add_transform(transform)
|
||||
|
||||
def add_post_transform(self, transform):
|
||||
# type: (Type[Transform]) -> None
|
||||
def add_post_transform(self, transform: "Type[Transform]") -> None:
|
||||
"""Register a Docutils transform to be applied before writing.
|
||||
|
||||
Add the standard docutils :class:`Transform` subclass *transform* to
|
||||
@ -858,22 +863,22 @@ class Sphinx:
|
||||
"""
|
||||
self.registry.add_post_transform(transform)
|
||||
|
||||
def add_javascript(self, filename, **kwargs):
|
||||
# type: (str, **str) -> None
|
||||
def add_javascript(self, filename: str, **kwargs: str) -> None:
|
||||
"""An alias of :meth:`add_js_file`."""
|
||||
warnings.warn('The app.add_javascript() is deprecated. '
|
||||
'Please use app.add_js_file() instead.',
|
||||
RemovedInSphinx40Warning, stacklevel=2)
|
||||
self.add_js_file(filename, **kwargs)
|
||||
|
||||
def add_js_file(self, filename, **kwargs):
|
||||
# type: (str, **str) -> None
|
||||
def add_js_file(self, filename: str, **kwargs: str) -> None:
|
||||
"""Register a JavaScript file to include in the HTML output.
|
||||
|
||||
Add *filename* to the list of JavaScript files that the default HTML
|
||||
template will include. The filename must be relative to the HTML
|
||||
static path , or a full URI with scheme. The keyword arguments are
|
||||
also accepted for attributes of ``<script>`` tag.
|
||||
static path , or a full URI with scheme. If the keyword argument
|
||||
``body`` is given, its value will be added between the
|
||||
``<script>`` tags. Extra keyword arguments are included as
|
||||
attributes of the ``<script>`` tag.
|
||||
|
||||
Example::
|
||||
|
||||
@ -883,6 +888,9 @@ class Sphinx:
|
||||
app.add_js_file('example.js', async="async")
|
||||
# => <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
|
||||
|
||||
.. versionchanged:: 1.8
|
||||
@ -893,8 +901,7 @@ class Sphinx:
|
||||
if hasattr(self.builder, 'add_js_file'):
|
||||
self.builder.add_js_file(filename, **kwargs) # type: ignore
|
||||
|
||||
def add_css_file(self, filename, **kwargs):
|
||||
# type: (str, **str) -> None
|
||||
def add_css_file(self, filename: str, **kwargs: str) -> None:
|
||||
"""Register a stylesheet to include in the HTML output.
|
||||
|
||||
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'):
|
||||
self.builder.add_css_file(filename, **kwargs) # type: ignore
|
||||
|
||||
def add_stylesheet(self, filename, alternate=False, title=None):
|
||||
# type: (str, bool, str) -> None
|
||||
def add_stylesheet(self, filename: str, alternate: bool = False, title: str = None
|
||||
) -> None:
|
||||
"""An alias of :meth:`add_css_file`."""
|
||||
warnings.warn('The app.add_stylesheet() is deprecated. '
|
||||
'Please use app.add_css_file() instead.',
|
||||
@ -951,8 +958,7 @@ class Sphinx:
|
||||
|
||||
self.add_css_file(filename, **attributes)
|
||||
|
||||
def add_latex_package(self, packagename, options=None):
|
||||
# type: (str, str) -> None
|
||||
def add_latex_package(self, packagename: str, options: str = None) -> None:
|
||||
r"""Register a package to include in the LaTeX source code.
|
||||
|
||||
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)
|
||||
|
||||
def add_lexer(self, alias, lexer):
|
||||
# type: (str, Union[Lexer, Type[Lexer]]) -> None
|
||||
def add_lexer(self, alias: str, lexer: Union[Lexer, "Type[Lexer]"]) -> None:
|
||||
"""Register a new lexer for source code.
|
||||
|
||||
Use *lexer* to highlight code blocks with the given language *alias*.
|
||||
@ -990,8 +995,7 @@ class Sphinx:
|
||||
else:
|
||||
lexer_classes[alias] = lexer
|
||||
|
||||
def add_autodocumenter(self, cls, override=False):
|
||||
# type: (Any, bool) -> None
|
||||
def add_autodocumenter(self, cls: Any, override: bool = False) -> None:
|
||||
"""Register a new documenter class for the autodoc extension.
|
||||
|
||||
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.add_directive('auto' + cls.objtype, AutodocDirective, override=override)
|
||||
|
||||
def add_autodoc_attrgetter(self, typ, getter):
|
||||
# type: (Type, Callable[[Any, str, Any], Any]) -> None
|
||||
def add_autodoc_attrgetter(self, typ: "Type", getter: Callable[[Any, str, Any], Any]
|
||||
) -> None:
|
||||
"""Register a new ``getattr``-like function for the autodoc extension.
|
||||
|
||||
Add *getter*, which must be a function with an interface compatible to
|
||||
@ -1026,8 +1030,7 @@ class Sphinx:
|
||||
logger.debug('[app] adding autodoc attrgetter: %r', (typ, getter))
|
||||
self.registry.add_autodoc_attrgetter(typ, getter)
|
||||
|
||||
def add_search_language(self, cls):
|
||||
# type: (Any) -> None
|
||||
def add_search_language(self, cls: Any) -> None:
|
||||
"""Register a new language for the HTML search index.
|
||||
|
||||
Add *cls*, which must be a subclass of
|
||||
@ -1043,8 +1046,7 @@ class Sphinx:
|
||||
assert issubclass(cls, SearchLanguage)
|
||||
languages[cls.lang] = cls
|
||||
|
||||
def add_source_suffix(self, suffix, filetype, override=False):
|
||||
# type: (str, str, bool) -> None
|
||||
def add_source_suffix(self, suffix: str, filetype: str, override: bool = False) -> None:
|
||||
"""Register a suffix of source files.
|
||||
|
||||
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)
|
||||
|
||||
def add_source_parser(self, *args, **kwargs):
|
||||
# type: (Any, Any) -> None
|
||||
def add_source_parser(self, *args: Any, **kwargs: Any) -> None:
|
||||
"""Register a parser class.
|
||||
|
||||
.. versionadded:: 1.4
|
||||
@ -1067,8 +1068,7 @@ class Sphinx:
|
||||
"""
|
||||
self.registry.add_source_parser(*args, **kwargs)
|
||||
|
||||
def add_env_collector(self, collector):
|
||||
# type: (Type[EnvironmentCollector]) -> None
|
||||
def add_env_collector(self, collector: "Type[EnvironmentCollector]") -> None:
|
||||
"""Register an environment collector class.
|
||||
|
||||
Refer to :ref:`collector-api`.
|
||||
@ -1078,8 +1078,7 @@ class Sphinx:
|
||||
logger.debug('[app] adding environment collector: %r', collector)
|
||||
collector().enable(self)
|
||||
|
||||
def add_html_theme(self, name, theme_path):
|
||||
# type: (str, str) -> None
|
||||
def add_html_theme(self, name: str, theme_path: str) -> None:
|
||||
"""Register a HTML 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)
|
||||
self.html_themes[name] = theme_path
|
||||
|
||||
def add_html_math_renderer(self, name, inline_renderers=None, block_renderers=None):
|
||||
# type: (str, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
|
||||
def add_html_math_renderer(self, name: str,
|
||||
inline_renderers: Tuple[Callable, Callable] = None,
|
||||
block_renderers: Tuple[Callable, Callable] = None) -> None:
|
||||
"""Register a math renderer for HTML.
|
||||
|
||||
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)
|
||||
|
||||
def add_message_catalog(self, catalog, locale_dir):
|
||||
# type: (str, str) -> None
|
||||
def add_message_catalog(self, catalog: str, locale_dir: str) -> None:
|
||||
"""Register a message catalog.
|
||||
|
||||
The *catalog* is a name of catalog, and *locale_dir* is a base path
|
||||
@ -1119,34 +1118,37 @@ class Sphinx:
|
||||
locale.init_console(locale_dir, catalog)
|
||||
|
||||
# ---- other methods -------------------------------------------------
|
||||
def is_parallel_allowed(self, typ):
|
||||
# type: (str) -> bool
|
||||
def is_parallel_allowed(self, typ: str) -> bool:
|
||||
"""Check parallel processing is allowed or not.
|
||||
|
||||
``typ`` is a type of processing; ``'read'`` or ``'write'``.
|
||||
"""
|
||||
if typ == 'read':
|
||||
attrname = 'parallel_read_safe'
|
||||
message = __("the %s extension does not declare if it is safe "
|
||||
"for parallel reading, assuming it isn't - please "
|
||||
"ask the extension author to check and make it "
|
||||
"explicit")
|
||||
message_not_declared = __("the %s extension does not declare if it "
|
||||
"is safe for parallel reading, assuming "
|
||||
"it isn't - please ask the extension author "
|
||||
"to check and make it explicit")
|
||||
message_not_safe = __("the %s extension is not safe for parallel reading")
|
||||
elif typ == 'write':
|
||||
attrname = 'parallel_write_safe'
|
||||
message = __("the %s extension does not declare if it is safe "
|
||||
"for parallel writing, assuming it isn't - please "
|
||||
"ask the extension author to check and make it "
|
||||
"explicit")
|
||||
message_not_declared = __("the %s extension does not declare if it "
|
||||
"is safe for parallel writing, assuming "
|
||||
"it isn't - please ask the extension author "
|
||||
"to check and make it explicit")
|
||||
message_not_safe = __("the %s extension is not safe for parallel writing")
|
||||
else:
|
||||
raise ValueError('parallel type %s is not supported' % typ)
|
||||
|
||||
for ext in self.extensions.values():
|
||||
allowed = getattr(ext, attrname, None)
|
||||
if allowed is None:
|
||||
logger.warning(message, ext.name)
|
||||
logger.warning(message_not_declared, ext.name)
|
||||
logger.warning(__('doing serial %s'), typ)
|
||||
return False
|
||||
elif not allowed:
|
||||
logger.warning(message_not_safe, ext.name)
|
||||
logger.warning(__('doing serial %s'), typ)
|
||||
return False
|
||||
|
||||
return True
|
||||
@ -1158,8 +1160,7 @@ class TemplateBridge:
|
||||
that renders templates given a template name and a context.
|
||||
"""
|
||||
|
||||
def init(self, builder, theme=None, dirs=None):
|
||||
# type: (Builder, Theme, List[str]) -> None
|
||||
def init(self, builder: "Builder", theme: Theme = None, dirs: List[str] = None) -> None:
|
||||
"""Called by the builder to initialize the template system.
|
||||
|
||||
*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')
|
||||
|
||||
def newest_template_mtime(self):
|
||||
# type: () -> float
|
||||
def newest_template_mtime(self) -> float:
|
||||
"""Called by the builder to determine if output files are outdated
|
||||
because of template changes. Return the mtime of the newest template
|
||||
file that was changed. The default implementation returns ``0``.
|
||||
"""
|
||||
return 0
|
||||
|
||||
def render(self, template, context):
|
||||
# type: (str, Dict) -> None
|
||||
def render(self, template: str, context: Dict) -> None:
|
||||
"""Called by the builder to render a template given as a filename with
|
||||
a specified context (a Python dictionary).
|
||||
"""
|
||||
raise NotImplementedError('must be implemented in subclasses')
|
||||
|
||||
def render_string(self, template, context):
|
||||
# type: (str, Dict) -> str
|
||||
def render_string(self, template: str, context: Dict) -> str:
|
||||
"""Called by the builder to render a template given as a string with a
|
||||
specified context (a Python dictionary).
|
||||
"""
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import pickle
|
||||
import time
|
||||
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.nodes import Node
|
||||
@ -44,6 +44,7 @@ except ImportError:
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Type # for python3.5.1
|
||||
from sphinx.application import Sphinx
|
||||
|
||||
|
||||
@ -117,11 +118,11 @@ class Builder:
|
||||
self.env.set_versioning_method(self.versioning_method,
|
||||
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 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.
|
||||
|
||||
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`.
|
||||
"""
|
||||
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
|
||||
with logging.pending_warnings():
|
||||
@ -378,7 +379,7 @@ class Builder:
|
||||
added, changed, removed = self.env.get_outdated_files(updated)
|
||||
|
||||
# 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)
|
||||
|
||||
# if files were added or removed, all documents with globbed toctrees
|
||||
@ -387,9 +388,11 @@ class Builder:
|
||||
# ... but not those that already were removed
|
||||
changed.update(self.env.glob_toctrees & self.env.found_docs)
|
||||
|
||||
if changed:
|
||||
reason = CONFIG_CHANGED_REASON.get(self.env.config_status, '')
|
||||
if updated: # explain the change iff build config status was not ok
|
||||
reason = (CONFIG_CHANGED_REASON.get(self.env.config_status, '') +
|
||||
(self.env.config_status_extra or ''))
|
||||
logger.info('[%s] ', reason, nonl=True)
|
||||
|
||||
logger.info(__('%s added, %s changed, %s removed'),
|
||||
len(added), len(changed), len(removed))
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -259,6 +259,15 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
Some readers crash because they interpret the part as a
|
||||
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):
|
||||
if 'refuri' in reference:
|
||||
m = self.refuri_re.match(reference['refuri'])
|
||||
@ -268,22 +277,14 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
reference['refid'] = self.fix_fragment('', reference['refid'])
|
||||
|
||||
for target in tree.traverse(nodes.target):
|
||||
for i, node_id in enumerate(target['ids']):
|
||||
if ':' in node_id:
|
||||
target['ids'][i] = self.fix_fragment('', node_id)
|
||||
update_node_id(target)
|
||||
|
||||
next_node = target.next_node(siblings=True) # type: Node
|
||||
next_node = target.next_node(ascend=True) # type: Node
|
||||
if isinstance(next_node, nodes.Element):
|
||||
for i, node_id in enumerate(next_node['ids']):
|
||||
if ':' in node_id:
|
||||
next_node['ids'][i] = self.fix_fragment('', node_id)
|
||||
update_node_id(next_node)
|
||||
|
||||
for desc_signature in tree.traverse(addnodes.desc_signature):
|
||||
ids = desc_signature.attributes['ids']
|
||||
newids = []
|
||||
for id in ids:
|
||||
newids.append(self.fix_fragment('', id))
|
||||
desc_signature.attributes['ids'] = newids
|
||||
update_node_id(desc_signature)
|
||||
|
||||
def add_visible_links(self, tree: nodes.document, show_urls: str = 'inline') -> None:
|
||||
"""Add visible link targets for external links"""
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -50,7 +50,7 @@ class ChangesBuilder(Builder):
|
||||
'deprecated': 'deprecated',
|
||||
}
|
||||
|
||||
def write(self, *ignored) -> None:
|
||||
def write(self, *ignored: Any) -> None:
|
||||
version = self.config.version
|
||||
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
|
||||
libchanges = {} # type: Dict[str, List[Tuple[str, str, int]]]
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
.. _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.
|
||||
"""
|
||||
|
||||
|
@ -4,12 +4,12 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
from os import path
|
||||
from typing import Any, Dict, Set
|
||||
from typing import Any, Dict
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
@ -45,10 +45,6 @@ class DirectoryHTMLBuilder(StandaloneHTMLBuilder):
|
||||
|
||||
return outfilename
|
||||
|
||||
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||
super().prepare_writing(docnames)
|
||||
self.globalcontext['no_search_suffix'] = True
|
||||
|
||||
|
||||
# for compatibility
|
||||
deprecated_alias('sphinx.builders.html',
|
||||
|
@ -282,7 +282,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
ENUM('horizontal', 'vertical'))
|
||||
|
||||
# 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)
|
||||
|
||||
return {
|
||||
|
@ -4,23 +4,23 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
from codecs import open
|
||||
from collections import defaultdict, OrderedDict
|
||||
from datetime import datetime, tzinfo, timedelta
|
||||
from io import StringIO
|
||||
from os import path, walk, getenv
|
||||
from time import time
|
||||
from 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 docutils import nodes
|
||||
from docutils.nodes import Element
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx import package_dir
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
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.i18n import CatalogInfo, docname_to_domain
|
||||
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.template import SphinxRenderer
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import DefaultDict # for python3.5.1
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -55,7 +59,15 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\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:
|
||||
@ -77,6 +89,12 @@ class Catalog:
|
||||
self.metadata[msg] = []
|
||||
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:
|
||||
"""
|
||||
@ -89,6 +107,30 @@ class MsgOrigin:
|
||||
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):
|
||||
"""Dummy tags module for I18nBuilder.
|
||||
|
||||
@ -164,8 +206,8 @@ if source_date_epoch is not None:
|
||||
|
||||
|
||||
class LocalTimeZone(tzinfo):
|
||||
def __init__(self, *args, **kw) -> None:
|
||||
super().__init__(*args, **kw) # type: ignore
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs) # type: ignore
|
||||
self.tzdelta = tzdelta
|
||||
|
||||
def utcoffset(self, dt: datetime) -> timedelta:
|
||||
@ -178,7 +220,7 @@ class LocalTimeZone(tzinfo):
|
||||
ltz = LocalTimeZone()
|
||||
|
||||
|
||||
def should_write(filepath: str, new_content: str):
|
||||
def should_write(filepath: str, new_content: str) -> bool:
|
||||
if not path.exists(filepath):
|
||||
return True
|
||||
try:
|
||||
@ -244,12 +286,15 @@ class MessageCatalogBuilder(I18nBuilder):
|
||||
|
||||
def finish(self) -> None:
|
||||
super().finish()
|
||||
data = {
|
||||
context = {
|
||||
'version': self.config.version,
|
||||
'copyright': self.config.copyright,
|
||||
'project': self.config.project,
|
||||
'ctime': datetime.fromtimestamp(
|
||||
timestamp, ltz).strftime('%Y-%m-%d %H:%M%z'),
|
||||
'last_translator': self.config.gettext_last_translator,
|
||||
'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(),
|
||||
__("writing message catalogs... "),
|
||||
@ -259,30 +304,10 @@ class MessageCatalogBuilder(I18nBuilder):
|
||||
# noop if config.gettext_compact is set
|
||||
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')
|
||||
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):
|
||||
with open(pofn, 'w', encoding='utf-8') as pofile:
|
||||
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_auto_build', True, '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 {
|
||||
'version': 'builtin',
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -15,7 +15,7 @@ import sys
|
||||
import warnings
|
||||
from hashlib import md5
|
||||
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.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.writers.html import HTMLWriter, HTMLTranslator
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Type # for python3.5.1
|
||||
|
||||
|
||||
# HTML5 Writer is available or not
|
||||
if is_html5_writer_available():
|
||||
from sphinx.writers.html5 import HTML5Translator
|
||||
@ -85,7 +90,7 @@ class Stylesheet(str):
|
||||
attributes = None # type: Dict[str, 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.filename = filename
|
||||
self.attributes = attributes
|
||||
@ -108,11 +113,10 @@ class JavaScript(str):
|
||||
attributes = None # type: Dict[str, 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.filename = filename
|
||||
self.attributes = attributes
|
||||
self.attributes.setdefault('type', 'text/javascript')
|
||||
|
||||
return self
|
||||
|
||||
@ -267,6 +271,19 @@ class StandaloneHTMLBuilder(Builder):
|
||||
style = 'sphinx'
|
||||
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:
|
||||
for filename, attrs in self.app.registry.css_files:
|
||||
self.add_css_file(filename, **attrs)
|
||||
@ -302,7 +319,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.script_files.append(JavaScript(filename, **kwargs))
|
||||
|
||||
@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:
|
||||
return HTMLTranslator
|
||||
else:
|
||||
@ -428,11 +445,8 @@ class StandaloneHTMLBuilder(Builder):
|
||||
else:
|
||||
self.last_updated = None
|
||||
|
||||
logo = self.config.html_logo and \
|
||||
path.basename(self.config.html_logo) or ''
|
||||
|
||||
favicon = self.config.html_favicon and \
|
||||
path.basename(self.config.html_favicon) or ''
|
||||
logo = path.basename(self.config.html_logo) if self.config.html_logo else ''
|
||||
favicon = path.basename(self.config.html_favicon) if self.config.html_favicon else ''
|
||||
|
||||
if not isinstance(self.config.html_use_opensearch, str):
|
||||
logger.warning(__('html_use_opensearch config value must now be a string'))
|
||||
@ -472,6 +486,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
'show_source': self.config.html_show_sourcelink,
|
||||
'sourcelink_suffix': self.config.html_sourcelink_suffix,
|
||||
'file_suffix': self.out_suffix,
|
||||
'link_suffix': self.link_suffix,
|
||||
'script_files': self.script_files,
|
||||
'language': self.config.language,
|
||||
'css_files': self.css_files,
|
||||
@ -482,7 +497,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
'parents': [],
|
||||
'logo': logo,
|
||||
'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:
|
||||
self.globalcontext.update(
|
||||
@ -534,10 +549,10 @@ class StandaloneHTMLBuilder(Builder):
|
||||
|
||||
# title rendered as HTML
|
||||
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
|
||||
source_suffix = path.splitext(self.env.doc2path(docname))[1]
|
||||
source_suffix = self.env.doc2path(docname, False)[len(docname):]
|
||||
|
||||
# the name for the copied 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.post_process_images(doctree)
|
||||
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)
|
||||
|
||||
def finish(self) -> None:
|
||||
@ -717,6 +732,10 @@ class StandaloneHTMLBuilder(Builder):
|
||||
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f:
|
||||
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:
|
||||
"""Copy a JavaScript file for translations."""
|
||||
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:
|
||||
for node in doctree.traverse(nodes.image):
|
||||
scale_keys = ('scale', 'width', 'height')
|
||||
if not any((key in node) for key in scale_keys) or \
|
||||
isinstance(node.parent, nodes.reference):
|
||||
# docutils does unfortunately not preserve the
|
||||
# ``target`` attribute on images, so we need to check
|
||||
# the parent node here.
|
||||
if not any((key in node) for key in ['scale', 'width', 'height']):
|
||||
# resizing options are not given. scaled image link is available
|
||||
# only for resized images.
|
||||
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']
|
||||
reference = nodes.reference('', '', internal=True)
|
||||
if uri in self.images:
|
||||
@ -846,7 +869,11 @@ class StandaloneHTMLBuilder(Builder):
|
||||
if self.indexer is not None and title:
|
||||
filename = self.env.doc2path(pagename, base=None)
|
||||
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:
|
||||
# fallback for old search-adapters
|
||||
self.indexer.feed(pagename, title, doctree) # type: ignore
|
||||
@ -857,11 +884,11 @@ class StandaloneHTMLBuilder(Builder):
|
||||
indexer_name, indexer_name),
|
||||
RemovedInSphinx40Warning)
|
||||
|
||||
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwds) -> str:
|
||||
if 'includehidden' not in kwds:
|
||||
kwds['includehidden'] = False
|
||||
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str:
|
||||
if 'includehidden' not in kwargs:
|
||||
kwargs['includehidden'] = False
|
||||
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:
|
||||
return path.join(self.outdir, os_path(pagename) + self.out_suffix)
|
||||
@ -970,7 +997,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
return False
|
||||
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)
|
||||
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))
|
||||
else:
|
||||
# str value (old styled)
|
||||
attrs.append('type="text/javascript"')
|
||||
attrs.append('src="%s"' % pathto(js, resource=True))
|
||||
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):
|
||||
logger.warning(__('html_extra_path entry %r does not exist'), 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)
|
||||
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):
|
||||
logger.warning(__('html_static_path entry %r does not exist'), 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)
|
||||
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')
|
||||
|
||||
# event handlers
|
||||
app.connect('config-inited', convert_html_css_files)
|
||||
app.connect('config-inited', convert_html_js_files)
|
||||
app.connect('config-inited', validate_html_extra_path)
|
||||
app.connect('config-inited', validate_html_static_path)
|
||||
app.connect('config-inited', validate_html_logo)
|
||||
app.connect('config-inited', validate_html_favicon)
|
||||
app.connect('config-inited', convert_html_css_files, priority=800)
|
||||
app.connect('config-inited', convert_html_js_files, priority=800)
|
||||
app.connect('config-inited', validate_html_extra_path, priority=800)
|
||||
app.connect('config-inited', validate_html_static_path, priority=800)
|
||||
app.connect('config-inited', validate_html_logo, priority=800)
|
||||
app.connect('config-inited', validate_html_favicon, priority=800)
|
||||
app.connect('builder-inited', validate_math_renderer)
|
||||
app.connect('html-page-context', setup_js_tag_helper)
|
||||
|
@ -5,7 +5,7 @@
|
||||
Build HTML help support files.
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -20,6 +20,8 @@ import sphinx.builders.latex.nodes # NOQA # Workaround: import this before wri
|
||||
from sphinx import package_dir, addnodes, highlighting
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.builders.latex.constants import ADDITIONAL_SETTINGS, DEFAULT_SETTINGS, SHORTHANDOFF
|
||||
from sphinx.builders.latex.theming import Theme, ThemeFactory
|
||||
from sphinx.builders.latex.util import ExtBabel
|
||||
from sphinx.config import Config, ENUM
|
||||
from sphinx.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.osutil import SEP, make_filename_from_project
|
||||
from sphinx.util.template import LaTeXRenderer
|
||||
from sphinx.writers.latex import (
|
||||
ADDITIONAL_SETTINGS, DEFAULT_SETTINGS, LaTeXWriter, LaTeXTranslator
|
||||
)
|
||||
from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
|
||||
|
||||
# load docutils.nodes after loading sphinx.builders.latex.nodes
|
||||
from docutils import nodes # NOQA
|
||||
@ -54,13 +54,13 @@ XINDY_LANG_OPTIONS = {
|
||||
'hr': '-L croatian -C utf8 ',
|
||||
'cs': '-L czech -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 ',
|
||||
'eo': '-L esperanto -C utf8 ',
|
||||
'et': '-L estonian -C utf8 ',
|
||||
'fi': '-L finnish -C utf8 ',
|
||||
'fr': '-L french -C utf8 ',
|
||||
'de': '-L german -C din5007-utf8 ',
|
||||
'de': '-L german-din5007 -C utf8 ',
|
||||
'is': '-L icelandic -C utf8 ',
|
||||
'it': '-L italian -C utf8 ',
|
||||
'la': '-L latin -C utf8 ',
|
||||
@ -73,9 +73,9 @@ XINDY_LANG_OPTIONS = {
|
||||
'pl': '-L polish -C utf8 ',
|
||||
'pt': '-L portuguese -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 ',
|
||||
'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 ',
|
||||
'tr': '-L turkish -C utf8 ',
|
||||
'hsb': '-L upper-sorbian -C utf8 ',
|
||||
@ -86,7 +86,7 @@ XINDY_LANG_OPTIONS = {
|
||||
'be': '-L belarusian -C utf8 ',
|
||||
'bg': '-L bulgarian -C utf8 ',
|
||||
'mk': '-L macedonian -C utf8 ',
|
||||
'mn': '-L mongolian -C cyrillic-utf8 ',
|
||||
'mn': '-L mongolian-cyrillic -C utf8 ',
|
||||
'ru': '-L russian -C utf8 ',
|
||||
'sr': '-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
|
||||
'el': '-L greek -C utf8 ',
|
||||
# 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 = [
|
||||
@ -127,18 +127,20 @@ class LaTeXBuilder(Builder):
|
||||
self.context = {} # type: Dict[str, Any]
|
||||
self.docnames = [] # type: Iterable[str]
|
||||
self.document_data = [] # type: List[Tuple[str, str, str, str, str, bool]]
|
||||
self.themes = ThemeFactory(self.app)
|
||||
self.usepackages = self.app.registry.latex_packages
|
||||
texescape.init()
|
||||
|
||||
self.init_context()
|
||||
self.init_babel()
|
||||
self.init_multilingual()
|
||||
|
||||
def get_outdated_docs(self) -> Union[str, List[str]]:
|
||||
return 'all documents' # for now
|
||||
|
||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||
if docname not in self.docnames:
|
||||
raise NoUri
|
||||
raise NoUri(docname, typ)
|
||||
else:
|
||||
return '%' + docname
|
||||
|
||||
@ -207,6 +209,41 @@ class LaTeXBuilder(Builder):
|
||||
logger.warning(__('no Babel option known for language %r'),
|
||||
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:
|
||||
highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style)
|
||||
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
|
||||
@ -216,47 +253,51 @@ class LaTeXBuilder(Builder):
|
||||
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
|
||||
f.write(highlighter.get_stylesheet())
|
||||
|
||||
def write(self, *ignored) -> None:
|
||||
def write(self, *ignored: Any) -> None:
|
||||
docwriter = LaTeXWriter(self)
|
||||
docsettings = OptionParser(
|
||||
defaults=self.env.settings,
|
||||
components=(docwriter,),
|
||||
read_config_files=True).get_default_values() # type: Any
|
||||
patch_settings(docsettings)
|
||||
|
||||
self.init_document_data()
|
||||
self.write_stylesheet()
|
||||
|
||||
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
|
||||
if len(entry) > 5:
|
||||
toctree_only = entry[5]
|
||||
destination = SphinxFileOutput(destination_path=path.join(self.outdir, targetname),
|
||||
encoding='utf-8', overwrite_if_changed=True)
|
||||
with progress_message(__("processing %s") % targetname):
|
||||
toctrees = self.env.get_doctree(docname).traverse(addnodes.toctree)
|
||||
if toctrees:
|
||||
if toctrees[0].get('maxdepth') > 0:
|
||||
tocdepth = toctrees[0].get('maxdepth')
|
||||
else:
|
||||
tocdepth = None
|
||||
doctree = self.env.get_doctree(docname)
|
||||
toctree = next(iter(doctree.traverse(addnodes.toctree)), None)
|
||||
if toctree and toctree.get('maxdepth') > 0:
|
||||
tocdepth = toctree.get('maxdepth')
|
||||
else:
|
||||
tocdepth = None
|
||||
|
||||
doctree = self.assemble_doctree(
|
||||
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
|
||||
self.post_process_images(doctree)
|
||||
self.update_doc_context(title, author)
|
||||
self.update_doc_context(title, author, theme)
|
||||
|
||||
with progress_message(__("writing")):
|
||||
docsettings.author = author
|
||||
docsettings.title = title
|
||||
docsettings.contentsname = self.get_contentsname(docname)
|
||||
docsettings.docname = docname
|
||||
docsettings.docclass = docclass
|
||||
docsettings._author = author
|
||||
docsettings._title = title
|
||||
docsettings._contentsname = doctree['contentsname']
|
||||
docsettings._docname = docname
|
||||
docsettings._docclass = theme.name
|
||||
|
||||
doctree.settings = docsettings
|
||||
docwriter.theme = theme
|
||||
docwriter.write(doctree, destination)
|
||||
|
||||
def get_contentsname(self, indexfile: str) -> str:
|
||||
@ -269,9 +310,13 @@ class LaTeXBuilder(Builder):
|
||||
|
||||
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['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
|
||||
self.docnames = set([indexfile] + appendices)
|
||||
@ -361,13 +406,6 @@ class LaTeXBuilder(Builder):
|
||||
copy_asset_file(path.join(staticdirname, 'Makefile_t'),
|
||||
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'))
|
||||
def copy_latex_additional_files(self) -> None:
|
||||
for filename in self.config.latex_additional_files:
|
||||
@ -387,6 +425,11 @@ class LaTeXBuilder(Builder):
|
||||
except Exception as err:
|
||||
logger.warning(__('cannot copy image file %r: %s'),
|
||||
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:
|
||||
formats = self.config.numfig_format
|
||||
@ -404,20 +447,68 @@ class LaTeXBuilder(Builder):
|
||||
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:
|
||||
for key in list(config.latex_elements):
|
||||
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,))
|
||||
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:
|
||||
""" Better default latex_engine settings for specific languages. """
|
||||
if config.language == 'ja':
|
||||
return 'platex'
|
||||
elif (config.language or '').startswith('zh'):
|
||||
return 'xelatex'
|
||||
elif config.language == 'el':
|
||||
return 'xelatex'
|
||||
else:
|
||||
return 'pdflatex'
|
||||
|
||||
@ -425,8 +516,12 @@ def default_latex_engine(config: Config) -> str:
|
||||
def default_latex_docclass(config: Config) -> Dict[str, str]:
|
||||
""" Better default latex_docclass settings for specific languages. """
|
||||
if config.language == 'ja':
|
||||
return {'manual': 'jsbook',
|
||||
'howto': 'jreport'}
|
||||
if config.latex_engine == 'uplatex':
|
||||
return {'manual': 'ujbook',
|
||||
'howto': 'ujreport'}
|
||||
else:
|
||||
return {'manual': 'jsbook',
|
||||
'howto': 'jreport'}
|
||||
else:
|
||||
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]]:
|
||||
""" 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,
|
||||
make_filename_from_project(config.project) + '.tex',
|
||||
texescape.escape_abbr(texescape.escape(config.project)),
|
||||
texescape.escape_abbr(texescape.escape(config.author)),
|
||||
'manual')]
|
||||
texescape.escape_abbr(project),
|
||||
texescape.escape_abbr(author),
|
||||
config.latex_theme)]
|
||||
|
||||
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.setup_extension('sphinx.builders.latex.transforms')
|
||||
|
||||
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,
|
||||
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_logo', None, None, [str])
|
||||
app.add_config_value('latex_appendices', [], None)
|
||||
app.add_config_value('latex_use_latex_multicolumn', False, None)
|
||||
app.add_config_value('latex_use_xindy', default_latex_use_xindy, None)
|
||||
app.add_config_value('latex_use_xindy', default_latex_use_xindy, None, [bool])
|
||||
app.add_config_value('latex_toplevel_sectioning', None, None,
|
||||
ENUM(None, 'part', 'chapter', 'section'))
|
||||
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_elements', {}, 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)
|
||||
|
||||
|
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.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
|
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.
|
||||
|
||||
: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.
|
||||
"""
|
||||
|
||||
@ -32,7 +32,7 @@ class FootnoteDocnameUpdater(SphinxTransform):
|
||||
default_priority = 700
|
||||
TARGET_NODES = (nodes.footnote, nodes.footnote_reference)
|
||||
|
||||
def apply(self, **kwargs) -> None:
|
||||
def apply(self, **kwargs: Any) -> None:
|
||||
matcher = NodeMatcher(*self.TARGET_NODES)
|
||||
for node in self.document.traverse(matcher): # type: nodes.Element
|
||||
node['docname'] = self.env.docname
|
||||
@ -51,7 +51,7 @@ class ShowUrlsTransform(SphinxPostTransform):
|
||||
# references are expanded to footnotes (or not)
|
||||
expanded = False
|
||||
|
||||
def run(self, **kwargs) -> None:
|
||||
def run(self, **kwargs: Any) -> None:
|
||||
try:
|
||||
# replace id_prefix temporarily
|
||||
settings = self.document.settings # type: Any
|
||||
@ -338,7 +338,7 @@ class LaTeXFootnoteTransform(SphinxPostTransform):
|
||||
default_priority = 600
|
||||
builders = ('latex',)
|
||||
|
||||
def run(self, **kwargs) -> None:
|
||||
def run(self, **kwargs: Any) -> None:
|
||||
footnotes = list(self.document.traverse(nodes.footnote))
|
||||
for node in footnotes:
|
||||
node.parent.remove(node)
|
||||
@ -490,7 +490,7 @@ class BibliographyTransform(SphinxPostTransform):
|
||||
default_priority = 750
|
||||
builders = ('latex',)
|
||||
|
||||
def run(self, **kwargs) -> None:
|
||||
def run(self, **kwargs: Any) -> None:
|
||||
citations = thebibliography()
|
||||
for node in self.document.traverse(nodes.citation):
|
||||
node.parent.remove(node)
|
||||
@ -509,7 +509,7 @@ class CitationReferenceTransform(SphinxPostTransform):
|
||||
default_priority = 5 # before ReferencesResolver
|
||||
builders = ('latex',)
|
||||
|
||||
def run(self, **kwargs) -> None:
|
||||
def run(self, **kwargs: Any) -> None:
|
||||
domain = cast(CitationDomain, self.env.get_domain('citation'))
|
||||
matcher = NodeMatcher(addnodes.pending_xref, refdomain='citation', reftype='ref')
|
||||
for node in self.document.traverse(matcher): # type: addnodes.pending_xref
|
||||
@ -529,7 +529,7 @@ class MathReferenceTransform(SphinxPostTransform):
|
||||
default_priority = 5 # before ReferencesResolver
|
||||
builders = ('latex',)
|
||||
|
||||
def run(self, **kwargs) -> None:
|
||||
def run(self, **kwargs: Any) -> None:
|
||||
equations = self.env.get_domain('math').data['objects']
|
||||
for node in self.document.traverse(addnodes.pending_xref):
|
||||
if node['refdomain'] == 'math' and node['reftype'] in ('eq', 'numref'):
|
||||
@ -544,7 +544,7 @@ class LiteralBlockTransform(SphinxPostTransform):
|
||||
default_priority = 400
|
||||
builders = ('latex',)
|
||||
|
||||
def run(self, **kwargs) -> None:
|
||||
def run(self, **kwargs: Any) -> None:
|
||||
matcher = NodeMatcher(nodes.container, literal_block=True)
|
||||
for node in self.document.traverse(matcher): # type: nodes.container
|
||||
newnode = captioned_literal_block('', *node.children, **node.attributes)
|
||||
@ -556,7 +556,7 @@ class DocumentTargetTransform(SphinxPostTransform):
|
||||
default_priority = 400
|
||||
builders = ('latex',)
|
||||
|
||||
def run(self, **kwargs) -> None:
|
||||
def run(self, **kwargs: Any) -> None:
|
||||
for node in self.document.traverse(addnodes.start_of_file):
|
||||
section = node.next_node(nodes.section)
|
||||
if section:
|
||||
@ -591,7 +591,7 @@ class IndexInSectionTitleTransform(SphinxTransform):
|
||||
"""
|
||||
default_priority = 400
|
||||
|
||||
def apply(self):
|
||||
def apply(self, **kwargs: Any) -> None:
|
||||
for node in self.document.traverse(nodes.title):
|
||||
if isinstance(node.parent, nodes.section):
|
||||
for i, index in enumerate(node.traverse(addnodes.index)):
|
||||
|
@ -8,6 +8,8 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from docutils.writers.latex2e import Babel
|
||||
|
||||
|
||||
@ -40,7 +42,7 @@ class ExtBabel(Babel):
|
||||
self.supported = False
|
||||
return 'english' # fallback to english
|
||||
|
||||
def get_mainlanguage_options(self) -> str:
|
||||
def get_mainlanguage_options(self) -> Optional[str]:
|
||||
"""Return options for polyglossia's ``\\setmainlanguage``."""
|
||||
if self.use_polyglossia is False:
|
||||
return None
|
||||
|
@ -4,10 +4,11 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import json
|
||||
import queue
|
||||
import re
|
||||
import socket
|
||||
@ -26,7 +27,7 @@ from sphinx.builders import Builder
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import encode_uri, requests, logging
|
||||
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.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
|
||||
# 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):
|
||||
if isinstance(chunk, bytes): # requests failed to decode
|
||||
chunk = chunk.decode() # manually try to decode it
|
||||
|
||||
parser.feed(chunk)
|
||||
if parser.found:
|
||||
break
|
||||
@ -78,6 +82,8 @@ class CheckExternalLinksBuilder(Builder):
|
||||
self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
|
||||
self.anchors_ignore = [re.compile(x)
|
||||
for x in self.app.config.linkcheck_anchors_ignore]
|
||||
self.auth = [(re.compile(pattern), auth_info) for pattern, auth_info
|
||||
in self.app.config.linkcheck_auth]
|
||||
self.good = set() # type: Set[str]
|
||||
self.broken = {} # type: Dict[str, str]
|
||||
self.redirected = {} # type: Dict[str, Tuple[str, int]]
|
||||
@ -85,6 +91,8 @@ class CheckExternalLinksBuilder(Builder):
|
||||
socket.setdefaulttimeout(5.0)
|
||||
# create output file
|
||||
open(path.join(self.outdir, 'output.txt'), 'w').close()
|
||||
# create JSON output file
|
||||
open(path.join(self.outdir, 'output.json'), 'w').close()
|
||||
|
||||
# create queues and worker threads
|
||||
self.wqueue = queue.Queue() # type: queue.Queue
|
||||
@ -101,7 +109,6 @@ class CheckExternalLinksBuilder(Builder):
|
||||
'allow_redirects': True,
|
||||
'headers': {
|
||||
'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:
|
||||
@ -125,11 +132,18 @@ class CheckExternalLinksBuilder(Builder):
|
||||
except UnicodeError:
|
||||
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:
|
||||
if anchor and self.app.config.linkcheck_anchors:
|
||||
# Read the whole document and see if #anchor exists
|
||||
response = requests.get(req_url, stream=True, config=self.app.config,
|
||||
**kwargs)
|
||||
auth=auth_info, **kwargs)
|
||||
found = check_anchor(response, unquote(anchor))
|
||||
|
||||
if not found:
|
||||
@ -138,13 +152,14 @@ class CheckExternalLinksBuilder(Builder):
|
||||
try:
|
||||
# try a HEAD request first, which should be easier on
|
||||
# the server and the network
|
||||
response = requests.head(req_url, config=self.app.config, **kwargs)
|
||||
response = requests.head(req_url, config=self.app.config,
|
||||
auth=auth_info, **kwargs)
|
||||
response.raise_for_status()
|
||||
except HTTPError:
|
||||
# retry with GET request if that fails, some servers
|
||||
# don't like HEAD requests.
|
||||
response = requests.get(req_url, stream=True, config=self.app.config,
|
||||
**kwargs)
|
||||
auth=auth_info, **kwargs)
|
||||
response.raise_for_status()
|
||||
except HTTPError as err:
|
||||
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:
|
||||
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':
|
||||
self.write_linkstat(linkstat)
|
||||
return
|
||||
if status == 'working' and info == 'old':
|
||||
self.write_linkstat(linkstat)
|
||||
return
|
||||
if lineno:
|
||||
logger.info('(line %4d) ', lineno, nonl=True)
|
||||
@ -224,29 +246,38 @@ class CheckExternalLinksBuilder(Builder):
|
||||
logger.info(darkgray('-ignored- ') + uri + ': ' + info)
|
||||
else:
|
||||
logger.info(darkgray('-ignored- ') + uri)
|
||||
self.write_linkstat(linkstat)
|
||||
elif status == 'local':
|
||||
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':
|
||||
logger.info(darkgreen('ok ') + uri + info)
|
||||
self.write_linkstat(linkstat)
|
||||
elif status == 'broken':
|
||||
self.write_entry('broken', docname, lineno, uri + ': ' + info)
|
||||
if self.app.quiet or self.app.warningiserror:
|
||||
logger.warning(__('broken link: %s (%s)'), uri, info,
|
||||
location=(self.env.doc2path(docname), lineno))
|
||||
location=(filename, lineno))
|
||||
else:
|
||||
logger.info(red('broken ') + uri + red(' - ' + info))
|
||||
self.write_entry('broken', docname, filename, lineno, uri + ': ' + info)
|
||||
self.write_linkstat(linkstat)
|
||||
elif status == 'redirected':
|
||||
text, color = {
|
||||
301: ('permanently', darkred),
|
||||
302: ('with Found', purple),
|
||||
303: ('with See Other', purple),
|
||||
307: ('temporarily', turquoise),
|
||||
0: ('with unknown code', purple),
|
||||
}[code]
|
||||
self.write_entry('redirected ' + text, docname, lineno,
|
||||
uri + ' to ' + info)
|
||||
try:
|
||||
text, color = {
|
||||
301: ('permanently', purple),
|
||||
302: ('with Found', purple),
|
||||
303: ('with See Other', purple),
|
||||
307: ('temporarily', turquoise),
|
||||
308: ('permanently', purple),
|
||||
}[code]
|
||||
except KeyError:
|
||||
text, color = ('with unknown code', purple)
|
||||
linkstat['text'] = text
|
||||
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:
|
||||
return ''
|
||||
@ -286,10 +317,15 @@ class CheckExternalLinksBuilder(Builder):
|
||||
if self.broken:
|
||||
self.app.statuscode = 1
|
||||
|
||||
def write_entry(self, what: str, docname: str, line: int, uri: str) -> None:
|
||||
with open(path.join(self.outdir, 'output.txt'), 'a', encoding='utf-8') as output:
|
||||
output.write("%s:%s: [%s] %s\n" % (self.env.doc2path(docname, None),
|
||||
line, what, uri))
|
||||
def write_entry(self, what: str, docname: str, filename: str, line: int,
|
||||
uri: str) -> None:
|
||||
with open(path.join(self.outdir, 'output.txt'), 'a') as output:
|
||||
output.write("%s:%s: [%s] %s\n" % (filename, line, what, uri))
|
||||
|
||||
def write_linkstat(self, data: dict) -> None:
|
||||
with open(path.join(self.outdir, 'output.json'), 'a') as output:
|
||||
output.write(json.dumps(data))
|
||||
output.write('\n')
|
||||
|
||||
def finish(self) -> None:
|
||||
for worker in self.workers:
|
||||
@ -300,6 +336,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_builder(CheckExternalLinksBuilder)
|
||||
|
||||
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_timeout', None, None, [int])
|
||||
app.add_config_value('linkcheck_workers', 5, None)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -53,10 +53,10 @@ class ManualPageBuilder(Builder):
|
||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||
if typ == 'token':
|
||||
return ''
|
||||
raise NoUri
|
||||
raise NoUri(docname, typ)
|
||||
|
||||
@progress_message(__('writing'))
|
||||
def write(self, *ignored) -> None:
|
||||
def write(self, *ignored: Any) -> None:
|
||||
docwriter = ManualPageWriter(self)
|
||||
docsettings = OptionParser(
|
||||
defaults=self.env.settings,
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -67,10 +67,10 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
||||
if hashindex >= 0:
|
||||
refnode['refuri'] = fname + refuri[hashindex:]
|
||||
|
||||
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwds) -> str:
|
||||
if 'includehidden' not in kwds:
|
||||
kwds['includehidden'] = False
|
||||
toctree = TocTree(self.env).get_toctree_for(docname, self, collapse, **kwds)
|
||||
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str:
|
||||
if 'includehidden' not in kwargs:
|
||||
kwargs['includehidden'] = False
|
||||
toctree = TocTree(self.env).get_toctree_for(docname, self, collapse, **kwargs)
|
||||
if toctree is not None:
|
||||
self.fix_refuris(toctree)
|
||||
return self.render_partial(toctree)['fragment']
|
||||
@ -149,7 +149,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
||||
'display_toc': display_toc,
|
||||
}
|
||||
|
||||
def write(self, *ignored) -> None:
|
||||
def write(self, *ignored: Any) -> None:
|
||||
docnames = self.env.all_docs
|
||||
|
||||
with progress_message(__('preparing documents')):
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -63,7 +63,7 @@ class TexinfoBuilder(Builder):
|
||||
|
||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||
if docname not in self.docnames:
|
||||
raise NoUri
|
||||
raise NoUri(docname, typ)
|
||||
else:
|
||||
return '%' + docname
|
||||
|
||||
@ -90,7 +90,7 @@ class TexinfoBuilder(Builder):
|
||||
docname = docname[:-5]
|
||||
self.titles.append((docname, entry[2]))
|
||||
|
||||
def write(self, *ignored) -> None:
|
||||
def write(self, *ignored: Any) -> None:
|
||||
self.init_document_data()
|
||||
for entry in self.document_data:
|
||||
docname, targetname, title, author = entry[:4]
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
@ -4,12 +4,12 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
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.io import StringOutput
|
||||
@ -23,6 +23,11 @@ from sphinx.util import logging
|
||||
from sphinx.util.osutil import ensuredir, os_path
|
||||
from sphinx.writers.xml import XMLWriter, PseudoXMLWriter
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Type # for python3.5.1
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -4,6 +4,6 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
@ -4,14 +4,16 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import bdb
|
||||
import locale
|
||||
import multiprocessing
|
||||
import os
|
||||
import pdb
|
||||
import sys
|
||||
import traceback
|
||||
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
|
||||
if isinstance(exception, bdb.BdbQuit):
|
||||
return
|
||||
|
||||
if args.pdb:
|
||||
import pdb
|
||||
print(red(__('Exception occurred while building, starting debugger:')),
|
||||
file=stderr)
|
||||
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)
|
||||
elif isinstance(exception, SphinxError):
|
||||
print(red('%s:' % exception.category), file=stderr)
|
||||
print(terminal_safe(str(exception)), file=stderr)
|
||||
print(str(exception), file=stderr)
|
||||
elif isinstance(exception, UnicodeError):
|
||||
print(red(__('Encoding error:')), 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',
|
||||
help=__('turn warnings into errors'))
|
||||
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',
|
||||
help=__('show full traceback on exception'))
|
||||
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
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -88,7 +88,7 @@ class Make:
|
||||
nocolor()
|
||||
|
||||
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:
|
||||
if not osname or os.name == osname:
|
||||
print(' %s %s' % (blue(bname.ljust(10)), description))
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -359,7 +359,7 @@ def generate(d: Dict, overwrite: bool = True, silent: bool = False, templatedir:
|
||||
|
||||
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)
|
||||
if d['sep']:
|
||||
@ -405,15 +405,15 @@ def generate(d: Dict, overwrite: bool = True, silent: bool = False, templatedir:
|
||||
batchfile_template = 'quickstart/make.bat_t'
|
||||
|
||||
if d['makefile'] is True:
|
||||
d['rsrcdir'] = d['sep'] and 'source' or '.'
|
||||
d['rbuilddir'] = d['sep'] and 'build' or d['dot'] + 'build'
|
||||
d['rsrcdir'] = 'source' if d['sep'] else '.'
|
||||
d['rbuilddir'] = 'build' if d['sep'] else d['dot'] + 'build'
|
||||
# use binary mode, to avoid writing \r\n on Windows
|
||||
write_file(path.join(d['path'], 'Makefile'),
|
||||
template.render(makefile_template, d), '\n')
|
||||
|
||||
if d['batchfile'] is True:
|
||||
d['rsrcdir'] = d['sep'] and 'source' or '.'
|
||||
d['rbuilddir'] = d['sep'] and 'build' or d['dot'] + 'build'
|
||||
d['rsrcdir'] = 'source' if d['sep'] else '.'
|
||||
d['rbuilddir'] = 'build' if d['sep'] else d['dot'] + 'build'
|
||||
write_file(path.join(d['path'], 'make.bat'),
|
||||
template.render(batchfile_template, d), '\r\n')
|
||||
|
||||
|
125
sphinx/config.py
125
sphinx/config.py
@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -14,7 +14,9 @@ import types
|
||||
import warnings
|
||||
from collections import OrderedDict
|
||||
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.errors import ConfigError, ExtensionError
|
||||
@ -23,14 +25,13 @@ from sphinx.util import logging
|
||||
from sphinx.util.i18n import format_date
|
||||
from sphinx.util.osutil import cd
|
||||
from sphinx.util.pycompat import execfile_
|
||||
from sphinx.util.tags import Tags
|
||||
from sphinx.util.typing import NoneType
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Callable, Dict, Generator, Iterator, List, Set, Tuple # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.util.tags import Tags # NOQA
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.environment import BuildEnvironment
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -43,8 +44,7 @@ ConfigValue = NamedTuple('ConfigValue', [('name', str),
|
||||
('rebuild', Union[bool, str])])
|
||||
|
||||
|
||||
def is_serializable(obj):
|
||||
# type: (Any) -> bool
|
||||
def is_serializable(obj: Any) -> bool:
|
||||
"""Check if object is serializable or not."""
|
||||
if isinstance(obj, UNSERIALIZABLE_TYPES):
|
||||
return False
|
||||
@ -64,12 +64,10 @@ class ENUM:
|
||||
Example:
|
||||
app.add_config_value('latex_show_urls', 'no', None, ENUM('no', 'footnote', 'inline'))
|
||||
"""
|
||||
def __init__(self, *candidates):
|
||||
# type: (str) -> None
|
||||
def __init__(self, *candidates: str) -> None:
|
||||
self.candidates = candidates
|
||||
|
||||
def match(self, value):
|
||||
# type: (Union[str, List, Tuple]) -> bool
|
||||
def match(self, value: Union[str, List, Tuple]) -> bool:
|
||||
if isinstance(value, (list, tuple)):
|
||||
return all(item in self.candidates for item in value)
|
||||
else:
|
||||
@ -148,6 +146,7 @@ class Config:
|
||||
'math_numfig': (True, 'env', []),
|
||||
'tls_verify': (True, 'env', []),
|
||||
'tls_cacerts': (None, 'env', []),
|
||||
'user_agent': (None, 'env', [str]),
|
||||
'smartquotes': (True, 'env', []),
|
||||
'smartquotes_action': ('qDe', 'env', []),
|
||||
'smartquotes_excludes': ({'languages': ['ja'],
|
||||
@ -155,36 +154,39 @@ class Config:
|
||||
'env', []),
|
||||
} # type: Dict[str, Tuple]
|
||||
|
||||
def __init__(self, config={}, overrides={}):
|
||||
# type: (Dict[str, Any], Dict[str, Any]) -> None
|
||||
self.overrides = overrides
|
||||
def __init__(self, config: Dict[str, Any] = {}, overrides: Dict[str, Any] = {}) -> None:
|
||||
self.overrides = dict(overrides)
|
||||
self.values = Config.config_values.copy()
|
||||
self._raw_config = config
|
||||
self.setup = config.get('setup', None) # type: Callable
|
||||
|
||||
if 'extensions' in overrides:
|
||||
if isinstance(overrides['extensions'], str):
|
||||
config['extensions'] = overrides.pop('extensions').split(',')
|
||||
if 'extensions' in self.overrides:
|
||||
if isinstance(self.overrides['extensions'], str):
|
||||
config['extensions'] = self.overrides.pop('extensions').split(',')
|
||||
else:
|
||||
config['extensions'] = overrides.pop('extensions')
|
||||
config['extensions'] = self.overrides.pop('extensions')
|
||||
self.extensions = config.get('extensions', []) # type: List[str]
|
||||
|
||||
@classmethod
|
||||
def read(cls, confdir, overrides=None, tags=None):
|
||||
# type: (str, Dict, Tags) -> Config
|
||||
def read(cls, confdir: str, overrides: Dict = None, tags: Tags = None) -> "Config":
|
||||
"""Create a Config object from configuration file."""
|
||||
filename = path.join(confdir, CONFIG_FILENAME)
|
||||
namespace = eval_config_file(filename, tags)
|
||||
return cls(namespace, overrides or {})
|
||||
|
||||
def convert_overrides(self, name, value):
|
||||
# type: (str, Any) -> Any
|
||||
def convert_overrides(self, name: str, value: Any) -> Any:
|
||||
if not isinstance(value, str):
|
||||
return value
|
||||
else:
|
||||
defvalue = self.values[name][0]
|
||||
if self.values[name][2] == Any:
|
||||
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):
|
||||
raise ValueError(__('cannot override dictionary config setting %r, '
|
||||
'ignoring (use %r to set individual elements)') %
|
||||
@ -205,8 +207,7 @@ class Config:
|
||||
else:
|
||||
return value
|
||||
|
||||
def pre_init_values(self):
|
||||
# type: () -> None
|
||||
def pre_init_values(self) -> None:
|
||||
"""
|
||||
Initialize some limited config variables before initialize i18n and loading extensions
|
||||
"""
|
||||
@ -220,8 +221,7 @@ class Config:
|
||||
except ValueError as exc:
|
||||
logger.warning("%s", exc)
|
||||
|
||||
def init_values(self):
|
||||
# type: () -> None
|
||||
def init_values(self) -> None:
|
||||
config = self._raw_config
|
||||
for valname, value in self.overrides.items():
|
||||
try:
|
||||
@ -243,8 +243,7 @@ class Config:
|
||||
if name in self.values:
|
||||
self.__dict__[name] = config[name]
|
||||
|
||||
def __getattr__(self, name):
|
||||
# type: (str) -> Any
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
if name.startswith('_'):
|
||||
raise AttributeError(name)
|
||||
if name not in self.values:
|
||||
@ -254,42 +253,34 @@ class Config:
|
||||
return default(self)
|
||||
return default
|
||||
|
||||
def __getitem__(self, name):
|
||||
# type: (str) -> str
|
||||
def __getitem__(self, name: str) -> str:
|
||||
return getattr(self, name)
|
||||
|
||||
def __setitem__(self, name, value):
|
||||
# type: (str, Any) -> None
|
||||
def __setitem__(self, name: str, value: Any) -> None:
|
||||
setattr(self, name, value)
|
||||
|
||||
def __delitem__(self, name):
|
||||
# type: (str) -> None
|
||||
def __delitem__(self, name: str) -> None:
|
||||
delattr(self, name)
|
||||
|
||||
def __contains__(self, name):
|
||||
# type: (str) -> bool
|
||||
def __contains__(self, name: str) -> bool:
|
||||
return name in self.values
|
||||
|
||||
def __iter__(self):
|
||||
# type: () -> Generator[ConfigValue, None, None]
|
||||
def __iter__(self) -> Generator[ConfigValue, None, None]:
|
||||
for name, value in self.values.items():
|
||||
yield ConfigValue(name, getattr(self, name), value[1])
|
||||
|
||||
def add(self, name, default, rebuild, types):
|
||||
# type: (str, Any, Union[bool, str], Any) -> None
|
||||
def add(self, name: str, default: Any, rebuild: Union[bool, str], types: Any) -> None:
|
||||
if name in self.values:
|
||||
raise ExtensionError(__('Config value %r already present') % name)
|
||||
else:
|
||||
self.values[name] = (default, rebuild, types)
|
||||
|
||||
def filter(self, rebuild):
|
||||
# type: (Union[str, List[str]]) -> Iterator[ConfigValue]
|
||||
def filter(self, rebuild: Union[str, List[str]]) -> Iterator[ConfigValue]:
|
||||
if isinstance(rebuild, str):
|
||||
rebuild = [rebuild]
|
||||
return (value for value in self if value.rebuild in rebuild)
|
||||
|
||||
def __getstate__(self):
|
||||
# type: () -> Dict
|
||||
def __getstate__(self) -> Dict:
|
||||
"""Obtains serializable data for pickling."""
|
||||
# remove potentially pickling-problematic values from config
|
||||
__dict__ = {}
|
||||
@ -312,13 +303,11 @@ class Config:
|
||||
|
||||
return __dict__
|
||||
|
||||
def __setstate__(self, state):
|
||||
# type: (Dict) -> None
|
||||
def __setstate__(self, state: Dict) -> None:
|
||||
self.__dict__.update(state)
|
||||
|
||||
|
||||
def eval_config_file(filename, tags):
|
||||
# type: (str, Tags) -> Dict[str, Any]
|
||||
def eval_config_file(filename: str, tags: Tags) -> Dict[str, Any]:
|
||||
"""Evaluate a config file."""
|
||||
namespace = {} # type: Dict[str, Any]
|
||||
namespace['__file__'] = filename
|
||||
@ -335,6 +324,9 @@ def eval_config_file(filename, tags):
|
||||
msg = __("The configuration file (or one of the modules it imports) "
|
||||
"called sys.exit()")
|
||||
raise ConfigError(msg)
|
||||
except ConfigError:
|
||||
# pass through ConfigError from conf.py as is. It will be shown in console.
|
||||
raise
|
||||
except Exception:
|
||||
msg = __("There is a programmable error in your configuration file:\n\n%s")
|
||||
raise ConfigError(msg % traceback.format_exc())
|
||||
@ -342,8 +334,7 @@ def eval_config_file(filename, tags):
|
||||
return namespace
|
||||
|
||||
|
||||
def convert_source_suffix(app, config):
|
||||
# type: (Sphinx, Config) -> None
|
||||
def convert_source_suffix(app: "Sphinx", config: Config) -> None:
|
||||
"""This converts old styled source_suffix to new styled one.
|
||||
|
||||
* old style: str or list
|
||||
@ -368,8 +359,7 @@ def convert_source_suffix(app, config):
|
||||
"But `%r' is given." % source_suffix))
|
||||
|
||||
|
||||
def init_numfig_format(app, config):
|
||||
# type: (Sphinx, Config) -> None
|
||||
def init_numfig_format(app: "Sphinx", config: Config) -> None:
|
||||
"""Initialize :confval:`numfig_format`."""
|
||||
numfig_format = {'section': _('Section %s'),
|
||||
'figure': _('Fig. %s'),
|
||||
@ -381,8 +371,7 @@ def init_numfig_format(app, config):
|
||||
config.numfig_format = numfig_format # type: ignore
|
||||
|
||||
|
||||
def correct_copyright_year(app, config):
|
||||
# type: (Sphinx, Config) -> None
|
||||
def correct_copyright_year(app: "Sphinx", config: Config) -> None:
|
||||
"""correct values of copyright year that are not coherent with
|
||||
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])
|
||||
|
||||
|
||||
def check_confval_types(app, config):
|
||||
# type: (Sphinx, Config) -> None
|
||||
def check_confval_types(app: "Sphinx", config: Config) -> None:
|
||||
"""check all values for deviation from the default value's type, since
|
||||
that can result in TypeErrors all over the place NB.
|
||||
"""
|
||||
@ -451,8 +439,7 @@ def check_confval_types(app, config):
|
||||
default=type(default)))
|
||||
|
||||
|
||||
def check_unicode(config):
|
||||
# type: (Config) -> None
|
||||
def check_unicode(config: Config) -> None:
|
||||
"""check all string values for non-ASCII characters in bytestrings,
|
||||
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')
|
||||
|
||||
|
||||
def check_primary_domain(app, config):
|
||||
# type: (Sphinx, Config) -> None
|
||||
def check_primary_domain(app: "Sphinx", config: Config) -> None:
|
||||
primary_domain = config.primary_domain
|
||||
if primary_domain and not app.registry.has_domain(primary_domain):
|
||||
logger.warning(__('primary_domain %r not found, ignored.'), primary_domain)
|
||||
config.primary_domain = None # type: ignore
|
||||
|
||||
|
||||
def check_master_doc(app, env, added, changed, removed):
|
||||
# type: (Sphinx, BuildEnvironment, Set[str], Set[str], Set[str]) -> Set[str]
|
||||
def check_master_doc(app: "Sphinx", env: "BuildEnvironment", added: Set[str],
|
||||
changed: Set[str], removed: Set[str]) -> Set[str]:
|
||||
"""Adjust master_doc to 'contents' to support an old project which does not have
|
||||
no master_doc setting.
|
||||
"""
|
||||
@ -491,13 +477,12 @@ def check_master_doc(app, env, added, changed, removed):
|
||||
return changed
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
app.connect('config-inited', convert_source_suffix)
|
||||
app.connect('config-inited', init_numfig_format)
|
||||
app.connect('config-inited', correct_copyright_year)
|
||||
app.connect('config-inited', check_confval_types)
|
||||
app.connect('config-inited', check_primary_domain)
|
||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||
app.connect('config-inited', convert_source_suffix, priority=800)
|
||||
app.connect('config-inited', init_numfig_format, priority=800)
|
||||
app.connect('config-inited', correct_copyright_year, priority=800)
|
||||
app.connect('config-inited', check_confval_types, priority=800)
|
||||
app.connect('config-inited', check_primary_domain, priority=800)
|
||||
app.connect('env-get-outdated', check_master_doc)
|
||||
|
||||
return {
|
||||
|
@ -4,17 +4,18 @@
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import warnings
|
||||
from importlib import import_module
|
||||
from typing import Any, Dict
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, Type # NOQA
|
||||
from typing import Type # for python3.5.1
|
||||
|
||||
|
||||
class RemovedInSphinx40Warning(DeprecationWarning):
|
||||
@ -28,25 +29,20 @@ class RemovedInSphinx50Warning(PendingDeprecationWarning):
|
||||
RemovedInNextVersionWarning = RemovedInSphinx40Warning
|
||||
|
||||
|
||||
def deprecated_alias(modname, objects, warning):
|
||||
# type: (str, Dict, Type[Warning]) -> None
|
||||
module = sys.modules.get(modname)
|
||||
if module is None:
|
||||
module = import_module(modname)
|
||||
|
||||
def deprecated_alias(modname: str, objects: Dict, warning: "Type[Warning]") -> None:
|
||||
module = import_module(modname)
|
||||
sys.modules[modname] = _ModuleWrapper(module, modname, objects, warning) # type: ignore
|
||||
|
||||
|
||||
class _ModuleWrapper:
|
||||
def __init__(self, module, modname, objects, warning):
|
||||
# type: (Any, str, Dict, Type[Warning]) -> None
|
||||
def __init__(self, module: Any, modname: str, objects: Dict, warning: "Type[Warning]"
|
||||
) -> None:
|
||||
self._module = module
|
||||
self._modname = modname
|
||||
self._objects = objects
|
||||
self._warning = warning
|
||||
|
||||
def __getattr__(self, name):
|
||||
# type: (str) -> Any
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
if name in self._objects:
|
||||
warnings.warn("%s.%s is deprecated. Check CHANGES for Sphinx "
|
||||
"API modifications." % (self._modname, name),
|
||||
@ -59,33 +55,27 @@ class _ModuleWrapper:
|
||||
class DeprecatedDict(dict):
|
||||
"""A deprecated dict which warns on each access."""
|
||||
|
||||
def __init__(self, data, message, warning):
|
||||
# type: (Dict, str, Type[Warning]) -> None
|
||||
def __init__(self, data: Dict, message: str, warning: "Type[Warning]") -> None:
|
||||
self.message = message
|
||||
self.warning = warning
|
||||
super().__init__(data)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
# type: (str, Any) -> None
|
||||
def __setitem__(self, key: str, value: Any) -> None:
|
||||
warnings.warn(self.message, self.warning, stacklevel=2)
|
||||
super().__setitem__(key, value)
|
||||
|
||||
def setdefault(self, key, default=None):
|
||||
# type: (str, Any) -> None
|
||||
def setdefault(self, key: str, default: Any = None) -> Any:
|
||||
warnings.warn(self.message, self.warning, stacklevel=2)
|
||||
return super().setdefault(key, default)
|
||||
|
||||
def __getitem__(self, key):
|
||||
# type: (str) -> None
|
||||
def __getitem__(self, key: str) -> None:
|
||||
warnings.warn(self.message, self.warning, stacklevel=2)
|
||||
return super().__getitem__(key)
|
||||
|
||||
def get(self, key, default=None):
|
||||
# type: (str, Any) -> None
|
||||
def get(self, key: str, default: Any = None) -> Any:
|
||||
warnings.warn(self.message, self.warning, stacklevel=2)
|
||||
return super().get(key, default)
|
||||
|
||||
def update(self, other=None): # type: ignore
|
||||
# type: (Dict) -> None
|
||||
def update(self, other: Dict) -> None: # type: ignore
|
||||
warnings.warn(self.message, self.warning, stacklevel=2)
|
||||
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