git @ Cat's Eye Technologies Falderal / 32d4ded
More broken but in better ways (cross fingers) Chris Pressey 5 years ago
1 changed file(s) with 57 addition(s) and 81 deletion(s). Raw diff Collapse all Expand all
147147 >>> b = Block()
148148 >>> b.append(u'test body line 1')
149149 >>> b.append(u'test body line 2')
150 >>> print b.text(prefix=u'| ')
151 | test body line 1
152 | test body line 2
153150 >>> print b.text()
154151 test body line 1
155152 test body line 2
182179 assert isinstance(line, unicode)
183180 self.lines.append(line)
184181
185 def text(self, prefix=None, seperator='\n'):
186 if prefix is None:
187 return seperator.join(self.lines)
188 else:
189 assert isinstance(prefix, unicode), repr(prefix)
190 return seperator.join(prefix + line for line in self.lines)
191
192 def classify(self):
193 """Returns a list of Blocks of more specific subclasses of Block."""
194
195 PREFIX = {
182 def text(self, seperator='\n'):
183 return seperator.join(self.lines)
184
185 def deconstruct(self):
186 """Return a list of pairs of (prefix, list of lines) representing
187 the contents of this Block. The pairs are in the order the runs
188 of prefixes occur in the block. The lines in the list of lines
189 have had their prefix stripped from them."""
190
191 PREFIX_MAP = {
196192 u'| ': TestBody,
197193 u'+ ': TestInput,
198194 u'? ': ExpectedError,
200196 u'->': Pragma,
201197 u'> ': LiterateCode,
202198 }
203
204 contains_subblocks = False
205 for prefix in PREFIX.keys():
206 if all(line.startswith(prefix) for line in self.lines):
207 cls = PREFIX[prefix]
208 return [cls(
209 line_num=self.line_num,
210 filename=self.filename,
211 lines=[line[len(prefix):] for line in self.lines],
212 )]
213 if any(line.startswith(prefix) for line in self.lines):
214 contains_subblocks = True
215 break
216
217 if not contains_subblocks:
218 return [InterveningMarkdown(
219 line_num=self.line_num,
220 filename=self.filename,
221 lines=self.lines
222 )]
223
224 # If we got here, it's a mixed block.
225 # TODO: Further classify.
226
227 # Split into individual blocks.
228 prefix = ''
229 blocks = []
230
231 def next(block):
232 if block is not None:
233 blocks.extend(block.classify())
234 return Block(line_num=self.line_num,
235 filename=self.filename)
236
237 block = next(None)
238
239 for line in self.lines:
240 line_prefix = line[:2]
241 if line_prefix != prefix:
242 block = next(block)
243 block.append(line)
244
245 next(block)
246
247 return blocks
199 PREFIXES = PREFIX_MAP.keys()
200
201 pairs = []
202 prefix_state = None
203 acc = []
204
205 for line in lines:
206 prefix_of_line = None
207 for prefix in PREFIXES:
208 if line.startswith(prefix):
209 prefix_of_line = prefix
210 break
211 if prefix_of_line == prefix_state:
212 acc.append(line[len(prefix_of_line):])
213 else:
214 pairs.append((prefix_state, acc))
215 prefix_state = prefix_of_line
216 acc = []
217 acc.append(line[len(prefix_of_line):])
218
219 pairs.append((prefix_state, acc))
220
221 return pairs
248222
249223
250224 class LiterateCode(Block):
271245 pass
272246
273247
274 class InterveningMarkdown(Block):
248 class InterveningText(Block):
275249 pass
276250
277251
316290 >>> d.append(u' = Expected result on output')
317291 >>> d.parse_lines_to_blocks()
318292 >>> [b.__class__.__name__ for b in d.blocks]
319 ['InterveningMarkdown', 'Pragma', 'TestBody', 'ExpectedError',
293 ['InterveningText', 'Pragma', 'TestBody', 'ExpectedError',
320294 'TestBody', 'TestInput', 'ExpectedResult']
321295 >>> [b.line_num for b in d.blocks]
322296 [1, 2, 3, 5, 6, 7, 8]
323297
324298 """
325 state = 'toplevel'
299 indent = u''
326300 blocks = []
327301 line_num = 1
328
329 def next(block):
330 if block is not None:
331 blocks.extend(block.classify())
332 return Block(line_num=line_num,
333 filename=self.filename)
334
335 block = next(None)
302 block = None
336303
337304 for line in self.lines:
338 if state == 'toplevel':
305 if indent == u'':
339306 if line.startswith(u' '):
340 state = 'indented'
341 block = next(block)
342
343 elif state == 'indented':
307 indent = u' '
308 if block is not None:
309 blocks.append(block)
310 block = Block(
311 line_num=line_num,
312 filename=self.filename
313 )
314 elif indent == u' ':
344315 if not line.startswith(u' '):
345 state = 'toplevel'
346 block = next(block)
347
348 if line.startswith(u' '):
349 line = line[4:]
316 indent = u''
317 if block is not None:
318 blocks.append(block)
319 block = InterveningText(
320 line_num=line_num,
321 filename=self.filename
322 )
323
324 line = line[len(indent):]
350325
351326 block.append(line)
352327 line_num += 1
353328
354 next(block)
329 if block is not None:
330 blocks.append(block)
355331
356332 self.blocks = blocks
357333