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
Copyright (C) 2012-2017 Edgewall Software