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