annotate fontaine/parser.py @ 0:243401c49520

Initial commit.
author Ludovic Chabant <ludovic@chabant.com>
date Mon, 02 Jan 2017 12:30:49 -0800
parents
children 74b83e3d921e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
1 import re
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
2 import logging
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
3
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
4
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
5 logger = logging.getLogger(__name__)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
6
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
7
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
8 class FontaineState:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
9 can_merge = False
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
10
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
11 def match(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
12 return False
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
13
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
14 def consume(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
15 raise NotImplementedError()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
16
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
17 def exit(self, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
18 pass
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
19
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
20
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
21 class FontaineParserError(Exception):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
22 def __init__(self, line_no, message):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
23 super().__init__("Error line %d: %s" % (line_no, message))
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
24
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
25
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
26 ANY_STATE = object()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
27 EOF_STATE = object()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
28
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
29
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
30 RE_EMPTY_LINE = re.compile(r"^$", re.M)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
31 RE_BLANK_LINE = re.compile(r"^\s*$", re.M)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
32
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
33 RE_TITLE_KEY_VALUE = re.compile(r"^(?P<key>[\w\s\-]+)\s*:")
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
34
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
35
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
36 class _TitlePageState(FontaineState):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
37 def __init__(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
38 super().__init__()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
39 self._cur_key = None
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
40 self._cur_val = None
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
41
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
42 def consume(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
43 line = fp.readline()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
44 if not line:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
45 return EOF_STATE
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
46
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
47 if RE_EMPTY_LINE.match(line):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
48 self._commit(ctx)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
49 # Finished with the page title, now move on to the first scene.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
50 # However, if we never had any page title, go back to the beginning
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
51 # so we don't consume anybody else's empty lines.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
52 if len(ctx.document.title_values) == 0:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
53 fp.seek0()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
54 return ANY_STATE
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
55
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
56 m = RE_TITLE_KEY_VALUE.match(line)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
57 if m:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
58 # Commit current value, start new one.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
59 self._commit(ctx)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
60 self._cur_key = m.group('key')
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
61 self._cur_val = line[m.end():].strip()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
62 else:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
63 if self._cur_val is None:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
64 if len(ctx.document.title_values) == 0:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
65 # Early exit because there's no title page.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
66 # Go back to the beginning so we don't consume somebody's
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
67 # first line of text.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
68 fp.seek0()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
69 return ANY_STATE
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
70
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
71 raise FontaineParserError(
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
72 fp.line_no,
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
73 "Page title needs to be followed by 2 empty lines.")
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
74
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
75 # Keep accumulating the value of one of the title page's values.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
76 self._cur_val += line.strip()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
77 return True
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
78
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
79 def exit(self, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
80 self._commit(ctx)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
81
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
82 def _commit(self, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
83 if self._cur_key is not None:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
84 ctx.document.title_values[self._cur_key] = self._cur_val
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
85 self._cur_key = None
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
86 self._cur_val = None
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
87
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
88
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
89 RE_SCENE_HEADER_PATTERN = re.compile(
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
90 r"^(int|ext|est|int/ext|int./ext|i/e)[\s\.]", re.I)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
91
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
92
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
93 class _SceneHeaderState(FontaineState):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
94 def match(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
95 lines = fp.peeklines(2)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
96 return (
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
97 RE_EMPTY_LINE.match(lines[0]) and
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
98 RE_SCENE_HEADER_PATTERN.match(lines[1]))
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
99
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
100 def consume(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
101 fp.readline() # Get past the blank line.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
102 line = fp.readline().rstrip('\r\n')
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
103 line = line.lstrip('.') # In case it was forced.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
104 ctx.document.addScene(line)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
105 return ANY_STATE
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
106
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
107
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
108 class _ActionState(FontaineState):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
109 can_merge = True
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
110
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
111 def __init__(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
112 super().__init__()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
113 self.text = ''
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
114
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
115 def match(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
116 return True
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
117
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
118 def consume(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
119 is_first_line = True
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
120 while True:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
121 line = fp.readline()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
122 if not line:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
123 return EOF_STATE
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
124
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
125 if is_first_line:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
126 line = line.lstrip('!')
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
127 is_first_line = False
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
128
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
129 self.text += line
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
130
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
131 if RE_EMPTY_LINE.match(fp.peekline()):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
132 break
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
133
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
134 return ANY_STATE
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
135
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
136 def exit(self, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
137 ctx.document.lastScene().addAction(self.text)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
138
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
139
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
140 RE_CHARACTER_LINE = re.compile(r"^[A-Z\-]+\s*(\(.*\))?$", re.M)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
141
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
142
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
143 class _CharacterState(FontaineState):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
144 def match(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
145 lines = fp.peeklines(3)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
146 return (RE_EMPTY_LINE.match(lines[0]) and
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
147 RE_CHARACTER_LINE.match(lines[1]) and
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
148 not RE_EMPTY_LINE.match(lines[2]))
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
149
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
150 def consume(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
151 fp.readline() # Get past the empty line.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
152 line = fp.readline().rstrip('\r\n')
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
153 line = line.lstrip('@') # In case it was forced.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
154 ctx.document.lastScene().addCharacter(line)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
155 return [_ParentheticalState, _DialogState]
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
156
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
157
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
158 RE_PARENTHETICAL_LINE = re.compile(r"^\s*\(.*\)\s*$", re.M)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
159
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
160
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
161 class _ParentheticalState(FontaineState):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
162 def match(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
163 # We only get here from a `_CharacterState` so we know the previous
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
164 # one is already that.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
165 line = fp.peekline()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
166 return RE_PARENTHETICAL_LINE.match(line)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
167
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
168 def consume(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
169 line = fp.readline().rstrip('\r\n')
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
170 ctx.document.lastScene().addParenthetical(line)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
171 return [_DialogState, _CharacterState, _ActionState]
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
172
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
173
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
174 class _DialogState(FontaineState):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
175 def __init__(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
176 super().__init__()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
177 self.text = ''
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
178
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
179 def match(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
180 line = fp.peekline()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
181 return not RE_EMPTY_LINE.match(line)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
182
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
183 def consume(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
184 while True:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
185 line = fp.readline()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
186 if not line:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
187 return EOF_STATE
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
188 self.text += line
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
189 if RE_EMPTY_LINE.match(fp.peekline()):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
190 break
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
191 return ANY_STATE
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
192
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
193 def exit(self, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
194 ctx.document.lastScene().addDialog(self.text.rstrip('\r\n'))
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
195
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
196
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
197 class _LyricsState(FontaineState):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
198 pass
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
199
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
200
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
201 class _TransitionState(FontaineState):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
202 pass
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
203
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
204
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
205 class _ForcedParagraphStates(FontaineState):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
206 STATE_SYMBOLS = {
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
207 '.': _SceneHeaderState,
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
208 '!': _ActionState,
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
209 '@': _CharacterState,
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
210 '~': _LyricsState,
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
211 '>': _TransitionState
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
212 }
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
213
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
214 def __init__(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
215 super().__init__()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
216 self._state_cls = None
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
217
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
218 def match(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
219 lines = fp.peeklines(2)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
220 if (RE_EMPTY_LINE.match(lines[0]) and
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
221 lines[1][:1] in self.STATE_SYMBOLS):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
222 self._state_cls = self.STATE_SYMBOLS[lines[1][:1]]
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
223 return True
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
224 return False
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
225
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
226 def consume(self, fp, ctx):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
227 return self._state_cls()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
228
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
229
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
230 STATES = [
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
231 _ForcedParagraphStates, # Must be first.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
232 _SceneHeaderState,
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
233 _CharacterState,
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
234 _TransitionState,
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
235 _ActionState, # Must be last.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
236 ]
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
237
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
238
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
239 class _PeekableFile:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
240 def __init__(self, fp):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
241 self.line_no = 1
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
242 self._fp = fp
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
243
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
244 def read(self, size=-1):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
245 return self._doRead(size, True)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
246
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
247 def read1(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
248 return self.read(1)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
249
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
250 def peek1(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
251 pos = self._fp.tell()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
252 c = self._doRead(1, False)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
253 self._fp.seek(pos)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
254 return c
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
255
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
256 def readline(self, size=-1):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
257 data = self._fp.readline(size)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
258 self.line_no += 1
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
259 return data
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
260
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
261 def peekline(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
262 pos = self._fp.tell()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
263 line = self._fp.readline()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
264 self._fp.seek(pos)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
265 return line
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
266
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
267 def peeklines(self, count):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
268 pos = self._fp.tell()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
269 lines = []
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
270 for i in range(count):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
271 lines.append(self._fp.readline())
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
272 self._fp.seek(pos)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
273 return lines
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
274
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
275 def seek0(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
276 self._fp.seek(0)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
277 self.line_no = 1
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
278
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
279 def _doRead(self, size, advance_line_no):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
280 data = self._fp.read(size)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
281 if advance_line_no:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
282 self.line_no += data.count('\n')
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
283 return data
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
284
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
285
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
286 class _FontaineStateMachine:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
287 def __init__(self, fp, doc):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
288 self.fp = _PeekableFile(fp)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
289 self.state = None
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
290 self.document = doc
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
291
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
292 @property
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
293 def line_no(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
294 return self.fp.line_no
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
295
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
296 def run(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
297 self.state = _TitlePageState()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
298 while True:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
299 logger.debug("State '%s' consuming from '%s'..." %
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
300 (self.state.__class__.__name__, self.fp.peekline()))
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
301 res = self.state.consume(self.fp, self)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
302
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
303 # See if we reached the end of the file.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
304 if not self.fp.peekline():
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
305 logger.debug("Reached end of line... ending parsing.")
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
306 res = EOF_STATE
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
307
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
308 # Figure out what to do next...
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
309
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
310 if res is None:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
311 raise Exception(
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
312 "States need to return `ANY_STATE`, one or more specific "
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
313 "states, or `EOF_STATE` if they reached the end of the "
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
314 "file.")
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
315
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
316 if res is True:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
317 # State continues to consume.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
318 continue
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
319
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
320 if res is ANY_STATE or isinstance(res, list):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
321 # State wants to exit, we need to figure out what is the
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
322 # next state.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
323 pos = self.fp._fp.tell()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
324 next_states = res
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
325 if next_states is ANY_STATE:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
326 next_states = STATES
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
327 logger.debug("Trying to match next state from: %s" %
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
328 [t.__name__ for t in next_states])
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
329 for sc in next_states:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
330 s = sc()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
331 if s.match(self.fp, self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
332 logger.debug("Matched state %s" %
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
333 s.__class__.__name__)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
334 self.fp._fp.seek(pos)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
335 res = s
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
336 break
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
337 else:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
338 raise Exception("Can't match following state after: %s" %
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
339 self.state)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
340 if self.state:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
341 if type(self.state) == type(res) and self.state.can_merge:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
342 # Don't switch states if the next state is the same
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
343 # type and that type supports merging.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
344 continue
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
345
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
346 self.state.exit(self)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
347
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
348 self.state = res
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
349 continue
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
350
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
351 if isinstance(res, FontaineState):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
352 # State wants to exit, wants a specific state to be next.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
353 if self.state:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
354 self.state.exit(self)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
355 self.state = res
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
356 continue
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
357
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
358 if res is EOF_STATE:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
359 # Reached end of file.
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
360 if self.state:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
361 self.state.exit(self)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
362 break
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
363
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
364 raise Exception("Unsupported state result: %s" % res)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
365
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
366
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
367 class FontaineParser:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
368 def __init__(self):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
369 pass
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
370
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
371 def parse(self, filein):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
372 if isinstance(filein, str):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
373 with open(filein, 'r') as fp:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
374 return self._doParse(fp)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
375 else:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
376 return self._doParse(fp)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
377
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
378 def parseString(self, text):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
379 import io
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
380 with io.StringIO(text) as fp:
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
381 return self._doParse(fp)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
382
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
383 def _doParse(self, fp):
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
384 from .document import FontaineDocument
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
385 doc = FontaineDocument()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
386 machine = _FontaineStateMachine(fp, doc)
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
387 machine.run()
243401c49520 Initial commit.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
388 return doc