changeset 514:5e7db1a72772 trunk

Fixed a bug where select() operated on the entire stream rather than only on the previous selection. Introduced the end() transformation to reset the current selection.
author athomas
date Wed, 06 Jun 2007 12:51:54 +0000
parents ed9f1300f3bf
children f85ec7f582b6
files genshi/filters/transform.py
diffstat 1 files changed, 43 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/genshi/filters/transform.py
+++ b/genshi/filters/transform.py
@@ -121,7 +121,7 @@
 
     >>> buffer = StreamBuffer()
     >>> print html | Transformer('head/title/text()').copy(buffer) \\
-    ...     .select('body').prepend(tag.h1(buffer))
+    ...     .end().select('body').prepend(tag.h1(buffer))
     <html><head><title>Some Title</title></head><body><h1>Some Title</h1>Some
     <em>body</em> text.</body></html>
 
@@ -187,7 +187,8 @@
     #{ Selection operations
 
     def select(self, path):
-        """Mark events matching the given XPath expression.
+        """Mark events matching the given XPath expression, within the current
+        selection.
 
         >>> html = HTML('<body>Some <em>test</em> text</body>')
         >>> print html | Transformer().select('.//em').trace()
@@ -228,6 +229,27 @@
         """
         return self | InvertTransformation()
 
+    def end(self):
+        """End current selection, allowing all events to be selected.
+
+        Example:
+
+        >>> html = HTML('<body>Some <em>test</em> text</body>')
+        >>> print html | Transformer('//em').end().trace()
+        ('OUTSIDE', ('START', (QName(u'body'), Attrs()), (None, 1, 0)))
+        ('OUTSIDE', ('TEXT', u'Some ', (None, 1, 6)))
+        ('OUTSIDE', ('START', (QName(u'em'), Attrs()), (None, 1, 11)))
+        ('OUTSIDE', ('TEXT', u'test', (None, 1, 15)))
+        ('OUTSIDE', ('END', QName(u'em'), (None, 1, 19)))
+        ('OUTSIDE', ('TEXT', u' text', (None, 1, 24)))
+        ('OUTSIDE', ('END', QName(u'body'), (None, 1, 29)))
+        <body>Some <em>test</em> text</body>
+
+        :return: the stream augmented by transformation marks
+        :rtype: `Transformer`
+        """
+        return self | EndTransformation()
+
     #{ Deletion operations
 
     def empty(self):
@@ -420,7 +442,7 @@
         >>> html = HTML('<html><head><title>Some Title</title></head>'
         ...             '<body>Some <em>body</em> text.</body></html>')
         >>> print html | Transformer('title/text()').copy(buffer) \\
-        ...     .select('body').prepend(tag.h1(buffer))
+        ...     .end().select('body').prepend(tag.h1(buffer))
         <html><head><title>Some Title</title></head><body><h1>Some
         Title</h1>Some <em>body</em> text.</body></html>
 
@@ -430,7 +452,7 @@
         >>> print buffer
         Some Title
         >>> print html | Transformer('head/title/text()').copy(buffer) \\
-        ...     .select('body/em').copy(buffer).select('body') \\
+        ...     .end().select('body/em').copy(buffer).end().select('body') \\
         ...     .prepend(tag.h1(buffer))
         <html><head><title>Some
         Title</title></head><body><h1><em>body</em></h1>Some <em>body</em>
@@ -454,7 +476,7 @@
         >>> html = HTML('<html><head><title>Some Title</title></head>'
         ...             '<body>Some <em>body</em> text.</body></html>')
         >>> print html | Transformer('.//em/text()').cut(buffer) \\
-        ...     .select('.//em').after(tag.h1(buffer))
+        ...     .end().select('.//em').after(tag.h1(buffer))
         <html><head><title>Some Title</title></head><body>Some
         <em/><h1>body</h1> text.</body></html>
 
@@ -508,7 +530,7 @@
 
     def _mark(self, stream):
         for event in stream:
-            yield None, event
+            yield OUTSIDE, event
 
     def _unmark(self, stream):
         for mark, event in stream:
@@ -537,6 +559,9 @@
         test = self.path.test()
         stream = iter(stream)
         for mark, event in stream:
+            if mark is None:
+                yield mark, event
+                continue
             result = test(event, {}, {})
             if result is True:
                 if event[0] is START:
@@ -580,6 +605,18 @@
                 yield OUTSIDE, event
 
 
+class EndTransformation(object):
+    """End the current selection."""
+
+    def __call__(self, stream):
+        """Apply the transform filter to the marked stream.
+
+        :param stream: the marked event stream to filter
+        """
+        for mark, event in stream:
+            yield OUTSIDE, event
+
+
 class EmptyTransformation(object):
     """Empty selected elements of all content."""
 
Copyright (C) 2012-2017 Edgewall Software