Merge pull request #2209 from tk0miya/2162_add_source_parser_API

Fix #2162: Add Sphinx.add_source_parser() to add source_suffix and source_parsers from extension
This commit is contained in:
Takeshi KOMIYA 2016-01-17 19:07:18 +09:00
commit 738bb589d9
7 changed files with 93 additions and 0 deletions

View File

@ -336,6 +336,12 @@ package.
.. versionadded:: 1.1 .. versionadded:: 1.1
.. method:: Sphinx.add_source_parser(name, suffix, parser)
Register a parser class for specified *suffix*.
.. versionadded:: 1.4
.. method:: Sphinx.require_sphinx(version) .. method:: Sphinx.require_sphinx(version)
Compare *version* (which must be a ``major.minor`` version string, Compare *version* (which must be a ``major.minor`` version string,

View File

@ -77,6 +77,7 @@ class Sphinx(object):
self.next_listener_id = 0 self.next_listener_id = 0
self._extensions = {} self._extensions = {}
self._extension_metadata = {} self._extension_metadata = {}
self._additional_source_parsers = {}
self._listeners = {} self._listeners = {}
self._setting_up_extension = ['?'] self._setting_up_extension = ['?']
self.domains = BUILTIN_DOMAINS.copy() self.domains = BUILTIN_DOMAINS.copy()
@ -185,6 +186,8 @@ class Sphinx(object):
self._init_i18n() self._init_i18n()
# check all configuration values for permissible types # check all configuration values for permissible types
self.config.check_types(self.warn) self.config.check_types(self.warn)
# set up source_parsers
self._init_source_parsers()
# set up the build environment # set up the build environment
self._init_env(freshenv) self._init_env(freshenv)
# set up the builder # set up the builder
@ -211,6 +214,13 @@ class Sphinx(object):
else: else:
self.info('not available for built-in messages') self.info('not available for built-in messages')
def _init_source_parsers(self):
for suffix, parser in iteritems(self._additional_source_parsers):
if suffix not in self.config.source_suffix:
self.config.source_suffix.append(suffix)
if suffix not in self.config.source_parsers:
self.config.source_parsers[suffix] = parser
def _init_env(self, freshenv): def _init_env(self, freshenv):
if freshenv: if freshenv:
self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.env = BuildEnvironment(self.srcdir, self.doctreedir,
@ -752,6 +762,10 @@ class Sphinx(object):
assert issubclass(cls, SearchLanguage) assert issubclass(cls, SearchLanguage)
languages[cls.lang] = cls languages[cls.lang] = cls
def add_source_parser(self, suffix, parser):
self.debug('[app] adding search source_parser: %r, %r', (suffix, parser))
self._additional_source_parsers[suffix] = parser
class TemplateBridge(object): class TemplateBridge(object):
""" """

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
import os
import sys
from docutils.parsers import Parser
sys.path.insert(0, os.path.abspath('.'))
class DummyTestParser(Parser):
pass
extensions = ['test_source_parser']
source_suffix = ['.rst', '.test']
source_parsers = {
'.test': DummyTestParser
}

View File

@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
from docutils.parsers import Parser
class TestSourceParser(Parser):
pass
def setup(app):
app.add_source_parser('.test', TestSourceParser)

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
import os
import sys
from docutils.parsers import Parser
sys.path.insert(0, os.path.abspath('.'))
class DummyMarkdownParser(Parser):
pass
extensions = ['test_source_parser']
source_suffix = ['.rst', '.md']
source_parsers = {
'.md': DummyMarkdownParser
}

View File

@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
from docutils.parsers import Parser
class TestSourceParser(Parser):
pass
def setup(app):
app.add_source_parser('.test', TestSourceParser)

View File

@ -88,3 +88,18 @@ def test_domain_override(app, status, warning):
assert app.override_domain(B) is None assert app.override_domain(B) is None
raises_msg(ExtensionError, 'new domain not a subclass of registered ' raises_msg(ExtensionError, 'new domain not a subclass of registered '
'foo domain', app.override_domain, C) 'foo domain', app.override_domain, C)
@with_app(testroot='add_source_parser')
def test_add_source_parser(app, status, warning):
assert set(app.config.source_suffix) == set(['.rst', '.md', '.test'])
assert set(app.config.source_parsers.keys()) == set(['.md', '.test'])
assert app.config.source_parsers['.md'].__name__ == 'DummyMarkdownParser'
assert app.config.source_parsers['.test'].__name__ == 'TestSourceParser'
@with_app(testroot='add_source_parser-conflicts-with-users-setting')
def test_add_source_parser_conflicts_with_users_setting(app, status, warning):
assert set(app.config.source_suffix) == set(['.rst', '.test'])
assert set(app.config.source_parsers.keys()) == set(['.test'])
assert app.config.source_parsers['.test'].__name__ == 'DummyTestParser'