Mercurial > genshi > genshi-test
changeset 217:d8b195b22a44
Fix `py:match` directive which would screw up in some scenarios due to incorrect handling of the substream. Closes #49.
author | cmlenz |
---|---|
date | Mon, 04 Sep 2006 23:27:38 +0000 |
parents | 0a01371cecbc |
children | af15e231d972 |
files | markup/path.py markup/template.py markup/tests/template.py |
diffstat | 3 files changed, 54 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/markup/path.py +++ b/markup/path.py @@ -193,9 +193,8 @@ # Both the node test and the predicates matched if matched: if last_step: - if ignore_context or kind is not START \ - or axis is ATTRIBUTE or axis is SELF \ - or len(stack) > 2: + if not ctxtnode or kind is not START \ + or axis is ATTRIBUTE or axis is SELF: retval = matched elif not ctxtnode or axis is SELF \ or axis is DESCENDANT_OR_SELF: @@ -221,7 +220,8 @@ # We're done with this step if it's the last step or the # axis isn't "self" - if last_step or axis is not SELF: + if last_step or (axis is not SELF and + axis is not DESCENDANT_OR_SELF): break if kind is START and axis is not DESCENDANT \
--- a/markup/template.py +++ b/markup/template.py @@ -996,6 +996,21 @@ if match_templates is None: match_templates = ctxt._match_templates + tail = [] + def _strip(stream): + depth = 1 + while 1: + kind, data, pos = stream.next() + if kind is START: + depth += 1 + elif kind is END: + depth -= 1 + if depth > 0: + yield kind, data, pos + else: + tail[:] = [(kind, data, pos)] + break + for kind, data, pos in stream: # We (currently) only care about start and end events for matching @@ -1017,15 +1032,11 @@ # Consume and store all events until an end event # corresponding to this start event is encountered content = [(kind, data, pos)] - depth = 1 - stream = self._match(stream, ctxt) - while depth > 0: - kind, data, pos = stream.next() - if kind is START: - depth += 1 - elif kind is END: - depth -= 1 - content.append((kind, data, pos)) + content += list(self._match(_strip(stream), ctxt)) + tail + + kind, data, pos = tail[0] + for test in [mt[0] for mt in match_templates]: + test(kind, data, pos, ctxt) # Make the select() function available in the body of the # match template
--- a/markup/tests/template.py +++ b/markup/tests/template.py @@ -601,6 +601,36 @@ <body><h2>Are you ready to mark up?</h2><hr/></body> </html>""", str(tmpl.generate())) + def test_multiple_matches(self): + tmpl = Template("""<html xmlns:py="http://markup.edgewall.org/"> + <input py:match="form//input" py:attrs="select('@*')" + value="${values[str(select('@name'))]}" /> + <form><p py:for="field in fields"> + <label>${field.capitalize()}</label> + <input type="text" name="${field}" /> + </p></form> + </html>""") + fields = ['hello_%s' % i for i in range(5)] + values = dict([('hello_%s' % i, i) for i in range(5)]) + self.assertEqual("""<html> + <form><p> + <label>Hello_0</label> + <input value="0" type="text" name="hello_0"/> + </p><p> + <label>Hello_1</label> + <input value="1" type="text" name="hello_1"/> + </p><p> + <label>Hello_2</label> + <input value="2" type="text" name="hello_2"/> + </p><p> + <label>Hello_3</label> + <input value="3" type="text" name="hello_3"/> + </p><p> + <label>Hello_4</label> + <input value="4" type="text" name="hello_4"/> + </p></form> + </html>""", str(tmpl.generate(fields=fields, values=values))) + # FIXME #def test_match_after_step(self): # tmpl = Template("""<div xmlns:py="http://markup.edgewall.org/">