mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Refactor sphinx.io; separate FileInput class for each file type
This commit is contained in:
parent
aa4fd0e1b7
commit
0e86ff2f11
@ -83,6 +83,7 @@ builtin_extensions = (
|
||||
'sphinx.directives.code',
|
||||
'sphinx.directives.other',
|
||||
'sphinx.directives.patches',
|
||||
'sphinx.io',
|
||||
'sphinx.parsers',
|
||||
'sphinx.roles',
|
||||
'sphinx.transforms.post_transforms',
|
||||
|
41
sphinx/io.py
41
sphinx/io.py
@ -120,7 +120,9 @@ def SphinxDummySourceClass(source, *args, **kwargs):
|
||||
return source
|
||||
|
||||
|
||||
class SphinxFileInput(FileInput):
|
||||
class SphinxBaseFileInput(FileInput):
|
||||
"""A base class of SphinxFileInput."""
|
||||
|
||||
def __init__(self, app, env, *args, **kwds):
|
||||
# type: (Sphinx, BuildEnvironment, Any, Any) -> None
|
||||
self.app = app
|
||||
@ -145,16 +147,7 @@ class SphinxFileInput(FileInput):
|
||||
# emit source-read event
|
||||
arg = [data]
|
||||
self.app.emit('source-read', self.env.docname, arg)
|
||||
data = arg[0]
|
||||
|
||||
parser = self.app.registry.get_source_parser(self.source_path)
|
||||
docinfo, data = split_docinfo(data)
|
||||
if 'restructuredtext' in parser.supported:
|
||||
if self.env.config.rst_epilog:
|
||||
data = data + '\n' + self.env.config.rst_epilog + '\n'
|
||||
if self.env.config.rst_prolog:
|
||||
data = self.env.config.rst_prolog + '\n' + data
|
||||
return docinfo + data
|
||||
return arg[0]
|
||||
|
||||
def warn_and_replace(self, error):
|
||||
# type: (Any) -> Tuple
|
||||
@ -172,12 +165,29 @@ class SphinxFileInput(FileInput):
|
||||
return (u'?', error.end)
|
||||
|
||||
|
||||
class SphinxFileInput(SphinxBaseFileInput):
|
||||
pass
|
||||
|
||||
|
||||
class SphinxRSTFileInput(SphinxBaseFileInput):
|
||||
def read(self):
|
||||
# type: () -> unicode
|
||||
data = SphinxBaseFileInput.read(self)
|
||||
docinfo, data = split_docinfo(data)
|
||||
if self.env.config.rst_epilog:
|
||||
data = data + '\n' + self.env.config.rst_epilog + '\n'
|
||||
if self.env.config.rst_prolog:
|
||||
data = self.env.config.rst_prolog + '\n' + data
|
||||
return docinfo + data
|
||||
|
||||
|
||||
def read_doc(app, env, filename):
|
||||
# type: (Sphinx, BuildEnvironment, unicode) -> nodes.document
|
||||
"""Parse a document and convert to doctree."""
|
||||
input_class = app.registry.get_source_input(filename)
|
||||
reader = SphinxStandaloneReader()
|
||||
source = SphinxFileInput(app, env, source=None, source_path=filename,
|
||||
encoding=env.config.source_encoding)
|
||||
source = input_class(app, env, source=None, source_path=filename,
|
||||
encoding=env.config.source_encoding)
|
||||
parser = app.registry.create_source_parser(app, filename)
|
||||
|
||||
pub = Publisher(reader=reader,
|
||||
@ -190,3 +200,8 @@ def read_doc(app, env, filename):
|
||||
pub.set_source(source, filename)
|
||||
pub.publish()
|
||||
return pub.document
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.registry.add_source_input('*', SphinxFileInput)
|
||||
app.registry.add_source_input('restructuredtext', SphinxRSTFileInput)
|
||||
|
@ -30,6 +30,7 @@ if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, Dict, Iterator, List, Type # NOQA
|
||||
from docutils import nodes # NOQA
|
||||
from docutils.io import Input # NOQA
|
||||
from docutils.parsers import Parser # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
@ -50,6 +51,7 @@ class SphinxComponentRegistry(object):
|
||||
self.builders = {} # type: Dict[unicode, Type[Builder]]
|
||||
self.domains = {} # type: Dict[unicode, Type[Domain]]
|
||||
self.source_parsers = {} # type: Dict[unicode, Parser]
|
||||
self.source_inputs = {} # type: Dict[unicode, Input]
|
||||
self.translators = {} # type: Dict[unicode, nodes.NodeVisitor]
|
||||
|
||||
def add_builder(self, builder):
|
||||
@ -190,6 +192,28 @@ class SphinxComponentRegistry(object):
|
||||
parser.set_application(app)
|
||||
return parser
|
||||
|
||||
def add_source_input(self, filetype, input_class):
|
||||
# type: (unicode, Type[Input]) -> None
|
||||
if filetype in self.source_inputs:
|
||||
raise ExtensionError(__('source_input for %r is already registered') % filetype)
|
||||
self.source_inputs[filetype] = input_class
|
||||
|
||||
def get_source_input(self, filename):
|
||||
# type: (unicode) -> Type[Input]
|
||||
parser = self.get_source_parser(filename)
|
||||
for filetype in parser.supported:
|
||||
if filetype in self.source_inputs:
|
||||
input_class = self.source_inputs[filetype]
|
||||
break
|
||||
else:
|
||||
# use special source_input for unknown file-type '*' (if exists)
|
||||
input_class = self.source_inputs.get('*')
|
||||
|
||||
if input_class is None:
|
||||
raise SphinxError(__('source_input for %s not registered') % filename)
|
||||
else:
|
||||
return input_class
|
||||
|
||||
def add_translator(self, name, translator):
|
||||
# type: (unicode, Type[nodes.NodeVisitor]) -> None
|
||||
self.translators[name] = translator
|
||||
|
Loading…
Reference in New Issue
Block a user