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.code',
|
||||||
'sphinx.directives.other',
|
'sphinx.directives.other',
|
||||||
'sphinx.directives.patches',
|
'sphinx.directives.patches',
|
||||||
|
'sphinx.io',
|
||||||
'sphinx.parsers',
|
'sphinx.parsers',
|
||||||
'sphinx.roles',
|
'sphinx.roles',
|
||||||
'sphinx.transforms.post_transforms',
|
'sphinx.transforms.post_transforms',
|
||||||
|
41
sphinx/io.py
41
sphinx/io.py
@ -120,7 +120,9 @@ def SphinxDummySourceClass(source, *args, **kwargs):
|
|||||||
return source
|
return source
|
||||||
|
|
||||||
|
|
||||||
class SphinxFileInput(FileInput):
|
class SphinxBaseFileInput(FileInput):
|
||||||
|
"""A base class of SphinxFileInput."""
|
||||||
|
|
||||||
def __init__(self, app, env, *args, **kwds):
|
def __init__(self, app, env, *args, **kwds):
|
||||||
# type: (Sphinx, BuildEnvironment, Any, Any) -> None
|
# type: (Sphinx, BuildEnvironment, Any, Any) -> None
|
||||||
self.app = app
|
self.app = app
|
||||||
@ -145,16 +147,7 @@ class SphinxFileInput(FileInput):
|
|||||||
# emit source-read event
|
# emit source-read event
|
||||||
arg = [data]
|
arg = [data]
|
||||||
self.app.emit('source-read', self.env.docname, arg)
|
self.app.emit('source-read', self.env.docname, arg)
|
||||||
data = arg[0]
|
return 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
|
|
||||||
|
|
||||||
def warn_and_replace(self, error):
|
def warn_and_replace(self, error):
|
||||||
# type: (Any) -> Tuple
|
# type: (Any) -> Tuple
|
||||||
@ -172,12 +165,29 @@ class SphinxFileInput(FileInput):
|
|||||||
return (u'?', error.end)
|
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):
|
def read_doc(app, env, filename):
|
||||||
# type: (Sphinx, BuildEnvironment, unicode) -> nodes.document
|
# type: (Sphinx, BuildEnvironment, unicode) -> nodes.document
|
||||||
"""Parse a document and convert to doctree."""
|
"""Parse a document and convert to doctree."""
|
||||||
|
input_class = app.registry.get_source_input(filename)
|
||||||
reader = SphinxStandaloneReader()
|
reader = SphinxStandaloneReader()
|
||||||
source = SphinxFileInput(app, env, source=None, source_path=filename,
|
source = input_class(app, env, source=None, source_path=filename,
|
||||||
encoding=env.config.source_encoding)
|
encoding=env.config.source_encoding)
|
||||||
parser = app.registry.create_source_parser(app, filename)
|
parser = app.registry.create_source_parser(app, filename)
|
||||||
|
|
||||||
pub = Publisher(reader=reader,
|
pub = Publisher(reader=reader,
|
||||||
@ -190,3 +200,8 @@ def read_doc(app, env, filename):
|
|||||||
pub.set_source(source, filename)
|
pub.set_source(source, filename)
|
||||||
pub.publish()
|
pub.publish()
|
||||||
return pub.document
|
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
|
# For type annotation
|
||||||
from typing import Any, Callable, Dict, Iterator, List, Type # NOQA
|
from typing import Any, Callable, Dict, Iterator, List, Type # NOQA
|
||||||
from docutils import nodes # NOQA
|
from docutils import nodes # NOQA
|
||||||
|
from docutils.io import Input # NOQA
|
||||||
from docutils.parsers import Parser # NOQA
|
from docutils.parsers import Parser # NOQA
|
||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
from sphinx.builders import Builder # NOQA
|
from sphinx.builders import Builder # NOQA
|
||||||
@ -50,6 +51,7 @@ class SphinxComponentRegistry(object):
|
|||||||
self.builders = {} # type: Dict[unicode, Type[Builder]]
|
self.builders = {} # type: Dict[unicode, Type[Builder]]
|
||||||
self.domains = {} # type: Dict[unicode, Type[Domain]]
|
self.domains = {} # type: Dict[unicode, Type[Domain]]
|
||||||
self.source_parsers = {} # type: Dict[unicode, Parser]
|
self.source_parsers = {} # type: Dict[unicode, Parser]
|
||||||
|
self.source_inputs = {} # type: Dict[unicode, Input]
|
||||||
self.translators = {} # type: Dict[unicode, nodes.NodeVisitor]
|
self.translators = {} # type: Dict[unicode, nodes.NodeVisitor]
|
||||||
|
|
||||||
def add_builder(self, builder):
|
def add_builder(self, builder):
|
||||||
@ -190,6 +192,28 @@ class SphinxComponentRegistry(object):
|
|||||||
parser.set_application(app)
|
parser.set_application(app)
|
||||||
return parser
|
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):
|
def add_translator(self, name, translator):
|
||||||
# type: (unicode, Type[nodes.NodeVisitor]) -> None
|
# type: (unicode, Type[nodes.NodeVisitor]) -> None
|
||||||
self.translators[name] = translator
|
self.translators[name] = translator
|
||||||
|
Loading…
Reference in New Issue
Block a user