summaryrefslogtreecommitdiff
path: root/sphinx/util/docutils.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/util/docutils.py')
-rw-r--r--sphinx/util/docutils.py61
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)