summaryrefslogtreecommitdiff
path: root/sphinx/io.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/io.py')
-rw-r--r--sphinx/io.py125
1 files changed, 125 insertions, 0 deletions
diff --git a/sphinx/io.py b/sphinx/io.py
new file mode 100644
index 000000000..a186e22e6
--- /dev/null
+++ b/sphinx/io.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.io
+ ~~~~~~~~~
+
+ Input/Output files
+
+ :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+from docutils.io import FileInput
+from docutils.readers import standalone
+from docutils.writers import UnfilteredWriter
+from six import string_types, text_type
+
+from sphinx.transforms import ApplySourceWorkaround, ExtraTranslatableNodes, Locale, \
+ CitationReferences, DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks, \
+ AutoNumbering, SortIds, RemoveTranslatableInline
+from sphinx.util import import_object, split_docinfo
+
+
+class SphinxBaseReader(standalone.Reader):
+ """
+ Add our source parsers
+ """
+ def __init__(self, app, parsers={}, *args, **kwargs):
+ standalone.Reader.__init__(self, *args, **kwargs)
+ self.parser_map = {}
+ for suffix, parser_class in parsers.items():
+ if isinstance(parser_class, string_types):
+ parser_class = import_object(parser_class, 'source parser')
+ parser = parser_class()
+ if hasattr(parser, 'set_application'):
+ parser.set_application(app)
+ self.parser_map[suffix] = parser
+
+ 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
+
+
+class SphinxStandaloneReader(SphinxBaseReader):
+ """
+ Add our own transforms.
+ """
+ transforms = [ApplySourceWorkaround, ExtraTranslatableNodes, Locale, CitationReferences,
+ DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks,
+ AutoNumbering, SortIds, RemoveTranslatableInline]
+
+
+class SphinxI18nReader(SphinxBaseReader):
+ """
+ Replacer for document.reporter.get_source_and_line method.
+
+ reST text lines for translation do not have the original source line number.
+ This class provides the correct line numbers when reporting.
+ """
+
+ transforms = [ApplySourceWorkaround, ExtraTranslatableNodes, CitationReferences,
+ DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks,
+ AutoNumbering, SortIds, RemoveTranslatableInline]
+
+ def __init__(self, *args, **kwargs):
+ SphinxBaseReader.__init__(self, *args, **kwargs)
+ self.lineno = None
+
+ def set_lineno_for_reporter(self, lineno):
+ self.lineno = lineno
+
+ def new_document(self):
+ document = SphinxBaseReader.new_document(self)
+ reporter = document.reporter
+
+ def get_source_and_line(lineno=None):
+ return reporter.source, self.lineno
+
+ reporter.get_source_and_line = get_source_and_line
+ return document
+
+
+class SphinxDummyWriter(UnfilteredWriter):
+ supported = ('html',) # needed to keep "meta" nodes
+
+ def translate(self):
+ pass
+
+
+class SphinxFileInput(FileInput):
+ def __init__(self, app, env, *args, **kwds):
+ self.app = app
+ self.env = env
+ kwds['error_handler'] = 'sphinx' # py3: handle error on open.
+ FileInput.__init__(self, *args, **kwds)
+
+ def decode(self, data):
+ if isinstance(data, text_type): # py3: `data` already decoded.
+ return data
+ return data.decode(self.encoding, 'sphinx') # py2: decoding
+
+ def read(self):
+ data = FileInput.read(self)
+ if self.app:
+ arg = [data]
+ self.app.emit('source-read', self.env.docname, arg)
+ data = arg[0]
+ 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