mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Add type-check annotations to sphinx.application
This commit is contained in:
parent
8cfb281b05
commit
9c66ac71ab
@ -22,13 +22,13 @@ from collections import deque
|
||||
|
||||
from six import iteritems, itervalues, text_type
|
||||
from six.moves import cStringIO
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import convert_directive_function, \
|
||||
directives, roles
|
||||
|
||||
import sphinx
|
||||
from sphinx import package_dir, locale
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.config import Config
|
||||
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \
|
||||
VersionRequirementError, ConfigError
|
||||
@ -36,15 +36,25 @@ from sphinx.domains import ObjType
|
||||
from sphinx.domains.std import GenericObject, Target, StandardDomain
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.io import SphinxStandaloneReader
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util import pycompat # noqa: F401
|
||||
from sphinx.util import import_object
|
||||
from sphinx.util.tags import Tags
|
||||
from sphinx.util.osutil import ENOENT
|
||||
from sphinx.util.logging import is_suppressed_warning
|
||||
from sphinx.util.console import bold, lightgray, darkgray, darkred, darkgreen, \
|
||||
term_width_line
|
||||
from sphinx.util.console import ( # type: ignore
|
||||
bold, lightgray, darkgray, darkred, darkgreen, term_width_line
|
||||
)
|
||||
from sphinx.util.i18n import find_catalog_source_files
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, IO, Iterable, Iterator, Tuple, Type, Union # NOQA
|
||||
from docutils.parsers import Parser # NOQA
|
||||
from docutils.transform import Transform # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
from sphinx.domains import Domain # NOQA
|
||||
|
||||
# List of all known core events. Maps name to arguments description.
|
||||
events = {
|
||||
'builder-inited': '',
|
||||
@ -60,7 +70,7 @@ events = {
|
||||
'html-collect-pages': 'builder',
|
||||
'html-page-context': 'pagename, context, doctree or None',
|
||||
'build-finished': 'exception',
|
||||
}
|
||||
} # type: Dict[unicode, unicode]
|
||||
builtin_extensions = (
|
||||
'sphinx.builders.applehelp',
|
||||
'sphinx.builders.changes',
|
||||
@ -90,14 +100,14 @@ builtin_extensions = (
|
||||
'sphinx.directives.other',
|
||||
'sphinx.directives.patches',
|
||||
'sphinx.roles',
|
||||
)
|
||||
) # type: Tuple[unicode, ...]
|
||||
|
||||
CONFIG_FILENAME = 'conf.py'
|
||||
ENV_PICKLE_FILENAME = 'environment.pickle'
|
||||
|
||||
# list of deprecated extensions. Keys are extension name.
|
||||
# Values are Sphinx version that merge the extension.
|
||||
EXTENSION_BLACKLIST = {"sphinxjp.themecore": "1.2"}
|
||||
EXTENSION_BLACKLIST = {"sphinxjp.themecore": "1.2"} # type: Dict[unicode, unicode]
|
||||
|
||||
|
||||
class Sphinx(object):
|
||||
@ -106,19 +116,20 @@ class Sphinx(object):
|
||||
confoverrides=None, status=sys.stdout, warning=sys.stderr,
|
||||
freshenv=False, warningiserror=False, tags=None, verbosity=0,
|
||||
parallel=0):
|
||||
# type: (unicode, unicode, unicode, unicode, unicode, Dict, IO, IO, bool, bool, unicode, int, int) -> None # NOQA
|
||||
self.verbosity = verbosity
|
||||
self.next_listener_id = 0
|
||||
self._extensions = {}
|
||||
self._extension_metadata = {}
|
||||
self._additional_source_parsers = {}
|
||||
self._listeners = {}
|
||||
self._setting_up_extension = ['?']
|
||||
self.domains = {}
|
||||
self._extensions = {} # type: Dict[unicode, Any]
|
||||
self._extension_metadata = {} # type: Dict[unicode, Dict[unicode, Any]]
|
||||
self._additional_source_parsers = {} # type: Dict[unicode, Parser]
|
||||
self._listeners = {} # type: Dict[unicode, Dict[int, Callable]]
|
||||
self._setting_up_extension = ['?'] # type: List[unicode]
|
||||
self.domains = {} # type: Dict[unicode, Type[Domain]]
|
||||
self.buildername = buildername
|
||||
self.builderclasses = {}
|
||||
self.builder = None
|
||||
self.env = None
|
||||
self.enumerable_nodes = {}
|
||||
self.builderclasses = {} # type: Dict[unicode, Type[Builder]]
|
||||
self.builder = None # type: Builder
|
||||
self.env = None # type: BuildEnvironment
|
||||
self.enumerable_nodes = {} # type: Dict[nodes.Node, Tuple[unicode, Callable]] # NOQA
|
||||
|
||||
self.srcdir = srcdir
|
||||
self.confdir = confdir
|
||||
@ -128,24 +139,24 @@ class Sphinx(object):
|
||||
self.parallel = parallel
|
||||
|
||||
if status is None:
|
||||
self._status = cStringIO()
|
||||
self._status = cStringIO() # type: IO
|
||||
self.quiet = True
|
||||
else:
|
||||
self._status = status
|
||||
self.quiet = False
|
||||
|
||||
if warning is None:
|
||||
self._warning = cStringIO()
|
||||
self._warning = cStringIO() # type: IO
|
||||
else:
|
||||
self._warning = warning
|
||||
self._warncount = 0
|
||||
self.warningiserror = warningiserror
|
||||
|
||||
self._events = events.copy()
|
||||
self._translators = {}
|
||||
self._translators = {} # type: Dict[unicode, nodes.GenericNodeVisitor]
|
||||
|
||||
# keep last few messages for traceback
|
||||
self.messagelog = deque(maxlen=10)
|
||||
self.messagelog = deque(maxlen=10) # type: deque
|
||||
|
||||
# say hello to the world
|
||||
self.info(bold('Running Sphinx v%s' % sphinx.__display_version__))
|
||||
@ -246,6 +257,7 @@ class Sphinx(object):
|
||||
self._init_enumerable_nodes()
|
||||
|
||||
def _init_i18n(self):
|
||||
# type: () -> None
|
||||
"""Load translated strings from the configured localedirs if enabled in
|
||||
the configuration.
|
||||
"""
|
||||
@ -271,6 +283,7 @@ class Sphinx(object):
|
||||
self.info('not available for built-in messages')
|
||||
|
||||
def _init_source_parsers(self):
|
||||
# type: () -> None
|
||||
for suffix, parser in iteritems(self._additional_source_parsers):
|
||||
if suffix not in self.config.source_suffix:
|
||||
self.config.source_suffix.append(suffix)
|
||||
@ -278,6 +291,7 @@ class Sphinx(object):
|
||||
self.config.source_parsers[suffix] = parser
|
||||
|
||||
def _init_env(self, freshenv):
|
||||
# type: (bool) -> None
|
||||
if freshenv:
|
||||
self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config)
|
||||
self.env.set_warnfunc(self.warn)
|
||||
@ -304,6 +318,7 @@ class Sphinx(object):
|
||||
return self._init_env(freshenv=True)
|
||||
|
||||
def _init_builder(self, buildername):
|
||||
# type: (unicode) -> None
|
||||
if buildername is None:
|
||||
print('No builder selected, using default: html', file=self._status)
|
||||
buildername = 'html'
|
||||
@ -315,12 +330,14 @@ class Sphinx(object):
|
||||
self.emit('builder-inited')
|
||||
|
||||
def _init_enumerable_nodes(self):
|
||||
# type: () -> None
|
||||
for node, settings in iteritems(self.enumerable_nodes):
|
||||
self.env.domains['std'].enumerable_nodes[node] = settings
|
||||
self.env.domains['std'].enumerable_nodes[node] = settings # type: ignore
|
||||
|
||||
# ---- main "build" method -------------------------------------------------
|
||||
|
||||
def build(self, force_all=False, filenames=None):
|
||||
# type: (bool, List[unicode]) -> None
|
||||
try:
|
||||
if force_all:
|
||||
self.builder.compile_all_catalogs()
|
||||
@ -354,6 +371,7 @@ class Sphinx(object):
|
||||
# ---- logging handling ----------------------------------------------------
|
||||
|
||||
def _log(self, message, wfile, nonl=False):
|
||||
# type: (unicode, IO, bool) -> None
|
||||
try:
|
||||
wfile.write(message)
|
||||
except UnicodeEncodeError:
|
||||
@ -367,6 +385,7 @@ class Sphinx(object):
|
||||
|
||||
def warn(self, message, location=None, prefix='WARNING: ',
|
||||
type=None, subtype=None, colorfunc=darkred):
|
||||
# type: (unicode, unicode, unicode, unicode, unicode, Callable) -> None
|
||||
"""Emit a warning.
|
||||
|
||||
If *location* is given, it should either be a tuple of (docname, lineno)
|
||||
@ -399,6 +418,7 @@ class Sphinx(object):
|
||||
self._log(colorfunc(warntext), self._warning, True)
|
||||
|
||||
def info(self, message='', nonl=False):
|
||||
# type: (unicode, bool) -> None
|
||||
"""Emit an informational message.
|
||||
|
||||
If *nonl* is true, don't emit a newline at the end (which implies that
|
||||
@ -407,6 +427,7 @@ class Sphinx(object):
|
||||
self._log(message, self._status, nonl)
|
||||
|
||||
def verbose(self, message, *args, **kwargs):
|
||||
# type: (unicode, Any, Any) -> None
|
||||
"""Emit a verbose informational message.
|
||||
|
||||
The message will only be emitted for verbosity levels >= 1 (i.e. at
|
||||
@ -422,6 +443,7 @@ class Sphinx(object):
|
||||
self._log(message, self._status)
|
||||
|
||||
def debug(self, message, *args, **kwargs):
|
||||
# type: (unicode, Any, Any) -> None
|
||||
"""Emit a debug-level informational message.
|
||||
|
||||
The message will only be emitted for verbosity levels >= 2 (i.e. at
|
||||
@ -437,6 +459,7 @@ class Sphinx(object):
|
||||
self._log(darkgray(message), self._status)
|
||||
|
||||
def debug2(self, message, *args, **kwargs):
|
||||
# type: (unicode, Any, Any) -> None
|
||||
"""Emit a lowlevel debug-level informational message.
|
||||
|
||||
The message will only be emitted for verbosity level 3 (i.e. three
|
||||
@ -452,6 +475,7 @@ class Sphinx(object):
|
||||
self._log(lightgray(message), self._status)
|
||||
|
||||
def _display_chunk(chunk):
|
||||
# type: (Any) -> unicode
|
||||
if isinstance(chunk, (list, tuple)):
|
||||
if len(chunk) == 1:
|
||||
return text_type(chunk[0])
|
||||
@ -460,6 +484,7 @@ class Sphinx(object):
|
||||
|
||||
def old_status_iterator(self, iterable, summary, colorfunc=darkgreen,
|
||||
stringify_func=_display_chunk):
|
||||
# type: (Iterable, unicode, Callable, Callable) -> Iterator
|
||||
l = 0
|
||||
for item in iterable:
|
||||
if l == 0:
|
||||
@ -473,6 +498,7 @@ class Sphinx(object):
|
||||
# new version with progress info
|
||||
def status_iterator(self, iterable, summary, colorfunc=darkgreen, length=0,
|
||||
stringify_func=_display_chunk):
|
||||
# type: (Iterable, unicode, Callable, int, Callable) -> Iterable
|
||||
if length == 0:
|
||||
for item in self.old_status_iterator(iterable, summary, colorfunc,
|
||||
stringify_func):
|
||||
@ -496,6 +522,7 @@ class Sphinx(object):
|
||||
# ---- general extensibility interface -------------------------------------
|
||||
|
||||
def setup_extension(self, extension):
|
||||
# type: (unicode) -> None
|
||||
"""Import and setup a Sphinx extension module. No-op if called twice."""
|
||||
self.debug('[app] setting up extension: %r', extension)
|
||||
if extension in self._extensions:
|
||||
@ -543,21 +570,25 @@ class Sphinx(object):
|
||||
self._setting_up_extension.pop()
|
||||
|
||||
def require_sphinx(self, version):
|
||||
# type: (unicode) -> None
|
||||
# check the Sphinx version if requested
|
||||
if version > sphinx.__display_version__[:3]:
|
||||
raise VersionRequirementError(version)
|
||||
|
||||
def import_object(self, objname, source=None):
|
||||
# type: (str, unicode) -> Any
|
||||
"""Import an object from a 'module.name' string."""
|
||||
return import_object(objname, source=None)
|
||||
|
||||
# event interface
|
||||
|
||||
def _validate_event(self, event):
|
||||
# type: (unicode) -> None
|
||||
if event not in self._events:
|
||||
raise ExtensionError('Unknown event name: %s' % event)
|
||||
|
||||
def connect(self, event, callback):
|
||||
# type: (unicode, Callable) -> int
|
||||
self._validate_event(event)
|
||||
listener_id = self.next_listener_id
|
||||
if event not in self._listeners:
|
||||
@ -570,11 +601,13 @@ class Sphinx(object):
|
||||
return listener_id
|
||||
|
||||
def disconnect(self, listener_id):
|
||||
# type: (int) -> None
|
||||
self.debug('[app] disconnecting event: [id=%s]', listener_id)
|
||||
for event in itervalues(self._listeners):
|
||||
event.pop(listener_id, None)
|
||||
|
||||
def emit(self, event, *args):
|
||||
# type: (unicode, Any) -> List
|
||||
try:
|
||||
self.debug2('[app] emitting event: %r%s', event, repr(args)[:100])
|
||||
except Exception:
|
||||
@ -588,6 +621,7 @@ class Sphinx(object):
|
||||
return results
|
||||
|
||||
def emit_firstresult(self, event, *args):
|
||||
# type: (unicode, Any) -> Any
|
||||
for result in self.emit(event, *args):
|
||||
if result is not None:
|
||||
return result
|
||||
@ -596,6 +630,7 @@ class Sphinx(object):
|
||||
# registering addon parts
|
||||
|
||||
def add_builder(self, builder):
|
||||
# type: (Type[Builder]) -> None
|
||||
self.debug('[app] adding builder: %r', builder)
|
||||
if not hasattr(builder, 'name'):
|
||||
raise ExtensionError('Builder class %s has no "name" attribute'
|
||||
@ -607,8 +642,9 @@ class Sphinx(object):
|
||||
self.builderclasses[builder.name] = builder
|
||||
|
||||
def add_config_value(self, name, default, rebuild, types=()):
|
||||
# type: (unicode, Any, Union[bool, unicode], Any) -> None
|
||||
self.debug('[app] adding config value: %r',
|
||||
(name, default, rebuild) + ((types,) if types else ()))
|
||||
(name, default, rebuild) + ((types,) if types else ())) # type: ignore
|
||||
if name in self.config.values:
|
||||
raise ExtensionError('Config value %r already present' % name)
|
||||
if rebuild in (False, True):
|
||||
@ -616,16 +652,19 @@ class Sphinx(object):
|
||||
self.config.values[name] = (default, rebuild, types)
|
||||
|
||||
def add_event(self, name):
|
||||
# type: (unicode) -> None
|
||||
self.debug('[app] adding event: %r', name)
|
||||
if name in self._events:
|
||||
raise ExtensionError('Event %r already present' % name)
|
||||
self._events[name] = ''
|
||||
|
||||
def set_translator(self, name, translator_class):
|
||||
# type: (unicode, Any) -> None
|
||||
self.info(bold('A Translator for the %s builder is changed.' % name))
|
||||
self._translators[name] = translator_class
|
||||
|
||||
def add_node(self, node, **kwds):
|
||||
# type: (nodes.Node, Any) -> None
|
||||
self.debug('[app] adding node: %r', (node, kwds))
|
||||
if not kwds.pop('override', False) and \
|
||||
hasattr(nodes.GenericNodeVisitor, 'visit_' + node.__name__):
|
||||
@ -644,17 +683,15 @@ class Sphinx(object):
|
||||
if translator is not None:
|
||||
pass
|
||||
elif key == 'html':
|
||||
from sphinx.writers.html import HTMLTranslator as translator
|
||||
from sphinx.writers.html import HTMLTranslator as translator # type: ignore
|
||||
elif key == 'latex':
|
||||
from sphinx.writers.latex import LaTeXTranslator as translator
|
||||
from sphinx.writers.latex import LaTeXTranslator as translator # type: ignore
|
||||
elif key == 'text':
|
||||
from sphinx.writers.text import TextTranslator as translator
|
||||
from sphinx.writers.text import TextTranslator as translator # type: ignore
|
||||
elif key == 'man':
|
||||
from sphinx.writers.manpage import ManualPageTranslator \
|
||||
as translator
|
||||
from sphinx.writers.manpage import ManualPageTranslator as translator # type: ignore # NOQA
|
||||
elif key == 'texinfo':
|
||||
from sphinx.writers.texinfo import TexinfoTranslator \
|
||||
as translator
|
||||
from sphinx.writers.texinfo import TexinfoTranslator as translator # type: ignore # NOQA
|
||||
else:
|
||||
# ignore invalid keys for compatibility
|
||||
continue
|
||||
@ -663,14 +700,16 @@ class Sphinx(object):
|
||||
setattr(translator, 'depart_'+node.__name__, depart)
|
||||
|
||||
def add_enumerable_node(self, node, figtype, title_getter=None, **kwds):
|
||||
# type: (nodes.Node, unicode, Callable, Any) -> None
|
||||
self.enumerable_nodes[node] = (figtype, title_getter)
|
||||
self.add_node(node, **kwds)
|
||||
|
||||
def _directive_helper(self, obj, content=None, arguments=None, **options):
|
||||
# type: (Any, unicode, Any, Any) -> Any
|
||||
if isinstance(obj, (types.FunctionType, types.MethodType)):
|
||||
obj.content = content
|
||||
obj.arguments = arguments or (0, 0, False)
|
||||
obj.options = options
|
||||
obj.content = content # type: ignore
|
||||
obj.arguments = arguments or (0, 0, False) # type: ignore
|
||||
obj.options = options # type: ignore
|
||||
return convert_directive_function(obj)
|
||||
else:
|
||||
if content or arguments or options:
|
||||
@ -679,6 +718,7 @@ class Sphinx(object):
|
||||
return obj
|
||||
|
||||
def add_directive(self, name, obj, content=None, arguments=None, **options):
|
||||
# type: (unicode, Any, unicode, Any, Any) -> None
|
||||
self.debug('[app] adding directive: %r',
|
||||
(name, obj, content, arguments, options))
|
||||
if name in directives._directives:
|
||||
@ -690,6 +730,7 @@ class Sphinx(object):
|
||||
name, self._directive_helper(obj, content, arguments, **options))
|
||||
|
||||
def add_role(self, name, role):
|
||||
# type: (unicode, Any) -> None
|
||||
self.debug('[app] adding role: %r', (name, role))
|
||||
if name in roles._roles:
|
||||
self.warn('while setting up extension %s: role %r is '
|
||||
@ -699,6 +740,7 @@ class Sphinx(object):
|
||||
roles.register_local_role(name, role)
|
||||
|
||||
def add_generic_role(self, name, nodeclass):
|
||||
# type: (unicode, Any) -> None
|
||||
# don't use roles.register_generic_role because it uses
|
||||
# register_canonical_role
|
||||
self.debug('[app] adding generic role: %r', (name, nodeclass))
|
||||
@ -711,12 +753,14 @@ class Sphinx(object):
|
||||
roles.register_local_role(name, role)
|
||||
|
||||
def add_domain(self, domain):
|
||||
# type: (Type[Domain]) -> None
|
||||
self.debug('[app] adding domain: %r', domain)
|
||||
if domain.name in self.domains:
|
||||
raise ExtensionError('domain %s already registered' % domain.name)
|
||||
self.domains[domain.name] = domain
|
||||
|
||||
def override_domain(self, domain):
|
||||
# type: (Type[Domain]) -> None
|
||||
self.debug('[app] overriding domain: %r', domain)
|
||||
if domain.name not in self.domains:
|
||||
raise ExtensionError('domain %s not yet registered' % domain.name)
|
||||
@ -727,6 +771,7 @@ class Sphinx(object):
|
||||
|
||||
def add_directive_to_domain(self, domain, name, obj,
|
||||
content=None, arguments=None, **options):
|
||||
# type: (unicode, unicode, Any, unicode, Any, Any) -> None
|
||||
self.debug('[app] adding directive to domain: %r',
|
||||
(domain, name, obj, content, arguments, options))
|
||||
if domain not in self.domains:
|
||||
@ -735,12 +780,14 @@ class Sphinx(object):
|
||||
self._directive_helper(obj, content, arguments, **options)
|
||||
|
||||
def add_role_to_domain(self, domain, name, role):
|
||||
# type: (unicode, unicode, Any) -> None
|
||||
self.debug('[app] adding role to domain: %r', (domain, name, role))
|
||||
if domain not in self.domains:
|
||||
raise ExtensionError('domain %s not yet registered' % domain)
|
||||
self.domains[domain].roles[name] = role
|
||||
|
||||
def add_index_to_domain(self, domain, index):
|
||||
# type: (unicode, unicode) -> None
|
||||
self.debug('[app] adding index to domain: %r', (domain, index))
|
||||
if domain not in self.domains:
|
||||
raise ExtensionError('domain %s not yet registered' % domain)
|
||||
@ -749,15 +796,16 @@ class Sphinx(object):
|
||||
def add_object_type(self, directivename, rolename, indextemplate='',
|
||||
parse_node=None, ref_nodeclass=None, objname='',
|
||||
doc_field_types=[]):
|
||||
# type: (unicode, unicode, unicode, Callable, nodes.Node, unicode, List) -> None
|
||||
self.debug('[app] adding object type: %r',
|
||||
(directivename, rolename, indextemplate, parse_node,
|
||||
ref_nodeclass, objname, doc_field_types))
|
||||
StandardDomain.object_types[directivename] = \
|
||||
ObjType(objname or directivename, rolename)
|
||||
# create a subclass of GenericObject as the new directive
|
||||
new_directive = type(directivename, (GenericObject, object),
|
||||
new_directive = type(directivename, (GenericObject, object), # type: ignore
|
||||
{'indextemplate': indextemplate,
|
||||
'parse_node': staticmethod(parse_node),
|
||||
'parse_node': staticmethod(parse_node), # type: ignore
|
||||
'doc_field_types': doc_field_types})
|
||||
StandardDomain.directives[directivename] = new_directive
|
||||
# XXX support more options?
|
||||
@ -768,23 +816,26 @@ class Sphinx(object):
|
||||
|
||||
def add_crossref_type(self, directivename, rolename, indextemplate='',
|
||||
ref_nodeclass=None, objname=''):
|
||||
# type: (unicode, unicode, unicode, nodes.Node, unicode) -> None
|
||||
self.debug('[app] adding crossref type: %r',
|
||||
(directivename, rolename, indextemplate, ref_nodeclass,
|
||||
objname))
|
||||
StandardDomain.object_types[directivename] = \
|
||||
ObjType(objname or directivename, rolename)
|
||||
# create a subclass of Target as the new directive
|
||||
new_directive = type(directivename, (Target, object),
|
||||
new_directive = type(directivename, (Target, object), # type: ignore
|
||||
{'indextemplate': indextemplate})
|
||||
StandardDomain.directives[directivename] = new_directive
|
||||
# XXX support more options?
|
||||
StandardDomain.roles[rolename] = XRefRole(innernodeclass=ref_nodeclass)
|
||||
|
||||
def add_transform(self, transform):
|
||||
# type: (Transform) -> None
|
||||
self.debug('[app] adding transform: %r', transform)
|
||||
SphinxStandaloneReader.transforms.append(transform)
|
||||
|
||||
def add_javascript(self, filename):
|
||||
# type: (unicode) -> None
|
||||
self.debug('[app] adding javascript: %r', filename)
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
if '://' in filename:
|
||||
@ -794,6 +845,7 @@ class Sphinx(object):
|
||||
posixpath.join('_static', filename))
|
||||
|
||||
def add_stylesheet(self, filename):
|
||||
# type: (unicode) -> None
|
||||
self.debug('[app] adding stylesheet: %r', filename)
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
if '://' in filename:
|
||||
@ -803,10 +855,12 @@ class Sphinx(object):
|
||||
posixpath.join('_static', filename))
|
||||
|
||||
def add_latex_package(self, packagename, options=None):
|
||||
# type: (unicode, unicode) -> None
|
||||
self.debug('[app] adding latex package: %r', packagename)
|
||||
self.builder.usepackages.append((packagename, options))
|
||||
|
||||
def add_lexer(self, alias, lexer):
|
||||
# type: (unicode, Any) -> None
|
||||
self.debug('[app] adding lexer: %r', (alias, lexer))
|
||||
from sphinx.highlighting import lexers
|
||||
if lexers is None:
|
||||
@ -814,23 +868,27 @@ class Sphinx(object):
|
||||
lexers[alias] = lexer
|
||||
|
||||
def add_autodocumenter(self, cls):
|
||||
# type: (Any) -> None
|
||||
self.debug('[app] adding autodocumenter: %r', cls)
|
||||
from sphinx.ext import autodoc
|
||||
autodoc.add_documenter(cls)
|
||||
self.add_directive('auto' + cls.objtype, autodoc.AutoDirective)
|
||||
|
||||
def add_autodoc_attrgetter(self, type, getter):
|
||||
# type: (Any, Callable) -> None
|
||||
self.debug('[app] adding autodoc attrgetter: %r', (type, getter))
|
||||
from sphinx.ext import autodoc
|
||||
autodoc.AutoDirective._special_attrgetters[type] = getter
|
||||
|
||||
def add_search_language(self, cls):
|
||||
# type: (Any) -> None
|
||||
self.debug('[app] adding search language: %r', cls)
|
||||
from sphinx.search import languages, SearchLanguage
|
||||
assert issubclass(cls, SearchLanguage)
|
||||
languages[cls.lang] = cls
|
||||
|
||||
def add_source_parser(self, suffix, parser):
|
||||
# type: (unicode, Parser) -> None
|
||||
self.debug('[app] adding search source_parser: %r, %r', suffix, parser)
|
||||
if suffix in self._additional_source_parsers:
|
||||
self.warn('while setting up extension %s: source_parser for %r is '
|
||||
@ -847,6 +905,7 @@ class TemplateBridge(object):
|
||||
"""
|
||||
|
||||
def init(self, builder, theme=None, dirs=None):
|
||||
# type: (Builder, unicode, List[unicode]) -> None
|
||||
"""Called by the builder to initialize the template system.
|
||||
|
||||
*builder* is the builder object; you'll probably want to look at the
|
||||
@ -858,6 +917,7 @@ class TemplateBridge(object):
|
||||
raise NotImplementedError('must be implemented in subclasses')
|
||||
|
||||
def newest_template_mtime(self):
|
||||
# type: () -> float
|
||||
"""Called by the builder to determine if output files are outdated
|
||||
because of template changes. Return the mtime of the newest template
|
||||
file that was changed. The default implementation returns ``0``.
|
||||
@ -865,12 +925,14 @@ class TemplateBridge(object):
|
||||
return 0
|
||||
|
||||
def render(self, template, context):
|
||||
# type: (unicode, Dict) -> None
|
||||
"""Called by the builder to render a template given as a filename with
|
||||
a specified context (a Python dictionary).
|
||||
"""
|
||||
raise NotImplementedError('must be implemented in subclasses')
|
||||
|
||||
def render_string(self, template, context):
|
||||
# type: (unicode, Dict) -> unicode
|
||||
"""Called by the builder to render a template given as a string with a
|
||||
specified context (a Python dictionary).
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user