Add support for per-suffix parsers

Override 'read' method in SphinxStandaloneReader to consider the suffix
of the file being processed and potentially choose to use a different
parser. Add 'parsers' argument to constructor taking a dictionary of
suffixes to names of parsers to use for the suffix, as provided by a
configuration variable of the same name.

This adds the ability to do something like:

    parsers = {'.md': 'markdown.parsers'}

...to use markdown.parsers.Parser to parse .md files. Note that the
custom parser is ONLY used to parse files matching the suffix; otherwise
the default (reST) parser is used.
This commit is contained in:
Matthew Woehlke 2015-02-28 00:03:55 -05:00
parent cdc4f5d8bb
commit cacf38140a
2 changed files with 33 additions and 1 deletions

View File

@ -55,6 +55,7 @@ class Config(object):
source_encoding = ('utf-8-sig', 'env'),
exclude_patterns = ([], 'env'),
default_role = (None, 'env'),
parsers = ({}, 'env'),
add_function_parentheses = (True, 'env'),
add_module_names = (True, 'env'),
trim_footnote_reference_space = (False, 'env'),

View File

@ -102,6 +102,36 @@ class SphinxStandaloneReader(standalone.Reader):
DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks,
AutoNumbering, SortIds, RemoveTranslatableInline]
@staticmethod
def get_parser_class(parser_name):
"""Return the Parser class from the `parser_name` module."""
try:
module = __import__(parser_name, globals(), locals(), ['Parser'], level=1)
except ImportError:
module = __import__(parser_name, globals(), locals(), ['Parser'], level=0)
return module.Parser
def __init__(self, parsers={}, *args, **kwargs):
standalone.Reader.__init__(self, *args, **kwargs)
self.parser_map = {}
for suffix, parser_name in parsers.items():
self.parser_map[suffix] = self.get_parser_class(parser_name)()
def read(self, source, parser, settings):
self.source = source
for suffix in self.parser_map:
if source.source_path.endswith(suffix):
self.parser = self.parser_map[suffix]
break
if not self.parser:
self.parser = parser
self.settings = settings
self.input = self.source.read()
self.parse()
return self.document
def get_transforms(self):
return standalone.Reader.get_transforms(self) + self.transforms
@ -752,7 +782,8 @@ class BuildEnvironment:
codecs.register_error('sphinx', self.warn_and_replace)
# publish manually
pub = Publisher(reader=SphinxStandaloneReader(),
reader = SphinxStandaloneReader(parsers=self.config.parsers)
pub = Publisher(reader=reader,
writer=SphinxDummyWriter(),
destination_class=NullOutput)
pub.set_components(None, 'restructuredtext', None)