diff options
Diffstat (limited to 'sphinx/util/docutils.py')
-rw-r--r-- | sphinx/util/docutils.py | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py index bed786f4b..4438f9123 100644 --- a/sphinx/util/docutils.py +++ b/sphinx/util/docutils.py @@ -10,17 +10,33 @@ """ from __future__ import absolute_import +import re from copy import copy from contextlib import contextmanager + import docutils +from docutils.utils import Reporter from docutils.parsers.rst import directives, roles +from sphinx.util import logging + +logger = logging.getLogger(__name__) +report_re = re.compile('^(.+?:\\d+): \\((DEBUG|INFO|WARNING|ERROR|SEVERE)/(\\d+)?\\) ' + '(.+?)\n?$') + +if False: + # For type annotation + from typing import Any, Callable, Iterator, List, Tuple # NOQA + from docutils import nodes # NOQA + from sphinx.environment import BuildEnvironment # NOQA + __version_info__ = tuple(map(int, docutils.__version__.split('.'))) @contextmanager def docutils_namespace(): + # type: () -> Iterator[None] """Create namespace for reST parsers.""" try: _directives = copy(directives._directives) @@ -41,17 +57,21 @@ class sphinx_domains(object): markup takes precedence. """ def __init__(self, env): + # type: (BuildEnvironment) -> None self.env = env - self.directive_func = None - self.roles_func = None + self.directive_func = None # type: Callable + self.roles_func = None # type: Callable def __enter__(self): + # type: () -> None self.enable() def __exit__(self, type, value, traceback): + # type: (unicode, unicode, unicode) -> None self.disable() def enable(self): + # type: () -> None self.directive_func = directives.directive self.role_func = roles.role @@ -59,10 +79,12 @@ class sphinx_domains(object): roles.role = self.lookup_role def disable(self): + # type: () -> None directives.directive = self.directive_func roles.role = self.role_func def lookup_domain_element(self, type, name): + # type: (unicode, unicode) -> Tuple[Any, List] """Lookup a markup element (directive or role), given its name which can be a full name (with domain). """ @@ -71,7 +93,7 @@ class sphinx_domains(object): if ':' in name: domain_name, name = name.split(':', 1) if domain_name in self.env.domains: - domain = self.env.domains[domain_name] + domain = self.env.get_domain(domain_name) element = getattr(domain, type)(name) if element is not None: return element, [] @@ -84,20 +106,51 @@ class sphinx_domains(object): return element, [] # always look in the std domain - element = getattr(self.env.domains['std'], type)(name) + element = getattr(self.env.get_domain('std'), type)(name) if element is not None: return element, [] raise ElementLookupError def lookup_directive(self, name, lang_module, document): + # type: (unicode, unicode, nodes.document) -> Tuple[Any, List] try: return self.lookup_domain_element('directive', name) except ElementLookupError: return self.directive_func(name, lang_module, document) def lookup_role(self, name, lang_module, lineno, reporter): + # type: (unicode, unicode, int, Any) -> Tuple[Any, List] try: return self.lookup_domain_element('role', name) except ElementLookupError: return self.role_func(name, lang_module, lineno, reporter) + + +class WarningStream(object): + def write(self, text): + # type: (unicode) -> None + matched = report_re.search(text) # type: ignore + if not matched: + logger.warning(text.rstrip("\r\n")) + else: + location, type, level, message = matched.groups() + logger.log(type, message, location=location) + + +class LoggingReporter(Reporter): + def __init__(self, source, report_level, halt_level, + debug=False, error_handler='backslashreplace'): + # type: (unicode, int, int, bool, unicode) -> None + stream = WarningStream() + Reporter.__init__(self, source, report_level, halt_level, + stream, debug, error_handler=error_handler) + + def set_conditions(self, category, report_level, halt_level, debug=False): + # type: (unicode, int, int, bool) -> None + Reporter.set_conditions(self, category, report_level, halt_level, debug=debug) + + +def is_html5_writer_available(): + # type: () -> bool + return __version_info__ > (0, 13, 0) |