mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '2.0' into refactor_todo2
This commit is contained in:
commit
f6dfab33d2
32
CHANGES
32
CHANGES
@ -10,6 +10,10 @@ Incompatible changes
|
|||||||
Deprecated
|
Deprecated
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
* The ``info`` and ``warn`` arguments of
|
||||||
|
``sphinx.ext.autosummary.generate.generate_autosummary_docs()``
|
||||||
|
* ``sphinx.ext.autosummary.generate._simple_info()``
|
||||||
|
* ``sphinx.ext.autosummary.generate._simple_warn()``
|
||||||
* ``sphinx.ext.todo.merge_info()``
|
* ``sphinx.ext.todo.merge_info()``
|
||||||
* ``sphinx.ext.todo.process_todo_nodes()``
|
* ``sphinx.ext.todo.process_todo_nodes()``
|
||||||
* ``sphinx.ext.todo.process_todos()``
|
* ``sphinx.ext.todo.process_todos()``
|
||||||
@ -21,10 +25,15 @@ Features added
|
|||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
* py domain: duplicated warning does not point the location of source code
|
||||||
|
* #1125: html theme: scrollbar is hard to see on classic theme and macOS
|
||||||
|
* #5502: linkcheck: Consider HTTP 503 response as not an error
|
||||||
|
* #6439: Make generated download links reproducible
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Release 2.1.1 (in development)
|
Release 2.1.2 (in development)
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
@ -45,6 +54,27 @@ Bugs fixed
|
|||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
Release 2.1.1 (released Jun 10, 2019)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Incompatible changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* #6447: autodoc: Stop to generate document for undocumented module variables
|
||||||
|
|
||||||
|
Bugs fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
* #6442: LaTeX: admonitions of :rst:dir:`note` type can get separated from
|
||||||
|
immediately preceding section title by pagebreak
|
||||||
|
* #6448: autodoc: crashed when autodocumenting classes with ``__slots__ = None``
|
||||||
|
* #6451: autodoc: generates docs for "optional import"ed modules as variables
|
||||||
|
* #6452: autosummary: crashed when generating document of properties
|
||||||
|
* #6455: napoleon: docstrings for properties are not processed
|
||||||
|
* #6436: napoleon: "Unknown target name" error if variable name ends with
|
||||||
|
underscore
|
||||||
|
* #6440: apidoc: missing blank lines between modules
|
||||||
|
|
||||||
Release 2.1.0 (released Jun 02, 2019)
|
Release 2.1.0 (released Jun 02, 2019)
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ the source and the compiled catalogs.
|
|||||||
|
|
||||||
When a new locale is submitted, add a new directory with the ISO 639-1 language
|
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
|
identifier and put ``sphinx.po`` in there. Don't forget to update the possible
|
||||||
values for :confval:`language` in ``doc/config.rst``.
|
values for :confval:`language` in ``doc/usage/configuration.rst``.
|
||||||
|
|
||||||
The Sphinx core messages can also be translated on `Transifex
|
The Sphinx core messages can also be translated on `Transifex
|
||||||
<https://www.transifex.com/>`_. There exists a client tool named ``tx`` in the
|
<https://www.transifex.com/>`_. There exists a client tool named ``tx`` in the
|
||||||
|
@ -26,6 +26,22 @@ The following is a list of deprecated interfaces.
|
|||||||
- (will be) Removed
|
- (will be) Removed
|
||||||
- Alternatives
|
- Alternatives
|
||||||
|
|
||||||
|
* - The ``info`` and ``warn`` arguments of
|
||||||
|
``sphinx.ext.autosummary.generate.generate_autosummary_docs()``
|
||||||
|
- 2.2
|
||||||
|
- 4.0
|
||||||
|
- ``logging.info()`` and ``logging.warning()``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autosummary.generate._simple_info()``
|
||||||
|
- 2.2
|
||||||
|
- 4.0
|
||||||
|
- ``logging.info()``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autosummary.generate._simple_warn()``
|
||||||
|
- 2.2
|
||||||
|
- 4.0
|
||||||
|
- ``logging.warning()``
|
||||||
|
|
||||||
* - ``sphinx.ext.todo.merge_info()``
|
* - ``sphinx.ext.todo.merge_info()``
|
||||||
- 2.2
|
- 2.2
|
||||||
- 4.0
|
- 4.0
|
||||||
|
@ -5,9 +5,6 @@ license_file = LICENSE
|
|||||||
tag_build = .dev
|
tag_build = .dev
|
||||||
tag_date = true
|
tag_date = true
|
||||||
|
|
||||||
[bdist_wheel]
|
|
||||||
universal = 1
|
|
||||||
|
|
||||||
[aliases]
|
[aliases]
|
||||||
release = egg_info -Db ''
|
release = egg_info -Db ''
|
||||||
upload = upload --sign --identity=36580288
|
upload = upload --sign --identity=36580288
|
||||||
|
@ -11,22 +11,27 @@
|
|||||||
import pickle
|
import pickle
|
||||||
import time
|
import time
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, Iterable, List, Sequence, Set, Tuple, Type, Union
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Node
|
||||||
|
|
||||||
from sphinx.environment import CONFIG_OK, CONFIG_CHANGED_REASON
|
from sphinx.config import Config
|
||||||
|
from sphinx.environment import BuildEnvironment, CONFIG_OK, CONFIG_CHANGED_REASON
|
||||||
from sphinx.environment.adapters.asset import ImageAdapter
|
from sphinx.environment.adapters.asset import ImageAdapter
|
||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
|
from sphinx.events import EventManager
|
||||||
from sphinx.io import read_doc
|
from sphinx.io import read_doc
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import import_object, logging, rst, progress_message, status_iterator
|
from sphinx.util import import_object, logging, rst, progress_message, status_iterator
|
||||||
from sphinx.util.build_phase import BuildPhase
|
from sphinx.util.build_phase import BuildPhase
|
||||||
from sphinx.util.console import bold # type: ignore
|
from sphinx.util.console import bold # type: ignore
|
||||||
from sphinx.util.docutils import sphinx_domains
|
from sphinx.util.docutils import sphinx_domains
|
||||||
from sphinx.util.i18n import CatalogRepository, docname_to_domain
|
from sphinx.util.i18n import CatalogInfo, CatalogRepository, docname_to_domain
|
||||||
from sphinx.util.osutil import SEP, ensuredir, relative_uri, relpath
|
from sphinx.util.osutil import SEP, ensuredir, relative_uri, relpath
|
||||||
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, \
|
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, \
|
||||||
parallel_available
|
parallel_available
|
||||||
|
from sphinx.util.tags import Tags
|
||||||
|
|
||||||
# side effect: registers roles and directives
|
# side effect: registers roles and directives
|
||||||
from sphinx import roles # noqa
|
from sphinx import roles # noqa
|
||||||
@ -39,13 +44,7 @@ except ImportError:
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, Iterable, List, Sequence, Set, Tuple, Type, Union # NOQA
|
from sphinx.application import Sphinx
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.config import Config # NOQA
|
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
|
||||||
from sphinx.events import EventManager # NOQA
|
|
||||||
from sphinx.util.i18n import CatalogInfo # NOQA
|
|
||||||
from sphinx.util.tags import Tags # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -84,8 +83,7 @@ class Builder:
|
|||||||
#: The builder supports data URIs or not.
|
#: The builder supports data URIs or not.
|
||||||
supported_data_uri_images = False
|
supported_data_uri_images = False
|
||||||
|
|
||||||
def __init__(self, app):
|
def __init__(self, app: "Sphinx") -> None:
|
||||||
# type: (Sphinx) -> None
|
|
||||||
self.srcdir = app.srcdir
|
self.srcdir = app.srcdir
|
||||||
self.confdir = app.confdir
|
self.confdir = app.confdir
|
||||||
self.outdir = app.outdir
|
self.outdir = app.outdir
|
||||||
@ -113,20 +111,17 @@ class Builder:
|
|||||||
self.parallel_ok = False
|
self.parallel_ok = False
|
||||||
self.finish_tasks = None # type: Any
|
self.finish_tasks = None # type: Any
|
||||||
|
|
||||||
def set_environment(self, env):
|
def set_environment(self, env: BuildEnvironment) -> None:
|
||||||
# type: (BuildEnvironment) -> None
|
|
||||||
"""Store BuildEnvironment object."""
|
"""Store BuildEnvironment object."""
|
||||||
self.env = env
|
self.env = env
|
||||||
self.env.set_versioning_method(self.versioning_method,
|
self.env.set_versioning_method(self.versioning_method,
|
||||||
self.versioning_compare)
|
self.versioning_compare)
|
||||||
|
|
||||||
def get_translator_class(self, *args):
|
def get_translator_class(self, *args) -> Type[nodes.NodeVisitor]:
|
||||||
# type: (Any) -> Type[nodes.NodeVisitor]
|
|
||||||
"""Return a class of translator."""
|
"""Return a class of translator."""
|
||||||
return self.app.registry.get_translator_class(self)
|
return self.app.registry.get_translator_class(self)
|
||||||
|
|
||||||
def create_translator(self, *args):
|
def create_translator(self, *args) -> nodes.NodeVisitor:
|
||||||
# type: (Any) -> nodes.NodeVisitor
|
|
||||||
"""Return an instance of translator.
|
"""Return an instance of translator.
|
||||||
|
|
||||||
This method returns an instance of ``default_translator_class`` by default.
|
This method returns an instance of ``default_translator_class`` by default.
|
||||||
@ -135,15 +130,13 @@ class Builder:
|
|||||||
return self.app.registry.create_translator(self, *args)
|
return self.app.registry.create_translator(self, *args)
|
||||||
|
|
||||||
# helper methods
|
# helper methods
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Load necessary templates and perform initialization. The default
|
"""Load necessary templates and perform initialization. The default
|
||||||
implementation does nothing.
|
implementation does nothing.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def create_template_bridge(self):
|
def create_template_bridge(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Return the template bridge configured."""
|
"""Return the template bridge configured."""
|
||||||
if self.config.template_bridge:
|
if self.config.template_bridge:
|
||||||
self.templates = import_object(self.config.template_bridge,
|
self.templates = import_object(self.config.template_bridge,
|
||||||
@ -152,8 +145,7 @@ class Builder:
|
|||||||
from sphinx.jinja2glue import BuiltinTemplateLoader
|
from sphinx.jinja2glue import BuiltinTemplateLoader
|
||||||
self.templates = BuiltinTemplateLoader()
|
self.templates = BuiltinTemplateLoader()
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
"""Return the target URI for a document name.
|
"""Return the target URI for a document name.
|
||||||
|
|
||||||
*typ* can be used to qualify the link characteristic for individual
|
*typ* can be used to qualify the link characteristic for individual
|
||||||
@ -161,8 +153,7 @@ class Builder:
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def get_relative_uri(self, from_, to, typ=None):
|
def get_relative_uri(self, from_: str, to: str, typ: str = None) -> str:
|
||||||
# type: (str, str, str) -> str
|
|
||||||
"""Return a relative URI between two source filenames.
|
"""Return a relative URI between two source filenames.
|
||||||
|
|
||||||
May raise environment.NoUri if there's no way to return a sensible URI.
|
May raise environment.NoUri if there's no way to return a sensible URI.
|
||||||
@ -170,8 +161,7 @@ class Builder:
|
|||||||
return relative_uri(self.get_target_uri(from_),
|
return relative_uri(self.get_target_uri(from_),
|
||||||
self.get_target_uri(to, typ))
|
self.get_target_uri(to, typ))
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> Union[str, Iterable[str]]:
|
||||||
# type: () -> Union[str, Iterable[str]]
|
|
||||||
"""Return an iterable of output files that are outdated, or a string
|
"""Return an iterable of output files that are outdated, or a string
|
||||||
describing what an update build will build.
|
describing what an update build will build.
|
||||||
|
|
||||||
@ -181,13 +171,11 @@ class Builder:
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def get_asset_paths(self):
|
def get_asset_paths(self) -> List[str]:
|
||||||
# type: () -> List[str]
|
|
||||||
"""Return list of paths for assets (ex. templates, CSS, etc.)."""
|
"""Return list of paths for assets (ex. templates, CSS, etc.)."""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def post_process_images(self, doctree):
|
def post_process_images(self, doctree: Node) -> None:
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
"""Pick the best candidate for all image URIs."""
|
"""Pick the best candidate for all image URIs."""
|
||||||
images = ImageAdapter(self.env)
|
images = ImageAdapter(self.env)
|
||||||
for node in doctree.traverse(nodes.image):
|
for node in doctree.traverse(nodes.image):
|
||||||
@ -220,13 +208,11 @@ class Builder:
|
|||||||
|
|
||||||
# compile po methods
|
# compile po methods
|
||||||
|
|
||||||
def compile_catalogs(self, catalogs, message):
|
def compile_catalogs(self, catalogs: Set[CatalogInfo], message: str) -> None:
|
||||||
# type: (Set[CatalogInfo], str) -> None
|
|
||||||
if not self.config.gettext_auto_build:
|
if not self.config.gettext_auto_build:
|
||||||
return
|
return
|
||||||
|
|
||||||
def cat2relpath(cat):
|
def cat2relpath(cat: CatalogInfo) -> str:
|
||||||
# type: (CatalogInfo) -> str
|
|
||||||
return relpath(cat.mo_path, self.env.srcdir).replace(path.sep, SEP)
|
return relpath(cat.mo_path, self.env.srcdir).replace(path.sep, SEP)
|
||||||
|
|
||||||
logger.info(bold(__('building [mo]: ')) + message)
|
logger.info(bold(__('building [mo]: ')) + message)
|
||||||
@ -235,17 +221,14 @@ class Builder:
|
|||||||
stringify_func=cat2relpath):
|
stringify_func=cat2relpath):
|
||||||
catalog.write_mo(self.config.language)
|
catalog.write_mo(self.config.language)
|
||||||
|
|
||||||
def compile_all_catalogs(self):
|
def compile_all_catalogs(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
repo = CatalogRepository(self.srcdir, self.config.locale_dirs,
|
repo = CatalogRepository(self.srcdir, self.config.locale_dirs,
|
||||||
self.config.language, self.config.source_encoding)
|
self.config.language, self.config.source_encoding)
|
||||||
message = __('all of %d po files') % len(list(repo.catalogs))
|
message = __('all of %d po files') % len(list(repo.catalogs))
|
||||||
self.compile_catalogs(set(repo.catalogs), message)
|
self.compile_catalogs(set(repo.catalogs), message)
|
||||||
|
|
||||||
def compile_specific_catalogs(self, specified_files):
|
def compile_specific_catalogs(self, specified_files: List[str]) -> None:
|
||||||
# type: (List[str]) -> None
|
def to_domain(fpath: str) -> str:
|
||||||
def to_domain(fpath):
|
|
||||||
# type: (str) -> str
|
|
||||||
docname = self.env.path2doc(path.abspath(fpath))
|
docname = self.env.path2doc(path.abspath(fpath))
|
||||||
if docname:
|
if docname:
|
||||||
return docname_to_domain(docname, self.config.gettext_compact)
|
return docname_to_domain(docname, self.config.gettext_compact)
|
||||||
@ -262,8 +245,7 @@ class Builder:
|
|||||||
message = __('targets for %d po files that are specified') % len(catalogs)
|
message = __('targets for %d po files that are specified') % len(catalogs)
|
||||||
self.compile_catalogs(catalogs, message)
|
self.compile_catalogs(catalogs, message)
|
||||||
|
|
||||||
def compile_update_catalogs(self):
|
def compile_update_catalogs(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
repo = CatalogRepository(self.srcdir, self.config.locale_dirs,
|
repo = CatalogRepository(self.srcdir, self.config.locale_dirs,
|
||||||
self.config.language, self.config.source_encoding)
|
self.config.language, self.config.source_encoding)
|
||||||
catalogs = {c for c in repo.catalogs if c.is_outdated()}
|
catalogs = {c for c in repo.catalogs if c.is_outdated()}
|
||||||
@ -272,13 +254,11 @@ class Builder:
|
|||||||
|
|
||||||
# build methods
|
# build methods
|
||||||
|
|
||||||
def build_all(self):
|
def build_all(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Build all source files."""
|
"""Build all source files."""
|
||||||
self.build(None, summary=__('all source files'), method='all')
|
self.build(None, summary=__('all source files'), method='all')
|
||||||
|
|
||||||
def build_specific(self, filenames):
|
def build_specific(self, filenames: List[str]) -> None:
|
||||||
# type: (List[str]) -> None
|
|
||||||
"""Only rebuild as much as needed for changes in the *filenames*."""
|
"""Only rebuild as much as needed for changes in the *filenames*."""
|
||||||
# bring the filenames to the canonical format, that is,
|
# bring the filenames to the canonical format, that is,
|
||||||
# relative to the source directory and without source_suffix.
|
# relative to the source directory and without source_suffix.
|
||||||
@ -306,8 +286,7 @@ class Builder:
|
|||||||
self.build(to_write, method='specific',
|
self.build(to_write, method='specific',
|
||||||
summary=__('%d source files given on command line') % len(to_write))
|
summary=__('%d source files given on command line') % len(to_write))
|
||||||
|
|
||||||
def build_update(self):
|
def build_update(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Only rebuild what was changed or added since last build."""
|
"""Only rebuild what was changed or added since last build."""
|
||||||
to_build = self.get_outdated_docs()
|
to_build = self.get_outdated_docs()
|
||||||
if isinstance(to_build, str):
|
if isinstance(to_build, str):
|
||||||
@ -318,8 +297,7 @@ class Builder:
|
|||||||
summary=__('targets for %d source files that are out of date') %
|
summary=__('targets for %d source files that are out of date') %
|
||||||
len(to_build))
|
len(to_build))
|
||||||
|
|
||||||
def build(self, docnames, summary=None, method='update'):
|
def build(self, docnames: Iterable[str], summary: str = None, method: str = 'update') -> None: # NOQA
|
||||||
# type: (Iterable[str], str, str) -> None
|
|
||||||
"""Main build method.
|
"""Main build method.
|
||||||
|
|
||||||
First updates the environment, and then calls :meth:`write`.
|
First updates the environment, and then calls :meth:`write`.
|
||||||
@ -387,8 +365,7 @@ class Builder:
|
|||||||
# wait for all tasks
|
# wait for all tasks
|
||||||
self.finish_tasks.join()
|
self.finish_tasks.join()
|
||||||
|
|
||||||
def read(self):
|
def read(self) -> List[str]:
|
||||||
# type: () -> List[str]
|
|
||||||
"""(Re-)read all files new or changed since last update.
|
"""(Re-)read all files new or changed since last update.
|
||||||
|
|
||||||
Store all environment docnames in the canonical format (ie using SEP as
|
Store all environment docnames in the canonical format (ie using SEP as
|
||||||
@ -450,8 +427,7 @@ class Builder:
|
|||||||
|
|
||||||
return sorted(docnames)
|
return sorted(docnames)
|
||||||
|
|
||||||
def _read_serial(self, docnames):
|
def _read_serial(self, docnames: List[str]) -> None:
|
||||||
# type: (List[str]) -> None
|
|
||||||
for docname in status_iterator(docnames, __('reading sources... '), "purple",
|
for docname in status_iterator(docnames, __('reading sources... '), "purple",
|
||||||
len(docnames), self.app.verbosity):
|
len(docnames), self.app.verbosity):
|
||||||
# remove all inventory entries for that file
|
# remove all inventory entries for that file
|
||||||
@ -459,23 +435,20 @@ class Builder:
|
|||||||
self.env.clear_doc(docname)
|
self.env.clear_doc(docname)
|
||||||
self.read_doc(docname)
|
self.read_doc(docname)
|
||||||
|
|
||||||
def _read_parallel(self, docnames, nproc):
|
def _read_parallel(self, docnames: List[str], nproc: int) -> None:
|
||||||
# type: (List[str], int) -> None
|
|
||||||
# clear all outdated docs at once
|
# clear all outdated docs at once
|
||||||
for docname in docnames:
|
for docname in docnames:
|
||||||
self.events.emit('env-purge-doc', self.env, docname)
|
self.events.emit('env-purge-doc', self.env, docname)
|
||||||
self.env.clear_doc(docname)
|
self.env.clear_doc(docname)
|
||||||
|
|
||||||
def read_process(docs):
|
def read_process(docs: List[str]) -> bytes:
|
||||||
# type: (List[str]) -> bytes
|
|
||||||
self.env.app = self.app
|
self.env.app = self.app
|
||||||
for docname in docs:
|
for docname in docs:
|
||||||
self.read_doc(docname)
|
self.read_doc(docname)
|
||||||
# allow pickling self to send it back
|
# allow pickling self to send it back
|
||||||
return pickle.dumps(self.env, pickle.HIGHEST_PROTOCOL)
|
return pickle.dumps(self.env, pickle.HIGHEST_PROTOCOL)
|
||||||
|
|
||||||
def merge(docs, otherenv):
|
def merge(docs: List[str], otherenv: bytes) -> None:
|
||||||
# type: (List[str], bytes) -> None
|
|
||||||
env = pickle.loads(otherenv)
|
env = pickle.loads(otherenv)
|
||||||
self.env.merge_info_from(docs, env, self.app)
|
self.env.merge_info_from(docs, env, self.app)
|
||||||
|
|
||||||
@ -490,8 +463,7 @@ class Builder:
|
|||||||
logger.info(bold(__('waiting for workers...')))
|
logger.info(bold(__('waiting for workers...')))
|
||||||
tasks.join()
|
tasks.join()
|
||||||
|
|
||||||
def read_doc(self, docname):
|
def read_doc(self, docname: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
"""Parse a file and add/update inventory entries for the doctree."""
|
"""Parse a file and add/update inventory entries for the doctree."""
|
||||||
self.env.prepare_settings(docname)
|
self.env.prepare_settings(docname)
|
||||||
|
|
||||||
@ -516,8 +488,7 @@ class Builder:
|
|||||||
|
|
||||||
self.write_doctree(docname, doctree)
|
self.write_doctree(docname, doctree)
|
||||||
|
|
||||||
def write_doctree(self, docname, doctree):
|
def write_doctree(self, docname: str, doctree: nodes.document) -> None:
|
||||||
# type: (str, nodes.document) -> None
|
|
||||||
"""Write the doctree to a file."""
|
"""Write the doctree to a file."""
|
||||||
# make it picklable
|
# make it picklable
|
||||||
doctree.reporter = None
|
doctree.reporter = None
|
||||||
@ -531,8 +502,7 @@ class Builder:
|
|||||||
with open(doctree_filename, 'wb') as f:
|
with open(doctree_filename, 'wb') as f:
|
||||||
pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
|
pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
|
||||||
|
|
||||||
def write(self, build_docnames, updated_docnames, method='update'):
|
def write(self, build_docnames: Iterable[str], updated_docnames: Sequence[str], method: str = 'update') -> None: # NOQA
|
||||||
# type: (Iterable[str], Sequence[str], str) -> None
|
|
||||||
if build_docnames is None or build_docnames == ['__all__']:
|
if build_docnames is None or build_docnames == ['__all__']:
|
||||||
# build_all
|
# build_all
|
||||||
build_docnames = self.env.found_docs
|
build_docnames = self.env.found_docs
|
||||||
@ -561,8 +531,7 @@ class Builder:
|
|||||||
else:
|
else:
|
||||||
self._write_serial(sorted(docnames))
|
self._write_serial(sorted(docnames))
|
||||||
|
|
||||||
def _write_serial(self, docnames):
|
def _write_serial(self, docnames: Sequence[str]) -> None:
|
||||||
# type: (Sequence[str]) -> None
|
|
||||||
with logging.pending_warnings():
|
with logging.pending_warnings():
|
||||||
for docname in status_iterator(docnames, __('writing output... '), "darkgreen",
|
for docname in status_iterator(docnames, __('writing output... '), "darkgreen",
|
||||||
len(docnames), self.app.verbosity):
|
len(docnames), self.app.verbosity):
|
||||||
@ -572,10 +541,8 @@ class Builder:
|
|||||||
self.write_doc_serialized(docname, doctree)
|
self.write_doc_serialized(docname, doctree)
|
||||||
self.write_doc(docname, doctree)
|
self.write_doc(docname, doctree)
|
||||||
|
|
||||||
def _write_parallel(self, docnames, nproc):
|
def _write_parallel(self, docnames: Sequence[str], nproc: int) -> None:
|
||||||
# type: (Sequence[str], int) -> None
|
def write_process(docs: List[Tuple[str, nodes.document]]) -> None:
|
||||||
def write_process(docs):
|
|
||||||
# type: (List[Tuple[str, nodes.document]]) -> None
|
|
||||||
self.app.phase = BuildPhase.WRITING
|
self.app.phase = BuildPhase.WRITING
|
||||||
for docname, doctree in docs:
|
for docname, doctree in docs:
|
||||||
self.write_doc(docname, doctree)
|
self.write_doc(docname, doctree)
|
||||||
@ -605,41 +572,35 @@ class Builder:
|
|||||||
logger.info(bold(__('waiting for workers...')))
|
logger.info(bold(__('waiting for workers...')))
|
||||||
tasks.join()
|
tasks.join()
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
# type: (Set[str]) -> None
|
|
||||||
"""A place where you can add logic before :meth:`write_doc` is run"""
|
"""A place where you can add logic before :meth:`write_doc` is run"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname: str, doctree: nodes.document) -> None:
|
||||||
# type: (str, nodes.document) -> None
|
|
||||||
"""Where you actually write something to the filesystem."""
|
"""Where you actually write something to the filesystem."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def write_doc_serialized(self, docname, doctree):
|
def write_doc_serialized(self, docname: str, doctree: nodes.document) -> None:
|
||||||
# type: (str, nodes.document) -> None
|
|
||||||
"""Handle parts of write_doc that must be called in the main process
|
"""Handle parts of write_doc that must be called in the main process
|
||||||
if parallel build is active.
|
if parallel build is active.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Finish the building process.
|
"""Finish the building process.
|
||||||
|
|
||||||
The default implementation does nothing.
|
The default implementation does nothing.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Cleanup any resources.
|
"""Cleanup any resources.
|
||||||
|
|
||||||
The default implementation does nothing.
|
The default implementation does nothing.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_builder_config(self, option, default):
|
def get_builder_config(self, option: str, default: str) -> Any:
|
||||||
# type: (str, str) -> Any
|
|
||||||
"""Return a builder specific option.
|
"""Return a builder specific option.
|
||||||
|
|
||||||
This method allows customization of common builder settings by
|
This method allows customization of common builder settings by
|
||||||
|
@ -14,9 +14,11 @@ import re
|
|||||||
import warnings
|
import warnings
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, List, Set, Tuple
|
||||||
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile
|
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Element, Node
|
||||||
from docutils.utils import smartquotes
|
from docutils.utils import smartquotes
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
@ -34,10 +36,6 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
Image = None
|
Image = None
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, List, Set, Tuple # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -93,8 +91,7 @@ Guide = namedtuple('Guide', ['type', 'title', 'uri'])
|
|||||||
NavPoint = namedtuple('NavPoint', ['navpoint', 'playorder', 'text', 'refuri', 'children'])
|
NavPoint = namedtuple('NavPoint', ['navpoint', 'playorder', 'text', 'refuri', 'children'])
|
||||||
|
|
||||||
|
|
||||||
def sphinx_smarty_pants(t, language='en'):
|
def sphinx_smarty_pants(t: str, language: str = 'en') -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
t = t.replace('"', '"')
|
t = t.replace('"', '"')
|
||||||
t = smartquotes.educateDashesOldSchool(t)
|
t = smartquotes.educateDashesOldSchool(t)
|
||||||
t = smartquotes.educateQuotes(t, language)
|
t = smartquotes.educateQuotes(t, language)
|
||||||
@ -145,8 +142,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
template_dir = ""
|
template_dir = ""
|
||||||
doctype = ""
|
doctype = ""
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
super().init()
|
super().init()
|
||||||
# the output files for epub must be .html only
|
# the output files for epub must be .html only
|
||||||
self.out_suffix = '.xhtml'
|
self.out_suffix = '.xhtml'
|
||||||
@ -157,17 +153,14 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
self.use_index = self.get_builder_config('use_index', 'epub')
|
self.use_index = self.get_builder_config('use_index', 'epub')
|
||||||
self.refnodes = [] # type: List[Dict[str, Any]]
|
self.refnodes = [] # type: List[Dict[str, Any]]
|
||||||
|
|
||||||
def create_build_info(self):
|
def create_build_info(self) -> BuildInfo:
|
||||||
# type: () -> BuildInfo
|
|
||||||
return BuildInfo(self.config, self.tags, ['html', 'epub'])
|
return BuildInfo(self.config, self.tags, ['html', 'epub'])
|
||||||
|
|
||||||
def get_theme_config(self):
|
def get_theme_config(self) -> Tuple[str, Dict]:
|
||||||
# type: () -> Tuple[str, Dict]
|
|
||||||
return self.config.epub_theme, self.config.epub_theme_options
|
return self.config.epub_theme, self.config.epub_theme_options
|
||||||
|
|
||||||
# generic support functions
|
# generic support functions
|
||||||
def make_id(self, name):
|
def make_id(self, name: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
# id_cache is intentionally mutable
|
# id_cache is intentionally mutable
|
||||||
"""Return a unique id for name."""
|
"""Return a unique id for name."""
|
||||||
id = self.id_cache.get(name)
|
id = self.id_cache.get(name)
|
||||||
@ -176,8 +169,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
self.id_cache[name] = id
|
self.id_cache[name] = id
|
||||||
return id
|
return id
|
||||||
|
|
||||||
def esc(self, name):
|
def esc(self, name: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
"""Replace all characters not allowed in text an attribute values."""
|
"""Replace all characters not allowed in text an attribute values."""
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
'%s.esc() is deprecated. Use html.escape() instead.' % self.__class__.__name__,
|
'%s.esc() is deprecated. Use html.escape() instead.' % self.__class__.__name__,
|
||||||
@ -189,8 +181,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
name = name.replace('\'', ''')
|
name = name.replace('\'', ''')
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def get_refnodes(self, doctree, result):
|
def get_refnodes(self, doctree: Node, result: List[Dict[str, Any]]) -> List[Dict[str, Any]]: # NOQA
|
||||||
# type: (nodes.Node, List[Dict[str, Any]]) -> List[Dict[str, Any]]
|
|
||||||
"""Collect section titles, their depth in the toc and the refuri."""
|
"""Collect section titles, their depth in the toc and the refuri."""
|
||||||
# XXX: is there a better way than checking the attribute
|
# XXX: is there a better way than checking the attribute
|
||||||
# toctree-l[1-8] on the parent node?
|
# toctree-l[1-8] on the parent node?
|
||||||
@ -213,8 +204,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
result = self.get_refnodes(elem, result)
|
result = self.get_refnodes(elem, result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def check_refnodes(self, nodes):
|
def check_refnodes(self, nodes: List[Dict[str, Any]]) -> None:
|
||||||
# type: (List[Dict[str, Any]]) -> None
|
|
||||||
appeared = set() # type: Set[str]
|
appeared = set() # type: Set[str]
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
if node['refuri'] in appeared:
|
if node['refuri'] in appeared:
|
||||||
@ -222,8 +212,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
else:
|
else:
|
||||||
appeared.add(node['refuri'])
|
appeared.add(node['refuri'])
|
||||||
|
|
||||||
def get_toc(self):
|
def get_toc(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Get the total table of contents, containing the master_doc
|
"""Get the total table of contents, containing the master_doc
|
||||||
and pre and post files not managed by sphinx.
|
and pre and post files not managed by sphinx.
|
||||||
"""
|
"""
|
||||||
@ -238,8 +227,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
item['refuri'] = master_dir + item['refuri']
|
item['refuri'] = master_dir + item['refuri']
|
||||||
self.toc_add_files(self.refnodes)
|
self.toc_add_files(self.refnodes)
|
||||||
|
|
||||||
def toc_add_files(self, refnodes):
|
def toc_add_files(self, refnodes: List[Dict[str, Any]]) -> None:
|
||||||
# type: (List[Dict[str, Any]]) -> None
|
|
||||||
"""Add the master_doc, pre and post files to a list of refnodes.
|
"""Add the master_doc, pre and post files to a list of refnodes.
|
||||||
"""
|
"""
|
||||||
refnodes.insert(0, {
|
refnodes.insert(0, {
|
||||||
@ -261,13 +249,11 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
'text': ssp(html.escape(text))
|
'text': ssp(html.escape(text))
|
||||||
})
|
})
|
||||||
|
|
||||||
def fix_fragment(self, prefix, fragment):
|
def fix_fragment(self, prefix: str, fragment: str) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
"""Return a href/id attribute with colons replaced by hyphens."""
|
"""Return a href/id attribute with colons replaced by hyphens."""
|
||||||
return prefix + fragment.replace(':', '-')
|
return prefix + fragment.replace(':', '-')
|
||||||
|
|
||||||
def fix_ids(self, tree):
|
def fix_ids(self, tree: nodes.document) -> None:
|
||||||
# type: (nodes.document) -> None
|
|
||||||
"""Replace colons with hyphens in href and id attributes.
|
"""Replace colons with hyphens in href and id attributes.
|
||||||
|
|
||||||
Some readers crash because they interpret the part as a
|
Some readers crash because they interpret the part as a
|
||||||
@ -286,7 +272,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
if ':' in node_id:
|
if ':' in node_id:
|
||||||
target['ids'][i] = self.fix_fragment('', node_id)
|
target['ids'][i] = self.fix_fragment('', node_id)
|
||||||
|
|
||||||
next_node = target.next_node(siblings=True) # type: nodes.Node
|
next_node = target.next_node(siblings=True) # type: Node
|
||||||
if isinstance(next_node, nodes.Element):
|
if isinstance(next_node, nodes.Element):
|
||||||
for i, node_id in enumerate(next_node['ids']):
|
for i, node_id in enumerate(next_node['ids']):
|
||||||
if ':' in node_id:
|
if ':' in node_id:
|
||||||
@ -299,20 +285,17 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
newids.append(self.fix_fragment('', id))
|
newids.append(self.fix_fragment('', id))
|
||||||
desc_signature.attributes['ids'] = newids
|
desc_signature.attributes['ids'] = newids
|
||||||
|
|
||||||
def add_visible_links(self, tree, show_urls='inline'):
|
def add_visible_links(self, tree: nodes.document, show_urls: str = 'inline') -> None:
|
||||||
# type: (nodes.document, str) -> None
|
|
||||||
"""Add visible link targets for external links"""
|
"""Add visible link targets for external links"""
|
||||||
|
|
||||||
def make_footnote_ref(doc, label):
|
def make_footnote_ref(doc: nodes.document, label: str) -> nodes.footnote_reference:
|
||||||
# type: (nodes.document, str) -> nodes.footnote_reference
|
|
||||||
"""Create a footnote_reference node with children"""
|
"""Create a footnote_reference node with children"""
|
||||||
footnote_ref = nodes.footnote_reference('[#]_')
|
footnote_ref = nodes.footnote_reference('[#]_')
|
||||||
footnote_ref.append(nodes.Text(label))
|
footnote_ref.append(nodes.Text(label))
|
||||||
doc.note_autofootnote_ref(footnote_ref)
|
doc.note_autofootnote_ref(footnote_ref)
|
||||||
return footnote_ref
|
return footnote_ref
|
||||||
|
|
||||||
def make_footnote(doc, label, uri):
|
def make_footnote(doc: nodes.document, label: str, uri: str) -> nodes.footnote:
|
||||||
# type: (nodes.document, str, str) -> nodes.footnote
|
|
||||||
"""Create a footnote node with children"""
|
"""Create a footnote node with children"""
|
||||||
footnote = nodes.footnote(uri)
|
footnote = nodes.footnote(uri)
|
||||||
para = nodes.paragraph()
|
para = nodes.paragraph()
|
||||||
@ -322,8 +305,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
doc.note_autofootnote(footnote)
|
doc.note_autofootnote(footnote)
|
||||||
return footnote
|
return footnote
|
||||||
|
|
||||||
def footnote_spot(tree):
|
def footnote_spot(tree: nodes.document) -> Tuple[Element, int]:
|
||||||
# type: (nodes.document) -> Tuple[nodes.Element, int]
|
|
||||||
"""Find or create a spot to place footnotes.
|
"""Find or create a spot to place footnotes.
|
||||||
|
|
||||||
The function returns the tuple (parent, index)."""
|
The function returns the tuple (parent, index)."""
|
||||||
@ -371,8 +353,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
footnote.add_backref(footnote_ref['ids'][0])
|
footnote.add_backref(footnote_ref['ids'][0])
|
||||||
fn_idx += 1
|
fn_idx += 1
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname: str, doctree: nodes.document) -> None:
|
||||||
# type: (str, nodes.document) -> None
|
|
||||||
"""Write one document file.
|
"""Write one document file.
|
||||||
|
|
||||||
This method is overwritten in order to fix fragment identifiers
|
This method is overwritten in order to fix fragment identifiers
|
||||||
@ -382,8 +363,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
self.add_visible_links(doctree, self.config.epub_show_urls)
|
self.add_visible_links(doctree, self.config.epub_show_urls)
|
||||||
super().write_doc(docname, doctree)
|
super().write_doc(docname, doctree)
|
||||||
|
|
||||||
def fix_genindex(self, tree):
|
def fix_genindex(self, tree: List[Tuple[str, List[Tuple[str, Any]]]]) -> None:
|
||||||
# type: (List[Tuple[str, List[Tuple[str, Any]]]]) -> None
|
|
||||||
"""Fix href attributes for genindex pages."""
|
"""Fix href attributes for genindex pages."""
|
||||||
# XXX: modifies tree inline
|
# XXX: modifies tree inline
|
||||||
# Logic modeled from themes/basic/genindex.html
|
# Logic modeled from themes/basic/genindex.html
|
||||||
@ -401,14 +381,12 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
subentrylinks[i] = (ismain,
|
subentrylinks[i] = (ismain,
|
||||||
self.fix_fragment(m.group(1), m.group(2)))
|
self.fix_fragment(m.group(1), m.group(2)))
|
||||||
|
|
||||||
def is_vector_graphics(self, filename):
|
def is_vector_graphics(self, filename: str) -> bool:
|
||||||
# type: (str) -> bool
|
|
||||||
"""Does the filename extension indicate a vector graphic format?"""
|
"""Does the filename extension indicate a vector graphic format?"""
|
||||||
ext = path.splitext(filename)[-1]
|
ext = path.splitext(filename)[-1]
|
||||||
return ext in VECTOR_GRAPHICS_EXTENSIONS
|
return ext in VECTOR_GRAPHICS_EXTENSIONS
|
||||||
|
|
||||||
def copy_image_files_pil(self):
|
def copy_image_files_pil(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Copy images using Pillow, the Python Imaging Libary.
|
"""Copy images using Pillow, the Python Imaging Libary.
|
||||||
The method tries to read and write the files with Pillow, converting
|
The method tries to read and write the files with Pillow, converting
|
||||||
the format and resizing the image if necessary/possible.
|
the format and resizing the image if necessary/possible.
|
||||||
@ -447,8 +425,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
logger.warning(__('cannot write image file %r: %s'),
|
logger.warning(__('cannot write image file %r: %s'),
|
||||||
path.join(self.srcdir, src), err)
|
path.join(self.srcdir, src), err)
|
||||||
|
|
||||||
def copy_image_files(self):
|
def copy_image_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Copy image files to destination directory.
|
"""Copy image files to destination directory.
|
||||||
This overwritten method can use Pillow to convert image files.
|
This overwritten method can use Pillow to convert image files.
|
||||||
"""
|
"""
|
||||||
@ -462,13 +439,11 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
else:
|
else:
|
||||||
super().copy_image_files()
|
super().copy_image_files()
|
||||||
|
|
||||||
def copy_download_files(self):
|
def copy_download_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def handle_page(self, pagename, addctx, templatename='page.html',
|
def handle_page(self, pagename: str, addctx: Dict, templatename: str = 'page.html',
|
||||||
outfilename=None, event_arg=None):
|
outfilename: str = None, event_arg: Any = None) -> None:
|
||||||
# type: (str, Dict, str, str, Any) -> None
|
|
||||||
"""Create a rendered page.
|
"""Create a rendered page.
|
||||||
|
|
||||||
This method is overwritten for genindex pages in order to fix href link
|
This method is overwritten for genindex pages in order to fix href link
|
||||||
@ -481,8 +456,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
addctx['doctype'] = self.doctype
|
addctx['doctype'] = self.doctype
|
||||||
super().handle_page(pagename, addctx, templatename, outfilename, event_arg)
|
super().handle_page(pagename, addctx, templatename, outfilename, event_arg)
|
||||||
|
|
||||||
def build_mimetype(self, outdir=None, outname='mimetype'):
|
def build_mimetype(self, outdir: str = None, outname: str = 'mimetype') -> None:
|
||||||
# type: (str, str) -> None
|
|
||||||
"""Write the metainfo file mimetype."""
|
"""Write the metainfo file mimetype."""
|
||||||
if outdir:
|
if outdir:
|
||||||
warnings.warn('The arguments of EpubBuilder.build_mimetype() is deprecated.',
|
warnings.warn('The arguments of EpubBuilder.build_mimetype() is deprecated.',
|
||||||
@ -494,8 +468,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
copy_asset_file(path.join(self.template_dir, 'mimetype'),
|
copy_asset_file(path.join(self.template_dir, 'mimetype'),
|
||||||
path.join(outdir, outname))
|
path.join(outdir, outname))
|
||||||
|
|
||||||
def build_container(self, outdir=None, outname='META-INF/container.xml'):
|
def build_container(self, outdir: str = None, outname: str = 'META-INF/container.xml') -> None: # NOQA
|
||||||
# type: (str, str) -> None
|
|
||||||
"""Write the metainfo file META-INF/container.xml."""
|
"""Write the metainfo file META-INF/container.xml."""
|
||||||
if outdir:
|
if outdir:
|
||||||
warnings.warn('The arguments of EpubBuilder.build_container() is deprecated.',
|
warnings.warn('The arguments of EpubBuilder.build_container() is deprecated.',
|
||||||
@ -508,8 +481,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
ensuredir(path.dirname(filename))
|
ensuredir(path.dirname(filename))
|
||||||
copy_asset_file(path.join(self.template_dir, 'container.xml'), filename)
|
copy_asset_file(path.join(self.template_dir, 'container.xml'), filename)
|
||||||
|
|
||||||
def content_metadata(self):
|
def content_metadata(self) -> Dict[str, Any]:
|
||||||
# type: () -> Dict[str, Any]
|
|
||||||
"""Create a dictionary with all metadata for the content.opf
|
"""Create a dictionary with all metadata for the content.opf
|
||||||
file properly escaped.
|
file properly escaped.
|
||||||
"""
|
"""
|
||||||
@ -528,8 +500,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
metadata['guides'] = []
|
metadata['guides'] = []
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def build_content(self, outdir=None, outname='content.opf'):
|
def build_content(self, outdir: str = None, outname: str = 'content.opf') -> None:
|
||||||
# type: (str, str) -> None
|
|
||||||
"""Write the metainfo file content.opf It contains bibliographic data,
|
"""Write the metainfo file content.opf It contains bibliographic data,
|
||||||
a file list and the spine (the reading order).
|
a file list and the spine (the reading order).
|
||||||
"""
|
"""
|
||||||
@ -648,8 +619,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
path.join(outdir, outname),
|
path.join(outdir, outname),
|
||||||
metadata)
|
metadata)
|
||||||
|
|
||||||
def new_navpoint(self, node, level, incr=True):
|
def new_navpoint(self, node: Dict[str, Any], level: int, incr: bool = True) -> NavPoint:
|
||||||
# type: (Dict[str, Any], int, bool) -> NavPoint
|
|
||||||
"""Create a new entry in the toc from the node at given level."""
|
"""Create a new entry in the toc from the node at given level."""
|
||||||
# XXX Modifies the node
|
# XXX Modifies the node
|
||||||
if incr:
|
if incr:
|
||||||
@ -658,8 +628,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
return NavPoint('navPoint%d' % self.tocid, self.playorder,
|
return NavPoint('navPoint%d' % self.tocid, self.playorder,
|
||||||
node['text'], node['refuri'], [])
|
node['text'], node['refuri'], [])
|
||||||
|
|
||||||
def build_navpoints(self, nodes):
|
def build_navpoints(self, nodes: List[Dict[str, Any]]) -> List[NavPoint]:
|
||||||
# type: (List[Dict[str, Any]]) -> List[NavPoint]
|
|
||||||
"""Create the toc navigation structure.
|
"""Create the toc navigation structure.
|
||||||
|
|
||||||
Subelements of a node are nested inside the navpoint. For nested nodes
|
Subelements of a node are nested inside the navpoint. For nested nodes
|
||||||
@ -703,8 +672,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
return navstack[0].children
|
return navstack[0].children
|
||||||
|
|
||||||
def toc_metadata(self, level, navpoints):
|
def toc_metadata(self, level: int, navpoints: List[NavPoint]) -> Dict[str, Any]:
|
||||||
# type: (int, List[NavPoint]) -> Dict[str, Any]
|
|
||||||
"""Create a dictionary with all metadata for the toc.ncx file
|
"""Create a dictionary with all metadata for the toc.ncx file
|
||||||
properly escaped.
|
properly escaped.
|
||||||
"""
|
"""
|
||||||
@ -715,8 +683,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
metadata['navpoints'] = navpoints
|
metadata['navpoints'] = navpoints
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def build_toc(self, outdir=None, outname='toc.ncx'):
|
def build_toc(self, outdir: str = None, outname: str = 'toc.ncx') -> None:
|
||||||
# type: (str, str) -> None
|
|
||||||
"""Write the metainfo file toc.ncx."""
|
"""Write the metainfo file toc.ncx."""
|
||||||
if outdir:
|
if outdir:
|
||||||
warnings.warn('The arguments of EpubBuilder.build_toc() is deprecated.',
|
warnings.warn('The arguments of EpubBuilder.build_toc() is deprecated.',
|
||||||
@ -743,8 +710,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
path.join(outdir, outname),
|
path.join(outdir, outname),
|
||||||
self.toc_metadata(level, navpoints))
|
self.toc_metadata(level, navpoints))
|
||||||
|
|
||||||
def build_epub(self, outdir=None, outname=None):
|
def build_epub(self, outdir: str = None, outname: str = None) -> None:
|
||||||
# type: (str, str) -> None
|
|
||||||
"""Write the epub file.
|
"""Write the epub file.
|
||||||
|
|
||||||
It is a zip file with the mimetype file stored uncompressed as the first
|
It is a zip file with the mimetype file stored uncompressed as the first
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
from sphinxcontrib.applehelp import (
|
from sphinxcontrib.applehelp import (
|
||||||
AppleHelpCodeSigningFailed,
|
AppleHelpCodeSigningFailed,
|
||||||
@ -16,13 +17,9 @@ from sphinxcontrib.applehelp import (
|
|||||||
AppleHelpBuilder,
|
AppleHelpBuilder,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
deprecated_alias('sphinx.builders.applehelp',
|
deprecated_alias('sphinx.builders.applehelp',
|
||||||
{
|
{
|
||||||
@ -33,8 +30,7 @@ deprecated_alias('sphinx.builders.applehelp',
|
|||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
warnings.warn('sphinx.builders.applehelp has been moved to sphinxcontrib-applehelp.',
|
warnings.warn('sphinx.builders.applehelp has been moved to sphinxcontrib-applehelp.',
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
app.setup_extension('sphinxcontrib.applehelp')
|
app.setup_extension('sphinxcontrib.applehelp')
|
||||||
|
@ -10,9 +10,11 @@
|
|||||||
|
|
||||||
import html
|
import html
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, List, Tuple
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
from sphinx import package_dir
|
from sphinx import package_dir
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.domains.changeset import ChangeSetDomain
|
from sphinx.domains.changeset import ChangeSetDomain
|
||||||
from sphinx.locale import _, __
|
from sphinx.locale import _, __
|
||||||
@ -22,11 +24,6 @@ from sphinx.util.console import bold # type: ignore
|
|||||||
from sphinx.util.fileutil import copy_asset_file
|
from sphinx.util.fileutil import copy_asset_file
|
||||||
from sphinx.util.osutil import ensuredir, os_path
|
from sphinx.util.osutil import ensuredir, os_path
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, List, Tuple # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -38,15 +35,13 @@ class ChangesBuilder(Builder):
|
|||||||
name = 'changes'
|
name = 'changes'
|
||||||
epilog = __('The overview file is in %(outdir)s.')
|
epilog = __('The overview file is in %(outdir)s.')
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.create_template_bridge()
|
self.create_template_bridge()
|
||||||
theme_factory = HTMLThemeFactory(self.app)
|
theme_factory = HTMLThemeFactory(self.app)
|
||||||
self.theme = theme_factory.create('default')
|
self.theme = theme_factory.create('default')
|
||||||
self.templates.init(self, self.theme)
|
self.templates.init(self, self.theme)
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> str:
|
||||||
# type: () -> str
|
|
||||||
return self.outdir
|
return self.outdir
|
||||||
|
|
||||||
typemap = {
|
typemap = {
|
||||||
@ -55,8 +50,7 @@ class ChangesBuilder(Builder):
|
|||||||
'deprecated': 'deprecated',
|
'deprecated': 'deprecated',
|
||||||
}
|
}
|
||||||
|
|
||||||
def write(self, *ignored):
|
def write(self, *ignored) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
version = self.config.version
|
version = self.config.version
|
||||||
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
|
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
|
||||||
libchanges = {} # type: Dict[str, List[Tuple[str, str, int]]]
|
libchanges = {} # type: Dict[str, List[Tuple[str, str, int]]]
|
||||||
@ -121,8 +115,7 @@ class ChangesBuilder(Builder):
|
|||||||
'.. versionchanged:: %s' % version,
|
'.. versionchanged:: %s' % version,
|
||||||
'.. deprecated:: %s' % version]
|
'.. deprecated:: %s' % version]
|
||||||
|
|
||||||
def hl(no, line):
|
def hl(no: int, line: str) -> str:
|
||||||
# type: (int, str) -> str
|
|
||||||
line = '<a name="L%s"> </a>' % no + html.escape(line)
|
line = '<a name="L%s"> </a>' % no + html.escape(line)
|
||||||
for x in hltext:
|
for x in hltext:
|
||||||
if x in line:
|
if x in line:
|
||||||
@ -155,21 +148,18 @@ class ChangesBuilder(Builder):
|
|||||||
copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'),
|
copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'),
|
||||||
self.outdir)
|
self.outdir)
|
||||||
|
|
||||||
def hl(self, text, version):
|
def hl(self, text: str, version: str) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
text = html.escape(text)
|
text = html.escape(text)
|
||||||
for directive in ['versionchanged', 'versionadded', 'deprecated']:
|
for directive in ['versionchanged', 'versionadded', 'deprecated']:
|
||||||
text = text.replace('.. %s:: %s' % (directive, version),
|
text = text.replace('.. %s:: %s' % (directive, version),
|
||||||
'<b>.. %s:: %s</b>' % (directive, version))
|
'<b>.. %s:: %s</b>' % (directive, version))
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_builder(ChangesBuilder)
|
app.add_builder(ChangesBuilder)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -11,18 +11,14 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
from sphinxcontrib.devhelp import DevhelpBuilder
|
from sphinxcontrib.devhelp import DevhelpBuilder
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
|
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
deprecated_alias('sphinx.builders.devhelp',
|
deprecated_alias('sphinx.builders.devhelp',
|
||||||
{
|
{
|
||||||
'DevhelpBuilder': DevhelpBuilder,
|
'DevhelpBuilder': DevhelpBuilder,
|
||||||
@ -30,8 +26,7 @@ deprecated_alias('sphinx.builders.devhelp',
|
|||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
warnings.warn('sphinx.builders.devhelp has been moved to sphinxcontrib-devhelp.',
|
warnings.warn('sphinx.builders.devhelp has been moved to sphinxcontrib-devhelp.',
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
app.setup_extension('sphinxcontrib.devhelp')
|
app.setup_extension('sphinxcontrib.devhelp')
|
||||||
|
@ -9,17 +9,14 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, Set
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util.osutil import SEP, os_path
|
from sphinx.util.osutil import SEP, os_path
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, Set # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -31,16 +28,14 @@ class DirectoryHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
"""
|
"""
|
||||||
name = 'dirhtml'
|
name = 'dirhtml'
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
if docname == 'index':
|
if docname == 'index':
|
||||||
return ''
|
return ''
|
||||||
if docname.endswith(SEP + 'index'):
|
if docname.endswith(SEP + 'index'):
|
||||||
return docname[:-5] # up to sep
|
return docname[:-5] # up to sep
|
||||||
return docname + SEP
|
return docname + SEP
|
||||||
|
|
||||||
def get_outfilename(self, pagename):
|
def get_outfilename(self, pagename: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
if pagename == 'index' or pagename.endswith(SEP + 'index'):
|
if pagename == 'index' or pagename.endswith(SEP + 'index'):
|
||||||
outfilename = path.join(self.outdir, os_path(pagename) +
|
outfilename = path.join(self.outdir, os_path(pagename) +
|
||||||
self.out_suffix)
|
self.out_suffix)
|
||||||
@ -50,8 +45,7 @@ class DirectoryHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
return outfilename
|
return outfilename
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
# type: (Set[str]) -> None
|
|
||||||
super().prepare_writing(docnames)
|
super().prepare_writing(docnames)
|
||||||
self.globalcontext['no_search_suffix'] = True
|
self.globalcontext['no_search_suffix'] = True
|
||||||
|
|
||||||
@ -64,8 +58,7 @@ deprecated_alias('sphinx.builders.html',
|
|||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.setup_extension('sphinx.builders.html')
|
app.setup_extension('sphinx.builders.html')
|
||||||
|
|
||||||
app.add_builder(DirectoryHTMLBuilder)
|
app.add_builder(DirectoryHTMLBuilder)
|
||||||
|
@ -8,16 +8,14 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from typing import Any, Dict, Set
|
||||||
|
|
||||||
|
from docutils.nodes import Node
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, Set # NOQA
|
|
||||||
from docutils import nodes # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
class DummyBuilder(Builder):
|
class DummyBuilder(Builder):
|
||||||
name = 'dummy'
|
name = 'dummy'
|
||||||
@ -25,33 +23,26 @@ class DummyBuilder(Builder):
|
|||||||
|
|
||||||
allow_parallel = True
|
allow_parallel = True
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> Set[str]:
|
||||||
# type: () -> Set[str]
|
|
||||||
return self.env.found_docs
|
return self.env.found_docs
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
# type: (Set[str]) -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname: str, doctree: Node) -> None:
|
||||||
# type: (str, nodes.Node) -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_builder(DummyBuilder)
|
app.add_builder(DummyBuilder)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -13,10 +13,12 @@ import html
|
|||||||
import warnings
|
import warnings
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, List, Set, Tuple
|
||||||
|
|
||||||
from sphinx import package_dir
|
from sphinx import package_dir
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import _epub_base
|
from sphinx.builders import _epub_base
|
||||||
from sphinx.config import ENUM
|
from sphinx.config import Config, ENUM
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging, xmlname_checker
|
from sphinx.util import logging, xmlname_checker
|
||||||
@ -24,12 +26,6 @@ from sphinx.util.fileutil import copy_asset_file
|
|||||||
from sphinx.util.i18n import format_date
|
from sphinx.util.i18n import format_date
|
||||||
from sphinx.util.osutil import make_filename
|
from sphinx.util.osutil import make_filename
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, List, Set, Tuple # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.config import Config # NOQA
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -75,8 +71,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
use_meta_charset = True
|
use_meta_charset = True
|
||||||
|
|
||||||
# Finish by building the epub file
|
# Finish by building the epub file
|
||||||
def handle_finish(self):
|
def handle_finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""Create the metainfo files and finally the epub."""
|
"""Create the metainfo files and finally the epub."""
|
||||||
self.get_toc()
|
self.get_toc()
|
||||||
self.build_mimetype()
|
self.build_mimetype()
|
||||||
@ -86,13 +81,11 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
self.build_toc()
|
self.build_toc()
|
||||||
self.build_epub()
|
self.build_epub()
|
||||||
|
|
||||||
def validate_config_value(self):
|
def validate_config_value(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
warnings.warn('Epub3Builder.validate_config_value() is deprecated.',
|
warnings.warn('Epub3Builder.validate_config_value() is deprecated.',
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
|
||||||
def content_metadata(self):
|
def content_metadata(self) -> Dict:
|
||||||
# type: () -> Dict
|
|
||||||
"""Create a dictionary with all metadata for the content.opf
|
"""Create a dictionary with all metadata for the content.opf
|
||||||
file properly escaped.
|
file properly escaped.
|
||||||
"""
|
"""
|
||||||
@ -108,8 +101,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
metadata['epub_version'] = self.config.epub_version
|
metadata['epub_version'] = self.config.epub_version
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
# type: (Set[str]) -> None
|
|
||||||
super().prepare_writing(docnames)
|
super().prepare_writing(docnames)
|
||||||
|
|
||||||
writing_mode = self.config.epub_writing_mode
|
writing_mode = self.config.epub_writing_mode
|
||||||
@ -118,8 +110,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
self.globalcontext['use_meta_charset'] = self.use_meta_charset
|
self.globalcontext['use_meta_charset'] = self.use_meta_charset
|
||||||
self.globalcontext['skip_ua_compatible'] = True
|
self.globalcontext['skip_ua_compatible'] = True
|
||||||
|
|
||||||
def build_navlist(self, navnodes):
|
def build_navlist(self, navnodes: List[Dict[str, Any]]) -> List[NavPoint]:
|
||||||
# type: (List[Dict[str, Any]]) -> List[NavPoint]
|
|
||||||
"""Create the toc navigation structure.
|
"""Create the toc navigation structure.
|
||||||
|
|
||||||
This method is almost same as build_navpoints method in epub.py.
|
This method is almost same as build_navpoints method in epub.py.
|
||||||
@ -161,8 +152,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
|
|
||||||
return navstack[0].children
|
return navstack[0].children
|
||||||
|
|
||||||
def navigation_doc_metadata(self, navlist):
|
def navigation_doc_metadata(self, navlist: List[NavPoint]) -> Dict:
|
||||||
# type: (List[NavPoint]) -> Dict
|
|
||||||
"""Create a dictionary with all metadata for the nav.xhtml file
|
"""Create a dictionary with all metadata for the nav.xhtml file
|
||||||
properly escaped.
|
properly escaped.
|
||||||
"""
|
"""
|
||||||
@ -172,8 +162,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
metadata['navlist'] = navlist
|
metadata['navlist'] = navlist
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def build_navigation_doc(self, outdir=None, outname='nav.xhtml'):
|
def build_navigation_doc(self, outdir: str = None, outname: str = 'nav.xhtml') -> None:
|
||||||
# type: (str, str) -> None
|
|
||||||
"""Write the metainfo file nav.xhtml."""
|
"""Write the metainfo file nav.xhtml."""
|
||||||
if outdir:
|
if outdir:
|
||||||
warnings.warn('The arguments of Epub3Builder.build_navigation_doc() '
|
warnings.warn('The arguments of Epub3Builder.build_navigation_doc() '
|
||||||
@ -202,8 +191,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
self.files.append(outname)
|
self.files.append(outname)
|
||||||
|
|
||||||
|
|
||||||
def validate_config_values(app):
|
def validate_config_values(app: Sphinx) -> None:
|
||||||
# type: (Sphinx) -> None
|
|
||||||
if app.builder.name != 'epub':
|
if app.builder.name != 'epub':
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -242,8 +230,7 @@ def validate_config_values(app):
|
|||||||
logger.warning(__('conf value "version" should not be empty for EPUB3'))
|
logger.warning(__('conf value "version" should not be empty for EPUB3'))
|
||||||
|
|
||||||
|
|
||||||
def convert_epub_css_files(app, config):
|
def convert_epub_css_files(app: Sphinx, config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""This converts string styled epub_css_files to tuple styled one."""
|
"""This converts string styled epub_css_files to tuple styled one."""
|
||||||
epub_css_files = [] # type: List[Tuple[str, Dict]]
|
epub_css_files = [] # type: List[Tuple[str, Dict]]
|
||||||
for entry in config.epub_css_files:
|
for entry in config.epub_css_files:
|
||||||
@ -260,8 +247,7 @@ def convert_epub_css_files(app, config):
|
|||||||
config.epub_css_files = epub_css_files # type: ignore
|
config.epub_css_files = epub_css_files # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_builder(Epub3Builder)
|
app.add_builder(Epub3Builder)
|
||||||
|
|
||||||
# config values
|
# config values
|
||||||
|
@ -14,27 +14,25 @@ from datetime import datetime, tzinfo, timedelta
|
|||||||
from io import StringIO
|
from io import StringIO
|
||||||
from os import path, walk, getenv
|
from os import path, walk, getenv
|
||||||
from time import time
|
from time import time
|
||||||
|
from typing import Any, DefaultDict, Dict, Iterable, List, Set, Tuple, Union
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Element
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.domains.python import pairindextypes
|
from sphinx.domains.python import pairindextypes
|
||||||
from sphinx.errors import ThemeError
|
from sphinx.errors import ThemeError
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import split_index_msg, logging, status_iterator
|
from sphinx.util import split_index_msg, logging, status_iterator
|
||||||
from sphinx.util.console import bold # type: ignore
|
from sphinx.util.console import bold # type: ignore
|
||||||
from sphinx.util.i18n import docname_to_domain
|
from sphinx.util.i18n import CatalogInfo, docname_to_domain
|
||||||
from sphinx.util.nodes import extract_messages, traverse_translatable_index
|
from sphinx.util.nodes import extract_messages, traverse_translatable_index
|
||||||
from sphinx.util.osutil import relpath, ensuredir, canon_path
|
from sphinx.util.osutil import relpath, ensuredir, canon_path
|
||||||
from sphinx.util.tags import Tags
|
from sphinx.util.tags import Tags
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, DefaultDict, Dict, Iterable, List, Set, Tuple, Union # NOQA
|
|
||||||
from docutils import nodes # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.util.i18n import CatalogInfo # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -63,15 +61,13 @@ msgstr ""
|
|||||||
class Catalog:
|
class Catalog:
|
||||||
"""Catalog of translatable messages."""
|
"""Catalog of translatable messages."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.messages = [] # type: List[str]
|
self.messages = [] # type: List[str]
|
||||||
# retain insertion order, a la OrderedDict
|
# retain insertion order, a la OrderedDict
|
||||||
self.metadata = OrderedDict() # type: Dict[str, List[Tuple[str, int, str]]]
|
self.metadata = OrderedDict() # type: Dict[str, List[Tuple[str, int, str]]]
|
||||||
# msgid -> file, line, uid
|
# msgid -> file, line, uid
|
||||||
|
|
||||||
def add(self, msg, origin):
|
def add(self, msg: str, origin: Union[Element, "MsgOrigin"]) -> None:
|
||||||
# type: (str, Union[nodes.Element, MsgOrigin]) -> None
|
|
||||||
if not hasattr(origin, 'uid'):
|
if not hasattr(origin, 'uid'):
|
||||||
# Nodes that are replicated like todo don't have a uid,
|
# Nodes that are replicated like todo don't have a uid,
|
||||||
# however i18n is also unnecessary.
|
# however i18n is also unnecessary.
|
||||||
@ -87,8 +83,7 @@ class MsgOrigin:
|
|||||||
Origin holder for Catalog message origin.
|
Origin holder for Catalog message origin.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, source, line):
|
def __init__(self, source: str, line: int) -> None:
|
||||||
# type: (str, int) -> None
|
|
||||||
self.source = source
|
self.source = source
|
||||||
self.line = line
|
self.line = line
|
||||||
self.uid = uuid4().hex
|
self.uid = uuid4().hex
|
||||||
@ -100,8 +95,7 @@ class I18nTags(Tags):
|
|||||||
To translate all text inside of only nodes, this class
|
To translate all text inside of only nodes, this class
|
||||||
always returns True value even if no tags are defined.
|
always returns True value even if no tags are defined.
|
||||||
"""
|
"""
|
||||||
def eval_condition(self, condition):
|
def eval_condition(self, condition: Any) -> bool:
|
||||||
# type: (Any) -> bool
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@ -115,32 +109,26 @@ class I18nBuilder(Builder):
|
|||||||
# be set by `gettext_uuid`
|
# be set by `gettext_uuid`
|
||||||
use_message_catalog = False
|
use_message_catalog = False
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
super().init()
|
super().init()
|
||||||
self.env.set_versioning_method(self.versioning_method,
|
self.env.set_versioning_method(self.versioning_method,
|
||||||
self.env.config.gettext_uuid)
|
self.env.config.gettext_uuid)
|
||||||
self.tags = I18nTags()
|
self.tags = I18nTags()
|
||||||
self.catalogs = defaultdict(Catalog) # type: DefaultDict[str, Catalog]
|
self.catalogs = defaultdict(Catalog) # type: DefaultDict[str, Catalog]
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> Set[str]:
|
||||||
# type: () -> Set[str]
|
|
||||||
return self.env.found_docs
|
return self.env.found_docs
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
# type: (Set[str]) -> None
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def compile_catalogs(self, catalogs, message):
|
def compile_catalogs(self, catalogs: Set[CatalogInfo], message: str) -> None:
|
||||||
# type: (Set[CatalogInfo], str) -> None
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname: str, doctree: nodes.document) -> None:
|
||||||
# type: (str, nodes.document) -> None
|
|
||||||
catalog = self.catalogs[docname_to_domain(docname, self.config.gettext_compact)]
|
catalog = self.catalogs[docname_to_domain(docname, self.config.gettext_compact)]
|
||||||
|
|
||||||
for toctree in self.env.tocs[docname].traverse(addnodes.toctree):
|
for toctree in self.env.tocs[docname].traverse(addnodes.toctree):
|
||||||
@ -176,26 +164,21 @@ if source_date_epoch is not None:
|
|||||||
|
|
||||||
|
|
||||||
class LocalTimeZone(tzinfo):
|
class LocalTimeZone(tzinfo):
|
||||||
|
def __init__(self, *args, **kw) -> None:
|
||||||
def __init__(self, *args, **kw):
|
|
||||||
# type: (Any, Any) -> None
|
|
||||||
super().__init__(*args, **kw) # type: ignore
|
super().__init__(*args, **kw) # type: ignore
|
||||||
self.tzdelta = tzdelta
|
self.tzdelta = tzdelta
|
||||||
|
|
||||||
def utcoffset(self, dt):
|
def utcoffset(self, dt: datetime) -> timedelta:
|
||||||
# type: (datetime) -> timedelta
|
|
||||||
return self.tzdelta
|
return self.tzdelta
|
||||||
|
|
||||||
def dst(self, dt):
|
def dst(self, dt: datetime) -> timedelta:
|
||||||
# type: (datetime) -> timedelta
|
|
||||||
return timedelta(0)
|
return timedelta(0)
|
||||||
|
|
||||||
|
|
||||||
ltz = LocalTimeZone()
|
ltz = LocalTimeZone()
|
||||||
|
|
||||||
|
|
||||||
def should_write(filepath, new_content):
|
def should_write(filepath: str, new_content: str):
|
||||||
# type: (str, str) -> bool
|
|
||||||
if not path.exists(filepath):
|
if not path.exists(filepath):
|
||||||
return True
|
return True
|
||||||
try:
|
try:
|
||||||
@ -220,14 +203,12 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
name = 'gettext'
|
name = 'gettext'
|
||||||
epilog = __('The message catalogs are in %(outdir)s.')
|
epilog = __('The message catalogs are in %(outdir)s.')
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
super().init()
|
super().init()
|
||||||
self.create_template_bridge()
|
self.create_template_bridge()
|
||||||
self.templates.init(self)
|
self.templates.init(self)
|
||||||
|
|
||||||
def _collect_templates(self):
|
def _collect_templates(self) -> Set[str]:
|
||||||
# type: () -> Set[str]
|
|
||||||
template_files = set()
|
template_files = set()
|
||||||
for template_path in self.config.templates_path:
|
for template_path in self.config.templates_path:
|
||||||
tmpl_abs_path = path.join(self.app.srcdir, template_path)
|
tmpl_abs_path = path.join(self.app.srcdir, template_path)
|
||||||
@ -238,8 +219,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
template_files.add(filename)
|
template_files.add(filename)
|
||||||
return template_files
|
return template_files
|
||||||
|
|
||||||
def _extract_from_template(self):
|
def _extract_from_template(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
files = list(self._collect_templates())
|
files = list(self._collect_templates())
|
||||||
files.sort()
|
files.sort()
|
||||||
logger.info(bold(__('building [%s]: ') % self.name), nonl=True)
|
logger.info(bold(__('building [%s]: ') % self.name), nonl=True)
|
||||||
@ -258,13 +238,11 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise ThemeError('%s: %r' % (template, exc))
|
raise ThemeError('%s: %r' % (template, exc))
|
||||||
|
|
||||||
def build(self, docnames, summary=None, method='update'):
|
def build(self, docnames: Iterable[str], summary: str = None, method: str = 'update') -> None: # NOQA
|
||||||
# type: (Iterable[str], str, str) -> None
|
|
||||||
self._extract_from_template()
|
self._extract_from_template()
|
||||||
super().build(docnames, summary, method)
|
super().build(docnames, summary, method)
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
super().finish()
|
super().finish()
|
||||||
data = {
|
data = {
|
||||||
'version': self.config.version,
|
'version': self.config.version,
|
||||||
@ -310,8 +288,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
pofile.write(content)
|
pofile.write(content)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_builder(MessageCatalogBuilder)
|
app.add_builder(MessageCatalogBuilder)
|
||||||
|
|
||||||
app.add_config_value('gettext_compact', True, 'gettext')
|
app.add_config_value('gettext_compact', True, 'gettext')
|
||||||
|
@ -15,16 +15,21 @@ import sys
|
|||||||
import warnings
|
import warnings
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, IO, Iterable, Iterator, List, Set, Type, Tuple
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.core import publish_parts
|
from docutils.core import publish_parts
|
||||||
from docutils.frontend import OptionParser
|
from docutils.frontend import OptionParser
|
||||||
from docutils.io import DocTreeInput, StringOutput
|
from docutils.io import DocTreeInput, StringOutput
|
||||||
|
from docutils.nodes import Node
|
||||||
from docutils.utils import relative_path
|
from docutils.utils import relative_path
|
||||||
|
|
||||||
from sphinx import package_dir, __display_version__
|
from sphinx import package_dir, __display_version__
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
|
from sphinx.config import Config
|
||||||
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
||||||
|
from sphinx.domains import Domain, Index, IndexEntry
|
||||||
from sphinx.environment.adapters.asset import ImageAdapter
|
from sphinx.environment.adapters.asset import ImageAdapter
|
||||||
from sphinx.environment.adapters.indexentries import IndexEntries
|
from sphinx.environment.adapters.indexentries import IndexEntries
|
||||||
from sphinx.environment.adapters.toctree import TocTree
|
from sphinx.environment.adapters.toctree import TocTree
|
||||||
@ -41,16 +46,9 @@ from sphinx.util.i18n import format_date
|
|||||||
from sphinx.util.inventory import InventoryFile
|
from sphinx.util.inventory import InventoryFile
|
||||||
from sphinx.util.matching import patmatch, Matcher, DOTFILES
|
from sphinx.util.matching import patmatch, Matcher, DOTFILES
|
||||||
from sphinx.util.osutil import os_path, relative_uri, ensuredir, movefile, copyfile
|
from sphinx.util.osutil import os_path, relative_uri, ensuredir, movefile, copyfile
|
||||||
|
from sphinx.util.tags import Tags
|
||||||
from sphinx.writers.html import HTMLWriter, HTMLTranslator
|
from sphinx.writers.html import HTMLWriter, HTMLTranslator
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, IO, Iterable, Iterator, List, Set, Type, Tuple # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.config import Config # NOQA
|
|
||||||
from sphinx.domains import Domain, Index, IndexEntry # NOQA
|
|
||||||
from sphinx.util.tags import Tags # NOQA
|
|
||||||
|
|
||||||
# HTML5 Writer is avialable or not
|
# HTML5 Writer is avialable or not
|
||||||
if is_html5_writer_available():
|
if is_html5_writer_available():
|
||||||
from sphinx.writers.html5 import HTML5Translator
|
from sphinx.writers.html5 import HTML5Translator
|
||||||
@ -65,8 +63,7 @@ logger = logging.getLogger(__name__)
|
|||||||
return_codes_re = re.compile('[\r\n]+')
|
return_codes_re = re.compile('[\r\n]+')
|
||||||
|
|
||||||
|
|
||||||
def get_stable_hash(obj):
|
def get_stable_hash(obj: Any) -> str:
|
||||||
# type: (Any) -> str
|
|
||||||
"""
|
"""
|
||||||
Return a stable hash for a Python data structure. We can't just use
|
Return a stable hash for a Python data structure. We can't just use
|
||||||
the md5 of str(obj) since for example dictionary items are enumerated
|
the md5 of str(obj) since for example dictionary items are enumerated
|
||||||
@ -89,8 +86,7 @@ class Stylesheet(str):
|
|||||||
attributes = None # type: Dict[str, str]
|
attributes = None # type: Dict[str, str]
|
||||||
filename = None # type: str
|
filename = None # type: str
|
||||||
|
|
||||||
def __new__(cls, filename, *args, **attributes):
|
def __new__(cls, filename: str, *args: str, **attributes: str) -> None:
|
||||||
# type: (str, str, str) -> None
|
|
||||||
self = str.__new__(cls, filename) # type: ignore
|
self = str.__new__(cls, filename) # type: ignore
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.attributes = attributes
|
self.attributes = attributes
|
||||||
@ -105,23 +101,20 @@ class Stylesheet(str):
|
|||||||
|
|
||||||
class JSContainer(list):
|
class JSContainer(list):
|
||||||
"""The container for JavaScript scripts."""
|
"""The container for JavaScript scripts."""
|
||||||
def insert(self, index, obj):
|
def insert(self, index: int, obj: str) -> None:
|
||||||
# type: (int, str) -> None
|
|
||||||
warnings.warn('To modify script_files in the theme is deprecated. '
|
warnings.warn('To modify script_files in the theme is deprecated. '
|
||||||
'Please insert a <script> tag directly in your theme instead.',
|
'Please insert a <script> tag directly in your theme instead.',
|
||||||
RemovedInSphinx30Warning, stacklevel=3)
|
RemovedInSphinx30Warning, stacklevel=3)
|
||||||
super().insert(index, obj)
|
super().insert(index, obj)
|
||||||
|
|
||||||
def extend(self, other): # type: ignore
|
def extend(self, other: List[str]) -> None: # type: ignore
|
||||||
# type: (List[str]) -> None
|
|
||||||
warnings.warn('To modify script_files in the theme is deprecated. '
|
warnings.warn('To modify script_files in the theme is deprecated. '
|
||||||
'Please insert a <script> tag directly in your theme instead.',
|
'Please insert a <script> tag directly in your theme instead.',
|
||||||
RemovedInSphinx30Warning, stacklevel=3)
|
RemovedInSphinx30Warning, stacklevel=3)
|
||||||
for item in other:
|
for item in other:
|
||||||
self.append(item)
|
self.append(item)
|
||||||
|
|
||||||
def __iadd__(self, other): # type: ignore
|
def __iadd__(self, other: List[str]) -> "JSContainer": # type: ignore
|
||||||
# type: (List[str]) -> JSContainer
|
|
||||||
warnings.warn('To modify script_files in the theme is deprecated. '
|
warnings.warn('To modify script_files in the theme is deprecated. '
|
||||||
'Please insert a <script> tag directly in your theme instead.',
|
'Please insert a <script> tag directly in your theme instead.',
|
||||||
RemovedInSphinx30Warning, stacklevel=3)
|
RemovedInSphinx30Warning, stacklevel=3)
|
||||||
@ -129,8 +122,7 @@ class JSContainer(list):
|
|||||||
self.append(item)
|
self.append(item)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other: List[str]) -> "JSContainer":
|
||||||
# type: (List[str]) -> JSContainer
|
|
||||||
ret = JSContainer(self)
|
ret = JSContainer(self)
|
||||||
ret += other
|
ret += other
|
||||||
return ret
|
return ret
|
||||||
@ -146,8 +138,7 @@ class JavaScript(str):
|
|||||||
attributes = None # type: Dict[str, str]
|
attributes = None # type: Dict[str, str]
|
||||||
filename = None # type: str
|
filename = None # type: str
|
||||||
|
|
||||||
def __new__(cls, filename, **attributes):
|
def __new__(cls, filename: str, **attributes: str) -> None:
|
||||||
# type: (str, **str) -> None
|
|
||||||
self = str.__new__(cls, filename) # type: ignore
|
self = str.__new__(cls, filename) # type: ignore
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.attributes = attributes
|
self.attributes = attributes
|
||||||
@ -164,8 +155,7 @@ class BuildInfo:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load(cls, f):
|
def load(cls, f: IO) -> "BuildInfo":
|
||||||
# type: (IO) -> BuildInfo
|
|
||||||
try:
|
try:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
assert lines[0].rstrip() == '# Sphinx build info version 1'
|
assert lines[0].rstrip() == '# Sphinx build info version 1'
|
||||||
@ -179,8 +169,7 @@ class BuildInfo:
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise ValueError(__('build info file is broken: %r') % exc)
|
raise ValueError(__('build info file is broken: %r') % exc)
|
||||||
|
|
||||||
def __init__(self, config=None, tags=None, config_categories=[]):
|
def __init__(self, config: Config = None, tags: Tags = None, config_categories: List[str] = []) -> None: # NOQA
|
||||||
# type: (Config, Tags, List[str]) -> None
|
|
||||||
self.config_hash = ''
|
self.config_hash = ''
|
||||||
self.tags_hash = ''
|
self.tags_hash = ''
|
||||||
|
|
||||||
@ -191,13 +180,11 @@ class BuildInfo:
|
|||||||
if tags:
|
if tags:
|
||||||
self.tags_hash = get_stable_hash(sorted(tags))
|
self.tags_hash = get_stable_hash(sorted(tags))
|
||||||
|
|
||||||
def __eq__(self, other): # type: ignore
|
def __eq__(self, other: "BuildInfo") -> bool: # type: ignore
|
||||||
# type: (BuildInfo) -> bool
|
|
||||||
return (self.config_hash == other.config_hash and
|
return (self.config_hash == other.config_hash and
|
||||||
self.tags_hash == other.tags_hash)
|
self.tags_hash == other.tags_hash)
|
||||||
|
|
||||||
def dump(self, f):
|
def dump(self, f: IO) -> None:
|
||||||
# type: (IO) -> None
|
|
||||||
f.write('# Sphinx build info version 1\n'
|
f.write('# Sphinx build info version 1\n'
|
||||||
'# This file hashes the configuration used when building these files.'
|
'# This file hashes the configuration used when building these files.'
|
||||||
' When it is not found, a full rebuild will be done.\n'
|
' When it is not found, a full rebuild will be done.\n'
|
||||||
@ -237,8 +224,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
imgpath = None # type: str
|
imgpath = None # type: str
|
||||||
domain_indices = [] # type: List[Tuple[str, Type[Index], List[Tuple[str, List[IndexEntry]]], bool]] # NOQA
|
domain_indices = [] # type: List[Tuple[str, Type[Index], List[Tuple[str, List[IndexEntry]]], bool]] # NOQA
|
||||||
|
|
||||||
def __init__(self, app):
|
def __init__(self, app: Sphinx) -> None:
|
||||||
# type: (Sphinx) -> None
|
|
||||||
super().__init__(app)
|
super().__init__(app)
|
||||||
|
|
||||||
# CSS files
|
# CSS files
|
||||||
@ -247,8 +233,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
# JS files
|
# JS files
|
||||||
self.script_files = JSContainer() # type: List[JavaScript]
|
self.script_files = JSContainer() # type: List[JavaScript]
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.build_info = self.create_build_info()
|
self.build_info = self.create_build_info()
|
||||||
# basename of images directory
|
# basename of images directory
|
||||||
self.imagedir = '_images'
|
self.imagedir = '_images'
|
||||||
@ -274,12 +259,10 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
|
|
||||||
self.use_index = self.get_builder_config('use_index', 'html')
|
self.use_index = self.get_builder_config('use_index', 'html')
|
||||||
|
|
||||||
def create_build_info(self):
|
def create_build_info(self) -> BuildInfo:
|
||||||
# type: () -> BuildInfo
|
|
||||||
return BuildInfo(self.config, self.tags, ['html'])
|
return BuildInfo(self.config, self.tags, ['html'])
|
||||||
|
|
||||||
def _get_translations_js(self):
|
def _get_translations_js(self) -> str:
|
||||||
# type: () -> str
|
|
||||||
candidates = [path.join(dir, self.config.language,
|
candidates = [path.join(dir, self.config.language,
|
||||||
'LC_MESSAGES', 'sphinx.js')
|
'LC_MESSAGES', 'sphinx.js')
|
||||||
for dir in self.config.locale_dirs] + \
|
for dir in self.config.locale_dirs] + \
|
||||||
@ -293,12 +276,10 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
return jsfile
|
return jsfile
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_theme_config(self):
|
def get_theme_config(self) -> Tuple[str, Dict]:
|
||||||
# type: () -> Tuple[str, Dict]
|
|
||||||
return self.config.html_theme, self.config.html_theme_options
|
return self.config.html_theme, self.config.html_theme_options
|
||||||
|
|
||||||
def init_templates(self):
|
def init_templates(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
theme_factory = HTMLThemeFactory(self.app)
|
theme_factory = HTMLThemeFactory(self.app)
|
||||||
themename, themeoptions = self.get_theme_config()
|
themename, themeoptions = self.get_theme_config()
|
||||||
self.theme = theme_factory.create(themename)
|
self.theme = theme_factory.create(themename)
|
||||||
@ -306,8 +287,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
self.create_template_bridge()
|
self.create_template_bridge()
|
||||||
self.templates.init(self, self.theme)
|
self.templates.init(self, self.theme)
|
||||||
|
|
||||||
def init_highlighter(self):
|
def init_highlighter(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
# determine Pygments style and create the highlighter
|
# determine Pygments style and create the highlighter
|
||||||
if self.config.pygments_style is not None:
|
if self.config.pygments_style is not None:
|
||||||
style = self.config.pygments_style
|
style = self.config.pygments_style
|
||||||
@ -317,23 +297,20 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
style = 'sphinx'
|
style = 'sphinx'
|
||||||
self.highlighter = PygmentsBridge('html', style)
|
self.highlighter = PygmentsBridge('html', style)
|
||||||
|
|
||||||
def init_css_files(self):
|
def init_css_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
for filename, attrs in self.app.registry.css_files:
|
for filename, attrs in self.app.registry.css_files:
|
||||||
self.add_css_file(filename, **attrs)
|
self.add_css_file(filename, **attrs)
|
||||||
|
|
||||||
for filename, attrs in self.get_builder_config('css_files', 'html'):
|
for filename, attrs in self.get_builder_config('css_files', 'html'):
|
||||||
self.add_css_file(filename, **attrs)
|
self.add_css_file(filename, **attrs)
|
||||||
|
|
||||||
def add_css_file(self, filename, **kwargs):
|
def add_css_file(self, filename: str, **kwargs: str) -> None:
|
||||||
# type: (str, **str) -> None
|
|
||||||
if '://' not in filename:
|
if '://' not in filename:
|
||||||
filename = posixpath.join('_static', filename)
|
filename = posixpath.join('_static', filename)
|
||||||
|
|
||||||
self.css_files.append(Stylesheet(filename, **kwargs)) # type: ignore
|
self.css_files.append(Stylesheet(filename, **kwargs)) # type: ignore
|
||||||
|
|
||||||
def init_js_files(self):
|
def init_js_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.add_js_file('jquery.js')
|
self.add_js_file('jquery.js')
|
||||||
self.add_js_file('underscore.js')
|
self.add_js_file('underscore.js')
|
||||||
self.add_js_file('doctools.js')
|
self.add_js_file('doctools.js')
|
||||||
@ -348,24 +325,21 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
if self.config.language and self._get_translations_js():
|
if self.config.language and self._get_translations_js():
|
||||||
self.add_js_file('translations.js')
|
self.add_js_file('translations.js')
|
||||||
|
|
||||||
def add_js_file(self, filename, **kwargs):
|
def add_js_file(self, filename: str, **kwargs: str) -> None:
|
||||||
# type: (str, **str) -> None
|
|
||||||
if filename and '://' not in filename:
|
if filename and '://' not in filename:
|
||||||
filename = posixpath.join('_static', filename)
|
filename = posixpath.join('_static', filename)
|
||||||
|
|
||||||
self.script_files.append(JavaScript(filename, **kwargs))
|
self.script_files.append(JavaScript(filename, **kwargs))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def default_translator_class(self): # type: ignore
|
def default_translator_class(self) -> Type[nodes.NodeVisitor]: # type: ignore
|
||||||
# type: () -> Type[nodes.NodeVisitor]
|
|
||||||
if not html5_ready or self.config.html4_writer:
|
if not html5_ready or self.config.html4_writer:
|
||||||
return HTMLTranslator
|
return HTMLTranslator
|
||||||
else:
|
else:
|
||||||
return HTML5Translator
|
return HTML5Translator
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def math_renderer_name(self):
|
def math_renderer_name(self) -> str:
|
||||||
# type: () -> str
|
|
||||||
name = self.get_builder_config('math_renderer', 'html')
|
name = self.get_builder_config('math_renderer', 'html')
|
||||||
if name is not None:
|
if name is not None:
|
||||||
# use given name
|
# use given name
|
||||||
@ -384,8 +358,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
# many math_renderers are registered. can't choose automatically!
|
# many math_renderers are registered. can't choose automatically!
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> Iterator[str]:
|
||||||
# type: () -> Iterator[str]
|
|
||||||
try:
|
try:
|
||||||
with open(path.join(self.outdir, '.buildinfo')) as fp:
|
with open(path.join(self.outdir, '.buildinfo')) as fp:
|
||||||
buildinfo = BuildInfo.load(fp)
|
buildinfo = BuildInfo.load(fp)
|
||||||
@ -421,12 +394,10 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
# source doesn't exist anymore
|
# source doesn't exist anymore
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_asset_paths(self):
|
def get_asset_paths(self) -> List[str]:
|
||||||
# type: () -> List[str]
|
|
||||||
return self.config.html_extra_path + self.config.html_static_path
|
return self.config.html_extra_path + self.config.html_static_path
|
||||||
|
|
||||||
def render_partial(self, node):
|
def render_partial(self, node: Node) -> Dict[str, str]:
|
||||||
# type: (nodes.Node) -> Dict[str, str]
|
|
||||||
"""Utility: Render a lone doctree node."""
|
"""Utility: Render a lone doctree node."""
|
||||||
if node is None:
|
if node is None:
|
||||||
return {'fragment': ''}
|
return {'fragment': ''}
|
||||||
@ -440,8 +411,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
settings_overrides={'output_encoding': 'unicode'},
|
settings_overrides={'output_encoding': 'unicode'},
|
||||||
source=doc)
|
source=doc)
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
# type: (Set[str]) -> None
|
|
||||||
# create the search indexer
|
# create the search indexer
|
||||||
self.indexer = None
|
self.indexer = None
|
||||||
if self.search:
|
if self.search:
|
||||||
@ -550,8 +520,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
self.theme.get_options(self.theme_options).items())
|
self.theme.get_options(self.theme_options).items())
|
||||||
self.globalcontext.update(self.config.html_context)
|
self.globalcontext.update(self.config.html_context)
|
||||||
|
|
||||||
def get_doc_context(self, docname, body, metatags):
|
def get_doc_context(self, docname: str, body: str, metatags: str) -> Dict[str, Any]:
|
||||||
# type: (str, str, str) -> Dict[str, Any]
|
|
||||||
"""Collect items for the template context of a page."""
|
"""Collect items for the template context of a page."""
|
||||||
# find out relations
|
# find out relations
|
||||||
prev = next = None
|
prev = next = None
|
||||||
@ -631,8 +600,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
'page_source_suffix': source_suffix,
|
'page_source_suffix': source_suffix,
|
||||||
}
|
}
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname: str, doctree: nodes.document) -> None:
|
||||||
# type: (str, nodes.document) -> None
|
|
||||||
destination = StringOutput(encoding='utf-8')
|
destination = StringOutput(encoding='utf-8')
|
||||||
doctree.settings = self.docsettings
|
doctree.settings = self.docsettings
|
||||||
|
|
||||||
@ -649,16 +617,14 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
ctx = self.get_doc_context(docname, body, metatags)
|
ctx = self.get_doc_context(docname, body, metatags)
|
||||||
self.handle_page(docname, ctx, event_arg=doctree)
|
self.handle_page(docname, ctx, event_arg=doctree)
|
||||||
|
|
||||||
def write_doc_serialized(self, docname, doctree):
|
def write_doc_serialized(self, docname: str, doctree: nodes.document) -> None:
|
||||||
# type: (str, nodes.document) -> None
|
|
||||||
self.imgpath = relative_uri(self.get_target_uri(docname), self.imagedir)
|
self.imgpath = relative_uri(self.get_target_uri(docname), self.imagedir)
|
||||||
self.post_process_images(doctree)
|
self.post_process_images(doctree)
|
||||||
title_node = self.env.longtitles.get(docname)
|
title_node = self.env.longtitles.get(docname)
|
||||||
title = title_node and self.render_partial(title_node)['title'] or ''
|
title = title_node and self.render_partial(title_node)['title'] or ''
|
||||||
self.index_page(docname, doctree, title)
|
self.index_page(docname, doctree, title)
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.finish_tasks.add_task(self.gen_indices)
|
self.finish_tasks.add_task(self.gen_indices)
|
||||||
self.finish_tasks.add_task(self.gen_additional_pages)
|
self.finish_tasks.add_task(self.gen_additional_pages)
|
||||||
self.finish_tasks.add_task(self.copy_image_files)
|
self.finish_tasks.add_task(self.copy_image_files)
|
||||||
@ -670,8 +636,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
# dump the search index
|
# dump the search index
|
||||||
self.handle_finish()
|
self.handle_finish()
|
||||||
|
|
||||||
def gen_indices(self):
|
def gen_indices(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
logger.info(bold(__('generating indices...')), nonl=True)
|
logger.info(bold(__('generating indices...')), nonl=True)
|
||||||
|
|
||||||
# the global general index
|
# the global general index
|
||||||
@ -683,8 +648,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
|
|
||||||
logger.info('')
|
logger.info('')
|
||||||
|
|
||||||
def gen_additional_pages(self):
|
def gen_additional_pages(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
# pages from extensions
|
# pages from extensions
|
||||||
for pagelist in self.events.emit('html-collect-pages'):
|
for pagelist in self.events.emit('html-collect-pages'):
|
||||||
for pagename, context, template in pagelist:
|
for pagename, context, template in pagelist:
|
||||||
@ -710,8 +674,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
|
|
||||||
logger.info('')
|
logger.info('')
|
||||||
|
|
||||||
def write_genindex(self):
|
def write_genindex(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
# the total count of lines for each index letter, used to distribute
|
# the total count of lines for each index letter, used to distribute
|
||||||
# the entries into two columns
|
# the entries into two columns
|
||||||
genindex = IndexEntries(self.env).create_index(self)
|
genindex = IndexEntries(self.env).create_index(self)
|
||||||
@ -740,8 +703,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
else:
|
else:
|
||||||
self.handle_page('genindex', genindexcontext, 'genindex.html')
|
self.handle_page('genindex', genindexcontext, 'genindex.html')
|
||||||
|
|
||||||
def write_domain_indices(self):
|
def write_domain_indices(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
for indexname, indexcls, content, collapse in self.domain_indices:
|
for indexname, indexcls, content, collapse in self.domain_indices:
|
||||||
indexcontext = {
|
indexcontext = {
|
||||||
'indextitle': indexcls.localname,
|
'indextitle': indexcls.localname,
|
||||||
@ -751,8 +713,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
logger.info(' ' + indexname, nonl=True)
|
logger.info(' ' + indexname, nonl=True)
|
||||||
self.handle_page(indexname, indexcontext, 'domainindex.html')
|
self.handle_page(indexname, indexcontext, 'domainindex.html')
|
||||||
|
|
||||||
def copy_image_files(self):
|
def copy_image_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
if self.images:
|
if self.images:
|
||||||
stringify_func = ImageAdapter(self.app.env).get_original_image_uri
|
stringify_func = ImageAdapter(self.app.env).get_original_image_uri
|
||||||
ensuredir(path.join(self.outdir, self.imagedir))
|
ensuredir(path.join(self.outdir, self.imagedir))
|
||||||
@ -767,11 +728,10 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
logger.warning(__('cannot copy image file %r: %s'),
|
logger.warning(__('cannot copy image file %r: %s'),
|
||||||
path.join(self.srcdir, src), err)
|
path.join(self.srcdir, src), err)
|
||||||
|
|
||||||
def copy_download_files(self):
|
def copy_download_files(self) -> None:
|
||||||
# type: () -> None
|
def to_relpath(f: str) -> str:
|
||||||
def to_relpath(f):
|
|
||||||
# type: (str) -> str
|
|
||||||
return relative_path(self.srcdir, f)
|
return relative_path(self.srcdir, f)
|
||||||
|
|
||||||
# copy downloadable files
|
# copy downloadable files
|
||||||
if self.env.dlfiles:
|
if self.env.dlfiles:
|
||||||
ensuredir(path.join(self.outdir, '_downloads'))
|
ensuredir(path.join(self.outdir, '_downloads'))
|
||||||
@ -786,8 +746,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
logger.warning(__('cannot copy downloadable file %r: %s'),
|
logger.warning(__('cannot copy downloadable file %r: %s'),
|
||||||
path.join(self.srcdir, src), err)
|
path.join(self.srcdir, src), err)
|
||||||
|
|
||||||
def copy_static_files(self):
|
def copy_static_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
try:
|
try:
|
||||||
# copy static files
|
# copy static files
|
||||||
logger.info(bold(__('copying static files... ')), nonl=True)
|
logger.info(bold(__('copying static files... ')), nonl=True)
|
||||||
@ -851,8 +810,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
except OSError as err:
|
except OSError as err:
|
||||||
logger.warning(__('cannot copy static file %r'), err)
|
logger.warning(__('cannot copy static file %r'), err)
|
||||||
|
|
||||||
def copy_extra_files(self):
|
def copy_extra_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
try:
|
try:
|
||||||
# copy html_extra_path files
|
# copy html_extra_path files
|
||||||
logger.info(bold(__('copying extra files... ')), nonl=True)
|
logger.info(bold(__('copying extra files... ')), nonl=True)
|
||||||
@ -869,22 +827,19 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
except OSError as err:
|
except OSError as err:
|
||||||
logger.warning(__('cannot copy extra file %r'), err)
|
logger.warning(__('cannot copy extra file %r'), err)
|
||||||
|
|
||||||
def write_buildinfo(self):
|
def write_buildinfo(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
try:
|
try:
|
||||||
with open(path.join(self.outdir, '.buildinfo'), 'w') as fp:
|
with open(path.join(self.outdir, '.buildinfo'), 'w') as fp:
|
||||||
self.build_info.dump(fp)
|
self.build_info.dump(fp)
|
||||||
except OSError as exc:
|
except OSError as exc:
|
||||||
logger.warning(__('Failed to write build info file: %r'), exc)
|
logger.warning(__('Failed to write build info file: %r'), exc)
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
# clean up theme stuff
|
# clean up theme stuff
|
||||||
if self.theme:
|
if self.theme:
|
||||||
self.theme.cleanup()
|
self.theme.cleanup()
|
||||||
|
|
||||||
def post_process_images(self, doctree):
|
def post_process_images(self, doctree: Node) -> None:
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
"""Pick the best candidate for an image and link down-scaled images to
|
"""Pick the best candidate for an image and link down-scaled images to
|
||||||
their high res version.
|
their high res version.
|
||||||
"""
|
"""
|
||||||
@ -909,8 +864,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
node.replace_self(reference)
|
node.replace_self(reference)
|
||||||
reference.append(node)
|
reference.append(node)
|
||||||
|
|
||||||
def load_indexer(self, docnames):
|
def load_indexer(self, docnames: Iterable[str]) -> None:
|
||||||
# type: (Iterable[str]) -> None
|
|
||||||
keep = set(self.env.all_docs) - set(docnames)
|
keep = set(self.env.all_docs) - set(docnames)
|
||||||
try:
|
try:
|
||||||
searchindexfn = path.join(self.outdir, self.searchindex_filename)
|
searchindexfn = path.join(self.outdir, self.searchindex_filename)
|
||||||
@ -928,8 +882,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
# delete all entries for files that will be rebuilt
|
# delete all entries for files that will be rebuilt
|
||||||
self.indexer.prune(keep)
|
self.indexer.prune(keep)
|
||||||
|
|
||||||
def index_page(self, pagename, doctree, title):
|
def index_page(self, pagename: str, doctree: nodes.document, title: str) -> None:
|
||||||
# type: (str, nodes.document, str) -> None
|
|
||||||
# only index pages with title
|
# only index pages with title
|
||||||
if self.indexer is not None and title:
|
if self.indexer is not None and title:
|
||||||
filename = self.env.doc2path(pagename, base=None)
|
filename = self.env.doc2path(pagename, base=None)
|
||||||
@ -945,22 +898,19 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
indexer_name, indexer_name),
|
indexer_name, indexer_name),
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
def _get_local_toctree(self, docname, collapse=True, **kwds):
|
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwds) -> str:
|
||||||
# type: (str, bool, Any) -> str
|
|
||||||
if 'includehidden' not in kwds:
|
if 'includehidden' not in kwds:
|
||||||
kwds['includehidden'] = False
|
kwds['includehidden'] = False
|
||||||
return self.render_partial(TocTree(self.env).get_toctree_for(
|
return self.render_partial(TocTree(self.env).get_toctree_for(
|
||||||
docname, self, collapse, **kwds))['fragment']
|
docname, self, collapse, **kwds))['fragment']
|
||||||
|
|
||||||
def get_outfilename(self, pagename):
|
def get_outfilename(self, pagename: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
return path.join(self.outdir, os_path(pagename) + self.out_suffix)
|
return path.join(self.outdir, os_path(pagename) + self.out_suffix)
|
||||||
|
|
||||||
def add_sidebars(self, pagename, ctx):
|
def add_sidebars(self, pagename: str, ctx: Dict) -> None:
|
||||||
# type: (str, Dict) -> None
|
def has_wildcard(pattern: str) -> bool:
|
||||||
def has_wildcard(pattern):
|
|
||||||
# type: (str) -> bool
|
|
||||||
return any(char in pattern for char in '*?[')
|
return any(char in pattern for char in '*?[')
|
||||||
|
|
||||||
sidebars = None
|
sidebars = None
|
||||||
matched = None
|
matched = None
|
||||||
customsidebar = None
|
customsidebar = None
|
||||||
@ -1009,13 +959,11 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
|
|
||||||
# --------- these are overwritten by the serialization builder
|
# --------- these are overwritten by the serialization builder
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
return docname + self.link_suffix
|
return docname + self.link_suffix
|
||||||
|
|
||||||
def handle_page(self, pagename, addctx, templatename='page.html',
|
def handle_page(self, pagename: str, addctx: Dict, templatename: str = 'page.html',
|
||||||
outfilename=None, event_arg=None):
|
outfilename: str = None, event_arg: Any = None) -> None:
|
||||||
# type: (str, Dict, str, str, Any) -> None
|
|
||||||
ctx = self.globalcontext.copy()
|
ctx = self.globalcontext.copy()
|
||||||
# current_page_name is backwards compatibility
|
# current_page_name is backwards compatibility
|
||||||
ctx['pagename'] = ctx['current_page_name'] = pagename
|
ctx['pagename'] = ctx['current_page_name'] = pagename
|
||||||
@ -1031,8 +979,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
else:
|
else:
|
||||||
ctx['pageurl'] = None
|
ctx['pageurl'] = None
|
||||||
|
|
||||||
def pathto(otheruri, resource=False, baseuri=default_baseuri):
|
def pathto(otheruri: str, resource: bool = False, baseuri: str = default_baseuri) -> str: # NOQA
|
||||||
# type: (str, bool, str) -> str
|
|
||||||
if resource and '://' in otheruri:
|
if resource and '://' in otheruri:
|
||||||
# allow non-local resources given by scheme
|
# allow non-local resources given by scheme
|
||||||
return otheruri
|
return otheruri
|
||||||
@ -1044,8 +991,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
return uri
|
return uri
|
||||||
ctx['pathto'] = pathto
|
ctx['pathto'] = pathto
|
||||||
|
|
||||||
def css_tag(css):
|
def css_tag(css: Stylesheet) -> str:
|
||||||
# type: (Stylesheet) -> str
|
|
||||||
attrs = []
|
attrs = []
|
||||||
for key in sorted(css.attributes):
|
for key in sorted(css.attributes):
|
||||||
value = css.attributes[key]
|
value = css.attributes[key]
|
||||||
@ -1055,8 +1001,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
return '<link %s />' % ' '.join(attrs)
|
return '<link %s />' % ' '.join(attrs)
|
||||||
ctx['css_tag'] = css_tag
|
ctx['css_tag'] = css_tag
|
||||||
|
|
||||||
def hasdoc(name):
|
def hasdoc(name: str) -> bool:
|
||||||
# type: (str) -> bool
|
|
||||||
if name in self.env.all_docs:
|
if name in self.env.all_docs:
|
||||||
return True
|
return True
|
||||||
elif name == 'search' and self.search:
|
elif name == 'search' and self.search:
|
||||||
@ -1066,8 +1011,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
return False
|
return False
|
||||||
ctx['hasdoc'] = hasdoc
|
ctx['hasdoc'] = hasdoc
|
||||||
|
|
||||||
def warn(*args, **kwargs):
|
def warn(*args, **kwargs) -> str:
|
||||||
# type: (Any, Any) -> str
|
|
||||||
"""Simple warn() wrapper for themes."""
|
"""Simple warn() wrapper for themes."""
|
||||||
warnings.warn('The template function warn() was deprecated. '
|
warnings.warn('The template function warn() was deprecated. '
|
||||||
'Use warning() instead.',
|
'Use warning() instead.',
|
||||||
@ -1114,24 +1058,21 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
ensuredir(path.dirname(source_name))
|
ensuredir(path.dirname(source_name))
|
||||||
copyfile(self.env.doc2path(pagename), source_name)
|
copyfile(self.env.doc2path(pagename), source_name)
|
||||||
|
|
||||||
def update_page_context(self, pagename, templatename, ctx, event_arg):
|
def update_page_context(self, pagename: str, templatename: str,
|
||||||
# type: (str, str, Dict, Any) -> None
|
ctx: Dict, event_arg: Any) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def handle_finish(self):
|
def handle_finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
if self.indexer:
|
if self.indexer:
|
||||||
self.finish_tasks.add_task(self.dump_search_index)
|
self.finish_tasks.add_task(self.dump_search_index)
|
||||||
self.finish_tasks.add_task(self.dump_inventory)
|
self.finish_tasks.add_task(self.dump_inventory)
|
||||||
|
|
||||||
def dump_inventory(self):
|
def dump_inventory(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
logger.info(bold(__('dumping object inventory... ')), nonl=True)
|
logger.info(bold(__('dumping object inventory... ')), nonl=True)
|
||||||
InventoryFile.dump(path.join(self.outdir, INVENTORY_FILENAME), self.env, self)
|
InventoryFile.dump(path.join(self.outdir, INVENTORY_FILENAME), self.env, self)
|
||||||
logger.info(__('done'))
|
logger.info(__('done'))
|
||||||
|
|
||||||
def dump_search_index(self):
|
def dump_search_index(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
logger.info(
|
logger.info(
|
||||||
bold(__('dumping search index in %s ... ') % self.indexer.label()),
|
bold(__('dumping search index in %s ... ') % self.indexer.label()),
|
||||||
nonl=True)
|
nonl=True)
|
||||||
@ -1149,8 +1090,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
logger.info(__('done'))
|
logger.info(__('done'))
|
||||||
|
|
||||||
|
|
||||||
def convert_html_css_files(app, config):
|
def convert_html_css_files(app: Sphinx, config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""This converts string styled html_css_files to tuple styled one."""
|
"""This converts string styled html_css_files to tuple styled one."""
|
||||||
html_css_files = [] # type: List[Tuple[str, Dict]]
|
html_css_files = [] # type: List[Tuple[str, Dict]]
|
||||||
for entry in config.html_css_files:
|
for entry in config.html_css_files:
|
||||||
@ -1167,8 +1107,7 @@ def convert_html_css_files(app, config):
|
|||||||
config.html_css_files = html_css_files # type: ignore
|
config.html_css_files = html_css_files # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def convert_html_js_files(app, config):
|
def convert_html_js_files(app: Sphinx, config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""This converts string styled html_js_files to tuple styled one."""
|
"""This converts string styled html_js_files to tuple styled one."""
|
||||||
html_js_files = [] # type: List[Tuple[str, Dict]]
|
html_js_files = [] # type: List[Tuple[str, Dict]]
|
||||||
for entry in config.html_js_files:
|
for entry in config.html_js_files:
|
||||||
@ -1185,16 +1124,15 @@ def convert_html_js_files(app, config):
|
|||||||
config.html_js_files = html_js_files # type: ignore
|
config.html_js_files = html_js_files # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def setup_js_tag_helper(app, pagename, templatexname, context, doctree):
|
def setup_js_tag_helper(app: Sphinx, pagename: str, templatexname: str,
|
||||||
# type: (Sphinx, str, str, Dict, nodes.Node) -> None
|
context: Dict, doctree: Node) -> None:
|
||||||
"""Set up js_tag() template helper.
|
"""Set up js_tag() template helper.
|
||||||
|
|
||||||
.. note:: This set up function is added to keep compatibility with webhelper.
|
.. note:: This set up function is added to keep compatibility with webhelper.
|
||||||
"""
|
"""
|
||||||
pathto = context.get('pathto')
|
pathto = context.get('pathto')
|
||||||
|
|
||||||
def js_tag(js):
|
def js_tag(js: JavaScript) -> str:
|
||||||
# type: (JavaScript) -> str
|
|
||||||
attrs = []
|
attrs = []
|
||||||
body = ''
|
body = ''
|
||||||
if isinstance(js, JavaScript):
|
if isinstance(js, JavaScript):
|
||||||
@ -1216,8 +1154,7 @@ def setup_js_tag_helper(app, pagename, templatexname, context, doctree):
|
|||||||
context['js_tag'] = js_tag
|
context['js_tag'] = js_tag
|
||||||
|
|
||||||
|
|
||||||
def validate_math_renderer(app):
|
def validate_math_renderer(app: Sphinx) -> None:
|
||||||
# type: (Sphinx) -> None
|
|
||||||
if app.builder.format != 'html':
|
if app.builder.format != 'html':
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -1235,8 +1172,7 @@ import sphinx.builders.singlehtml # NOQA
|
|||||||
import sphinxcontrib.serializinghtml # NOQA
|
import sphinxcontrib.serializinghtml # NOQA
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
# builders
|
# builders
|
||||||
app.add_builder(StandaloneHTMLBuilder)
|
app.add_builder(StandaloneHTMLBuilder)
|
||||||
|
|
||||||
|
@ -10,20 +10,16 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
from sphinxcontrib.htmlhelp import (
|
from sphinxcontrib.htmlhelp import (
|
||||||
chm_locales, chm_htmlescape, HTMLHelpBuilder, default_htmlhelp_basename
|
chm_locales, chm_htmlescape, HTMLHelpBuilder, default_htmlhelp_basename
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
|
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
deprecated_alias('sphinx.builders.htmlhelp',
|
deprecated_alias('sphinx.builders.htmlhelp',
|
||||||
{
|
{
|
||||||
'chm_locales': chm_locales,
|
'chm_locales': chm_locales,
|
||||||
@ -34,8 +30,7 @@ deprecated_alias('sphinx.builders.htmlhelp',
|
|||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
warnings.warn('sphinx.builders.htmlhelp has been moved to sphinxcontrib-htmlhelp.',
|
warnings.warn('sphinx.builders.htmlhelp has been moved to sphinxcontrib-htmlhelp.',
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
app.setup_extension('sphinxcontrib.htmlhelp')
|
app.setup_extension('sphinxcontrib.htmlhelp')
|
||||||
|
@ -11,14 +11,17 @@
|
|||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, Iterable, List, Tuple, Union
|
||||||
|
|
||||||
from docutils.frontend import OptionParser
|
from docutils.frontend import OptionParser
|
||||||
|
from docutils.nodes import Node
|
||||||
|
|
||||||
import sphinx.builders.latex.nodes # NOQA # Workaround: import this before writer to avoid ImportError
|
import sphinx.builders.latex.nodes # NOQA # Workaround: import this before writer to avoid ImportError
|
||||||
from sphinx import package_dir, addnodes, highlighting
|
from sphinx import package_dir, addnodes, highlighting
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.builders.latex.util import ExtBabel
|
from sphinx.builders.latex.util import ExtBabel
|
||||||
from sphinx.config import ENUM
|
from sphinx.config import Config, ENUM
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.environment.adapters.asset import ImageAdapter
|
from sphinx.environment.adapters.asset import ImageAdapter
|
||||||
from sphinx.errors import NoUri, SphinxError
|
from sphinx.errors import NoUri, SphinxError
|
||||||
@ -38,12 +41,6 @@ from sphinx.writers.latex import (
|
|||||||
# load docutils.nodes after loading sphinx.builders.latex.nodes
|
# load docutils.nodes after loading sphinx.builders.latex.nodes
|
||||||
from docutils import nodes # NOQA
|
from docutils import nodes # NOQA
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, Iterable, List, Tuple, Union # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.config import Config # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
XINDY_LANG_OPTIONS = {
|
XINDY_LANG_OPTIONS = {
|
||||||
# language codes from docutils.writers.latex2e.Babel
|
# language codes from docutils.writers.latex2e.Babel
|
||||||
@ -125,8 +122,7 @@ class LaTeXBuilder(Builder):
|
|||||||
supported_remote_images = False
|
supported_remote_images = False
|
||||||
default_translator_class = LaTeXTranslator
|
default_translator_class = LaTeXTranslator
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.babel = None # type: ExtBabel
|
self.babel = None # type: ExtBabel
|
||||||
self.context = {} # type: Dict[str, Any]
|
self.context = {} # type: Dict[str, Any]
|
||||||
self.docnames = [] # type: Iterable[str]
|
self.docnames = [] # type: Iterable[str]
|
||||||
@ -137,24 +133,20 @@ class LaTeXBuilder(Builder):
|
|||||||
self.init_context()
|
self.init_context()
|
||||||
self.init_babel()
|
self.init_babel()
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> Union[str, List[str]]:
|
||||||
# type: () -> Union[str, List[str]]
|
|
||||||
return 'all documents' # for now
|
return 'all documents' # for now
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
if docname not in self.docnames:
|
if docname not in self.docnames:
|
||||||
raise NoUri
|
raise NoUri
|
||||||
else:
|
else:
|
||||||
return '%' + docname
|
return '%' + docname
|
||||||
|
|
||||||
def get_relative_uri(self, from_, to, typ=None):
|
def get_relative_uri(self, from_: str, to: str, typ: str = None) -> str:
|
||||||
# type: (str, str, str) -> str
|
|
||||||
# ignore source path
|
# ignore source path
|
||||||
return self.get_target_uri(to, typ)
|
return self.get_target_uri(to, typ)
|
||||||
|
|
||||||
def init_document_data(self):
|
def init_document_data(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
preliminary_document_data = [list(x) for x in self.config.latex_documents]
|
preliminary_document_data = [list(x) for x in self.config.latex_documents]
|
||||||
if not preliminary_document_data:
|
if not preliminary_document_data:
|
||||||
logger.warning(__('no "latex_documents" config value found; no documents '
|
logger.warning(__('no "latex_documents" config value found; no documents '
|
||||||
@ -173,8 +165,7 @@ class LaTeXBuilder(Builder):
|
|||||||
docname = docname[:-5]
|
docname = docname[:-5]
|
||||||
self.titles.append((docname, entry[2]))
|
self.titles.append((docname, entry[2]))
|
||||||
|
|
||||||
def init_context(self):
|
def init_context(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.context = DEFAULT_SETTINGS.copy()
|
self.context = DEFAULT_SETTINGS.copy()
|
||||||
|
|
||||||
# Add special settings for latex_engine
|
# Add special settings for latex_engine
|
||||||
@ -208,8 +199,7 @@ class LaTeXBuilder(Builder):
|
|||||||
# Show the release label only if release value exists
|
# Show the release label only if release value exists
|
||||||
self.context.setdefault('releasename', _('Release'))
|
self.context.setdefault('releasename', _('Release'))
|
||||||
|
|
||||||
def init_babel(self):
|
def init_babel(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.babel = ExtBabel(self.config.language, not self.context['babel'])
|
self.babel = ExtBabel(self.config.language, not self.context['babel'])
|
||||||
if self.config.language and not self.babel.is_supported_language():
|
if self.config.language and not self.babel.is_supported_language():
|
||||||
# emit warning if specified language is invalid
|
# emit warning if specified language is invalid
|
||||||
@ -217,8 +207,7 @@ class LaTeXBuilder(Builder):
|
|||||||
logger.warning(__('no Babel option known for language %r'),
|
logger.warning(__('no Babel option known for language %r'),
|
||||||
self.config.language)
|
self.config.language)
|
||||||
|
|
||||||
def write_stylesheet(self):
|
def write_stylesheet(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style)
|
highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style)
|
||||||
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
|
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
|
||||||
with open(stylesheet, 'w') as f:
|
with open(stylesheet, 'w') as f:
|
||||||
@ -227,8 +216,7 @@ class LaTeXBuilder(Builder):
|
|||||||
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
|
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
|
||||||
f.write(highlighter.get_stylesheet())
|
f.write(highlighter.get_stylesheet())
|
||||||
|
|
||||||
def write(self, *ignored):
|
def write(self, *ignored) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
docwriter = LaTeXWriter(self)
|
docwriter = LaTeXWriter(self)
|
||||||
docsettings = OptionParser(
|
docsettings = OptionParser(
|
||||||
defaults=self.env.settings,
|
defaults=self.env.settings,
|
||||||
@ -271,8 +259,7 @@ class LaTeXBuilder(Builder):
|
|||||||
doctree.settings = docsettings
|
doctree.settings = docsettings
|
||||||
docwriter.write(doctree, destination)
|
docwriter.write(doctree, destination)
|
||||||
|
|
||||||
def get_contentsname(self, indexfile):
|
def get_contentsname(self, indexfile: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
tree = self.env.get_doctree(indexfile)
|
tree = self.env.get_doctree(indexfile)
|
||||||
contentsname = None
|
contentsname = None
|
||||||
for toctree in tree.traverse(addnodes.toctree):
|
for toctree in tree.traverse(addnodes.toctree):
|
||||||
@ -282,13 +269,11 @@ class LaTeXBuilder(Builder):
|
|||||||
|
|
||||||
return contentsname
|
return contentsname
|
||||||
|
|
||||||
def update_doc_context(self, title, author):
|
def update_doc_context(self, title: str, author: str) -> None:
|
||||||
# type: (str, str) -> None
|
|
||||||
self.context['title'] = title
|
self.context['title'] = title
|
||||||
self.context['author'] = author
|
self.context['author'] = author
|
||||||
|
|
||||||
def assemble_doctree(self, indexfile, toctree_only, appendices):
|
def assemble_doctree(self, indexfile: str, toctree_only: bool, appendices: List[str]) -> nodes.document: # NOQA
|
||||||
# type: (str, bool, List[str]) -> nodes.document
|
|
||||||
self.docnames = set([indexfile] + appendices)
|
self.docnames = set([indexfile] + appendices)
|
||||||
logger.info(darkgreen(indexfile) + " ", nonl=True)
|
logger.info(darkgreen(indexfile) + " ", nonl=True)
|
||||||
tree = self.env.get_doctree(indexfile)
|
tree = self.env.get_doctree(indexfile)
|
||||||
@ -319,7 +304,7 @@ class LaTeXBuilder(Builder):
|
|||||||
for pendingnode in largetree.traverse(addnodes.pending_xref):
|
for pendingnode in largetree.traverse(addnodes.pending_xref):
|
||||||
docname = pendingnode['refdocname']
|
docname = pendingnode['refdocname']
|
||||||
sectname = pendingnode['refsectname']
|
sectname = pendingnode['refsectname']
|
||||||
newnodes = [nodes.emphasis(sectname, sectname)] # type: List[nodes.Node]
|
newnodes = [nodes.emphasis(sectname, sectname)] # type: List[Node]
|
||||||
for subdir, title in self.titles:
|
for subdir, title in self.titles:
|
||||||
if docname.startswith(subdir):
|
if docname.startswith(subdir):
|
||||||
newnodes.append(nodes.Text(_(' (in '), _(' (in ')))
|
newnodes.append(nodes.Text(_(' (in '), _(' (in ')))
|
||||||
@ -331,13 +316,11 @@ class LaTeXBuilder(Builder):
|
|||||||
pendingnode.replace_self(newnodes)
|
pendingnode.replace_self(newnodes)
|
||||||
return largetree
|
return largetree
|
||||||
|
|
||||||
def apply_transforms(self, doctree):
|
def apply_transforms(self, doctree: nodes.document) -> None:
|
||||||
# type: (nodes.document) -> None
|
|
||||||
warnings.warn('LaTeXBuilder.apply_transforms() is deprecated.',
|
warnings.warn('LaTeXBuilder.apply_transforms() is deprecated.',
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.copy_image_files()
|
self.copy_image_files()
|
||||||
self.write_message_catalog()
|
self.write_message_catalog()
|
||||||
self.copy_support_files()
|
self.copy_support_files()
|
||||||
@ -346,8 +329,7 @@ class LaTeXBuilder(Builder):
|
|||||||
self.copy_latex_additional_files()
|
self.copy_latex_additional_files()
|
||||||
|
|
||||||
@progress_message(__('copying TeX support files'))
|
@progress_message(__('copying TeX support files'))
|
||||||
def copy_support_files(self):
|
def copy_support_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""copy TeX support files from texinputs."""
|
"""copy TeX support files from texinputs."""
|
||||||
# configure usage of xindy (impacts Makefile and latexmkrc)
|
# configure usage of xindy (impacts Makefile and latexmkrc)
|
||||||
# FIXME: convert this rather to a confval with suitable default
|
# FIXME: convert this rather to a confval with suitable default
|
||||||
@ -387,14 +369,12 @@ class LaTeXBuilder(Builder):
|
|||||||
copy_asset_file(path.join(self.confdir, self.config.latex_logo), self.outdir)
|
copy_asset_file(path.join(self.confdir, self.config.latex_logo), self.outdir)
|
||||||
|
|
||||||
@progress_message(__('copying additional files'))
|
@progress_message(__('copying additional files'))
|
||||||
def copy_latex_additional_files(self):
|
def copy_latex_additional_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
for filename in self.config.latex_additional_files:
|
for filename in self.config.latex_additional_files:
|
||||||
logger.info(' ' + filename, nonl=True)
|
logger.info(' ' + filename, nonl=True)
|
||||||
copy_asset_file(path.join(self.confdir, filename), self.outdir)
|
copy_asset_file(path.join(self.confdir, filename), self.outdir)
|
||||||
|
|
||||||
def copy_image_files(self):
|
def copy_image_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
if self.images:
|
if self.images:
|
||||||
stringify_func = ImageAdapter(self.app.env).get_original_image_uri
|
stringify_func = ImageAdapter(self.app.env).get_original_image_uri
|
||||||
for src in status_iterator(self.images, __('copying images... '), "brown",
|
for src in status_iterator(self.images, __('copying images... '), "brown",
|
||||||
@ -408,8 +388,7 @@ class LaTeXBuilder(Builder):
|
|||||||
logger.warning(__('cannot copy image file %r: %s'),
|
logger.warning(__('cannot copy image file %r: %s'),
|
||||||
path.join(self.srcdir, src), err)
|
path.join(self.srcdir, src), err)
|
||||||
|
|
||||||
def write_message_catalog(self):
|
def write_message_catalog(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
formats = self.config.numfig_format
|
formats = self.config.numfig_format
|
||||||
context = {
|
context = {
|
||||||
'addtocaptions': r'\@iden',
|
'addtocaptions': r'\@iden',
|
||||||
@ -425,8 +404,7 @@ class LaTeXBuilder(Builder):
|
|||||||
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())
|
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())
|
||||||
|
|
||||||
|
|
||||||
def validate_config_values(app, config):
|
def validate_config_values(app: Sphinx, config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
for key in list(config.latex_elements):
|
for key in list(config.latex_elements):
|
||||||
if key not in DEFAULT_SETTINGS:
|
if key not in DEFAULT_SETTINGS:
|
||||||
msg = __("Unknown configure key: latex_elements[%r]. ignored.")
|
msg = __("Unknown configure key: latex_elements[%r]. ignored.")
|
||||||
@ -434,8 +412,7 @@ def validate_config_values(app, config):
|
|||||||
config.latex_elements.pop(key)
|
config.latex_elements.pop(key)
|
||||||
|
|
||||||
|
|
||||||
def default_latex_engine(config):
|
def default_latex_engine(config: Config) -> str:
|
||||||
# type: (Config) -> str
|
|
||||||
""" Better default latex_engine settings for specific languages. """
|
""" Better default latex_engine settings for specific languages. """
|
||||||
if config.language == 'ja':
|
if config.language == 'ja':
|
||||||
return 'platex'
|
return 'platex'
|
||||||
@ -445,8 +422,7 @@ def default_latex_engine(config):
|
|||||||
return 'pdflatex'
|
return 'pdflatex'
|
||||||
|
|
||||||
|
|
||||||
def default_latex_docclass(config):
|
def default_latex_docclass(config: Config) -> Dict[str, str]:
|
||||||
# type: (Config) -> Dict[str, str]
|
|
||||||
""" Better default latex_docclass settings for specific languages. """
|
""" Better default latex_docclass settings for specific languages. """
|
||||||
if config.language == 'ja':
|
if config.language == 'ja':
|
||||||
return {'manual': 'jsbook',
|
return {'manual': 'jsbook',
|
||||||
@ -455,14 +431,12 @@ def default_latex_docclass(config):
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def default_latex_use_xindy(config):
|
def default_latex_use_xindy(config: Config) -> bool:
|
||||||
# type: (Config) -> bool
|
|
||||||
""" Better default latex_use_xindy settings for specific engines. """
|
""" Better default latex_use_xindy settings for specific engines. """
|
||||||
return config.latex_engine in {'xelatex', 'lualatex'}
|
return config.latex_engine in {'xelatex', 'lualatex'}
|
||||||
|
|
||||||
|
|
||||||
def default_latex_documents(config):
|
def default_latex_documents(config: Config) -> List[Tuple[str, str, str, str, str]]:
|
||||||
# type: (Config) -> List[Tuple[str, str, str, str, str]]
|
|
||||||
""" Better default latex_documents settings. """
|
""" Better default latex_documents settings. """
|
||||||
return [(config.master_doc,
|
return [(config.master_doc,
|
||||||
make_filename_from_project(config.project) + '.tex',
|
make_filename_from_project(config.project) + '.tex',
|
||||||
@ -471,8 +445,7 @@ def default_latex_documents(config):
|
|||||||
'manual')]
|
'manual')]
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.setup_extension('sphinx.builders.latex.transforms')
|
app.setup_extension('sphinx.builders.latex.transforms')
|
||||||
|
|
||||||
app.add_builder(LaTeXBuilder)
|
app.add_builder(LaTeXBuilder)
|
||||||
|
@ -8,11 +8,14 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from typing import Any, Dict, List, Set, Tuple
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Element, Node
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders.latex.nodes import (
|
from sphinx.builders.latex.nodes import (
|
||||||
captioned_literal_block, footnotemark, footnotetext, math_reference, thebibliography
|
captioned_literal_block, footnotemark, footnotetext, math_reference, thebibliography
|
||||||
)
|
)
|
||||||
@ -21,11 +24,6 @@ from sphinx.transforms import SphinxTransform
|
|||||||
from sphinx.transforms.post_transforms import SphinxPostTransform
|
from sphinx.transforms.post_transforms import SphinxPostTransform
|
||||||
from sphinx.util.nodes import NodeMatcher
|
from sphinx.util.nodes import NodeMatcher
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, List, Set, Tuple # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:')
|
URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:')
|
||||||
|
|
||||||
|
|
||||||
@ -34,8 +32,7 @@ class FootnoteDocnameUpdater(SphinxTransform):
|
|||||||
default_priority = 700
|
default_priority = 700
|
||||||
TARGET_NODES = (nodes.footnote, nodes.footnote_reference)
|
TARGET_NODES = (nodes.footnote, nodes.footnote_reference)
|
||||||
|
|
||||||
def apply(self, **kwargs):
|
def apply(self, **kwargs) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
matcher = NodeMatcher(*self.TARGET_NODES)
|
matcher = NodeMatcher(*self.TARGET_NODES)
|
||||||
for node in self.document.traverse(matcher): # type: nodes.Element
|
for node in self.document.traverse(matcher): # type: nodes.Element
|
||||||
node['docname'] = self.env.docname
|
node['docname'] = self.env.docname
|
||||||
@ -54,8 +51,7 @@ class ShowUrlsTransform(SphinxPostTransform):
|
|||||||
# references are expanded to footnotes (or not)
|
# references are expanded to footnotes (or not)
|
||||||
expanded = False
|
expanded = False
|
||||||
|
|
||||||
def run(self, **kwargs):
|
def run(self, **kwargs) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
try:
|
try:
|
||||||
# replace id_prefix temporarily
|
# replace id_prefix temporarily
|
||||||
settings = self.document.settings # type: Any
|
settings = self.document.settings # type: Any
|
||||||
@ -69,8 +65,7 @@ class ShowUrlsTransform(SphinxPostTransform):
|
|||||||
# restore id_prefix
|
# restore id_prefix
|
||||||
settings.id_prefix = id_prefix
|
settings.id_prefix = id_prefix
|
||||||
|
|
||||||
def expand_show_urls(self):
|
def expand_show_urls(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
show_urls = self.config.latex_show_urls
|
show_urls = self.config.latex_show_urls
|
||||||
if show_urls is False or show_urls == 'no':
|
if show_urls is False or show_urls == 'no':
|
||||||
return
|
return
|
||||||
@ -93,8 +88,7 @@ class ShowUrlsTransform(SphinxPostTransform):
|
|||||||
textnode = nodes.Text(" (%s)" % uri)
|
textnode = nodes.Text(" (%s)" % uri)
|
||||||
node.parent.insert(index + 1, textnode)
|
node.parent.insert(index + 1, textnode)
|
||||||
|
|
||||||
def get_docname_for_node(self, node):
|
def get_docname_for_node(self, node: Node) -> str:
|
||||||
# type: (nodes.Node) -> str
|
|
||||||
while node:
|
while node:
|
||||||
if isinstance(node, nodes.document):
|
if isinstance(node, nodes.document):
|
||||||
return self.env.path2doc(node['source'])
|
return self.env.path2doc(node['source'])
|
||||||
@ -105,8 +99,7 @@ class ShowUrlsTransform(SphinxPostTransform):
|
|||||||
|
|
||||||
return None # never reached here. only for type hinting
|
return None # never reached here. only for type hinting
|
||||||
|
|
||||||
def create_footnote(self, uri, docname):
|
def create_footnote(self, uri: str, docname: str) -> Tuple[nodes.footnote, nodes.footnote_reference]: # NOQA
|
||||||
# type: (str, str) -> Tuple[nodes.footnote, nodes.footnote_reference]
|
|
||||||
reference = nodes.reference('', nodes.Text(uri), refuri=uri, nolinkurl=True)
|
reference = nodes.reference('', nodes.Text(uri), refuri=uri, nolinkurl=True)
|
||||||
footnote = nodes.footnote(uri, auto=1, docname=docname)
|
footnote = nodes.footnote(uri, auto=1, docname=docname)
|
||||||
footnote['names'].append('#')
|
footnote['names'].append('#')
|
||||||
@ -122,8 +115,7 @@ class ShowUrlsTransform(SphinxPostTransform):
|
|||||||
|
|
||||||
return footnote, footnote_ref
|
return footnote, footnote_ref
|
||||||
|
|
||||||
def renumber_footnotes(self):
|
def renumber_footnotes(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
collector = FootnoteCollector(self.document)
|
collector = FootnoteCollector(self.document)
|
||||||
self.document.walkabout(collector)
|
self.document.walkabout(collector)
|
||||||
|
|
||||||
@ -153,31 +145,26 @@ class ShowUrlsTransform(SphinxPostTransform):
|
|||||||
class FootnoteCollector(nodes.NodeVisitor):
|
class FootnoteCollector(nodes.NodeVisitor):
|
||||||
"""Collect footnotes and footnote references on the document"""
|
"""Collect footnotes and footnote references on the document"""
|
||||||
|
|
||||||
def __init__(self, document):
|
def __init__(self, document: nodes.document) -> None:
|
||||||
# type: (nodes.document) -> None
|
|
||||||
self.auto_footnotes = [] # type: List[nodes.footnote]
|
self.auto_footnotes = [] # type: List[nodes.footnote]
|
||||||
self.used_footnote_numbers = set() # type: Set[str]
|
self.used_footnote_numbers = set() # type: Set[str]
|
||||||
self.footnote_refs = [] # type: List[nodes.footnote_reference]
|
self.footnote_refs = [] # type: List[nodes.footnote_reference]
|
||||||
super().__init__(document)
|
super().__init__(document)
|
||||||
|
|
||||||
def unknown_visit(self, node):
|
def unknown_visit(self, node: Node) -> None:
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def unknown_departure(self, node):
|
def unknown_departure(self, node: Node) -> None:
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def visit_footnote(self, node):
|
def visit_footnote(self, node: nodes.footnote) -> None:
|
||||||
# type: (nodes.footnote) -> None
|
|
||||||
if node.get('auto'):
|
if node.get('auto'):
|
||||||
self.auto_footnotes.append(node)
|
self.auto_footnotes.append(node)
|
||||||
else:
|
else:
|
||||||
for name in node['names']:
|
for name in node['names']:
|
||||||
self.used_footnote_numbers.add(name)
|
self.used_footnote_numbers.add(name)
|
||||||
|
|
||||||
def visit_footnote_reference(self, node):
|
def visit_footnote_reference(self, node: nodes.footnote_reference) -> None:
|
||||||
# type: (nodes.footnote_reference) -> None
|
|
||||||
self.footnote_refs.append(node)
|
self.footnote_refs.append(node)
|
||||||
|
|
||||||
|
|
||||||
@ -351,8 +338,7 @@ class LaTeXFootnoteTransform(SphinxPostTransform):
|
|||||||
default_priority = 600
|
default_priority = 600
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs):
|
def run(self, **kwargs) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
footnotes = list(self.document.traverse(nodes.footnote))
|
footnotes = list(self.document.traverse(nodes.footnote))
|
||||||
for node in footnotes:
|
for node in footnotes:
|
||||||
node.parent.remove(node)
|
node.parent.remove(node)
|
||||||
@ -362,8 +348,7 @@ class LaTeXFootnoteTransform(SphinxPostTransform):
|
|||||||
|
|
||||||
|
|
||||||
class LaTeXFootnoteVisitor(nodes.NodeVisitor):
|
class LaTeXFootnoteVisitor(nodes.NodeVisitor):
|
||||||
def __init__(self, document, footnotes):
|
def __init__(self, document: nodes.document, footnotes: List[nodes.footnote]) -> None:
|
||||||
# type: (nodes.document, List[nodes.footnote]) -> None
|
|
||||||
self.appeared = set() # type: Set[Tuple[str, str]]
|
self.appeared = set() # type: Set[Tuple[str, str]]
|
||||||
self.footnotes = footnotes # type: List[nodes.footnote]
|
self.footnotes = footnotes # type: List[nodes.footnote]
|
||||||
self.pendings = [] # type: List[nodes.footnote]
|
self.pendings = [] # type: List[nodes.footnote]
|
||||||
@ -371,21 +356,17 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
|
|||||||
self.restricted = None # type: nodes.Element
|
self.restricted = None # type: nodes.Element
|
||||||
super().__init__(document)
|
super().__init__(document)
|
||||||
|
|
||||||
def unknown_visit(self, node):
|
def unknown_visit(self, node: Node) -> None:
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def unknown_departure(self, node):
|
def unknown_departure(self, node: Node) -> None:
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def restrict(self, node):
|
def restrict(self, node: Element) -> None:
|
||||||
# type: (nodes.Element) -> None
|
|
||||||
if self.restricted is None:
|
if self.restricted is None:
|
||||||
self.restricted = node
|
self.restricted = node
|
||||||
|
|
||||||
def unrestrict(self, node):
|
def unrestrict(self, node: Element) -> None:
|
||||||
# type: (nodes.Element) -> None
|
|
||||||
if self.restricted == node:
|
if self.restricted == node:
|
||||||
self.restricted = None
|
self.restricted = None
|
||||||
pos = node.parent.index(node)
|
pos = node.parent.index(node)
|
||||||
@ -394,37 +375,29 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
|
|||||||
node.parent.insert(pos + i + 1, fntext)
|
node.parent.insert(pos + i + 1, fntext)
|
||||||
self.pendings = []
|
self.pendings = []
|
||||||
|
|
||||||
def visit_figure(self, node):
|
def visit_figure(self, node: nodes.figure) -> None:
|
||||||
# type: (nodes.figure) -> None
|
|
||||||
self.restrict(node)
|
self.restrict(node)
|
||||||
|
|
||||||
def depart_figure(self, node):
|
def depart_figure(self, node: nodes.figure) -> None:
|
||||||
# type: (nodes.figure) -> None
|
|
||||||
self.unrestrict(node)
|
self.unrestrict(node)
|
||||||
|
|
||||||
def visit_term(self, node):
|
def visit_term(self, node: nodes.term) -> None:
|
||||||
# type: (nodes.term) -> None
|
|
||||||
self.restrict(node)
|
self.restrict(node)
|
||||||
|
|
||||||
def depart_term(self, node):
|
def depart_term(self, node: nodes.term) -> None:
|
||||||
# type: (nodes.term) -> None
|
|
||||||
self.unrestrict(node)
|
self.unrestrict(node)
|
||||||
|
|
||||||
def visit_caption(self, node):
|
def visit_caption(self, node: nodes.caption) -> None:
|
||||||
# type: (nodes.caption) -> None
|
|
||||||
self.restrict(node)
|
self.restrict(node)
|
||||||
|
|
||||||
def depart_caption(self, node):
|
def depart_caption(self, node: nodes.caption) -> None:
|
||||||
# type: (nodes.caption) -> None
|
|
||||||
self.unrestrict(node)
|
self.unrestrict(node)
|
||||||
|
|
||||||
def visit_title(self, node):
|
def visit_title(self, node: nodes.title) -> None:
|
||||||
# type: (nodes.title) -> None
|
|
||||||
if isinstance(node.parent, (nodes.section, nodes.table)):
|
if isinstance(node.parent, (nodes.section, nodes.table)):
|
||||||
self.restrict(node)
|
self.restrict(node)
|
||||||
|
|
||||||
def depart_title(self, node):
|
def depart_title(self, node: nodes.title) -> None:
|
||||||
# type: (nodes.title) -> None
|
|
||||||
if isinstance(node.parent, nodes.section):
|
if isinstance(node.parent, nodes.section):
|
||||||
self.unrestrict(node)
|
self.unrestrict(node)
|
||||||
elif isinstance(node.parent, nodes.table):
|
elif isinstance(node.parent, nodes.table):
|
||||||
@ -432,18 +405,15 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
|
|||||||
self.pendings = []
|
self.pendings = []
|
||||||
self.unrestrict(node)
|
self.unrestrict(node)
|
||||||
|
|
||||||
def visit_thead(self, node):
|
def visit_thead(self, node: nodes.thead) -> None:
|
||||||
# type: (nodes.thead) -> None
|
|
||||||
self.restrict(node)
|
self.restrict(node)
|
||||||
|
|
||||||
def depart_thead(self, node):
|
def depart_thead(self, node: nodes.thead) -> None:
|
||||||
# type: (nodes.thead) -> None
|
|
||||||
self.table_footnotes += self.pendings
|
self.table_footnotes += self.pendings
|
||||||
self.pendings = []
|
self.pendings = []
|
||||||
self.unrestrict(node)
|
self.unrestrict(node)
|
||||||
|
|
||||||
def depart_table(self, node):
|
def depart_table(self, node: nodes.table) -> None:
|
||||||
# type: (nodes.table) -> None
|
|
||||||
tbody = list(node.traverse(nodes.tbody))[0]
|
tbody = list(node.traverse(nodes.tbody))[0]
|
||||||
for footnote in reversed(self.table_footnotes):
|
for footnote in reversed(self.table_footnotes):
|
||||||
fntext = footnotetext('', *footnote.children)
|
fntext = footnotetext('', *footnote.children)
|
||||||
@ -451,16 +421,13 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
|
|||||||
|
|
||||||
self.table_footnotes = []
|
self.table_footnotes = []
|
||||||
|
|
||||||
def visit_footnote(self, node):
|
def visit_footnote(self, node: nodes.footnote) -> None:
|
||||||
# type: (nodes.footnote) -> None
|
|
||||||
self.restrict(node)
|
self.restrict(node)
|
||||||
|
|
||||||
def depart_footnote(self, node):
|
def depart_footnote(self, node: nodes.footnote) -> None:
|
||||||
# type: (nodes.footnote) -> None
|
|
||||||
self.unrestrict(node)
|
self.unrestrict(node)
|
||||||
|
|
||||||
def visit_footnote_reference(self, node):
|
def visit_footnote_reference(self, node: nodes.footnote_reference) -> None:
|
||||||
# type: (nodes.footnote_reference) -> None
|
|
||||||
number = node.astext().strip()
|
number = node.astext().strip()
|
||||||
docname = node['docname']
|
docname = node['docname']
|
||||||
if self.restricted:
|
if self.restricted:
|
||||||
@ -481,8 +448,7 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
|
|||||||
self.appeared.add((docname, number))
|
self.appeared.add((docname, number))
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
def get_footnote_by_reference(self, node):
|
def get_footnote_by_reference(self, node: nodes.footnote_reference) -> nodes.footnote:
|
||||||
# type: (nodes.footnote_reference) -> nodes.footnote
|
|
||||||
docname = node['docname']
|
docname = node['docname']
|
||||||
for footnote in self.footnotes:
|
for footnote in self.footnotes:
|
||||||
if docname == footnote['docname'] and footnote['ids'][0] == node['refid']:
|
if docname == footnote['docname'] and footnote['ids'][0] == node['refid']:
|
||||||
@ -524,8 +490,7 @@ class BibliographyTransform(SphinxPostTransform):
|
|||||||
default_priority = 750
|
default_priority = 750
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs):
|
def run(self, **kwargs) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
citations = thebibliography()
|
citations = thebibliography()
|
||||||
for node in self.document.traverse(nodes.citation):
|
for node in self.document.traverse(nodes.citation):
|
||||||
node.parent.remove(node)
|
node.parent.remove(node)
|
||||||
@ -544,8 +509,7 @@ class CitationReferenceTransform(SphinxPostTransform):
|
|||||||
default_priority = 5 # before ReferencesResolver
|
default_priority = 5 # before ReferencesResolver
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs):
|
def run(self, **kwargs) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
domain = cast(CitationDomain, self.env.get_domain('citation'))
|
domain = cast(CitationDomain, self.env.get_domain('citation'))
|
||||||
matcher = NodeMatcher(addnodes.pending_xref, refdomain='citation', reftype='ref')
|
matcher = NodeMatcher(addnodes.pending_xref, refdomain='citation', reftype='ref')
|
||||||
for node in self.document.traverse(matcher): # type: addnodes.pending_xref
|
for node in self.document.traverse(matcher): # type: addnodes.pending_xref
|
||||||
@ -565,8 +529,7 @@ class MathReferenceTransform(SphinxPostTransform):
|
|||||||
default_priority = 5 # before ReferencesResolver
|
default_priority = 5 # before ReferencesResolver
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs):
|
def run(self, **kwargs) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
equations = self.env.get_domain('math').data['objects']
|
equations = self.env.get_domain('math').data['objects']
|
||||||
for node in self.document.traverse(addnodes.pending_xref):
|
for node in self.document.traverse(addnodes.pending_xref):
|
||||||
if node['refdomain'] == 'math' and node['reftype'] in ('eq', 'numref'):
|
if node['refdomain'] == 'math' and node['reftype'] in ('eq', 'numref'):
|
||||||
@ -581,8 +544,7 @@ class LiteralBlockTransform(SphinxPostTransform):
|
|||||||
default_priority = 400
|
default_priority = 400
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs):
|
def run(self, **kwargs) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
matcher = NodeMatcher(nodes.container, literal_block=True)
|
matcher = NodeMatcher(nodes.container, literal_block=True)
|
||||||
for node in self.document.traverse(matcher): # type: nodes.container
|
for node in self.document.traverse(matcher): # type: nodes.container
|
||||||
newnode = captioned_literal_block('', *node.children, **node.attributes)
|
newnode = captioned_literal_block('', *node.children, **node.attributes)
|
||||||
@ -594,8 +556,7 @@ class DocumentTargetTransform(SphinxPostTransform):
|
|||||||
default_priority = 400
|
default_priority = 400
|
||||||
builders = ('latex',)
|
builders = ('latex',)
|
||||||
|
|
||||||
def run(self, **kwargs):
|
def run(self, **kwargs) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
for node in self.document.traverse(addnodes.start_of_file):
|
for node in self.document.traverse(addnodes.start_of_file):
|
||||||
section = node.next_node(nodes.section)
|
section = node.next_node(nodes.section)
|
||||||
if section:
|
if section:
|
||||||
@ -639,8 +600,7 @@ class IndexInSectionTitleTransform(SphinxTransform):
|
|||||||
node.parent.insert(i + 1, index)
|
node.parent.insert(i + 1, index)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_transform(FootnoteDocnameUpdater)
|
app.add_transform(FootnoteDocnameUpdater)
|
||||||
app.add_post_transform(BibliographyTransform)
|
app.add_post_transform(BibliographyTransform)
|
||||||
app.add_post_transform(CitationReferenceTransform)
|
app.add_post_transform(CitationReferenceTransform)
|
||||||
|
@ -18,30 +18,25 @@ from sphinx.deprecation import RemovedInSphinx30Warning
|
|||||||
class ExtBabel(Babel):
|
class ExtBabel(Babel):
|
||||||
cyrillic_languages = ('bulgarian', 'kazakh', 'mongolian', 'russian', 'ukrainian')
|
cyrillic_languages = ('bulgarian', 'kazakh', 'mongolian', 'russian', 'ukrainian')
|
||||||
|
|
||||||
def __init__(self, language_code, use_polyglossia=False):
|
def __init__(self, language_code: str, use_polyglossia: bool = False) -> None:
|
||||||
# type: (str, bool) -> None
|
|
||||||
self.language_code = language_code
|
self.language_code = language_code
|
||||||
self.use_polyglossia = use_polyglossia
|
self.use_polyglossia = use_polyglossia
|
||||||
self.supported = True
|
self.supported = True
|
||||||
super().__init__(language_code or '')
|
super().__init__(language_code or '')
|
||||||
|
|
||||||
def get_shorthandoff(self):
|
def get_shorthandoff(self) -> str:
|
||||||
# type: () -> str
|
|
||||||
warnings.warn('ExtBabel.get_shorthandoff() is deprecated.',
|
warnings.warn('ExtBabel.get_shorthandoff() is deprecated.',
|
||||||
RemovedInSphinx30Warning, stacklevel=2)
|
RemovedInSphinx30Warning, stacklevel=2)
|
||||||
from sphinx.writers.latex import SHORTHANDOFF
|
from sphinx.writers.latex import SHORTHANDOFF
|
||||||
return SHORTHANDOFF
|
return SHORTHANDOFF
|
||||||
|
|
||||||
def uses_cyrillic(self):
|
def uses_cyrillic(self) -> bool:
|
||||||
# type: () -> bool
|
|
||||||
return self.language in self.cyrillic_languages
|
return self.language in self.cyrillic_languages
|
||||||
|
|
||||||
def is_supported_language(self):
|
def is_supported_language(self) -> bool:
|
||||||
# type: () -> bool
|
|
||||||
return self.supported
|
return self.supported
|
||||||
|
|
||||||
def language_name(self, language_code):
|
def language_name(self, language_code: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
language = super().language_name(language_code)
|
language = super().language_name(language_code)
|
||||||
if language == 'ngerman' and self.use_polyglossia:
|
if language == 'ngerman' and self.use_polyglossia:
|
||||||
# polyglossia calls new orthography (Neue Rechtschreibung) as
|
# polyglossia calls new orthography (Neue Rechtschreibung) as
|
||||||
@ -55,8 +50,7 @@ class ExtBabel(Babel):
|
|||||||
self.supported = False
|
self.supported = False
|
||||||
return 'english' # fallback to english
|
return 'english' # fallback to english
|
||||||
|
|
||||||
def get_mainlanguage_options(self):
|
def get_mainlanguage_options(self) -> str:
|
||||||
# type: () -> str
|
|
||||||
"""Return options for polyglossia's ``\\setmainlanguage``."""
|
"""Return options for polyglossia's ``\\setmainlanguage``."""
|
||||||
if self.use_polyglossia is False:
|
if self.use_polyglossia is False:
|
||||||
return None
|
return None
|
||||||
|
@ -14,11 +14,14 @@ import socket
|
|||||||
import threading
|
import threading
|
||||||
from html.parser import HTMLParser
|
from html.parser import HTMLParser
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, List, Set, Tuple
|
||||||
from urllib.parse import unquote
|
from urllib.parse import unquote
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Node
|
||||||
from requests.exceptions import HTTPError
|
from requests.exceptions import HTTPError
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import encode_uri, requests, logging
|
from sphinx.util import encode_uri, requests, logging
|
||||||
@ -28,12 +31,6 @@ from sphinx.util.console import ( # type: ignore
|
|||||||
from sphinx.util.nodes import get_node_line
|
from sphinx.util.nodes import get_node_line
|
||||||
from sphinx.util.requests import is_ssl_error
|
from sphinx.util.requests import is_ssl_error
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, List, Set, Tuple # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.util.requests.requests import Response # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -41,23 +38,20 @@ logger = logging.getLogger(__name__)
|
|||||||
class AnchorCheckParser(HTMLParser):
|
class AnchorCheckParser(HTMLParser):
|
||||||
"""Specialized HTML parser that looks for a specific anchor."""
|
"""Specialized HTML parser that looks for a specific anchor."""
|
||||||
|
|
||||||
def __init__(self, search_anchor):
|
def __init__(self, search_anchor: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.search_anchor = search_anchor
|
self.search_anchor = search_anchor
|
||||||
self.found = False
|
self.found = False
|
||||||
|
|
||||||
def handle_starttag(self, tag, attrs):
|
def handle_starttag(self, tag: Any, attrs: Any) -> None:
|
||||||
# type: (Any, Any) -> None
|
|
||||||
for key, value in attrs:
|
for key, value in attrs:
|
||||||
if key in ('id', 'name') and value == self.search_anchor:
|
if key in ('id', 'name') and value == self.search_anchor:
|
||||||
self.found = True
|
self.found = True
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def check_anchor(response, anchor):
|
def check_anchor(response: requests.requests.Response, anchor: str) -> bool:
|
||||||
# type: (Response, str) -> bool
|
|
||||||
"""Reads HTML data from a response object `response` searching for `anchor`.
|
"""Reads HTML data from a response object `response` searching for `anchor`.
|
||||||
Returns True if anchor was found, False otherwise.
|
Returns True if anchor was found, False otherwise.
|
||||||
"""
|
"""
|
||||||
@ -80,8 +74,7 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
epilog = __('Look for any errors in the above output or in '
|
epilog = __('Look for any errors in the above output or in '
|
||||||
'%(outdir)s/output.txt')
|
'%(outdir)s/output.txt')
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
|
self.to_ignore = [re.compile(x) for x in self.app.config.linkcheck_ignore]
|
||||||
self.anchors_ignore = [re.compile(x)
|
self.anchors_ignore = [re.compile(x)
|
||||||
for x in self.app.config.linkcheck_anchors_ignore]
|
for x in self.app.config.linkcheck_anchors_ignore]
|
||||||
@ -103,8 +96,7 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
thread.start()
|
thread.start()
|
||||||
self.workers.append(thread)
|
self.workers.append(thread)
|
||||||
|
|
||||||
def check_thread(self):
|
def check_thread(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'allow_redirects': True,
|
'allow_redirects': True,
|
||||||
'headers': {
|
'headers': {
|
||||||
@ -115,8 +107,7 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
if self.app.config.linkcheck_timeout:
|
if self.app.config.linkcheck_timeout:
|
||||||
kwargs['timeout'] = self.app.config.linkcheck_timeout
|
kwargs['timeout'] = self.app.config.linkcheck_timeout
|
||||||
|
|
||||||
def check_uri():
|
def check_uri() -> Tuple[str, str, int]:
|
||||||
# type: () -> Tuple[str, str, int]
|
|
||||||
# split off anchor
|
# split off anchor
|
||||||
if '#' in uri:
|
if '#' in uri:
|
||||||
req_url, anchor = uri.split('#', 1)
|
req_url, anchor = uri.split('#', 1)
|
||||||
@ -159,6 +150,9 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
if err.response.status_code == 401:
|
if err.response.status_code == 401:
|
||||||
# We'll take "Unauthorized" as working.
|
# We'll take "Unauthorized" as working.
|
||||||
return 'working', ' - unauthorized', 0
|
return 'working', ' - unauthorized', 0
|
||||||
|
elif err.response.status_code == 503:
|
||||||
|
# We'll take "Service Unavailable" as ignored.
|
||||||
|
return 'ignored', str(err), 0
|
||||||
else:
|
else:
|
||||||
return 'broken', str(err), 0
|
return 'broken', str(err), 0
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
@ -179,8 +173,7 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
else:
|
else:
|
||||||
return 'redirected', new_url, 0
|
return 'redirected', new_url, 0
|
||||||
|
|
||||||
def check():
|
def check() -> Tuple[str, str, int]:
|
||||||
# type: () -> Tuple[str, str, int]
|
|
||||||
# check for various conditions without bothering the network
|
# check for various conditions without bothering the network
|
||||||
if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'ftp:')):
|
if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'ftp:')):
|
||||||
return 'unchecked', '', 0
|
return 'unchecked', '', 0
|
||||||
@ -218,8 +211,7 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
status, info, code = check()
|
status, info, code = check()
|
||||||
self.rqueue.put((uri, docname, lineno, status, info, code))
|
self.rqueue.put((uri, docname, lineno, status, info, code))
|
||||||
|
|
||||||
def process_result(self, result):
|
def process_result(self, result: Tuple[str, str, int, str, str, int]) -> None:
|
||||||
# type: (Tuple[str, str, int, str, str, int]) -> None
|
|
||||||
uri, docname, lineno, status, info, code = result
|
uri, docname, lineno, status, info, code = result
|
||||||
if status == 'unchecked':
|
if status == 'unchecked':
|
||||||
return
|
return
|
||||||
@ -256,20 +248,16 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
uri + ' to ' + info)
|
uri + ' to ' + info)
|
||||||
logger.info(color('redirect ') + uri + color(' - ' + text + ' to ' + info))
|
logger.info(color('redirect ') + uri + color(' - ' + text + ' to ' + info))
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> Set[str]:
|
||||||
# type: () -> Set[str]
|
|
||||||
return self.env.found_docs
|
return self.env.found_docs
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
# type: (Set[str]) -> None
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname: str, doctree: Node) -> None:
|
||||||
# type: (str, nodes.Node) -> None
|
|
||||||
logger.info('')
|
logger.info('')
|
||||||
n = 0
|
n = 0
|
||||||
|
|
||||||
@ -298,20 +286,17 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
if self.broken:
|
if self.broken:
|
||||||
self.app.statuscode = 1
|
self.app.statuscode = 1
|
||||||
|
|
||||||
def write_entry(self, what, docname, line, uri):
|
def write_entry(self, what: str, docname: str, line: int, uri: str) -> None:
|
||||||
# type: (str, str, int, str) -> None
|
|
||||||
with open(path.join(self.outdir, 'output.txt'), 'a', encoding='utf-8') as output:
|
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),
|
output.write("%s:%s: [%s] %s\n" % (self.env.doc2path(docname, None),
|
||||||
line, what, uri))
|
line, what, uri))
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
for worker in self.workers:
|
for worker in self.workers:
|
||||||
self.wqueue.put((None, None, None), False)
|
self.wqueue.put((None, None, None), False)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_builder(CheckExternalLinksBuilder)
|
app.add_builder(CheckExternalLinksBuilder)
|
||||||
|
|
||||||
app.add_config_value('linkcheck_ignore', [], None)
|
app.add_config_value('linkcheck_ignore', [], None)
|
||||||
|
@ -9,12 +9,15 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, List, Set, Tuple, Union
|
||||||
|
|
||||||
from docutils.frontend import OptionParser
|
from docutils.frontend import OptionParser
|
||||||
from docutils.io import FileOutput
|
from docutils.io import FileOutput
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
|
from sphinx.config import Config
|
||||||
from sphinx.errors import NoUri
|
from sphinx.errors import NoUri
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
@ -24,12 +27,6 @@ from sphinx.util.nodes import inline_all_toctrees
|
|||||||
from sphinx.util.osutil import make_filename_from_project
|
from sphinx.util.osutil import make_filename_from_project
|
||||||
from sphinx.writers.manpage import ManualPageWriter, ManualPageTranslator
|
from sphinx.writers.manpage import ManualPageWriter, ManualPageTranslator
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, List, Set, Tuple, Union # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.config import Config # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -45,25 +42,21 @@ class ManualPageBuilder(Builder):
|
|||||||
default_translator_class = ManualPageTranslator
|
default_translator_class = ManualPageTranslator
|
||||||
supported_image_types = [] # type: List[str]
|
supported_image_types = [] # type: List[str]
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
if not self.config.man_pages:
|
if not self.config.man_pages:
|
||||||
logger.warning(__('no "man_pages" config value found; no manual pages '
|
logger.warning(__('no "man_pages" config value found; no manual pages '
|
||||||
'will be written'))
|
'will be written'))
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> Union[str, List[str]]:
|
||||||
# type: () -> Union[str, List[str]]
|
|
||||||
return 'all manpages' # for now
|
return 'all manpages' # for now
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
if typ == 'token':
|
if typ == 'token':
|
||||||
return ''
|
return ''
|
||||||
raise NoUri
|
raise NoUri
|
||||||
|
|
||||||
@progress_message(__('writing'))
|
@progress_message(__('writing'))
|
||||||
def write(self, *ignored):
|
def write(self, *ignored) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
docwriter = ManualPageWriter(self)
|
docwriter = ManualPageWriter(self)
|
||||||
docsettings = OptionParser(
|
docsettings = OptionParser(
|
||||||
defaults=self.env.settings,
|
defaults=self.env.settings,
|
||||||
@ -106,21 +99,18 @@ class ManualPageBuilder(Builder):
|
|||||||
|
|
||||||
docwriter.write(largetree, destination)
|
docwriter.write(largetree, destination)
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def default_man_pages(config):
|
def default_man_pages(config: Config) -> List[Tuple[str, str, str, List[str], int]]:
|
||||||
# type: (Config) -> List[Tuple[str, str, str, List[str], int]]
|
|
||||||
""" Better default man_pages settings. """
|
""" Better default man_pages settings. """
|
||||||
filename = make_filename_from_project(config.project)
|
filename = make_filename_from_project(config.project)
|
||||||
return [(config.master_doc, filename, '%s %s' % (config.project, config.release),
|
return [(config.master_doc, filename, '%s %s' % (config.project, config.release),
|
||||||
[config.author], 1)]
|
[config.author], 1)]
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_builder(ManualPageBuilder)
|
app.add_builder(ManualPageBuilder)
|
||||||
|
|
||||||
app.add_config_value('man_pages', default_man_pages, None)
|
app.add_config_value('man_pages', default_man_pages, None)
|
||||||
|
@ -9,17 +9,14 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
from sphinxcontrib.qthelp import QtHelpBuilder, render_file
|
from sphinxcontrib.qthelp import QtHelpBuilder, render_file
|
||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
deprecated_alias('sphinx.builders.qthelp',
|
deprecated_alias('sphinx.builders.qthelp',
|
||||||
{
|
{
|
||||||
@ -29,8 +26,7 @@ deprecated_alias('sphinx.builders.qthelp',
|
|||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
warnings.warn('sphinx.builders.qthelp has been moved to sphinxcontrib-qthelp.',
|
warnings.warn('sphinx.builders.qthelp has been moved to sphinxcontrib-qthelp.',
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
@ -9,9 +9,12 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, List, Tuple, Union
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Node
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
from sphinx.environment.adapters.toctree import TocTree
|
from sphinx.environment.adapters.toctree import TocTree
|
||||||
@ -21,11 +24,6 @@ from sphinx.util import progress_message
|
|||||||
from sphinx.util.console import darkgreen # type: ignore
|
from sphinx.util.console import darkgreen # type: ignore
|
||||||
from sphinx.util.nodes import inline_all_toctrees
|
from sphinx.util.nodes import inline_all_toctrees
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, List, Tuple, Union # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -39,12 +37,10 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
copysource = False
|
copysource = False
|
||||||
|
|
||||||
def get_outdated_docs(self): # type: ignore
|
def get_outdated_docs(self) -> Union[str, List[str]]: # type: ignore
|
||||||
# type: () -> Union[str, List[str]]
|
|
||||||
return 'all documents'
|
return 'all documents'
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
if docname in self.env.all_docs:
|
if docname in self.env.all_docs:
|
||||||
# all references are on the same page...
|
# all references are on the same page...
|
||||||
return self.config.master_doc + self.out_suffix + \
|
return self.config.master_doc + self.out_suffix + \
|
||||||
@ -53,13 +49,11 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
# chances are this is a html_additional_page
|
# chances are this is a html_additional_page
|
||||||
return docname + self.out_suffix
|
return docname + self.out_suffix
|
||||||
|
|
||||||
def get_relative_uri(self, from_, to, typ=None):
|
def get_relative_uri(self, from_: str, to: str, typ: str = None) -> str:
|
||||||
# type: (str, str, str) -> str
|
|
||||||
# ignore source
|
# ignore source
|
||||||
return self.get_target_uri(to, typ)
|
return self.get_target_uri(to, typ)
|
||||||
|
|
||||||
def fix_refuris(self, tree):
|
def fix_refuris(self, tree: Node) -> None:
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
# fix refuris with double anchor
|
# fix refuris with double anchor
|
||||||
fname = self.config.master_doc + self.out_suffix
|
fname = self.config.master_doc + self.out_suffix
|
||||||
for refnode in tree.traverse(nodes.reference):
|
for refnode in tree.traverse(nodes.reference):
|
||||||
@ -73,8 +67,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
if hashindex >= 0:
|
if hashindex >= 0:
|
||||||
refnode['refuri'] = fname + refuri[hashindex:]
|
refnode['refuri'] = fname + refuri[hashindex:]
|
||||||
|
|
||||||
def _get_local_toctree(self, docname, collapse=True, **kwds):
|
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwds) -> str:
|
||||||
# type: (str, bool, Any) -> str
|
|
||||||
if 'includehidden' not in kwds:
|
if 'includehidden' not in kwds:
|
||||||
kwds['includehidden'] = False
|
kwds['includehidden'] = False
|
||||||
toctree = TocTree(self.env).get_toctree_for(docname, self, collapse, **kwds)
|
toctree = TocTree(self.env).get_toctree_for(docname, self, collapse, **kwds)
|
||||||
@ -82,8 +75,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
self.fix_refuris(toctree)
|
self.fix_refuris(toctree)
|
||||||
return self.render_partial(toctree)['fragment']
|
return self.render_partial(toctree)['fragment']
|
||||||
|
|
||||||
def assemble_doctree(self):
|
def assemble_doctree(self) -> nodes.document:
|
||||||
# type: () -> nodes.document
|
|
||||||
master = self.config.master_doc
|
master = self.config.master_doc
|
||||||
tree = self.env.get_doctree(master)
|
tree = self.env.get_doctree(master)
|
||||||
tree = inline_all_toctrees(self, set(), master, tree, darkgreen, [master])
|
tree = inline_all_toctrees(self, set(), master, tree, darkgreen, [master])
|
||||||
@ -92,8 +84,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
self.fix_refuris(tree)
|
self.fix_refuris(tree)
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
def assemble_toc_secnumbers(self):
|
def assemble_toc_secnumbers(self) -> Dict[str, Dict[str, Tuple[int, ...]]]:
|
||||||
# type: () -> Dict[str, Dict[str, Tuple[int, ...]]]
|
|
||||||
# Assemble toc_secnumbers to resolve section numbers on SingleHTML.
|
# Assemble toc_secnumbers to resolve section numbers on SingleHTML.
|
||||||
# Merge all secnumbers to single secnumber.
|
# Merge all secnumbers to single secnumber.
|
||||||
#
|
#
|
||||||
@ -111,8 +102,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
return {self.config.master_doc: new_secnumbers}
|
return {self.config.master_doc: new_secnumbers}
|
||||||
|
|
||||||
def assemble_toc_fignumbers(self):
|
def assemble_toc_fignumbers(self) -> Dict[str, Dict[str, Dict[str, Tuple[int, ...]]]]:
|
||||||
# type: () -> Dict[str, Dict[str, Dict[str, Tuple[int, ...]]]]
|
|
||||||
# Assemble toc_fignumbers to resolve figure numbers on SingleHTML.
|
# Assemble toc_fignumbers to resolve figure numbers on SingleHTML.
|
||||||
# Merge all fignumbers to single fignumber.
|
# Merge all fignumbers to single fignumber.
|
||||||
#
|
#
|
||||||
@ -133,8 +123,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
return {self.config.master_doc: new_fignumbers}
|
return {self.config.master_doc: new_fignumbers}
|
||||||
|
|
||||||
def get_doc_context(self, docname, body, metatags):
|
def get_doc_context(self, docname: str, body: str, metatags: str) -> Dict:
|
||||||
# type: (str, str, str) -> Dict
|
|
||||||
# no relation links...
|
# no relation links...
|
||||||
toctree = TocTree(self.env).get_toctree_for(self.config.master_doc, self, False)
|
toctree = TocTree(self.env).get_toctree_for(self.config.master_doc, self, False)
|
||||||
# if there is no toctree, toc is None
|
# if there is no toctree, toc is None
|
||||||
@ -160,8 +149,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
'display_toc': display_toc,
|
'display_toc': display_toc,
|
||||||
}
|
}
|
||||||
|
|
||||||
def write(self, *ignored):
|
def write(self, *ignored) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
docnames = self.env.all_docs
|
docnames = self.env.all_docs
|
||||||
|
|
||||||
with progress_message(__('preparing documents')):
|
with progress_message(__('preparing documents')):
|
||||||
@ -176,8 +164,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
self.write_doc_serialized(self.config.master_doc, doctree)
|
self.write_doc_serialized(self.config.master_doc, doctree)
|
||||||
self.write_doc(self.config.master_doc, doctree)
|
self.write_doc(self.config.master_doc, doctree)
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.write_additional_files()
|
self.write_additional_files()
|
||||||
self.copy_image_files()
|
self.copy_image_files()
|
||||||
self.copy_download_files()
|
self.copy_download_files()
|
||||||
@ -187,8 +174,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
self.dump_inventory()
|
self.dump_inventory()
|
||||||
|
|
||||||
@progress_message(__('writing additional files'))
|
@progress_message(__('writing additional files'))
|
||||||
def write_additional_files(self):
|
def write_additional_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
# no indices or search pages are supported
|
# no indices or search pages are supported
|
||||||
|
|
||||||
# additional pages from conf.py
|
# additional pages from conf.py
|
||||||
@ -210,8 +196,7 @@ deprecated_alias('sphinx.builders.html',
|
|||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.setup_extension('sphinx.builders.html')
|
app.setup_extension('sphinx.builders.html')
|
||||||
|
|
||||||
app.add_builder(SingleFileHTMLBuilder)
|
app.add_builder(SingleFileHTMLBuilder)
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, Iterable, List, Tuple, Union
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.frontend import OptionParser
|
from docutils.frontend import OptionParser
|
||||||
@ -17,7 +18,9 @@ from docutils.io import FileOutput
|
|||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx import package_dir
|
from sphinx import package_dir
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
|
from sphinx.config import Config
|
||||||
from sphinx.environment.adapters.asset import ImageAdapter
|
from sphinx.environment.adapters.asset import ImageAdapter
|
||||||
from sphinx.errors import NoUri
|
from sphinx.errors import NoUri
|
||||||
from sphinx.locale import _, __
|
from sphinx.locale import _, __
|
||||||
@ -30,12 +33,6 @@ from sphinx.util.nodes import inline_all_toctrees
|
|||||||
from sphinx.util.osutil import SEP, ensuredir, make_filename_from_project
|
from sphinx.util.osutil import SEP, ensuredir, make_filename_from_project
|
||||||
from sphinx.writers.texinfo import TexinfoWriter, TexinfoTranslator
|
from sphinx.writers.texinfo import TexinfoWriter, TexinfoTranslator
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.config import Config # NOQA
|
|
||||||
from typing import Any, Dict, Iterable, List, Tuple, Union # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
template_dir = os.path.join(package_dir, 'templates', 'texinfo')
|
template_dir = os.path.join(package_dir, 'templates', 'texinfo')
|
||||||
@ -57,29 +54,24 @@ class TexinfoBuilder(Builder):
|
|||||||
'image/gif']
|
'image/gif']
|
||||||
default_translator_class = TexinfoTranslator
|
default_translator_class = TexinfoTranslator
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.docnames = [] # type: Iterable[str]
|
self.docnames = [] # type: Iterable[str]
|
||||||
self.document_data = [] # type: List[Tuple[str, str, str, str, str, str, str, bool]]
|
self.document_data = [] # type: List[Tuple[str, str, str, str, str, str, str, bool]]
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> Union[str, List[str]]:
|
||||||
# type: () -> Union[str, List[str]]
|
|
||||||
return 'all documents' # for now
|
return 'all documents' # for now
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
if docname not in self.docnames:
|
if docname not in self.docnames:
|
||||||
raise NoUri
|
raise NoUri
|
||||||
else:
|
else:
|
||||||
return '%' + docname
|
return '%' + docname
|
||||||
|
|
||||||
def get_relative_uri(self, from_, to, typ=None):
|
def get_relative_uri(self, from_: str, to: str, typ: str = None) -> str:
|
||||||
# type: (str, str, str) -> str
|
|
||||||
# ignore source path
|
# ignore source path
|
||||||
return self.get_target_uri(to, typ)
|
return self.get_target_uri(to, typ)
|
||||||
|
|
||||||
def init_document_data(self):
|
def init_document_data(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
preliminary_document_data = [list(x) for x in self.config.texinfo_documents]
|
preliminary_document_data = [list(x) for x in self.config.texinfo_documents]
|
||||||
if not preliminary_document_data:
|
if not preliminary_document_data:
|
||||||
logger.warning(__('no "texinfo_documents" config value found; no documents '
|
logger.warning(__('no "texinfo_documents" config value found; no documents '
|
||||||
@ -98,8 +90,7 @@ class TexinfoBuilder(Builder):
|
|||||||
docname = docname[:-5]
|
docname = docname[:-5]
|
||||||
self.titles.append((docname, entry[2]))
|
self.titles.append((docname, entry[2]))
|
||||||
|
|
||||||
def write(self, *ignored):
|
def write(self, *ignored) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
self.init_document_data()
|
self.init_document_data()
|
||||||
for entry in self.document_data:
|
for entry in self.document_data:
|
||||||
docname, targetname, title, author = entry[:4]
|
docname, targetname, title, author = entry[:4]
|
||||||
@ -136,8 +127,7 @@ class TexinfoBuilder(Builder):
|
|||||||
docwriter.write(doctree, destination)
|
docwriter.write(doctree, destination)
|
||||||
self.copy_image_files(targetname[:-5])
|
self.copy_image_files(targetname[:-5])
|
||||||
|
|
||||||
def assemble_doctree(self, indexfile, toctree_only, appendices):
|
def assemble_doctree(self, indexfile: str, toctree_only: bool, appendices: List[str]) -> nodes.document: # NOQA
|
||||||
# type: (str, bool, List[str]) -> nodes.document
|
|
||||||
self.docnames = set([indexfile] + appendices)
|
self.docnames = set([indexfile] + appendices)
|
||||||
logger.info(darkgreen(indexfile) + " ", nonl=True)
|
logger.info(darkgreen(indexfile) + " ", nonl=True)
|
||||||
tree = self.env.get_doctree(indexfile)
|
tree = self.env.get_doctree(indexfile)
|
||||||
@ -179,12 +169,10 @@ class TexinfoBuilder(Builder):
|
|||||||
pendingnode.replace_self(newnodes)
|
pendingnode.replace_self(newnodes)
|
||||||
return largetree
|
return largetree
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.copy_support_files()
|
self.copy_support_files()
|
||||||
|
|
||||||
def copy_image_files(self, targetname):
|
def copy_image_files(self, targetname: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
if self.images:
|
if self.images:
|
||||||
stringify_func = ImageAdapter(self.app.env).get_original_image_uri
|
stringify_func = ImageAdapter(self.app.env).get_original_image_uri
|
||||||
for src in status_iterator(self.images, __('copying images... '), "brown",
|
for src in status_iterator(self.images, __('copying images... '), "brown",
|
||||||
@ -199,8 +187,7 @@ class TexinfoBuilder(Builder):
|
|||||||
logger.warning(__('cannot copy image file %r: %s'),
|
logger.warning(__('cannot copy image file %r: %s'),
|
||||||
path.join(self.srcdir, src), err)
|
path.join(self.srcdir, src), err)
|
||||||
|
|
||||||
def copy_support_files(self):
|
def copy_support_files(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
try:
|
try:
|
||||||
with progress_message(__('copying Texinfo support files')):
|
with progress_message(__('copying Texinfo support files')):
|
||||||
logger.info('Makefile ', nonl=True)
|
logger.info('Makefile ', nonl=True)
|
||||||
@ -209,16 +196,14 @@ class TexinfoBuilder(Builder):
|
|||||||
logger.warning(__("error writing file Makefile: %s"), err)
|
logger.warning(__("error writing file Makefile: %s"), err)
|
||||||
|
|
||||||
|
|
||||||
def default_texinfo_documents(config):
|
def default_texinfo_documents(config: Config) -> List[Tuple[str, str, str, str, str, str, str]]: # NOQA
|
||||||
# type: (Config) -> List[Tuple[str, str, str, str, str, str, str]]
|
|
||||||
""" Better default texinfo_documents settings. """
|
""" Better default texinfo_documents settings. """
|
||||||
filename = make_filename_from_project(config.project)
|
filename = make_filename_from_project(config.project)
|
||||||
return [(config.master_doc, filename, config.project, config.author, filename,
|
return [(config.master_doc, filename, config.project, config.author, filename,
|
||||||
'One line description of project', 'Miscellaneous')]
|
'One line description of project', 'Miscellaneous')]
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_builder(TexinfoBuilder)
|
app.add_builder(TexinfoBuilder)
|
||||||
|
|
||||||
app.add_config_value('texinfo_documents', default_texinfo_documents, None)
|
app.add_config_value('texinfo_documents', default_texinfo_documents, None)
|
||||||
|
@ -9,21 +9,18 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, Iterator, Set, Tuple
|
||||||
|
|
||||||
from docutils.io import StringOutput
|
from docutils.io import StringOutput
|
||||||
|
from docutils.nodes import Node
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util.osutil import ensuredir, os_path
|
from sphinx.util.osutil import ensuredir, os_path
|
||||||
from sphinx.writers.text import TextWriter, TextTranslator
|
from sphinx.writers.text import TextWriter, TextTranslator
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, Iterator, Set, Tuple # NOQA
|
|
||||||
from docutils import nodes # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -38,13 +35,11 @@ class TextBuilder(Builder):
|
|||||||
|
|
||||||
current_docname = None # type: str
|
current_docname = None # type: str
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
# section numbers for headings in the currently visited document
|
# section numbers for headings in the currently visited document
|
||||||
self.secnumbers = {} # type: Dict[str, Tuple[int, ...]]
|
self.secnumbers = {} # type: Dict[str, Tuple[int, ...]]
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> Iterator[str]:
|
||||||
# type: () -> Iterator[str]
|
|
||||||
for docname in self.env.found_docs:
|
for docname in self.env.found_docs:
|
||||||
if docname not in self.env.all_docs:
|
if docname not in self.env.all_docs:
|
||||||
yield docname
|
yield docname
|
||||||
@ -62,16 +57,13 @@ class TextBuilder(Builder):
|
|||||||
# source doesn't exist anymore
|
# source doesn't exist anymore
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
# type: (Set[str]) -> None
|
|
||||||
self.writer = TextWriter(self)
|
self.writer = TextWriter(self)
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname: str, doctree: Node) -> None:
|
||||||
# type: (str, nodes.Node) -> None
|
|
||||||
self.current_docname = docname
|
self.current_docname = docname
|
||||||
self.secnumbers = self.env.toc_secnumbers.get(docname, {})
|
self.secnumbers = self.env.toc_secnumbers.get(docname, {})
|
||||||
destination = StringOutput(encoding='utf-8')
|
destination = StringOutput(encoding='utf-8')
|
||||||
@ -84,13 +76,11 @@ class TextBuilder(Builder):
|
|||||||
except OSError as err:
|
except OSError as err:
|
||||||
logger.warning(__("error writing file %s: %s"), outfilename, err)
|
logger.warning(__("error writing file %s: %s"), outfilename, err)
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_builder(TextBuilder)
|
app.add_builder(TextBuilder)
|
||||||
|
|
||||||
app.add_config_value('text_sectionchars', '*=-~"+`', 'env')
|
app.add_config_value('text_sectionchars', '*=-~"+`', 'env')
|
||||||
|
@ -9,23 +9,20 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Dict, Iterator, Set, Type, Union
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.io import StringOutput
|
from docutils.io import StringOutput
|
||||||
|
from docutils.nodes import Node
|
||||||
from docutils.writers.docutils_xml import XMLTranslator
|
from docutils.writers.docutils_xml import XMLTranslator
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util.osutil import ensuredir, os_path
|
from sphinx.util.osutil import ensuredir, os_path
|
||||||
from sphinx.writers.xml import XMLWriter, PseudoXMLWriter
|
from sphinx.writers.xml import XMLWriter, PseudoXMLWriter
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, Iterator, Set, Type # NOQA
|
|
||||||
from docutils.writers.xml import BaseXMLWriter # NOQA
|
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -40,15 +37,13 @@ class XMLBuilder(Builder):
|
|||||||
out_suffix = '.xml'
|
out_suffix = '.xml'
|
||||||
allow_parallel = True
|
allow_parallel = True
|
||||||
|
|
||||||
_writer_class = XMLWriter # type: Type[BaseXMLWriter]
|
_writer_class = XMLWriter # type: Union[Type[XMLWriter], Type[PseudoXMLWriter]]
|
||||||
default_translator_class = XMLTranslator
|
default_translator_class = XMLTranslator
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self) -> Iterator[str]:
|
||||||
# type: () -> Iterator[str]
|
|
||||||
for docname in self.env.found_docs:
|
for docname in self.env.found_docs:
|
||||||
if docname not in self.env.all_docs:
|
if docname not in self.env.all_docs:
|
||||||
yield docname
|
yield docname
|
||||||
@ -66,16 +61,13 @@ class XMLBuilder(Builder):
|
|||||||
# source doesn't exist anymore
|
# source doesn't exist anymore
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
||||||
# type: (str, str) -> str
|
|
||||||
return docname
|
return docname
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
# type: (Set[str]) -> None
|
|
||||||
self.writer = self._writer_class(self)
|
self.writer = self._writer_class(self)
|
||||||
|
|
||||||
def write_doc(self, docname, doctree):
|
def write_doc(self, docname: str, doctree: Node) -> None:
|
||||||
# type: (str, nodes.Node) -> None
|
|
||||||
# work around multiple string % tuple issues in docutils;
|
# work around multiple string % tuple issues in docutils;
|
||||||
# replace tuples in attribute values with lists
|
# replace tuples in attribute values with lists
|
||||||
doctree = doctree.deepcopy()
|
doctree = doctree.deepcopy()
|
||||||
@ -98,8 +90,7 @@ class XMLBuilder(Builder):
|
|||||||
except OSError as err:
|
except OSError as err:
|
||||||
logger.warning(__("error writing file %s: %s"), outfilename, err)
|
logger.warning(__("error writing file %s: %s"), outfilename, err)
|
||||||
|
|
||||||
def finish(self):
|
def finish(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@ -116,8 +107,7 @@ class PseudoXMLBuilder(XMLBuilder):
|
|||||||
_writer_class = PseudoXMLWriter
|
_writer_class = PseudoXMLWriter
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_builder(XMLBuilder)
|
app.add_builder(XMLBuilder)
|
||||||
app.add_builder(PseudoXMLBuilder)
|
app.add_builder(PseudoXMLBuilder)
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ you can select a language here by its language code. Sphinx will then
|
|||||||
translate text that it generates into that language.
|
translate text that it generates into that language.
|
||||||
|
|
||||||
For a list of supported codes, see
|
For a list of supported codes, see
|
||||||
http://sphinx-doc.org/config.html#confval-language.'''))
|
https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language.'''))
|
||||||
d['language'] = do_prompt(__('Project language'), 'en')
|
d['language'] = do_prompt(__('Project language'), 'en')
|
||||||
if d['language'] == 'en':
|
if d['language'] == 'en':
|
||||||
d['language'] = None
|
d['language'] = None
|
||||||
|
@ -9,23 +9,24 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from typing import List, cast
|
from typing import Any, Dict, List, Tuple
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Node
|
||||||
from docutils.parsers.rst import directives, roles
|
from docutils.parsers.rst import directives, roles
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx.addnodes import desc_signature
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
from sphinx.util import docutils
|
from sphinx.util import docutils
|
||||||
from sphinx.util.docfields import DocFieldTransformer, TypedField
|
from sphinx.util.docfields import DocFieldTransformer, Field, TypedField
|
||||||
from sphinx.util.docutils import SphinxDirective
|
from sphinx.util.docutils import SphinxDirective
|
||||||
|
from sphinx.util.typing import DirectiveOption
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, Tuple # NOQA
|
from sphinx.application import Sphinx
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.util.docfields import Field # NOQA
|
|
||||||
from sphinx.util.typing import DirectiveOption # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
# RE to strip backslash escapes
|
# RE to strip backslash escapes
|
||||||
@ -70,8 +71,7 @@ class ObjectDescription(SphinxDirective):
|
|||||||
# Warning: this might be removed in future version. Don't touch this from extensions.
|
# Warning: this might be removed in future version. Don't touch this from extensions.
|
||||||
_doc_field_type_map = {} # type: Dict[str, Tuple[Field, bool]]
|
_doc_field_type_map = {} # type: Dict[str, Tuple[Field, bool]]
|
||||||
|
|
||||||
def get_field_type_map(self):
|
def get_field_type_map(self) -> Dict[str, Tuple[Field, bool]]:
|
||||||
# type: () -> Dict[str, Tuple[Field, bool]]
|
|
||||||
if self._doc_field_type_map == {}:
|
if self._doc_field_type_map == {}:
|
||||||
for field in self.doc_field_types:
|
for field in self.doc_field_types:
|
||||||
for name in field.names:
|
for name in field.names:
|
||||||
@ -84,8 +84,7 @@ class ObjectDescription(SphinxDirective):
|
|||||||
|
|
||||||
return self._doc_field_type_map
|
return self._doc_field_type_map
|
||||||
|
|
||||||
def get_signatures(self):
|
def get_signatures(self) -> List[str]:
|
||||||
# type: () -> List[str]
|
|
||||||
"""
|
"""
|
||||||
Retrieve the signatures to document from the directive arguments. By
|
Retrieve the signatures to document from the directive arguments. By
|
||||||
default, signatures are given as arguments, one per line.
|
default, signatures are given as arguments, one per line.
|
||||||
@ -96,8 +95,7 @@ class ObjectDescription(SphinxDirective):
|
|||||||
# remove backslashes to support (dummy) escapes; helps Vim highlighting
|
# remove backslashes to support (dummy) escapes; helps Vim highlighting
|
||||||
return [strip_backslash_re.sub(r'\1', line.strip()) for line in lines]
|
return [strip_backslash_re.sub(r'\1', line.strip()) for line in lines]
|
||||||
|
|
||||||
def handle_signature(self, sig, signode):
|
def handle_signature(self, sig: str, signode: desc_signature) -> Any:
|
||||||
# type: (str, addnodes.desc_signature) -> Any
|
|
||||||
"""
|
"""
|
||||||
Parse the signature *sig* into individual nodes and append them to
|
Parse the signature *sig* into individual nodes and append them to
|
||||||
*signode*. If ValueError is raised, parsing is aborted and the whole
|
*signode*. If ValueError is raised, parsing is aborted and the whole
|
||||||
@ -109,8 +107,7 @@ class ObjectDescription(SphinxDirective):
|
|||||||
"""
|
"""
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
def add_target_and_index(self, name, sig, signode):
|
def add_target_and_index(self, name: Any, sig: str, signode: desc_signature) -> None:
|
||||||
# type: (Any, str, addnodes.desc_signature) -> None
|
|
||||||
"""
|
"""
|
||||||
Add cross-reference IDs and entries to self.indexnode, if applicable.
|
Add cross-reference IDs and entries to self.indexnode, if applicable.
|
||||||
|
|
||||||
@ -118,24 +115,21 @@ class ObjectDescription(SphinxDirective):
|
|||||||
"""
|
"""
|
||||||
return # do nothing by default
|
return # do nothing by default
|
||||||
|
|
||||||
def before_content(self):
|
def before_content(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""
|
"""
|
||||||
Called before parsing content. Used to set information about the current
|
Called before parsing content. Used to set information about the current
|
||||||
directive context on the build environment.
|
directive context on the build environment.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def after_content(self):
|
def after_content(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""
|
"""
|
||||||
Called after parsing content. Used to reset information about the
|
Called after parsing content. Used to reset information about the
|
||||||
current directive context on the build environment.
|
current directive context on the build environment.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
"""
|
"""
|
||||||
Main directive entry function, called by docutils upon encountering the
|
Main directive entry function, called by docutils upon encountering the
|
||||||
directive.
|
directive.
|
||||||
@ -212,8 +206,7 @@ class DefaultRole(SphinxDirective):
|
|||||||
optional_arguments = 1
|
optional_arguments = 1
|
||||||
final_argument_whitespace = False
|
final_argument_whitespace = False
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
if not self.arguments:
|
if not self.arguments:
|
||||||
docutils.unregister_role('')
|
docutils.unregister_role('')
|
||||||
return []
|
return []
|
||||||
@ -244,8 +237,7 @@ class DefaultDomain(SphinxDirective):
|
|||||||
final_argument_whitespace = False
|
final_argument_whitespace = False
|
||||||
option_spec = {} # type: Dict
|
option_spec = {} # type: Dict
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
domain_name = self.arguments[0].lower()
|
domain_name = self.arguments[0].lower()
|
||||||
# if domain_name not in env.domains:
|
# if domain_name not in env.domains:
|
||||||
# # try searching by label
|
# # try searching by label
|
||||||
@ -294,8 +286,7 @@ deprecated_alias('sphinx.directives',
|
|||||||
DescDirective = ObjectDescription
|
DescDirective = ObjectDescription
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
directives.register_directive('default-role', DefaultRole)
|
directives.register_directive('default-role', DefaultRole)
|
||||||
directives.register_directive('default-domain', DefaultDomain)
|
directives.register_directive('default-domain', DefaultDomain)
|
||||||
directives.register_directive('describe', ObjectDescription)
|
directives.register_directive('describe', ObjectDescription)
|
||||||
|
@ -9,12 +9,15 @@
|
|||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from difflib import unified_diff
|
from difflib import unified_diff
|
||||||
|
from typing import Any, Dict, List, Tuple
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Element, Node
|
||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
from docutils.statemachine import StringList
|
from docutils.statemachine import StringList
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx.config import Config
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
@ -23,9 +26,7 @@ from sphinx.util.docutils import SphinxDirective
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, List, Tuple # NOQA
|
from sphinx.application import Sphinx
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.config import Config # NOQA
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -45,8 +46,7 @@ class Highlight(SphinxDirective):
|
|||||||
'linenothreshold': directives.positive_int,
|
'linenothreshold': directives.positive_int,
|
||||||
}
|
}
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
language = self.arguments[0].strip()
|
language = self.arguments[0].strip()
|
||||||
linenothreshold = self.options.get('linenothreshold', sys.maxsize)
|
linenothreshold = self.options.get('linenothreshold', sys.maxsize)
|
||||||
force = 'force' in self.options
|
force = 'force' in self.options
|
||||||
@ -60,16 +60,14 @@ class Highlight(SphinxDirective):
|
|||||||
class HighlightLang(Highlight):
|
class HighlightLang(Highlight):
|
||||||
"""highlightlang directive (deprecated)"""
|
"""highlightlang directive (deprecated)"""
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
warnings.warn('highlightlang directive is deprecated. '
|
warnings.warn('highlightlang directive is deprecated. '
|
||||||
'Please use highlight directive instead.',
|
'Please use highlight directive instead.',
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
return super().run()
|
return super().run()
|
||||||
|
|
||||||
|
|
||||||
def dedent_lines(lines, dedent, location=None):
|
def dedent_lines(lines: List[str], dedent: int, location: Tuple[str, int] = None) -> List[str]:
|
||||||
# type: (List[str], int, Tuple[str, int]) -> List[str]
|
|
||||||
if not dedent:
|
if not dedent:
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
@ -86,8 +84,7 @@ def dedent_lines(lines, dedent, location=None):
|
|||||||
return new_lines
|
return new_lines
|
||||||
|
|
||||||
|
|
||||||
def container_wrapper(directive, literal_node, caption):
|
def container_wrapper(directive: SphinxDirective, literal_node: Node, caption: str) -> nodes.container: # NOQA
|
||||||
# type: (SphinxDirective, nodes.Node, str) -> nodes.container
|
|
||||||
container_node = nodes.container('', literal_block=True,
|
container_node = nodes.container('', literal_block=True,
|
||||||
classes=['literal-block-wrapper'])
|
classes=['literal-block-wrapper'])
|
||||||
parsed = nodes.Element()
|
parsed = nodes.Element()
|
||||||
@ -129,8 +126,7 @@ class CodeBlock(SphinxDirective):
|
|||||||
'name': directives.unchanged,
|
'name': directives.unchanged,
|
||||||
}
|
}
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
document = self.state.document
|
document = self.state.document
|
||||||
code = '\n'.join(self.content)
|
code = '\n'.join(self.content)
|
||||||
location = self.state_machine.get_source_and_line(self.lineno)
|
location = self.state_machine.get_source_and_line(self.lineno)
|
||||||
@ -157,7 +153,7 @@ class CodeBlock(SphinxDirective):
|
|||||||
lines = dedent_lines(lines, self.options['dedent'], location=location)
|
lines = dedent_lines(lines, self.options['dedent'], location=location)
|
||||||
code = '\n'.join(lines)
|
code = '\n'.join(lines)
|
||||||
|
|
||||||
literal = nodes.literal_block(code, code) # type: nodes.Element
|
literal = nodes.literal_block(code, code) # type: Element
|
||||||
if 'linenos' in self.options or 'lineno-start' in self.options:
|
if 'linenos' in self.options or 'lineno-start' in self.options:
|
||||||
literal['linenos'] = True
|
literal['linenos'] = True
|
||||||
literal['classes'] += self.options.get('class', [])
|
literal['classes'] += self.options.get('class', [])
|
||||||
@ -209,8 +205,7 @@ class LiteralIncludeReader:
|
|||||||
('diff', 'end-at'),
|
('diff', 'end-at'),
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, filename, options, config):
|
def __init__(self, filename: str, options: Dict, config: Config) -> None:
|
||||||
# type: (str, Dict, Config) -> None
|
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.options = options
|
self.options = options
|
||||||
self.encoding = options.get('encoding', config.source_encoding)
|
self.encoding = options.get('encoding', config.source_encoding)
|
||||||
@ -218,15 +213,13 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
self.parse_options()
|
self.parse_options()
|
||||||
|
|
||||||
def parse_options(self):
|
def parse_options(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
for option1, option2 in self.INVALID_OPTIONS_PAIR:
|
for option1, option2 in self.INVALID_OPTIONS_PAIR:
|
||||||
if option1 in self.options and option2 in self.options:
|
if option1 in self.options and option2 in self.options:
|
||||||
raise ValueError(__('Cannot use both "%s" and "%s" options') %
|
raise ValueError(__('Cannot use both "%s" and "%s" options') %
|
||||||
(option1, option2))
|
(option1, option2))
|
||||||
|
|
||||||
def read_file(self, filename, location=None):
|
def read_file(self, filename: str, location: Tuple[str, int] = None) -> List[str]:
|
||||||
# type: (str, Tuple[str, int]) -> List[str]
|
|
||||||
try:
|
try:
|
||||||
with open(filename, encoding=self.encoding, errors='strict') as f:
|
with open(filename, encoding=self.encoding, errors='strict') as f:
|
||||||
text = f.read()
|
text = f.read()
|
||||||
@ -241,8 +234,7 @@ class LiteralIncludeReader:
|
|||||||
'be wrong, try giving an :encoding: option') %
|
'be wrong, try giving an :encoding: option') %
|
||||||
(self.encoding, filename))
|
(self.encoding, filename))
|
||||||
|
|
||||||
def read(self, location=None):
|
def read(self, location: Tuple[str, int] = None) -> Tuple[str, int]:
|
||||||
# type: (Tuple[str, int]) -> Tuple[str, int]
|
|
||||||
if 'diff' in self.options:
|
if 'diff' in self.options:
|
||||||
lines = self.show_diff()
|
lines = self.show_diff()
|
||||||
else:
|
else:
|
||||||
@ -259,16 +251,14 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
return ''.join(lines), len(lines)
|
return ''.join(lines), len(lines)
|
||||||
|
|
||||||
def show_diff(self, location=None):
|
def show_diff(self, location: Tuple[str, int] = None) -> List[str]:
|
||||||
# type: (Tuple[str, int]) -> List[str]
|
|
||||||
new_lines = self.read_file(self.filename)
|
new_lines = self.read_file(self.filename)
|
||||||
old_filename = self.options.get('diff')
|
old_filename = self.options.get('diff')
|
||||||
old_lines = self.read_file(old_filename)
|
old_lines = self.read_file(old_filename)
|
||||||
diff = unified_diff(old_lines, new_lines, old_filename, self.filename)
|
diff = unified_diff(old_lines, new_lines, old_filename, self.filename)
|
||||||
return list(diff)
|
return list(diff)
|
||||||
|
|
||||||
def pyobject_filter(self, lines, location=None):
|
def pyobject_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
||||||
# type: (List[str], Tuple[str, int]) -> List[str]
|
|
||||||
pyobject = self.options.get('pyobject')
|
pyobject = self.options.get('pyobject')
|
||||||
if pyobject:
|
if pyobject:
|
||||||
from sphinx.pycode import ModuleAnalyzer
|
from sphinx.pycode import ModuleAnalyzer
|
||||||
@ -286,8 +276,7 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def lines_filter(self, lines, location=None):
|
def lines_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
||||||
# type: (List[str], Tuple[str, int]) -> List[str]
|
|
||||||
linespec = self.options.get('lines')
|
linespec = self.options.get('lines')
|
||||||
if linespec:
|
if linespec:
|
||||||
linelist = parselinenos(linespec, len(lines))
|
linelist = parselinenos(linespec, len(lines))
|
||||||
@ -311,8 +300,7 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def start_filter(self, lines, location=None):
|
def start_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
||||||
# type: (List[str], Tuple[str, int]) -> List[str]
|
|
||||||
if 'start-at' in self.options:
|
if 'start-at' in self.options:
|
||||||
start = self.options.get('start-at')
|
start = self.options.get('start-at')
|
||||||
inclusive = False
|
inclusive = False
|
||||||
@ -343,8 +331,7 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def end_filter(self, lines, location=None):
|
def end_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
||||||
# type: (List[str], Tuple[str, int]) -> List[str]
|
|
||||||
if 'end-at' in self.options:
|
if 'end-at' in self.options:
|
||||||
end = self.options.get('end-at')
|
end = self.options.get('end-at')
|
||||||
inclusive = True
|
inclusive = True
|
||||||
@ -371,24 +358,21 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def prepend_filter(self, lines, location=None):
|
def prepend_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
||||||
# type: (List[str], Tuple[str, int]) -> List[str]
|
|
||||||
prepend = self.options.get('prepend')
|
prepend = self.options.get('prepend')
|
||||||
if prepend:
|
if prepend:
|
||||||
lines.insert(0, prepend + '\n')
|
lines.insert(0, prepend + '\n')
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def append_filter(self, lines, location=None):
|
def append_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
||||||
# type: (List[str], Tuple[str, int]) -> List[str]
|
|
||||||
append = self.options.get('append')
|
append = self.options.get('append')
|
||||||
if append:
|
if append:
|
||||||
lines.append(append + '\n')
|
lines.append(append + '\n')
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def dedent_filter(self, lines, location=None):
|
def dedent_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
||||||
# type: (List[str], Tuple[str, int]) -> List[str]
|
|
||||||
if 'dedent' in self.options:
|
if 'dedent' in self.options:
|
||||||
return dedent_lines(lines, self.options.get('dedent'), location=location)
|
return dedent_lines(lines, self.options.get('dedent'), location=location)
|
||||||
else:
|
else:
|
||||||
@ -430,8 +414,7 @@ class LiteralInclude(SphinxDirective):
|
|||||||
'diff': directives.unchanged_required,
|
'diff': directives.unchanged_required,
|
||||||
}
|
}
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
document = self.state.document
|
document = self.state.document
|
||||||
if not document.settings.file_insertion_enabled:
|
if not document.settings.file_insertion_enabled:
|
||||||
return [document.reporter.warning('File insertion disabled',
|
return [document.reporter.warning('File insertion disabled',
|
||||||
@ -449,7 +432,7 @@ class LiteralInclude(SphinxDirective):
|
|||||||
reader = LiteralIncludeReader(filename, self.options, self.config)
|
reader = LiteralIncludeReader(filename, self.options, self.config)
|
||||||
text, lines = reader.read(location=location)
|
text, lines = reader.read(location=location)
|
||||||
|
|
||||||
retnode = nodes.literal_block(text, text, source=filename) # type: nodes.Element
|
retnode = nodes.literal_block(text, text, source=filename) # type: Element
|
||||||
retnode['force'] = 'force' in self.options
|
retnode['force'] = 'force' in self.options
|
||||||
self.set_source_info(retnode)
|
self.set_source_info(retnode)
|
||||||
if self.options.get('diff'): # if diff is set, set udiff
|
if self.options.get('diff'): # if diff is set, set udiff
|
||||||
@ -483,8 +466,7 @@ class LiteralInclude(SphinxDirective):
|
|||||||
return [document.reporter.warning(exc, line=self.lineno)]
|
return [document.reporter.warning(exc, line=self.lineno)]
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
directives.register_directive('highlight', Highlight)
|
directives.register_directive('highlight', Highlight)
|
||||||
directives.register_directive('highlightlang', HighlightLang)
|
directives.register_directive('highlightlang', HighlightLang)
|
||||||
directives.register_directive('code-block', CodeBlock)
|
directives.register_directive('code-block', CodeBlock)
|
||||||
|
@ -7,9 +7,11 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
from typing import Any, Dict, List
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Element, Node
|
||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
from docutils.parsers.rst.directives.admonitions import BaseAdmonition
|
from docutils.parsers.rst.directives.admonitions import BaseAdmonition
|
||||||
from docutils.parsers.rst.directives.misc import Class
|
from docutils.parsers.rst.directives.misc import Class
|
||||||
@ -25,15 +27,13 @@ from sphinx.util.nodes import explicit_title_re, process_index_entry
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, List # NOQA
|
from sphinx.application import Sphinx
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
glob_re = re.compile(r'.*[*?\[].*')
|
glob_re = re.compile(r'.*[*?\[].*')
|
||||||
|
|
||||||
|
|
||||||
def int_or_nothing(argument):
|
def int_or_nothing(argument: str) -> int:
|
||||||
# type: (str) -> int
|
|
||||||
if not argument:
|
if not argument:
|
||||||
return 999
|
return 999
|
||||||
return int(argument)
|
return int(argument)
|
||||||
@ -60,8 +60,7 @@ class TocTree(SphinxDirective):
|
|||||||
'reversed': directives.flag,
|
'reversed': directives.flag,
|
||||||
}
|
}
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
subnode = addnodes.toctree()
|
subnode = addnodes.toctree()
|
||||||
subnode['parent'] = self.env.docname
|
subnode['parent'] = self.env.docname
|
||||||
|
|
||||||
@ -160,11 +159,10 @@ class Author(SphinxDirective):
|
|||||||
final_argument_whitespace = True
|
final_argument_whitespace = True
|
||||||
option_spec = {} # type: Dict
|
option_spec = {} # type: Dict
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
if not self.config.show_authors:
|
if not self.config.show_authors:
|
||||||
return []
|
return []
|
||||||
para = nodes.paragraph(translatable=False) # type: nodes.Element
|
para = nodes.paragraph(translatable=False) # type: Element
|
||||||
emph = nodes.emphasis()
|
emph = nodes.emphasis()
|
||||||
para += emph
|
para += emph
|
||||||
if self.name == 'sectionauthor':
|
if self.name == 'sectionauthor':
|
||||||
@ -179,7 +177,7 @@ class Author(SphinxDirective):
|
|||||||
inodes, messages = self.state.inline_text(self.arguments[0], self.lineno)
|
inodes, messages = self.state.inline_text(self.arguments[0], self.lineno)
|
||||||
emph.extend(inodes)
|
emph.extend(inodes)
|
||||||
|
|
||||||
ret = [para] # type: List[nodes.Node]
|
ret = [para] # type: List[Node]
|
||||||
ret += messages
|
ret += messages
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -194,8 +192,7 @@ class Index(SphinxDirective):
|
|||||||
final_argument_whitespace = True
|
final_argument_whitespace = True
|
||||||
option_spec = {} # type: Dict
|
option_spec = {} # type: Dict
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
arguments = self.arguments[0].split('\n')
|
arguments = self.arguments[0].split('\n')
|
||||||
targetid = 'index-%s' % self.env.new_serialno('index')
|
targetid = 'index-%s' % self.env.new_serialno('index')
|
||||||
targetnode = nodes.target('', '', ids=[targetid])
|
targetnode = nodes.target('', '', ids=[targetid])
|
||||||
@ -226,8 +223,7 @@ class TabularColumns(SphinxDirective):
|
|||||||
final_argument_whitespace = True
|
final_argument_whitespace = True
|
||||||
option_spec = {} # type: Dict
|
option_spec = {} # type: Dict
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
node = addnodes.tabular_col_spec()
|
node = addnodes.tabular_col_spec()
|
||||||
node['spec'] = self.arguments[0]
|
node['spec'] = self.arguments[0]
|
||||||
self.set_source_info(node)
|
self.set_source_info(node)
|
||||||
@ -244,15 +240,14 @@ class Centered(SphinxDirective):
|
|||||||
final_argument_whitespace = True
|
final_argument_whitespace = True
|
||||||
option_spec = {} # type: Dict
|
option_spec = {} # type: Dict
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
if not self.arguments:
|
if not self.arguments:
|
||||||
return []
|
return []
|
||||||
subnode = addnodes.centered() # type: nodes.Element
|
subnode = addnodes.centered() # type: Element
|
||||||
inodes, messages = self.state.inline_text(self.arguments[0], self.lineno)
|
inodes, messages = self.state.inline_text(self.arguments[0], self.lineno)
|
||||||
subnode.extend(inodes)
|
subnode.extend(inodes)
|
||||||
|
|
||||||
ret = [subnode] # type: List[nodes.Node]
|
ret = [subnode] # type: List[Node]
|
||||||
ret += messages
|
ret += messages
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -267,8 +262,7 @@ class Acks(SphinxDirective):
|
|||||||
final_argument_whitespace = False
|
final_argument_whitespace = False
|
||||||
option_spec = {} # type: Dict
|
option_spec = {} # type: Dict
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
node = addnodes.acks()
|
node = addnodes.acks()
|
||||||
node.document = self.state.document
|
node.document = self.state.document
|
||||||
self.state.nested_parse(self.content, self.content_offset, node)
|
self.state.nested_parse(self.content, self.content_offset, node)
|
||||||
@ -291,8 +285,7 @@ class HList(SphinxDirective):
|
|||||||
'columns': int,
|
'columns': int,
|
||||||
}
|
}
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
ncolumns = self.options.get('columns', 2)
|
ncolumns = self.options.get('columns', 2)
|
||||||
node = nodes.paragraph()
|
node = nodes.paragraph()
|
||||||
node.document = self.state.document
|
node.document = self.state.document
|
||||||
@ -325,8 +318,7 @@ class Only(SphinxDirective):
|
|||||||
final_argument_whitespace = True
|
final_argument_whitespace = True
|
||||||
option_spec = {} # type: Dict
|
option_spec = {} # type: Dict
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
node = addnodes.only()
|
node = addnodes.only()
|
||||||
node.document = self.state.document
|
node.document = self.state.document
|
||||||
self.set_source_info(node)
|
self.set_source_info(node)
|
||||||
@ -380,8 +372,7 @@ class Include(BaseInclude, SphinxDirective):
|
|||||||
"correctly", i.e. relative to source directory.
|
"correctly", i.e. relative to source directory.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
if self.arguments[0].startswith('<') and \
|
if self.arguments[0].startswith('<') and \
|
||||||
self.arguments[0].endswith('>'):
|
self.arguments[0].endswith('>'):
|
||||||
# docutils "standard" includes, do not do path processing
|
# docutils "standard" includes, do not do path processing
|
||||||
@ -392,8 +383,7 @@ class Include(BaseInclude, SphinxDirective):
|
|||||||
return super().run()
|
return super().run()
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
directives.register_directive('toctree', TocTree)
|
directives.register_directive('toctree', TocTree)
|
||||||
directives.register_directive('sectionauthor', Author)
|
directives.register_directive('sectionauthor', Author)
|
||||||
directives.register_directive('moduleauthor', Author)
|
directives.register_directive('moduleauthor', Author)
|
||||||
|
@ -6,10 +6,11 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from typing import Any, Dict, List, Tuple
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import make_id
|
from docutils.nodes import Node, make_id, system_message
|
||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
from docutils.parsers.rst.directives import images, html, tables
|
from docutils.parsers.rst.directives import images, html, tables
|
||||||
|
|
||||||
@ -20,8 +21,7 @@ from sphinx.util.nodes import set_source_info
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Dict, List, Tuple # NOQA
|
from sphinx.application import Sphinx
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
class Figure(images.Figure):
|
class Figure(images.Figure):
|
||||||
@ -29,8 +29,7 @@ class Figure(images.Figure):
|
|||||||
instead of the image node.
|
instead of the image node.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
name = self.options.pop('name', None)
|
name = self.options.pop('name', None)
|
||||||
result = super().run()
|
result = super().run()
|
||||||
if len(result) == 2 or isinstance(result[0], nodes.system_message):
|
if len(result) == 2 or isinstance(result[0], nodes.system_message):
|
||||||
@ -52,8 +51,7 @@ class Figure(images.Figure):
|
|||||||
|
|
||||||
|
|
||||||
class Meta(html.Meta, SphinxDirective):
|
class Meta(html.Meta, SphinxDirective):
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
result = super().run()
|
result = super().run()
|
||||||
for node in result:
|
for node in result:
|
||||||
if (isinstance(node, nodes.pending) and
|
if (isinstance(node, nodes.pending) and
|
||||||
@ -74,8 +72,7 @@ class RSTTable(tables.RSTTable):
|
|||||||
|
|
||||||
Only for docutils-0.13 or older version."""
|
Only for docutils-0.13 or older version."""
|
||||||
|
|
||||||
def make_title(self):
|
def make_title(self) -> Tuple[nodes.title, List[system_message]]:
|
||||||
# type: () -> Tuple[nodes.title, List[nodes.system_message]]
|
|
||||||
title, message = super().make_title()
|
title, message = super().make_title()
|
||||||
if title:
|
if title:
|
||||||
set_source_info(self, title)
|
set_source_info(self, title)
|
||||||
@ -88,8 +85,7 @@ class CSVTable(tables.CSVTable):
|
|||||||
|
|
||||||
Only for docutils-0.13 or older version."""
|
Only for docutils-0.13 or older version."""
|
||||||
|
|
||||||
def make_title(self):
|
def make_title(self) -> Tuple[nodes.title, List[system_message]]:
|
||||||
# type: () -> Tuple[nodes.title, List[nodes.system_message]]
|
|
||||||
title, message = super().make_title()
|
title, message = super().make_title()
|
||||||
if title:
|
if title:
|
||||||
set_source_info(self, title)
|
set_source_info(self, title)
|
||||||
@ -102,8 +98,7 @@ class ListTable(tables.ListTable):
|
|||||||
|
|
||||||
Only for docutils-0.13 or older version."""
|
Only for docutils-0.13 or older version."""
|
||||||
|
|
||||||
def make_title(self):
|
def make_title(self) -> Tuple[nodes.title, List[system_message]]:
|
||||||
# type: () -> Tuple[nodes.title, List[nodes.system_message]]
|
|
||||||
title, message = super().make_title()
|
title, message = super().make_title()
|
||||||
if title:
|
if title:
|
||||||
set_source_info(self, title)
|
set_source_info(self, title)
|
||||||
@ -125,8 +120,7 @@ class Code(SphinxDirective):
|
|||||||
}
|
}
|
||||||
has_content = True
|
has_content = True
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
self.assert_has_content()
|
self.assert_has_content()
|
||||||
|
|
||||||
code = '\n'.join(self.content)
|
code = '\n'.join(self.content)
|
||||||
@ -169,8 +163,7 @@ class MathDirective(SphinxDirective):
|
|||||||
'nowrap': directives.flag,
|
'nowrap': directives.flag,
|
||||||
}
|
}
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> List[Node]:
|
||||||
# type: () -> List[nodes.Node]
|
|
||||||
latex = '\n'.join(self.content)
|
latex = '\n'.join(self.content)
|
||||||
if self.arguments and self.arguments[0]:
|
if self.arguments and self.arguments[0]:
|
||||||
latex = self.arguments[0] + '\n\n' + latex
|
latex = self.arguments[0] + '\n\n' + latex
|
||||||
@ -184,12 +177,11 @@ class MathDirective(SphinxDirective):
|
|||||||
self.add_name(node)
|
self.add_name(node)
|
||||||
self.set_source_info(node)
|
self.set_source_info(node)
|
||||||
|
|
||||||
ret = [node] # type: List[nodes.Node]
|
ret = [node] # type: List[Node]
|
||||||
self.add_target(ret)
|
self.add_target(ret)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def add_target(self, ret):
|
def add_target(self, ret: List[Node]) -> None:
|
||||||
# type: (List[nodes.Node]) -> None
|
|
||||||
node = cast(nodes.math_block, ret[0])
|
node = cast(nodes.math_block, ret[0])
|
||||||
|
|
||||||
# assign label automatically if math_number_all enabled
|
# assign label automatically if math_number_all enabled
|
||||||
@ -216,8 +208,7 @@ class MathDirective(SphinxDirective):
|
|||||||
self.state_machine.reporter.warning(exc, line=self.lineno)
|
self.state_machine.reporter.warning(exc, line=self.lineno)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict
|
|
||||||
directives.register_directive('figure', Figure)
|
directives.register_directive('figure', Figure)
|
||||||
directives.register_directive('meta', Meta)
|
directives.register_directive('meta', Meta)
|
||||||
directives.register_directive('table', RSTTable)
|
directives.register_directive('table', RSTTable)
|
||||||
|
@ -337,7 +337,8 @@ class PyObject(ObjectDescription):
|
|||||||
self.state.document.note_explicit_target(signode)
|
self.state.document.note_explicit_target(signode)
|
||||||
|
|
||||||
domain = cast(PythonDomain, self.env.get_domain('py'))
|
domain = cast(PythonDomain, self.env.get_domain('py'))
|
||||||
domain.note_object(fullname, self.objtype)
|
domain.note_object(fullname, self.objtype,
|
||||||
|
location=(self.env.docname, self.lineno))
|
||||||
|
|
||||||
indextext = self.get_index_text(modname, name_cls)
|
indextext = self.get_index_text(modname, name_cls)
|
||||||
if indextext:
|
if indextext:
|
||||||
@ -752,7 +753,7 @@ class PyModule(SphinxDirective):
|
|||||||
self.options.get('synopsis', ''),
|
self.options.get('synopsis', ''),
|
||||||
self.options.get('platform', ''),
|
self.options.get('platform', ''),
|
||||||
'deprecated' in self.options)
|
'deprecated' in self.options)
|
||||||
domain.note_object(modname, 'module')
|
domain.note_object(modname, 'module', location=(self.env.docname, self.lineno))
|
||||||
|
|
||||||
targetnode = nodes.target('', '', ids=['module-' + modname],
|
targetnode = nodes.target('', '', ids=['module-' + modname],
|
||||||
ismod=True)
|
ismod=True)
|
||||||
|
@ -137,7 +137,7 @@ class DownloadFileCollector(EnvironmentCollector):
|
|||||||
logger.warning(__('download file not readable: %s') % filename,
|
logger.warning(__('download file not readable: %s') % filename,
|
||||||
location=node, type='download', subtype='not_readable')
|
location=node, type='download', subtype='not_readable')
|
||||||
continue
|
continue
|
||||||
node['filename'] = app.env.dlfiles.add_file(app.env.docname, filename)
|
node['filename'] = app.env.dlfiles.add_file(app.env.docname, rel_filename)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
|
@ -549,10 +549,8 @@ class Documenter:
|
|||||||
|
|
||||||
if self.analyzer:
|
if self.analyzer:
|
||||||
attr_docs = self.analyzer.find_attr_docs()
|
attr_docs = self.analyzer.find_attr_docs()
|
||||||
tagorder = self.analyzer.tagorder
|
|
||||||
else:
|
else:
|
||||||
attr_docs = {}
|
attr_docs = {}
|
||||||
tagorder = {}
|
|
||||||
|
|
||||||
# process members and determine which to skip
|
# process members and determine which to skip
|
||||||
for (membername, member) in members:
|
for (membername, member) in members:
|
||||||
@ -582,13 +580,12 @@ class Documenter:
|
|||||||
membername in self.options.special_members:
|
membername in self.options.special_members:
|
||||||
keep = has_doc or self.options.undoc_members
|
keep = has_doc or self.options.undoc_members
|
||||||
elif (namespace, membername) in attr_docs:
|
elif (namespace, membername) in attr_docs:
|
||||||
has_doc = bool(attr_docs[namespace, membername])
|
|
||||||
if want_all and membername.startswith('_'):
|
if want_all and membername.startswith('_'):
|
||||||
# ignore members whose name starts with _ by default
|
# ignore members whose name starts with _ by default
|
||||||
keep = has_doc and self.options.private_members
|
keep = self.options.private_members
|
||||||
else:
|
else:
|
||||||
# keep documented attributes
|
# keep documented attributes
|
||||||
keep = has_doc
|
keep = True
|
||||||
isattr = True
|
isattr = True
|
||||||
elif want_all and membername.startswith('_'):
|
elif want_all and membername.startswith('_'):
|
||||||
# ignore members whose name starts with _ by default
|
# ignore members whose name starts with _ by default
|
||||||
@ -597,8 +594,6 @@ class Documenter:
|
|||||||
else:
|
else:
|
||||||
# ignore undocumented members if :undoc-members: is not given
|
# ignore undocumented members if :undoc-members: is not given
|
||||||
keep = has_doc or self.options.undoc_members
|
keep = has_doc or self.options.undoc_members
|
||||||
# module top level item or not
|
|
||||||
isattr = membername in tagorder
|
|
||||||
|
|
||||||
# give the user a chance to decide whether this member
|
# give the user a chance to decide whether this member
|
||||||
# should be skipped
|
# should be skipped
|
||||||
@ -1296,10 +1291,6 @@ class DataDocumenter(ModuleLevelDocumenter):
|
|||||||
return self.get_attr(self.parent or self.object, '__module__', None) \
|
return self.get_attr(self.parent or self.object, '__module__', None) \
|
||||||
or self.modname
|
or self.modname
|
||||||
|
|
||||||
def get_doc(self, encoding=None, ignore=1):
|
|
||||||
# type: (str, int) -> List[List[str]]
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore
|
class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore
|
||||||
"""
|
"""
|
||||||
|
@ -128,7 +128,7 @@ def get_object_members(subject, objpath, attrgetter, analyzer=None):
|
|||||||
members[name] = Attribute(name, True, value)
|
members[name] = Attribute(name, True, value)
|
||||||
|
|
||||||
# members in __slots__
|
# members in __slots__
|
||||||
if isclass(subject) and hasattr(subject, '__slots__'):
|
if isclass(subject) and getattr(subject, '__slots__', None) is not None:
|
||||||
from sphinx.ext.autodoc import SLOTSATTR
|
from sphinx.ext.autodoc import SLOTSATTR
|
||||||
|
|
||||||
for name in subject.__slots__:
|
for name in subject.__slots__:
|
||||||
|
@ -754,7 +754,6 @@ def process_generate_options(app):
|
|||||||
imported_members = app.config.autosummary_imported_members
|
imported_members = app.config.autosummary_imported_members
|
||||||
with mock(app.config.autosummary_mock_imports):
|
with mock(app.config.autosummary_mock_imports):
|
||||||
generate_autosummary_docs(genfiles, builder=app.builder,
|
generate_autosummary_docs(genfiles, builder=app.builder,
|
||||||
warn=logger.warning, info=logger.info,
|
|
||||||
suffix=suffix, base_path=app.srcdir,
|
suffix=suffix, base_path=app.srcdir,
|
||||||
app=app, imported_members=imported_members)
|
app=app, imported_members=imported_members)
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import os
|
|||||||
import pydoc
|
import pydoc
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import warnings
|
||||||
|
|
||||||
from jinja2 import BaseLoader, FileSystemLoader, TemplateNotFound
|
from jinja2 import BaseLoader, FileSystemLoader, TemplateNotFound
|
||||||
from jinja2.sandbox import SandboxedEnvironment
|
from jinja2.sandbox import SandboxedEnvironment
|
||||||
@ -30,10 +31,12 @@ from jinja2.sandbox import SandboxedEnvironment
|
|||||||
import sphinx.locale
|
import sphinx.locale
|
||||||
from sphinx import __display_version__
|
from sphinx import __display_version__
|
||||||
from sphinx import package_dir
|
from sphinx import package_dir
|
||||||
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.ext.autosummary import import_by_name, get_documenter
|
from sphinx.ext.autosummary import import_by_name, get_documenter
|
||||||
from sphinx.jinja2glue import BuiltinTemplateLoader
|
from sphinx.jinja2glue import BuiltinTemplateLoader
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.registry import SphinxComponentRegistry
|
from sphinx.registry import SphinxComponentRegistry
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util import rst
|
from sphinx.util import rst
|
||||||
from sphinx.util.inspect import safe_getattr
|
from sphinx.util.inspect import safe_getattr
|
||||||
from sphinx.util.osutil import ensuredir
|
from sphinx.util.osutil import ensuredir
|
||||||
@ -45,12 +48,17 @@ if False:
|
|||||||
from sphinx.ext.autodoc import Documenter # NOQA
|
from sphinx.ext.autodoc import Documenter # NOQA
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DummyApplication:
|
class DummyApplication:
|
||||||
"""Dummy Application class for sphinx-autogen command."""
|
"""Dummy Application class for sphinx-autogen command."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
self.registry = SphinxComponentRegistry()
|
self.registry = SphinxComponentRegistry()
|
||||||
|
self.messagelog = [] # type: List[str]
|
||||||
|
self.verbosity = 0
|
||||||
|
|
||||||
|
|
||||||
def setup_documenters(app):
|
def setup_documenters(app):
|
||||||
@ -127,10 +135,20 @@ class AutosummaryRenderer:
|
|||||||
# -- Generating output ---------------------------------------------------------
|
# -- Generating output ---------------------------------------------------------
|
||||||
|
|
||||||
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
|
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
|
||||||
warn=_simple_warn, info=_simple_info,
|
warn=None, info=None, base_path=None, builder=None,
|
||||||
base_path=None, builder=None, template_dir=None,
|
template_dir=None, imported_members=False, app=None):
|
||||||
imported_members=False, app=None):
|
|
||||||
# type: (List[str], str, str, Callable, Callable, str, Builder, str, bool, Any) -> None
|
# type: (List[str], str, str, Callable, Callable, str, Builder, str, bool, Any) -> None
|
||||||
|
if info:
|
||||||
|
warnings.warn('info argument for generate_autosummary_docs() is deprecated.',
|
||||||
|
RemovedInSphinx40Warning)
|
||||||
|
else:
|
||||||
|
info = logger.info
|
||||||
|
|
||||||
|
if warn:
|
||||||
|
warnings.warn('warn argument for generate_autosummary_docs() is deprecated.',
|
||||||
|
RemovedInSphinx40Warning)
|
||||||
|
else:
|
||||||
|
warn = logger.warning
|
||||||
|
|
||||||
showed_sources = list(sorted(sources))
|
showed_sources = list(sorted(sources))
|
||||||
if len(showed_sources) > 20:
|
if len(showed_sources) > 20:
|
||||||
@ -221,7 +239,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
|
|||||||
get_members(obj, {'attribute', 'property'})
|
get_members(obj, {'attribute', 'property'})
|
||||||
|
|
||||||
parts = name.split('.')
|
parts = name.split('.')
|
||||||
if doc.objtype in ('method', 'attribute'):
|
if doc.objtype in ('method', 'attribute', 'property'):
|
||||||
mod_name = '.'.join(parts[:-2])
|
mod_name = '.'.join(parts[:-2])
|
||||||
cls_name = parts[-2]
|
cls_name = parts[-2]
|
||||||
obj_name = '.'.join(parts[-2:])
|
obj_name = '.'.join(parts[-2:])
|
||||||
@ -420,6 +438,7 @@ def main(argv=sys.argv[1:]):
|
|||||||
sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx')
|
sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx')
|
||||||
|
|
||||||
app = DummyApplication()
|
app = DummyApplication()
|
||||||
|
logging.setup(app, sys.stdout, sys.stderr) # type: ignore
|
||||||
setup_documenters(app)
|
setup_documenters(app)
|
||||||
args = get_parser().parse_args(argv)
|
args = get_parser().parse_args(argv)
|
||||||
generate_autosummary_docs(args.source_file, args.output_dir,
|
generate_autosummary_docs(args.source_file, args.output_dir,
|
||||||
|
@ -328,6 +328,9 @@ class GoogleDocstring:
|
|||||||
|
|
||||||
def _escape_args_and_kwargs(self, name):
|
def _escape_args_and_kwargs(self, name):
|
||||||
# type: (str) -> str
|
# type: (str) -> str
|
||||||
|
if name.endswith('_'):
|
||||||
|
name = name[:-1] + r'\_'
|
||||||
|
|
||||||
if name[:2] == '**':
|
if name[:2] == '**':
|
||||||
return r'\*\*' + name[2:]
|
return r'\*\*' + name[2:]
|
||||||
elif name[:1] == '*':
|
elif name[:1] == '*':
|
||||||
@ -555,7 +558,7 @@ class GoogleDocstring:
|
|||||||
# type: () -> None
|
# type: () -> None
|
||||||
self._parsed_lines = self._consume_empty()
|
self._parsed_lines = self._consume_empty()
|
||||||
|
|
||||||
if self._name and (self._what == 'attribute' or self._what == 'data'):
|
if self._name and self._what in ('attribute', 'data', 'property'):
|
||||||
# Implicit stop using StopIteration no longer allowed in
|
# Implicit stop using StopIteration no longer allowed in
|
||||||
# Python 3.7; see PEP 479
|
# Python 3.7; see PEP 479
|
||||||
res = [] # type: List[str]
|
res = [] # type: List[str]
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,8 +1448,8 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr "\nWe xetz'ib'an ri wuj pa jun ch'abäl man Q'anch' ta,\nyatikïr nacha' jun chïk runuk'unem ch'ab'äl wawe' chi Sphinx tiq'ax\nruch'abäl ri wuj xtik'iyij pa ri ch'ab'äl re.\n\nChi natz'u rucholajem runuk'unem ch'ab'äl k'o chïk pa Sphinx, tab'e pa\nhttp://sphinx-doc.org/config.html#confval-language."
|
msgstr "\nWe xetz'ib'an ri wuj pa jun ch'abäl man Q'anch' ta,\nyatikïr nacha' jun chïk runuk'unem ch'ab'äl wawe' chi Sphinx tiq'ax\nruch'abäl ri wuj xtik'iyij pa ri ch'ab'äl re.\n\nChi natz'u rucholajem runuk'unem ch'ab'äl k'o chïk pa Sphinx, tab'e pa\nhttps://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
msgid "Project language"
|
msgid "Project language"
|
||||||
|
@ -1449,7 +1449,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1449,7 +1449,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1450,7 +1450,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1451,7 +1451,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1454,8 +1454,8 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr "\nSi los documentos están escritos en un idioma distinto al Inglés,\npuedes seleccionar un idioma aqui a través de su código. Sphinx traducirá\nlos textos que genere en dicho idioma.\n\nPara una lista de los códigos soportados visita: \nhttp://sphinx-doc.org/config.html#confval-language."
|
msgstr "\nSi los documentos están escritos en un idioma distinto al Inglés,\npuedes seleccionar un idioma aqui a través de su código. Sphinx traducirá\nlos textos que genere en dicho idioma.\n\nPara una lista de los códigos soportados visita: \nhttps://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
msgid "Project language"
|
msgid "Project language"
|
||||||
|
@ -1451,8 +1451,8 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr "\nKui su dokumendid pole kirjutatud inglise keeles, siis võid siin määrata\nkeele vastava keelekoodi abil. Sel juhul tõlgib Sphinx enda genereeritud\nteksti vastavasse keelde.\n\nToetatud keelekoodide kohta vaata\nhttp://sphinx-doc.org/config.html#confval-language."
|
msgstr "\nKui su dokumendid pole kirjutatud inglise keeles, siis võid siin määrata\nkeele vastava keelekoodi abil. Sel juhul tõlgib Sphinx enda genereeritud\nteksti vastavasse keelde.\n\nToetatud keelekoodide kohta vaata\nhttps://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
msgid "Project language"
|
msgid "Project language"
|
||||||
|
@ -1449,7 +1449,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1447,7 +1447,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1465,8 +1465,8 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr "\nSi le documents doit être écrit dans une autre langue que l'anglais, vous pouvez choisir une langue ici en saisissant son code. Sphinx traduira le texte qu'il génère dans cette langue. Pour une liste des codes supportés : http://sphinx-doc.org/config.html#confval-language."
|
msgstr "\nSi le documents doit être écrit dans une autre langue que l'anglais, vous pouvez choisir une langue ici en saisissant son code. Sphinx traduira le texte qu'il génère dans cette langue. Pour une liste des codes supportés : https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
msgid "Project language"
|
msgid "Project language"
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1449,8 +1449,8 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr "\nयदि प्रलेखों को अंग्रेजी के अलावा अन्य किसी भाषा में लिखा जाना है,\nतो यहाँ पर आप भाषा का कूटशब्द दे सकते हैं. स्फिंक्स तदपुरांत,\nजो वाक्यांश बनाता है उसे उस भाषा में अनुवादित करेगा.\n\nमान्य भाषा कूटशब्द सूची यहाँ पर देखें\nhttp://sphinx-doc.org/config.html#confval-language."
|
msgstr "\nयदि प्रलेखों को अंग्रेजी के अलावा अन्य किसी भाषा में लिखा जाना है,\nतो यहाँ पर आप भाषा का कूटशब्द दे सकते हैं. स्फिंक्स तदपुरांत,\nजो वाक्यांश बनाता है उसे उस भाषा में अनुवादित करेगा.\n\nमान्य भाषा कूटशब्द सूची यहाँ पर देखें\nhttps://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
msgid "Project language"
|
msgid "Project language"
|
||||||
|
@ -1447,7 +1447,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1452,7 +1452,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1451,7 +1451,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1452,7 +1452,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1460,8 +1460,8 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr "\nドキュメントを英語以外の言語で書く場合は、\n 言語コードで言語を選択できます。Sphinx は生成したテキストをその言語に翻訳します。\n\nサポートされているコードのリストについては、\nhttp://sphinx-doc.org/config.html#confval-language を参照してください。"
|
msgstr "\nドキュメントを英語以外の言語で書く場合は、\n 言語コードで言語を選択できます。Sphinx は生成したテキストをその言語に翻訳します。\n\nサポートされているコードのリストについては、\nhttps://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language を参照してください。"
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
msgid "Project language"
|
msgid "Project language"
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1447,7 +1447,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1447,7 +1447,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1449,7 +1449,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1453,7 +1453,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1451,8 +1451,8 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr "\nJeśli dokumenty mają być pisane w języku innym niż angielski,\nmożesz tutaj wybrać język przez jego kod. Sphinx następnie\nprzetłumaczy tekst, który generuje, na ten język.\n\nListę wspieranych kodów znajdziesz na\nhttp://sphinx-doc.org/config.html#confval-language."
|
msgstr "\nJeśli dokumenty mają być pisane w języku innym niż angielski,\nmożesz tutaj wybrać język przez jego kod. Sphinx następnie\nprzetłumaczy tekst, który generuje, na ten język.\n\nListę wspieranych kodów znajdziesz na\nhttps://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
msgid "Project language"
|
msgid "Project language"
|
||||||
|
@ -1447,7 +1447,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1451,7 +1451,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1449,7 +1449,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1449,7 +1449,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1453,7 +1453,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1450,7 +1450,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1447,7 +1447,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1461,7 +1461,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1447,7 +1447,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1447,7 +1447,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1447,7 +1447,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1449,7 +1449,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1447,7 +1447,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1448,7 +1448,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -1456,8 +1456,8 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr "\n如果用英语以外的语言编写文档,你可以在此按语言代码选择语种。\nSphinx 会把内置文本翻译成相应语言的版本。\n\n支持的语言代码列表见:\nhttp://sphinx-doc.org/config.html#confval-language。"
|
msgstr "\n如果用英语以外的语言编写文档,你可以在此按语言代码选择语种。\nSphinx 会把内置文本翻译成相应语言的版本。\n\n支持的语言代码列表见:\nhttps://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language。"
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
msgid "Project language"
|
msgid "Project language"
|
||||||
|
@ -1453,7 +1453,7 @@ msgid ""
|
|||||||
"translate text that it generates into that language.\n"
|
"translate text that it generates into that language.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"For a list of supported codes, see\n"
|
"For a list of supported codes, see\n"
|
||||||
"http://sphinx-doc.org/config.html#confval-language."
|
"https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: sphinx/cmd/quickstart.py:314
|
#: sphinx/cmd/quickstart.py:314
|
||||||
|
@ -357,6 +357,17 @@ class VariableCommentPicker(ast.NodeVisitor):
|
|||||||
except TypeError:
|
except TypeError:
|
||||||
pass # this assignment is not new definition!
|
pass # this assignment is not new definition!
|
||||||
|
|
||||||
|
def visit_Try(self, node):
|
||||||
|
# type: (ast.Try) -> None
|
||||||
|
"""Handles Try node and processes body and else-clause.
|
||||||
|
|
||||||
|
.. note:: pycode parser ignores objects definition in except-clause.
|
||||||
|
"""
|
||||||
|
for subnode in node.body:
|
||||||
|
self.visit(subnode)
|
||||||
|
for subnode in node.orelse:
|
||||||
|
self.visit(subnode)
|
||||||
|
|
||||||
def visit_ClassDef(self, node):
|
def visit_ClassDef(self, node):
|
||||||
# type: (ast.ClassDef) -> None
|
# type: (ast.ClassDef) -> None
|
||||||
"""Handles ClassDef node and set context."""
|
"""Handles ClassDef node and set context."""
|
||||||
|
@ -40,8 +40,8 @@ Submodules
|
|||||||
{{- [submodule, "module"] | join(" ") | e | heading(2) }}
|
{{- [submodule, "module"] | join(" ") | e | heading(2) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ automodule(submodule, automodule_options) }}
|
{{ automodule(submodule, automodule_options) }}
|
||||||
{%- endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{%- if not modulefirst and not is_namespace %}
|
{%- if not modulefirst and not is_namespace %}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
%
|
%
|
||||||
|
|
||||||
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
|
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
|
||||||
\ProvidesPackage{sphinx}[2019/01/12 v1.8.4 LaTeX package (Sphinx markup)]
|
\ProvidesPackage{sphinx}[2019/06/04 v2.1.1 LaTeX package (Sphinx markup)]
|
||||||
|
|
||||||
% provides \ltx@ifundefined
|
% provides \ltx@ifundefined
|
||||||
% (many packages load ltxcmds: graphicx does for pdftex and lualatex but
|
% (many packages load ltxcmds: graphicx does for pdftex and lualatex but
|
||||||
@ -1444,7 +1444,7 @@
|
|||||||
% Some are quite plain
|
% Some are quite plain
|
||||||
% the spx@notice@bordercolor etc are set in the sphinxadmonition environment
|
% the spx@notice@bordercolor etc are set in the sphinxadmonition environment
|
||||||
\newenvironment{sphinxlightbox}{%
|
\newenvironment{sphinxlightbox}{%
|
||||||
\par\allowbreak
|
\par
|
||||||
\noindent{\color{spx@notice@bordercolor}%
|
\noindent{\color{spx@notice@bordercolor}%
|
||||||
\rule{\linewidth}{\spx@notice@border}}\par\nobreak
|
\rule{\linewidth}{\spx@notice@border}}\par\nobreak
|
||||||
{\parskip\z@skip\noindent}%
|
{\parskip\z@skip\noindent}%
|
||||||
|
@ -13,6 +13,11 @@
|
|||||||
|
|
||||||
/* -- page layout ----------------------------------------------------------- */
|
/* -- page layout ----------------------------------------------------------- */
|
||||||
|
|
||||||
|
html {
|
||||||
|
/* CSS hack for macOS's scrollbar (see #1125) */
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: {{ theme_bodyfont }};
|
font-family: {{ theme_bodyfont }};
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
|
@ -337,15 +337,13 @@ _coding_re = re.compile(r'coding[:=]\s*([-\w.]+)')
|
|||||||
def detect_encoding(readline: Callable[[], bytes]) -> str:
|
def detect_encoding(readline: Callable[[], bytes]) -> str:
|
||||||
"""Like tokenize.detect_encoding() from Py3k, but a bit simplified."""
|
"""Like tokenize.detect_encoding() from Py3k, but a bit simplified."""
|
||||||
|
|
||||||
def read_or_stop():
|
def read_or_stop() -> bytes:
|
||||||
# type: () -> bytes
|
|
||||||
try:
|
try:
|
||||||
return readline()
|
return readline()
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_normal_name(orig_enc):
|
def get_normal_name(orig_enc: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
"""Imitates get_normal_name in tokenizer.c."""
|
"""Imitates get_normal_name in tokenizer.c."""
|
||||||
# Only care about the first 12 characters.
|
# Only care about the first 12 characters.
|
||||||
enc = orig_enc[:12].lower().replace('_', '-')
|
enc = orig_enc[:12].lower().replace('_', '-')
|
||||||
@ -356,8 +354,7 @@ def detect_encoding(readline: Callable[[], bytes]) -> str:
|
|||||||
return 'iso-8859-1'
|
return 'iso-8859-1'
|
||||||
return orig_enc
|
return orig_enc
|
||||||
|
|
||||||
def find_cookie(line):
|
def find_cookie(line: bytes) -> str:
|
||||||
# type: (bytes) -> str
|
|
||||||
try:
|
try:
|
||||||
line_string = line.decode('ascii')
|
line_string = line.decode('ascii')
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
|
@ -10,23 +10,22 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
from docutils.utils import get_source_line
|
from docutils.utils import get_source_line
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx.config import Config
|
||||||
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
||||||
from sphinx.transforms import SphinxTransform
|
from sphinx.transforms import SphinxTransform
|
||||||
from sphinx.util import import_object
|
from sphinx.util import import_object
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict # NOQA
|
from sphinx.application import Sphinx
|
||||||
from sphinx.application import Sphinx # NOQA
|
|
||||||
from sphinx.config import Config # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
def deprecate_source_parsers(app, config):
|
def deprecate_source_parsers(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
if config.source_parsers:
|
if config.source_parsers:
|
||||||
warnings.warn('The config variable "source_parsers" is deprecated. '
|
warnings.warn('The config variable "source_parsers" is deprecated. '
|
||||||
'Please update your extension for the parser and remove the setting.',
|
'Please update your extension for the parser and remove the setting.',
|
||||||
@ -37,8 +36,7 @@ def deprecate_source_parsers(app, config):
|
|||||||
app.add_source_parser(suffix, parser)
|
app.add_source_parser(suffix, parser)
|
||||||
|
|
||||||
|
|
||||||
def register_application_for_autosummary(app):
|
def register_application_for_autosummary(app: "Sphinx") -> None:
|
||||||
# type: (Sphinx) -> None
|
|
||||||
"""Register application object to autosummary module.
|
"""Register application object to autosummary module.
|
||||||
|
|
||||||
Since Sphinx-1.7, documenters and attrgetters are registered into
|
Since Sphinx-1.7, documenters and attrgetters are registered into
|
||||||
@ -55,8 +53,7 @@ class IndexEntriesMigrator(SphinxTransform):
|
|||||||
"""Migrating indexentries from old style (4columns) to new style (5columns)."""
|
"""Migrating indexentries from old style (4columns) to new style (5columns)."""
|
||||||
default_priority = 700
|
default_priority = 700
|
||||||
|
|
||||||
def apply(self, **kwargs):
|
def apply(self, **kwargs) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
for node in self.document.traverse(addnodes.index):
|
for node in self.document.traverse(addnodes.index):
|
||||||
for i, entries in enumerate(node['entries']):
|
for i, entries in enumerate(node['entries']):
|
||||||
if len(entries) == 4:
|
if len(entries) == 4:
|
||||||
@ -66,8 +63,7 @@ class IndexEntriesMigrator(SphinxTransform):
|
|||||||
node['entries'][i] = entries + (None,)
|
node['entries'][i] = entries + (None,)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.add_transform(IndexEntriesMigrator)
|
app.add_transform(IndexEntriesMigrator)
|
||||||
app.connect('config-inited', deprecate_source_parsers)
|
app.connect('config-inited', deprecate_source_parsers)
|
||||||
app.connect('builder-inited', register_application_for_autosummary)
|
app.connect('builder-inited', register_application_for_autosummary)
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# check if colorama is installed to support color on Windows
|
# check if colorama is installed to support color on Windows
|
||||||
@ -18,23 +19,17 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
colorama = None
|
colorama = None
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Dict # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
_ansi_re = re.compile('\x1b\\[(\\d\\d;){0,2}\\d\\dm')
|
_ansi_re = re.compile('\x1b\\[(\\d\\d;){0,2}\\d\\dm')
|
||||||
codes = {} # type: Dict[str, str]
|
codes = {} # type: Dict[str, str]
|
||||||
|
|
||||||
|
|
||||||
def terminal_safe(s):
|
def terminal_safe(s: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
"""safely encode a string for printing to the terminal."""
|
"""safely encode a string for printing to the terminal."""
|
||||||
return s.encode('ascii', 'backslashreplace').decode('ascii')
|
return s.encode('ascii', 'backslashreplace').decode('ascii')
|
||||||
|
|
||||||
|
|
||||||
def get_terminal_width():
|
def get_terminal_width() -> int:
|
||||||
# type: () -> int
|
|
||||||
"""Borrowed from the py lib."""
|
"""Borrowed from the py lib."""
|
||||||
try:
|
try:
|
||||||
import termios
|
import termios
|
||||||
@ -53,8 +48,7 @@ def get_terminal_width():
|
|||||||
_tw = get_terminal_width()
|
_tw = get_terminal_width()
|
||||||
|
|
||||||
|
|
||||||
def term_width_line(text):
|
def term_width_line(text: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
if not codes:
|
if not codes:
|
||||||
# if no coloring, don't output fancy backspaces
|
# if no coloring, don't output fancy backspaces
|
||||||
return text + '\n'
|
return text + '\n'
|
||||||
@ -63,8 +57,7 @@ def term_width_line(text):
|
|||||||
return text.ljust(_tw + len(text) - len(_ansi_re.sub('', text))) + '\r'
|
return text.ljust(_tw + len(text) - len(_ansi_re.sub('', text))) + '\r'
|
||||||
|
|
||||||
|
|
||||||
def color_terminal():
|
def color_terminal() -> bool:
|
||||||
# type: () -> bool
|
|
||||||
if sys.platform == 'win32' and colorama is not None:
|
if sys.platform == 'win32' and colorama is not None:
|
||||||
colorama.init()
|
colorama.init()
|
||||||
return True
|
return True
|
||||||
@ -80,21 +73,18 @@ def color_terminal():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def nocolor():
|
def nocolor() -> None:
|
||||||
# type: () -> None
|
|
||||||
if sys.platform == 'win32' and colorama is not None:
|
if sys.platform == 'win32' and colorama is not None:
|
||||||
colorama.deinit()
|
colorama.deinit()
|
||||||
codes.clear()
|
codes.clear()
|
||||||
|
|
||||||
|
|
||||||
def coloron():
|
def coloron() -> None:
|
||||||
# type: () -> None
|
|
||||||
codes.update(_orig_codes)
|
codes.update(_orig_codes)
|
||||||
|
|
||||||
|
|
||||||
def colorize(name, text, input_mode=False):
|
def colorize(name: str, text: str, input_mode: bool = False) -> str:
|
||||||
# type: (str, str, bool) -> str
|
def escseq(name: str) -> str:
|
||||||
def escseq(name):
|
|
||||||
# Wrap escape sequence with ``\1`` and ``\2`` to let readline know
|
# Wrap escape sequence with ``\1`` and ``\2`` to let readline know
|
||||||
# it is non-printable characters
|
# it is non-printable characters
|
||||||
# ref: https://tiswww.case.edu/php/chet/readline/readline.html
|
# ref: https://tiswww.case.edu/php/chet/readline/readline.html
|
||||||
@ -109,15 +99,12 @@ def colorize(name, text, input_mode=False):
|
|||||||
return escseq(name) + text + escseq('reset')
|
return escseq(name) + text + escseq('reset')
|
||||||
|
|
||||||
|
|
||||||
def strip_colors(s):
|
def strip_colors(s: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
return re.compile('\x1b.*?m').sub('', s)
|
return re.compile('\x1b.*?m').sub('', s)
|
||||||
|
|
||||||
|
|
||||||
def create_color_func(name):
|
def create_color_func(name: str) -> None:
|
||||||
# type: (str) -> None
|
def inner(text: str) -> str:
|
||||||
def inner(text):
|
|
||||||
# type: (str) -> str
|
|
||||||
return colorize(name, text)
|
return colorize(name, text)
|
||||||
globals()[name] = inner
|
globals()[name] = inner
|
||||||
|
|
||||||
|
@ -10,23 +10,23 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from typing import List, Tuple, cast
|
from typing import Any, Dict, List, Tuple, Type, Union
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from docutils.nodes import Node
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
|
from sphinx.util.typing import TextlikeNode
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Dict, Type, Union # NOQA
|
from sphinx.environment import BuildEnvironment
|
||||||
from sphinx.directive import ObjectDescription # NOQA
|
from sphinx.directive import ObjectDescription
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
|
||||||
from sphinx.util.typing import TextlikeNode # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
def _is_single_paragraph(node):
|
def _is_single_paragraph(node: nodes.field_body) -> bool:
|
||||||
# type: (nodes.field_body) -> bool
|
|
||||||
"""True if the node only contains one paragraph (and system messages)."""
|
"""True if the node only contains one paragraph (and system messages)."""
|
||||||
if len(node) == 0:
|
if len(node) == 0:
|
||||||
return False
|
return False
|
||||||
@ -55,9 +55,8 @@ class Field:
|
|||||||
is_grouped = False
|
is_grouped = False
|
||||||
is_typed = False
|
is_typed = False
|
||||||
|
|
||||||
def __init__(self, name, names=(), label=None, has_arg=True, rolename=None,
|
def __init__(self, name: str, names: Tuple[str, ...] = (), label: str = None,
|
||||||
bodyrolename=None):
|
has_arg: bool = True, rolename: str = None, bodyrolename: str = None) -> None:
|
||||||
# type: (str, Tuple[str, ...], str, bool, str, str) -> None
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.names = names
|
self.names = names
|
||||||
self.label = label
|
self.label = label
|
||||||
@ -65,15 +64,9 @@ class Field:
|
|||||||
self.rolename = rolename
|
self.rolename = rolename
|
||||||
self.bodyrolename = bodyrolename
|
self.bodyrolename = bodyrolename
|
||||||
|
|
||||||
def make_xref(self,
|
def make_xref(self, rolename: str, domain: str, target: str,
|
||||||
rolename, # type: str
|
innernode: Type[TextlikeNode] = addnodes.literal_emphasis,
|
||||||
domain, # type: str
|
contnode: Node = None, env: "BuildEnvironment" = None) -> Node:
|
||||||
target, # type: str
|
|
||||||
innernode=addnodes.literal_emphasis, # type: Type[TextlikeNode]
|
|
||||||
contnode=None, # type: nodes.Node
|
|
||||||
env=None, # type: BuildEnvironment
|
|
||||||
):
|
|
||||||
# type: (...) -> nodes.Node
|
|
||||||
if not rolename:
|
if not rolename:
|
||||||
return contnode or innernode(target, target)
|
return contnode or innernode(target, target)
|
||||||
refnode = addnodes.pending_xref('', refdomain=domain, refexplicit=False,
|
refnode = addnodes.pending_xref('', refdomain=domain, refexplicit=False,
|
||||||
@ -83,28 +76,16 @@ class Field:
|
|||||||
env.get_domain(domain).process_field_xref(refnode)
|
env.get_domain(domain).process_field_xref(refnode)
|
||||||
return refnode
|
return refnode
|
||||||
|
|
||||||
def make_xrefs(self,
|
def make_xrefs(self, rolename: str, domain: str, target: str,
|
||||||
rolename, # type: str
|
innernode: Type[TextlikeNode] = addnodes.literal_emphasis,
|
||||||
domain, # type: str
|
contnode: Node = None, env: "BuildEnvironment" = None) -> List[Node]:
|
||||||
target, # type: str
|
|
||||||
innernode=addnodes.literal_emphasis, # type: Type[TextlikeNode]
|
|
||||||
contnode=None, # type: nodes.Node
|
|
||||||
env=None, # type: BuildEnvironment
|
|
||||||
):
|
|
||||||
# type: (...) -> List[nodes.Node]
|
|
||||||
return [self.make_xref(rolename, domain, target, innernode, contnode, env)]
|
return [self.make_xref(rolename, domain, target, innernode, contnode, env)]
|
||||||
|
|
||||||
def make_entry(self, fieldarg, content):
|
def make_entry(self, fieldarg: str, content: List[Node]) -> Tuple[str, List[Node]]:
|
||||||
# type: (str, List[nodes.Node]) -> Tuple[str, List[nodes.Node]]
|
|
||||||
return (fieldarg, content)
|
return (fieldarg, content)
|
||||||
|
|
||||||
def make_field(self,
|
def make_field(self, types: Dict[str, List[Node]], domain: str,
|
||||||
types, # type: Dict[str, List[nodes.Node]]
|
item: Tuple, env: "BuildEnvironment" = None) -> nodes.field:
|
||||||
domain, # type: str
|
|
||||||
item, # type: Tuple
|
|
||||||
env=None, # type: BuildEnvironment
|
|
||||||
):
|
|
||||||
# type: (...) -> nodes.field
|
|
||||||
fieldarg, content = item
|
fieldarg, content = item
|
||||||
fieldname = nodes.field_name('', self.label)
|
fieldname = nodes.field_name('', self.label)
|
||||||
if fieldarg:
|
if fieldarg:
|
||||||
@ -138,19 +119,13 @@ class GroupedField(Field):
|
|||||||
is_grouped = True
|
is_grouped = True
|
||||||
list_type = nodes.bullet_list
|
list_type = nodes.bullet_list
|
||||||
|
|
||||||
def __init__(self, name, names=(), label=None, rolename=None,
|
def __init__(self, name: str, names: Tuple[str, ...] = (), label: str = None,
|
||||||
can_collapse=False):
|
rolename: str = None, can_collapse: bool = False) -> None:
|
||||||
# type: (str, Tuple[str, ...], str, str, bool) -> None
|
|
||||||
super().__init__(name, names, label, True, rolename)
|
super().__init__(name, names, label, True, rolename)
|
||||||
self.can_collapse = can_collapse
|
self.can_collapse = can_collapse
|
||||||
|
|
||||||
def make_field(self,
|
def make_field(self, types: Dict[str, List[Node]], domain: str,
|
||||||
types, # type: Dict[str, List[nodes.Node]]
|
items: Tuple, env: "BuildEnvironment" = None) -> nodes.field:
|
||||||
domain, # type: str
|
|
||||||
items, # type: Tuple
|
|
||||||
env=None, # type: BuildEnvironment
|
|
||||||
):
|
|
||||||
# type: (...) -> nodes.field
|
|
||||||
fieldname = nodes.field_name('', self.label)
|
fieldname = nodes.field_name('', self.label)
|
||||||
listnode = self.list_type()
|
listnode = self.list_type()
|
||||||
for fieldarg, content in items:
|
for fieldarg, content in items:
|
||||||
@ -191,22 +166,16 @@ class TypedField(GroupedField):
|
|||||||
"""
|
"""
|
||||||
is_typed = True
|
is_typed = True
|
||||||
|
|
||||||
def __init__(self, name, names=(), typenames=(), label=None,
|
def __init__(self, name: str, names: Tuple[str, ...] = (), typenames: Tuple[str, ...] = (),
|
||||||
rolename=None, typerolename=None, can_collapse=False):
|
label: str = None, rolename: str = None, typerolename: str = None,
|
||||||
# type: (str, Tuple[str, ...], Tuple[str, ...], str, str, str, bool) -> None
|
can_collapse: bool = False) -> None:
|
||||||
super().__init__(name, names, label, rolename, can_collapse)
|
super().__init__(name, names, label, rolename, can_collapse)
|
||||||
self.typenames = typenames
|
self.typenames = typenames
|
||||||
self.typerolename = typerolename
|
self.typerolename = typerolename
|
||||||
|
|
||||||
def make_field(self,
|
def make_field(self, types: Dict[str, List[Node]], domain: str,
|
||||||
types, # type: Dict[str, List[nodes.Node]]
|
items: Tuple, env: "BuildEnvironment" = None) -> nodes.field:
|
||||||
domain, # type: str
|
def handle_item(fieldarg: str, content: str) -> nodes.paragraph:
|
||||||
items, # type: Tuple
|
|
||||||
env=None, # type: BuildEnvironment
|
|
||||||
):
|
|
||||||
# type: (...) -> nodes.field
|
|
||||||
def handle_item(fieldarg, content):
|
|
||||||
# type: (str, str) -> nodes.paragraph
|
|
||||||
par = nodes.paragraph()
|
par = nodes.paragraph()
|
||||||
par.extend(self.make_xrefs(self.rolename, domain, fieldarg,
|
par.extend(self.make_xrefs(self.rolename, domain, fieldarg,
|
||||||
addnodes.literal_strong, env=env))
|
addnodes.literal_strong, env=env))
|
||||||
@ -246,13 +215,11 @@ class DocFieldTransformer:
|
|||||||
"""
|
"""
|
||||||
typemap = None # type: Dict[str, Tuple[Field, bool]]
|
typemap = None # type: Dict[str, Tuple[Field, bool]]
|
||||||
|
|
||||||
def __init__(self, directive):
|
def __init__(self, directive: "ObjectDescription") -> None:
|
||||||
# type: (ObjectDescription) -> None
|
|
||||||
self.directive = directive
|
self.directive = directive
|
||||||
self.typemap = directive.get_field_type_map()
|
self.typemap = directive.get_field_type_map()
|
||||||
|
|
||||||
def preprocess_fieldtypes(self, types):
|
def preprocess_fieldtypes(self, types: List[Field]) -> Dict[str, Tuple[Field, bool]]:
|
||||||
# type: (List[Field]) -> Dict[str, Tuple[Field, bool]]
|
|
||||||
warnings.warn('DocFieldTransformer.preprocess_fieldtypes() is deprecated.',
|
warnings.warn('DocFieldTransformer.preprocess_fieldtypes() is deprecated.',
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
typemap = {}
|
typemap = {}
|
||||||
@ -265,16 +232,14 @@ class DocFieldTransformer:
|
|||||||
typemap[name] = typed_field, True
|
typemap[name] = typed_field, True
|
||||||
return typemap
|
return typemap
|
||||||
|
|
||||||
def transform_all(self, node):
|
def transform_all(self, node: addnodes.desc_content) -> None:
|
||||||
# type: (addnodes.desc_content) -> None
|
|
||||||
"""Transform all field list children of a node."""
|
"""Transform all field list children of a node."""
|
||||||
# don't traverse, only handle field lists that are immediate children
|
# don't traverse, only handle field lists that are immediate children
|
||||||
for child in node:
|
for child in node:
|
||||||
if isinstance(child, nodes.field_list):
|
if isinstance(child, nodes.field_list):
|
||||||
self.transform(child)
|
self.transform(child)
|
||||||
|
|
||||||
def transform(self, node):
|
def transform(self, node: nodes.field_list) -> None:
|
||||||
# type: (nodes.field_list) -> None
|
|
||||||
"""Transform a single field list *node*."""
|
"""Transform a single field list *node*."""
|
||||||
typemap = self.typemap
|
typemap = self.typemap
|
||||||
|
|
||||||
|
@ -16,33 +16,33 @@ from contextlib import contextmanager
|
|||||||
from copy import copy
|
from copy import copy
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
from os import path
|
from os import path
|
||||||
from typing import IO, cast
|
from types import ModuleType
|
||||||
|
from typing import Any, Callable, Dict, Generator, IO, List, Optional, Set, Tuple, Type
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
import docutils
|
import docutils
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.io import FileOutput
|
from docutils.io import FileOutput
|
||||||
|
from docutils.nodes import Element, Node, system_message
|
||||||
from docutils.parsers.rst import Directive, directives, roles, convert_directive_function
|
from docutils.parsers.rst import Directive, directives, roles, convert_directive_function
|
||||||
from docutils.statemachine import StateMachine
|
from docutils.parsers.rst.states import Inliner
|
||||||
|
from docutils.statemachine import StateMachine, State, StringList
|
||||||
from docutils.utils import Reporter, unescape
|
from docutils.utils import Reporter, unescape
|
||||||
|
|
||||||
from sphinx.deprecation import RemovedInSphinx30Warning
|
from sphinx.deprecation import RemovedInSphinx30Warning
|
||||||
from sphinx.errors import ExtensionError, SphinxError
|
from sphinx.errors import ExtensionError, SphinxError
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
|
from sphinx.util.typing import RoleFunction
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
report_re = re.compile('^(.+?:(?:\\d+)?): \\((DEBUG|INFO|WARNING|ERROR|SEVERE)/(\\d+)?\\) ')
|
report_re = re.compile('^(.+?:(?:\\d+)?): \\((DEBUG|INFO|WARNING|ERROR|SEVERE)/(\\d+)?\\) ')
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from types import ModuleType # NOQA
|
from sphinx.builders import Builder
|
||||||
from typing import Any, Callable, Dict, Generator, List, Set, Tuple, Type # NOQA
|
from sphinx.config import Config
|
||||||
from docutils.parsers.rst.states import Inliner # NOQA
|
from sphinx.environment import BuildEnvironment
|
||||||
from docutils.statemachine import State, StringList # NOQA
|
|
||||||
from sphinx.builders import Builder # NOQA
|
|
||||||
from sphinx.config import Config # NOQA
|
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
|
||||||
from sphinx.util.typing import RoleFunction # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
__version_info__ = tuple(LooseVersion(docutils.__version__).version)
|
__version_info__ = tuple(LooseVersion(docutils.__version__).version)
|
||||||
@ -50,8 +50,7 @@ additional_nodes = set() # type: Set[Type[nodes.Element]]
|
|||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def docutils_namespace():
|
def docutils_namespace() -> Generator[None, None, None]:
|
||||||
# type: () -> Generator[None, None, None]
|
|
||||||
"""Create namespace for reST parsers."""
|
"""Create namespace for reST parsers."""
|
||||||
try:
|
try:
|
||||||
_directives = copy(directives._directives) # type: ignore
|
_directives = copy(directives._directives) # type: ignore
|
||||||
@ -67,14 +66,12 @@ def docutils_namespace():
|
|||||||
additional_nodes.discard(node)
|
additional_nodes.discard(node)
|
||||||
|
|
||||||
|
|
||||||
def is_directive_registered(name):
|
def is_directive_registered(name: str) -> bool:
|
||||||
# type: (str) -> bool
|
|
||||||
"""Check the *name* directive is already registered."""
|
"""Check the *name* directive is already registered."""
|
||||||
return name in directives._directives # type: ignore
|
return name in directives._directives # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def register_directive(name, directive):
|
def register_directive(name: str, directive: Type[Directive]) -> None:
|
||||||
# type: (str, Type[Directive]) -> None
|
|
||||||
"""Register a directive to docutils.
|
"""Register a directive to docutils.
|
||||||
|
|
||||||
This modifies global state of docutils. So it is better to use this
|
This modifies global state of docutils. So it is better to use this
|
||||||
@ -83,14 +80,12 @@ def register_directive(name, directive):
|
|||||||
directives.register_directive(name, directive)
|
directives.register_directive(name, directive)
|
||||||
|
|
||||||
|
|
||||||
def is_role_registered(name):
|
def is_role_registered(name: str) -> bool:
|
||||||
# type: (str) -> bool
|
|
||||||
"""Check the *name* role is already registered."""
|
"""Check the *name* role is already registered."""
|
||||||
return name in roles._roles # type: ignore
|
return name in roles._roles # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def register_role(name, role):
|
def register_role(name: str, role: RoleFunction) -> None:
|
||||||
# type: (str, RoleFunction) -> None
|
|
||||||
"""Register a role to docutils.
|
"""Register a role to docutils.
|
||||||
|
|
||||||
This modifies global state of docutils. So it is better to use this
|
This modifies global state of docutils. So it is better to use this
|
||||||
@ -99,20 +94,17 @@ def register_role(name, role):
|
|||||||
roles.register_local_role(name, role)
|
roles.register_local_role(name, role)
|
||||||
|
|
||||||
|
|
||||||
def unregister_role(name):
|
def unregister_role(name: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
"""Unregister a role from docutils."""
|
"""Unregister a role from docutils."""
|
||||||
roles._roles.pop(name, None) # type: ignore
|
roles._roles.pop(name, None) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def is_node_registered(node):
|
def is_node_registered(node: Type[Element]) -> bool:
|
||||||
# type: (Type[nodes.Element]) -> bool
|
|
||||||
"""Check the *node* is already registered."""
|
"""Check the *node* is already registered."""
|
||||||
return hasattr(nodes.GenericNodeVisitor, 'visit_' + node.__name__)
|
return hasattr(nodes.GenericNodeVisitor, 'visit_' + node.__name__)
|
||||||
|
|
||||||
|
|
||||||
def register_node(node):
|
def register_node(node: Type[Element]) -> None:
|
||||||
# type: (Type[nodes.Element]) -> None
|
|
||||||
"""Register a node to docutils.
|
"""Register a node to docutils.
|
||||||
|
|
||||||
This modifies global state of some visitors. So it is better to use this
|
This modifies global state of some visitors. So it is better to use this
|
||||||
@ -123,8 +115,7 @@ def register_node(node):
|
|||||||
additional_nodes.add(node)
|
additional_nodes.add(node)
|
||||||
|
|
||||||
|
|
||||||
def unregister_node(node):
|
def unregister_node(node: Type[Element]) -> None:
|
||||||
# type: (Type[nodes.Element]) -> None
|
|
||||||
"""Unregister a node from docutils.
|
"""Unregister a node from docutils.
|
||||||
|
|
||||||
This is inverse of ``nodes._add_nodes_class_names()``.
|
This is inverse of ``nodes._add_nodes_class_names()``.
|
||||||
@ -137,8 +128,7 @@ def unregister_node(node):
|
|||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def patched_get_language():
|
def patched_get_language() -> Generator[None, None, None]:
|
||||||
# type: () -> Generator[None, None, None]
|
|
||||||
"""Patch docutils.languages.get_language() temporarily.
|
"""Patch docutils.languages.get_language() temporarily.
|
||||||
|
|
||||||
This ignores the second argument ``reporter`` to suppress warnings.
|
This ignores the second argument ``reporter`` to suppress warnings.
|
||||||
@ -146,8 +136,7 @@ def patched_get_language():
|
|||||||
"""
|
"""
|
||||||
from docutils.languages import get_language
|
from docutils.languages import get_language
|
||||||
|
|
||||||
def patched_get_language(language_code, reporter=None):
|
def patched_get_language(language_code: str, reporter: Reporter = None) -> Any:
|
||||||
# type: (str, Reporter) -> Any
|
|
||||||
return get_language(language_code)
|
return get_language(language_code)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -159,8 +148,7 @@ def patched_get_language():
|
|||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def using_user_docutils_conf(confdir):
|
def using_user_docutils_conf(confdir: str) -> Generator[None, None, None]:
|
||||||
# type: (str) -> Generator[None, None, None]
|
|
||||||
"""Let docutils know the location of ``docutils.conf`` for Sphinx."""
|
"""Let docutils know the location of ``docutils.conf`` for Sphinx."""
|
||||||
try:
|
try:
|
||||||
docutilsconfig = os.environ.get('DOCUTILSCONFIG', None)
|
docutilsconfig = os.environ.get('DOCUTILSCONFIG', None)
|
||||||
@ -176,8 +164,7 @@ def using_user_docutils_conf(confdir):
|
|||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def patch_docutils(confdir=None):
|
def patch_docutils(confdir: str = None) -> Generator[None, None, None]:
|
||||||
# type: (str) -> Generator[None, None, None]
|
|
||||||
"""Patch to docutils temporarily."""
|
"""Patch to docutils temporarily."""
|
||||||
with patched_get_language(), using_user_docutils_conf(confdir):
|
with patched_get_language(), using_user_docutils_conf(confdir):
|
||||||
yield
|
yield
|
||||||
@ -191,35 +178,30 @@ class sphinx_domains:
|
|||||||
"""Monkey-patch directive and role dispatch, so that domain-specific
|
"""Monkey-patch directive and role dispatch, so that domain-specific
|
||||||
markup takes precedence.
|
markup takes precedence.
|
||||||
"""
|
"""
|
||||||
def __init__(self, env):
|
def __init__(self, env: "BuildEnvironment") -> None:
|
||||||
# type: (BuildEnvironment) -> None
|
|
||||||
self.env = env
|
self.env = env
|
||||||
self.directive_func = None # type: Callable
|
self.directive_func = None # type: Callable
|
||||||
self.roles_func = None # type: Callable
|
self.roles_func = None # type: Callable
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.enable()
|
self.enable()
|
||||||
|
|
||||||
def __exit__(self, type, value, traceback):
|
def __exit__(self, exc_type: Type[Exception], exc_value: Exception, traceback: Any) -> bool: # NOQA
|
||||||
# type: (str, str, str) -> None
|
|
||||||
self.disable()
|
self.disable()
|
||||||
|
return True
|
||||||
|
|
||||||
def enable(self):
|
def enable(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
self.directive_func = directives.directive
|
self.directive_func = directives.directive
|
||||||
self.role_func = roles.role
|
self.role_func = roles.role
|
||||||
|
|
||||||
directives.directive = self.lookup_directive # type: ignore
|
directives.directive = self.lookup_directive
|
||||||
roles.role = self.lookup_role # type: ignore
|
roles.role = self.lookup_role
|
||||||
|
|
||||||
def disable(self):
|
def disable(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
directives.directive = self.directive_func
|
directives.directive = self.directive_func
|
||||||
roles.role = self.role_func
|
roles.role = self.role_func
|
||||||
|
|
||||||
def lookup_domain_element(self, type, name):
|
def lookup_domain_element(self, type: str, name: str) -> Any:
|
||||||
# type: (str, str) -> Any
|
|
||||||
"""Lookup a markup element (directive or role), given its name which can
|
"""Lookup a markup element (directive or role), given its name which can
|
||||||
be a full name (with domain).
|
be a full name (with domain).
|
||||||
"""
|
"""
|
||||||
@ -247,24 +229,21 @@ class sphinx_domains:
|
|||||||
|
|
||||||
raise ElementLookupError
|
raise ElementLookupError
|
||||||
|
|
||||||
def lookup_directive(self, name, lang_module, document):
|
def lookup_directive(self, directive_name: str, language_module: ModuleType, document: nodes.document) -> Tuple[Optional[Type[Directive]], List[system_message]]: # NOQA
|
||||||
# type: (str, ModuleType, nodes.document) -> Tuple[Type[Directive], List[nodes.system_message]] # NOQA
|
|
||||||
try:
|
try:
|
||||||
return self.lookup_domain_element('directive', name)
|
return self.lookup_domain_element('directive', directive_name)
|
||||||
except ElementLookupError:
|
except ElementLookupError:
|
||||||
return self.directive_func(name, lang_module, document)
|
return self.directive_func(directive_name, language_module, document)
|
||||||
|
|
||||||
def lookup_role(self, name, lang_module, lineno, reporter):
|
def lookup_role(self, role_name: str, language_module: ModuleType, lineno: int, reporter: Reporter) -> Tuple[RoleFunction, List[system_message]]: # NOQA
|
||||||
# type: (str, ModuleType, int, Reporter) -> Tuple[RoleFunction, List[nodes.system_message]] # NOQA
|
|
||||||
try:
|
try:
|
||||||
return self.lookup_domain_element('role', name)
|
return self.lookup_domain_element('role', role_name)
|
||||||
except ElementLookupError:
|
except ElementLookupError:
|
||||||
return self.role_func(name, lang_module, lineno, reporter)
|
return self.role_func(role_name, language_module, lineno, reporter)
|
||||||
|
|
||||||
|
|
||||||
class WarningStream:
|
class WarningStream:
|
||||||
def write(self, text):
|
def write(self, text: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
matched = report_re.search(text)
|
matched = report_re.search(text)
|
||||||
if not matched:
|
if not matched:
|
||||||
logger.warning(text.rstrip("\r\n"))
|
logger.warning(text.rstrip("\r\n"))
|
||||||
@ -276,16 +255,14 @@ class WarningStream:
|
|||||||
|
|
||||||
class LoggingReporter(Reporter):
|
class LoggingReporter(Reporter):
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_reporter(cls, reporter):
|
def from_reporter(cls, reporter: Reporter) -> "LoggingReporter":
|
||||||
# type: (Reporter) -> LoggingReporter
|
|
||||||
"""Create an instance of LoggingReporter from other reporter object."""
|
"""Create an instance of LoggingReporter from other reporter object."""
|
||||||
return cls(reporter.source, reporter.report_level, reporter.halt_level,
|
return cls(reporter.source, reporter.report_level, reporter.halt_level,
|
||||||
reporter.debug_flag, reporter.error_handler)
|
reporter.debug_flag, reporter.error_handler)
|
||||||
|
|
||||||
def __init__(self, source, report_level=Reporter.WARNING_LEVEL,
|
def __init__(self, source: str, report_level: int = Reporter.WARNING_LEVEL,
|
||||||
halt_level=Reporter.SEVERE_LEVEL, debug=False,
|
halt_level: int = Reporter.SEVERE_LEVEL, debug: bool = False,
|
||||||
error_handler='backslashreplace'):
|
error_handler: str = 'backslashreplace') -> None:
|
||||||
# type: (str, int, int, bool, str) -> None
|
|
||||||
stream = cast(IO, WarningStream())
|
stream = cast(IO, WarningStream())
|
||||||
super().__init__(source, report_level, halt_level,
|
super().__init__(source, report_level, halt_level,
|
||||||
stream, debug, error_handler=error_handler)
|
stream, debug, error_handler=error_handler)
|
||||||
@ -294,18 +271,15 @@ class LoggingReporter(Reporter):
|
|||||||
class NullReporter(Reporter):
|
class NullReporter(Reporter):
|
||||||
"""A dummy reporter; write nothing."""
|
"""A dummy reporter; write nothing."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
super().__init__('', 999, 4)
|
super().__init__('', 999, 4)
|
||||||
|
|
||||||
|
|
||||||
def is_html5_writer_available():
|
def is_html5_writer_available() -> bool:
|
||||||
# type: () -> bool
|
|
||||||
return __version_info__ > (0, 13, 0)
|
return __version_info__ > (0, 13, 0)
|
||||||
|
|
||||||
|
|
||||||
def directive_helper(obj, has_content=None, argument_spec=None, **option_spec):
|
def directive_helper(obj: Any, has_content: bool = None, argument_spec: Tuple[int, int, bool] = None, **option_spec) -> Any: # NOQA
|
||||||
# type: (Any, bool, Tuple[int, int, bool], Any) -> Any
|
|
||||||
warnings.warn('function based directive support is now deprecated. '
|
warnings.warn('function based directive support is now deprecated. '
|
||||||
'Use class based directive instead.',
|
'Use class based directive instead.',
|
||||||
RemovedInSphinx30Warning)
|
RemovedInSphinx30Warning)
|
||||||
@ -323,8 +297,7 @@ def directive_helper(obj, has_content=None, argument_spec=None, **option_spec):
|
|||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def switch_source_input(state, content):
|
def switch_source_input(state: State, content: StringList) -> Generator[None, None, None]:
|
||||||
# type: (State, StringList) -> Generator[None, None, None]
|
|
||||||
"""Switch current source input of state temporarily."""
|
"""Switch current source input of state temporarily."""
|
||||||
try:
|
try:
|
||||||
# remember the original ``get_source_and_line()`` method
|
# remember the original ``get_source_and_line()`` method
|
||||||
@ -344,13 +317,11 @@ def switch_source_input(state, content):
|
|||||||
class SphinxFileOutput(FileOutput):
|
class SphinxFileOutput(FileOutput):
|
||||||
"""Better FileOutput class for Sphinx."""
|
"""Better FileOutput class for Sphinx."""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
self.overwrite_if_changed = kwargs.pop('overwrite_if_changed', False)
|
self.overwrite_if_changed = kwargs.pop('overwrite_if_changed', False)
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
def write(self, data):
|
def write(self, data: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
if (self.destination_path and self.autoclose and 'b' not in self.mode and
|
if (self.destination_path and self.autoclose and 'b' not in self.mode and
|
||||||
self.overwrite_if_changed and os.path.exists(self.destination_path)):
|
self.overwrite_if_changed and os.path.exists(self.destination_path)):
|
||||||
with open(self.destination_path, encoding=self.encoding) as f:
|
with open(self.destination_path, encoding=self.encoding) as f:
|
||||||
@ -371,19 +342,16 @@ class SphinxDirective(Directive):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def env(self):
|
def env(self) -> "BuildEnvironment":
|
||||||
# type: () -> BuildEnvironment
|
|
||||||
"""Reference to the :class:`.BuildEnvironment` object."""
|
"""Reference to the :class:`.BuildEnvironment` object."""
|
||||||
return self.state.document.settings.env
|
return self.state.document.settings.env
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def config(self):
|
def config(self) -> "Config":
|
||||||
# type: () -> Config
|
|
||||||
"""Reference to the :class:`.Config` object."""
|
"""Reference to the :class:`.Config` object."""
|
||||||
return self.env.config
|
return self.env.config
|
||||||
|
|
||||||
def set_source_info(self, node):
|
def set_source_info(self, node: Node) -> None:
|
||||||
# type: (nodes.Node) -> None
|
|
||||||
"""Set source and line number to the node."""
|
"""Set source and line number to the node."""
|
||||||
node.source, node.line = self.state_machine.get_source_and_line(self.lineno)
|
node.source, node.line = self.state_machine.get_source_and_line(self.lineno)
|
||||||
|
|
||||||
@ -406,8 +374,9 @@ class SphinxRole:
|
|||||||
content = None #: A list of strings, the directive content for customization
|
content = None #: A list of strings, the directive content for customization
|
||||||
#: (from the "role" directive).
|
#: (from the "role" directive).
|
||||||
|
|
||||||
def __call__(self, name, rawtext, text, lineno, inliner, options={}, content=[]):
|
def __call__(self, name: str, rawtext: str, text: str, lineno: int,
|
||||||
# type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA
|
inliner: Inliner, options: Dict = {}, content: List[str] = []
|
||||||
|
) -> Tuple[List[Node], List[system_message]]:
|
||||||
self.rawtext = rawtext
|
self.rawtext = rawtext
|
||||||
self.text = unescape(text)
|
self.text = unescape(text)
|
||||||
self.lineno = lineno
|
self.lineno = lineno
|
||||||
@ -427,24 +396,20 @@ class SphinxRole:
|
|||||||
|
|
||||||
return self.run()
|
return self.run()
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> Tuple[List[Node], List[system_message]]:
|
||||||
# type: () -> Tuple[List[nodes.Node], List[nodes.system_message]]
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def env(self):
|
def env(self) -> "BuildEnvironment":
|
||||||
# type: () -> BuildEnvironment
|
|
||||||
"""Reference to the :class:`.BuildEnvironment` object."""
|
"""Reference to the :class:`.BuildEnvironment` object."""
|
||||||
return self.inliner.document.settings.env
|
return self.inliner.document.settings.env
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def config(self):
|
def config(self) -> "Config":
|
||||||
# type: () -> Config
|
|
||||||
"""Reference to the :class:`.Config` object."""
|
"""Reference to the :class:`.Config` object."""
|
||||||
return self.env.config
|
return self.env.config
|
||||||
|
|
||||||
def set_source_info(self, node, lineno=None):
|
def set_source_info(self, node: Node, lineno: int = None) -> None:
|
||||||
# type: (nodes.Node, int) -> None
|
|
||||||
if lineno is None:
|
if lineno is None:
|
||||||
lineno = self.lineno
|
lineno = self.lineno
|
||||||
|
|
||||||
@ -466,8 +431,9 @@ class ReferenceRole(SphinxRole):
|
|||||||
# \x00 means the "<" was backslash-escaped
|
# \x00 means the "<" was backslash-escaped
|
||||||
explicit_title_re = re.compile(r'^(.+?)\s*(?<!\x00)<(.*?)>$', re.DOTALL)
|
explicit_title_re = re.compile(r'^(.+?)\s*(?<!\x00)<(.*?)>$', re.DOTALL)
|
||||||
|
|
||||||
def __call__(self, name, rawtext, text, lineno, inliner, options={}, content=[]):
|
def __call__(self, name: str, rawtext: str, text: str, lineno: int,
|
||||||
# type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA
|
inliner: Inliner, options: Dict = {}, content: List[str] = []
|
||||||
|
) -> Tuple[List[Node], List[system_message]]:
|
||||||
matched = self.explicit_title_re.match(text)
|
matched = self.explicit_title_re.match(text)
|
||||||
if matched:
|
if matched:
|
||||||
self.has_explicit_title = True
|
self.has_explicit_title = True
|
||||||
@ -490,8 +456,7 @@ class SphinxTranslator(nodes.NodeVisitor):
|
|||||||
This class is strongly coupled with Sphinx.
|
This class is strongly coupled with Sphinx.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, document, builder):
|
def __init__(self, document: nodes.document, builder: "Builder") -> None:
|
||||||
# type: (nodes.document, Builder) -> None
|
|
||||||
super().__init__(document)
|
super().__init__(document)
|
||||||
self.builder = builder
|
self.builder = builder
|
||||||
self.config = builder.config
|
self.config = builder.config
|
||||||
@ -503,8 +468,7 @@ class SphinxTranslator(nodes.NodeVisitor):
|
|||||||
__document_cache__ = None # type: nodes.document
|
__document_cache__ = None # type: nodes.document
|
||||||
|
|
||||||
|
|
||||||
def new_document(source_path, settings=None):
|
def new_document(source_path: str, settings: Any = None) -> nodes.document:
|
||||||
# type: (str, Any) -> nodes.document
|
|
||||||
"""Return a new empty document object. This is an alternative of docutils'.
|
"""Return a new empty document object. This is an alternative of docutils'.
|
||||||
|
|
||||||
This is a simple wrapper for ``docutils.utils.new_document()``. It
|
This is a simple wrapper for ``docutils.utils.new_document()``. It
|
||||||
|
@ -10,20 +10,20 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import zlib
|
import zlib
|
||||||
|
from typing import Callable, IO, Iterator
|
||||||
|
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
|
from sphinx.util.typing import Inventory
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Callable, IO, Iterator # NOQA
|
|
||||||
from sphinx.builders import Builder # NOQA
|
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
|
||||||
from sphinx.util.typing import Inventory # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
BUFSIZE = 16 * 1024
|
BUFSIZE = 16 * 1024
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
if False:
|
||||||
|
# For type annotation
|
||||||
|
from sphinx.builders import Builder
|
||||||
|
from sphinx.environment import BuildEnvironment
|
||||||
|
|
||||||
|
|
||||||
class InventoryFileReader:
|
class InventoryFileReader:
|
||||||
"""A file reader for inventory file.
|
"""A file reader for inventory file.
|
||||||
@ -31,21 +31,18 @@ class InventoryFileReader:
|
|||||||
This reader supports mixture of texts and compressed texts.
|
This reader supports mixture of texts and compressed texts.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, stream):
|
def __init__(self, stream: IO) -> None:
|
||||||
# type: (IO) -> None
|
|
||||||
self.stream = stream
|
self.stream = stream
|
||||||
self.buffer = b''
|
self.buffer = b''
|
||||||
self.eof = False
|
self.eof = False
|
||||||
|
|
||||||
def read_buffer(self):
|
def read_buffer(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
chunk = self.stream.read(BUFSIZE)
|
chunk = self.stream.read(BUFSIZE)
|
||||||
if chunk == b'':
|
if chunk == b'':
|
||||||
self.eof = True
|
self.eof = True
|
||||||
self.buffer += chunk
|
self.buffer += chunk
|
||||||
|
|
||||||
def readline(self):
|
def readline(self) -> str:
|
||||||
# type: () -> str
|
|
||||||
pos = self.buffer.find(b'\n')
|
pos = self.buffer.find(b'\n')
|
||||||
if pos != -1:
|
if pos != -1:
|
||||||
line = self.buffer[:pos].decode()
|
line = self.buffer[:pos].decode()
|
||||||
@ -59,15 +56,13 @@ class InventoryFileReader:
|
|||||||
|
|
||||||
return line
|
return line
|
||||||
|
|
||||||
def readlines(self):
|
def readlines(self) -> Iterator[str]:
|
||||||
# type: () -> Iterator[str]
|
|
||||||
while not self.eof:
|
while not self.eof:
|
||||||
line = self.readline()
|
line = self.readline()
|
||||||
if line:
|
if line:
|
||||||
yield line
|
yield line
|
||||||
|
|
||||||
def read_compressed_chunks(self):
|
def read_compressed_chunks(self) -> Iterator[bytes]:
|
||||||
# type: () -> Iterator[bytes]
|
|
||||||
decompressor = zlib.decompressobj()
|
decompressor = zlib.decompressobj()
|
||||||
while not self.eof:
|
while not self.eof:
|
||||||
self.read_buffer()
|
self.read_buffer()
|
||||||
@ -75,8 +70,7 @@ class InventoryFileReader:
|
|||||||
self.buffer = b''
|
self.buffer = b''
|
||||||
yield decompressor.flush()
|
yield decompressor.flush()
|
||||||
|
|
||||||
def read_compressed_lines(self):
|
def read_compressed_lines(self) -> Iterator[str]:
|
||||||
# type: () -> Iterator[str]
|
|
||||||
buf = b''
|
buf = b''
|
||||||
for chunk in self.read_compressed_chunks():
|
for chunk in self.read_compressed_chunks():
|
||||||
buf += chunk
|
buf += chunk
|
||||||
@ -89,8 +83,7 @@ class InventoryFileReader:
|
|||||||
|
|
||||||
class InventoryFile:
|
class InventoryFile:
|
||||||
@classmethod
|
@classmethod
|
||||||
def load(cls, stream, uri, joinfunc):
|
def load(cls, stream: IO, uri: str, joinfunc: Callable) -> Inventory:
|
||||||
# type: (IO, str, Callable) -> Inventory
|
|
||||||
reader = InventoryFileReader(stream)
|
reader = InventoryFileReader(stream)
|
||||||
line = reader.readline().rstrip()
|
line = reader.readline().rstrip()
|
||||||
if line == '# Sphinx inventory version 1':
|
if line == '# Sphinx inventory version 1':
|
||||||
@ -101,8 +94,7 @@ class InventoryFile:
|
|||||||
raise ValueError('invalid inventory header: %s' % line)
|
raise ValueError('invalid inventory header: %s' % line)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_v1(cls, stream, uri, join):
|
def load_v1(cls, stream: InventoryFileReader, uri: str, join: Callable) -> Inventory:
|
||||||
# type: (InventoryFileReader, str, Callable) -> Inventory
|
|
||||||
invdata = {} # type: Inventory
|
invdata = {} # type: Inventory
|
||||||
projname = stream.readline().rstrip()[11:]
|
projname = stream.readline().rstrip()[11:]
|
||||||
version = stream.readline().rstrip()[11:]
|
version = stream.readline().rstrip()[11:]
|
||||||
@ -120,8 +112,7 @@ class InventoryFile:
|
|||||||
return invdata
|
return invdata
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_v2(cls, stream, uri, join):
|
def load_v2(cls, stream: InventoryFileReader, uri: str, join: Callable) -> Inventory:
|
||||||
# type: (InventoryFileReader, str, Callable) -> Inventory
|
|
||||||
invdata = {} # type: Inventory
|
invdata = {} # type: Inventory
|
||||||
projname = stream.readline().rstrip()[11:]
|
projname = stream.readline().rstrip()[11:]
|
||||||
version = stream.readline().rstrip()[11:]
|
version = stream.readline().rstrip()[11:]
|
||||||
@ -150,10 +141,8 @@ class InventoryFile:
|
|||||||
return invdata
|
return invdata
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def dump(cls, filename, env, builder):
|
def dump(cls, filename: str, env: "BuildEnvironment", builder: "Builder") -> None:
|
||||||
# type: (str, BuildEnvironment, Builder) -> None
|
def escape(string: str) -> str:
|
||||||
def escape(string):
|
|
||||||
# type: (str) -> str
|
|
||||||
return re.sub("\\s+", " ", string)
|
return re.sub("\\s+", " ", string)
|
||||||
|
|
||||||
with open(os.path.join(filename), 'wb') as f:
|
with open(os.path.join(filename), 'wb') as f:
|
||||||
|
@ -10,10 +10,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
from typing import Any, Dict, IO, List, Match, Union
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Dict, IO, List, Match, Union # NOQA
|
|
||||||
|
|
||||||
_str_re = re.compile(r'"(\\\\|\\"|[^"])*"')
|
_str_re = re.compile(r'"(\\\\|\\"|[^"])*"')
|
||||||
_int_re = re.compile(r'\d+')
|
_int_re = re.compile(r'\d+')
|
||||||
@ -35,10 +32,8 @@ ESCAPE_DICT = {
|
|||||||
ESCAPED = re.compile(r'\\u.{4}|\\.')
|
ESCAPED = re.compile(r'\\u.{4}|\\.')
|
||||||
|
|
||||||
|
|
||||||
def encode_string(s):
|
def encode_string(s: str) -> str:
|
||||||
# type: (str) -> str
|
def replace(match: Match) -> str:
|
||||||
def replace(match):
|
|
||||||
# type: (Match) -> str
|
|
||||||
s = match.group(0)
|
s = match.group(0)
|
||||||
try:
|
try:
|
||||||
return ESCAPE_DICT[s]
|
return ESCAPE_DICT[s]
|
||||||
@ -55,8 +50,7 @@ def encode_string(s):
|
|||||||
return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"'
|
return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"'
|
||||||
|
|
||||||
|
|
||||||
def decode_string(s):
|
def decode_string(s: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
return ESCAPED.sub(lambda m: eval('"' + m.group() + '"'), s)
|
return ESCAPED.sub(lambda m: eval('"' + m.group() + '"'), s)
|
||||||
|
|
||||||
|
|
||||||
@ -78,8 +72,7 @@ do import static with
|
|||||||
double in super""".split())
|
double in super""".split())
|
||||||
|
|
||||||
|
|
||||||
def dumps(obj, key=False):
|
def dumps(obj: Any, key: bool = False) -> str:
|
||||||
# type: (Any, bool) -> str
|
|
||||||
if key:
|
if key:
|
||||||
if not isinstance(obj, str):
|
if not isinstance(obj, str):
|
||||||
obj = str(obj)
|
obj = str(obj)
|
||||||
@ -107,13 +100,11 @@ def dumps(obj, key=False):
|
|||||||
raise TypeError(type(obj))
|
raise TypeError(type(obj))
|
||||||
|
|
||||||
|
|
||||||
def dump(obj, f):
|
def dump(obj: Any, f: IO) -> None:
|
||||||
# type: (Any, IO) -> None
|
|
||||||
f.write(dumps(obj))
|
f.write(dumps(obj))
|
||||||
|
|
||||||
|
|
||||||
def loads(x):
|
def loads(x: str) -> Any:
|
||||||
# type: (str) -> Any
|
|
||||||
"""Loader that can read the JS subset the indexer produces."""
|
"""Loader that can read the JS subset the indexer produces."""
|
||||||
nothing = object()
|
nothing = object()
|
||||||
i = 0
|
i = 0
|
||||||
@ -205,6 +196,5 @@ def loads(x):
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def load(f):
|
def load(f: IO) -> Any:
|
||||||
# type: (IO) -> Any
|
|
||||||
return loads(f.read())
|
return loads(f.read())
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user