summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2017-11-15 14:48:30 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2017-12-12 18:24:52 +0900
commit0e86ff2f1133e529d148cea6cc235218d73cc7d4 (patch)
treef536f1ecb3bf9184336a563b82385cd7963cfaca
parentaa4fd0e1b7e3043dee6ad3344c477cc59d41f0e8 (diff)
downloadsphinx-git-0e86ff2f1133e529d148cea6cc235218d73cc7d4.tar.gz
Refactor sphinx.io; separate FileInput class for each file type
-rw-r--r--sphinx/application.py1
-rw-r--r--sphinx/io.py41
-rw-r--r--sphinx/registry.py24
3 files changed, 53 insertions, 13 deletions
diff --git a/sphinx/application.py b/sphinx/application.py
index 209c73202..05d302c81 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -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',
diff --git a/sphinx/io.py b/sphinx/io.py
index c290e7831..418e91b12 100644
--- a/sphinx/io.py
+++ b/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)
diff --git a/sphinx/registry.py b/sphinx/registry.py
index 3723bcc29..b627f23af 100644
--- a/sphinx/registry.py
+++ b/sphinx/registry.py
@@ -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