| 1 | # Authors: David Goodger; Ueli Schlaepfer |
|---|
| 2 | # Contact: goodger@users.sourceforge.net |
|---|
| 3 | # Revision: $Revision: 4183 $ |
|---|
| 4 | # Date: $Date: 2005-12-12 05:12:02 +0100 (Mon, 12 Dec 2005) $ |
|---|
| 5 | # Copyright: This module has been placed in the public domain. |
|---|
| 6 | |
|---|
| 7 | """ |
|---|
| 8 | This package contains Docutils Reader modules. |
|---|
| 9 | """ |
|---|
| 10 | |
|---|
| 11 | __docformat__ = 'reStructuredText' |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | from docutils import utils, parsers, Component |
|---|
| 15 | from docutils.transforms import universal |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | class Reader(Component): |
|---|
| 19 | |
|---|
| 20 | """ |
|---|
| 21 | Abstract base class for docutils Readers. |
|---|
| 22 | |
|---|
| 23 | Each reader module or package must export a subclass also called 'Reader'. |
|---|
| 24 | |
|---|
| 25 | The three steps of a Reader's responsibility are defined: `scan()`, |
|---|
| 26 | `parse()`, and `transform()`. Call `read()` to process a document. |
|---|
| 27 | """ |
|---|
| 28 | |
|---|
| 29 | component_type = 'reader' |
|---|
| 30 | config_section = 'readers' |
|---|
| 31 | |
|---|
| 32 | def get_transforms(self): |
|---|
| 33 | return Component.get_transforms(self) + [ |
|---|
| 34 | universal.Decorations, |
|---|
| 35 | universal.ExposeInternals, |
|---|
| 36 | universal.StripComments,] |
|---|
| 37 | |
|---|
| 38 | def __init__(self, parser=None, parser_name=None): |
|---|
| 39 | """ |
|---|
| 40 | Initialize the Reader instance. |
|---|
| 41 | |
|---|
| 42 | Several instance attributes are defined with dummy initial values. |
|---|
| 43 | Subclasses may use these attributes as they wish. |
|---|
| 44 | """ |
|---|
| 45 | |
|---|
| 46 | self.parser = parser |
|---|
| 47 | """A `parsers.Parser` instance shared by all doctrees. May be left |
|---|
| 48 | unspecified if the document source determines the parser.""" |
|---|
| 49 | |
|---|
| 50 | if parser is None and parser_name: |
|---|
| 51 | self.set_parser(parser_name) |
|---|
| 52 | |
|---|
| 53 | self.source = None |
|---|
| 54 | """`docutils.io` IO object, source of input data.""" |
|---|
| 55 | |
|---|
| 56 | self.input = None |
|---|
| 57 | """Raw text input; either a single string or, for more complex cases, |
|---|
| 58 | a collection of strings.""" |
|---|
| 59 | |
|---|
| 60 | def set_parser(self, parser_name): |
|---|
| 61 | """Set `self.parser` by name.""" |
|---|
| 62 | parser_class = parsers.get_parser_class(parser_name) |
|---|
| 63 | self.parser = parser_class() |
|---|
| 64 | |
|---|
| 65 | def read(self, source, parser, settings): |
|---|
| 66 | self.source = source |
|---|
| 67 | if not self.parser: |
|---|
| 68 | self.parser = parser |
|---|
| 69 | self.settings = settings |
|---|
| 70 | self.input = self.source.read() |
|---|
| 71 | self.parse() |
|---|
| 72 | return self.document |
|---|
| 73 | |
|---|
| 74 | def parse(self): |
|---|
| 75 | """Parse `self.input` into a document tree.""" |
|---|
| 76 | self.document = document = self.new_document() |
|---|
| 77 | self.parser.parse(self.input, document) |
|---|
| 78 | document.current_source = document.current_line = None |
|---|
| 79 | |
|---|
| 80 | def new_document(self): |
|---|
| 81 | """Create and return a new empty document tree (root node).""" |
|---|
| 82 | document = utils.new_document(self.source.source_path, self.settings) |
|---|
| 83 | return document |
|---|
| 84 | |
|---|
| 85 | |
|---|
| 86 | class ReReader(Reader): |
|---|
| 87 | |
|---|
| 88 | """ |
|---|
| 89 | A reader which rereads an existing document tree (e.g. a |
|---|
| 90 | deserializer). |
|---|
| 91 | |
|---|
| 92 | Often used in conjunction with `writers.UnfilteredWriter`. |
|---|
| 93 | """ |
|---|
| 94 | |
|---|
| 95 | def get_transforms(self): |
|---|
| 96 | # Do not add any transforms. They have already been applied |
|---|
| 97 | # by the reader which originally created the document. |
|---|
| 98 | return Component.get_transforms(self) |
|---|
| 99 | |
|---|
| 100 | |
|---|
| 101 | _reader_aliases = {} |
|---|
| 102 | |
|---|
| 103 | def get_reader_class(reader_name): |
|---|
| 104 | """Return the Reader class from the `reader_name` module.""" |
|---|
| 105 | reader_name = reader_name.lower() |
|---|
| 106 | if _reader_aliases.has_key(reader_name): |
|---|
| 107 | reader_name = _reader_aliases[reader_name] |
|---|
| 108 | module = __import__(reader_name, globals(), locals()) |
|---|
| 109 | return module.Reader |
|---|