diff markup/template.py @ 77:f5ec6d4a61e4 trunk

* Simplify implementation of the individual XPath tests (use closures instead of callable classes) * Add support for using `select("@*")` in `py:attrs` directives (#10).
author cmlenz
date Thu, 13 Jul 2006 12:32:11 +0000
parents 3722696d0343
children 46fed54f23cd
line wrap: on
line diff
--- a/markup/template.py
+++ b/markup/template.py
@@ -224,7 +224,12 @@
             attrs = self.expr.evaluate(ctxt)
             if attrs:
                 attrib = Attributes(attrib[:])
-                if not isinstance(attrs, list): # assume it's a dict
+                if isinstance(attrs, Stream):
+                    try:
+                        attrs = iter(attrs).next()
+                    except StopIteration:
+                        attrs = []
+                elif not isinstance(attrs, list): # assume it's a dict
                     attrs = attrs.items()
                 for name, value in attrs:
                     if value is None:
@@ -234,6 +239,7 @@
             yield kind, (tag, attrib), pos
             for event in stream:
                 yield event
+
         return self._apply_directives(_generate(), ctxt, directives)
 
 
@@ -799,6 +805,15 @@
             stream = filter_(iter(stream), ctxt)
         return Stream(stream)
 
+    def _ensure(self, stream, ctxt=None):
+        """Ensure that every item on the stream is actually a markup event."""
+        for event in stream:
+            try:
+                kind, data, pos = event
+            except ValueError:
+                kind, data, pos = event.totuple()
+            yield kind, data, pos
+
     def _eval(self, stream, ctxt=None):
         """Internal stream filter that evaluates any expressions in `START` and
         `TEXT` events.
@@ -840,8 +855,10 @@
                     # Test if the expression evaluated to an iterable, in which
                     # case we yield the individual items
                     try:
-                        for event in self._match(self._eval(iter(result), ctxt),
-                                                 ctxt):
+                        substream = iter(result)
+                        for filter_ in [self._ensure, self._eval, self._match]:
+                            substream = filter_(substream, ctxt)
+                        for event in substream:
                             yield event
                     except TypeError:
                         # Neither a string nor an iterable, so just pass it
Copyright (C) 2012-2017 Edgewall Software