diff options
Diffstat (limited to 'sphinx/io.py')
-rw-r--r-- | sphinx/io.py | 125 |
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 |