From fb227f24cba672b44b4b71d11ccef0ac891e2dd3 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 5 Sep 2016 18:27:32 +0900 Subject: [PATCH] docutils bridge --- sphinx/io.py | 9 +++++++++ sphinx/util/docutils.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/sphinx/io.py b/sphinx/io.py index c6fea570e..e29420d97 100644 --- a/sphinx/io.py +++ b/sphinx/io.py @@ -24,6 +24,7 @@ from sphinx.transforms.i18n import ( PreserveTranslatableMessages, Locale, RemoveTranslatableInline, ) from sphinx.util import import_object, split_docinfo +from sphinx.util.docutils import LoggingReporter if False: # For type annotation @@ -73,6 +74,14 @@ class SphinxBaseReader(standalone.Reader): # type: () -> List[Transform] return standalone.Reader.get_transforms(self) + self.transforms + def new_document(self): + document = standalone.Reader.new_document(self) + reporter = document.reporter + document.reporter = LoggingReporter(reporter.source, reporter.report_level, + reporter.halt_level, reporter.debug_flag, + reporter.error_handler) + return document + class SphinxStandaloneReader(SphinxBaseReader): """ diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py index 0704f553e..084579815 100644 --- a/sphinx/util/docutils.py +++ b/sphinx/util/docutils.py @@ -10,12 +10,20 @@ """ 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, Tuple # NOQA @@ -113,3 +121,36 @@ class sphinx_domains(object): return self.lookup_domain_element('role', name) except ElementLookupError: return self.role_func(name, lang_module, lineno, reporter) + + +class WarningStream(object): + level_mapping = { + 'DEBUG': logger.debug, + 'INFO': logger.info, + 'WARNING': logger.warning, + 'ERROR': logger.error, + 'SEVERE': logger.critical, + } + + def write(self, text): + matched = report_re.search(text) + if not matched: + logger.warning(text.rstrip("\r\n")) + else: + location, type, level, message = matched.groups() + if type in self.level_mapping: + logger_method = self.level_mapping.get(type) + logger_method(message, location=location) + else: + logger.warning(text.rstrip("\r\n")) + + +class LoggingReporter(Reporter): + def __init__(self, source, report_level, halt_level, + debug=False, error_handler='backslashreplace'): + 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): + Reporter.set_conditions(self, category, report_level, halt_level, debug=debug)