Mercurial > genshi > genshi-test
comparison genshi/template/markup.py @ 766:584aa6bfbe54
Fix bug where in some cases match templates would incorrectly applied multiple times.
author | cmlenz |
---|---|
date | Fri, 27 Jun 2008 14:20:05 +0000 |
parents | 0ea32786b624 |
children | b4c973fbe6f5 |
comparison
equal
deleted
inserted
replaced
762:2018fa1285f7 | 766:584aa6bfbe54 |
---|---|
219 stream.append((kind, data, pos)) | 219 stream.append((kind, data, pos)) |
220 | 220 |
221 assert len(streams) == 1 | 221 assert len(streams) == 1 |
222 return streams[0] | 222 return streams[0] |
223 | 223 |
224 def _match(self, stream, ctxt, match_templates=None, offset=0, **vars): | 224 def _match(self, stream, ctxt, start=0, end=None, **vars): |
225 """Internal stream filter that applies any defined match templates | 225 """Internal stream filter that applies any defined match templates |
226 to the stream. | 226 to the stream. |
227 """ | 227 """ |
228 if match_templates is None: | 228 match_templates = ctxt._match_templates |
229 match_templates = ctxt._match_templates | |
230 | 229 |
231 tail = [] | 230 tail = [] |
232 def _strip(stream): | 231 def _strip(stream): |
233 depth = 1 | 232 depth = 1 |
234 while 1: | 233 while 1: |
252 yield event | 251 yield event |
253 continue | 252 continue |
254 | 253 |
255 for idx, (test, path, template, hints, namespaces, directives) \ | 254 for idx, (test, path, template, hints, namespaces, directives) \ |
256 in enumerate(match_templates): | 255 in enumerate(match_templates): |
257 if idx < offset: | 256 if idx < start or end is not None and idx >= end: |
258 continue | 257 continue |
259 | 258 |
260 if test(event, namespaces, ctxt) is True: | 259 if test(event, namespaces, ctxt) is True: |
261 if 'match_once' in hints: | 260 if 'match_once' in hints: |
262 del match_templates[idx] | 261 del match_templates[idx] |
267 for test in [mt[0] for mt in match_templates[idx + 1:]]: | 266 for test in [mt[0] for mt in match_templates[idx + 1:]]: |
268 test(event, namespaces, ctxt, updateonly=True) | 267 test(event, namespaces, ctxt, updateonly=True) |
269 | 268 |
270 # Consume and store all events until an end event | 269 # Consume and store all events until an end event |
271 # corresponding to this start event is encountered | 270 # corresponding to this start event is encountered |
272 pre_match_templates = match_templates[:idx + 1] | 271 pre_end = idx + 1 |
273 if 'match_once' not in hints and 'not_recursive' in hints: | 272 if 'match_once' not in hints and 'not_recursive' in hints: |
274 pre_match_templates.pop() | 273 pre_end -= 1 |
275 inner = _strip(stream) | 274 inner = _strip(stream) |
276 if pre_match_templates: | 275 if pre_end > 0: |
277 inner = self._match(inner, ctxt, pre_match_templates) | 276 inner = self._match(inner, ctxt, end=pre_end) |
278 content = self._include(chain([event], inner, tail), ctxt) | 277 content = self._include(chain([event], inner, tail), ctxt) |
279 if 'not_buffered' not in hints: | 278 if 'not_buffered' not in hints: |
280 content = list(content) | 279 content = list(content) |
281 | 280 |
282 if tail: | 281 if tail: |
296 self._exec( | 295 self._exec( |
297 self._eval( | 296 self._eval( |
298 self._flatten(template, ctxt, **vars), | 297 self._flatten(template, ctxt, **vars), |
299 ctxt, **vars), | 298 ctxt, **vars), |
300 ctxt, **vars), | 299 ctxt, **vars), |
301 ctxt, match_templates, offset=idx + 1, **vars): | 300 ctxt, start=idx + 1, **vars): |
302 yield event | 301 yield event |
303 | 302 |
304 break | 303 break |
305 | 304 |
306 else: # no matches | 305 else: # no matches |