# HG changeset patch # User athomas # Date 1181134314 0 # Node ID e293bbb40507e6ea1144d11f084ae7b629bbcd6e # Parent bdaf75981ec7675476d2e4b8164c9d4b21f9f074 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. diff --git a/genshi/filters/transform.py b/genshi/filters/transform.py --- 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)) Some Title

Some Title

Some body text. @@ -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('Some test text') >>> 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('Some test text') + >>> 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))) + Some test text + + :return: the stream augmented by transformation marks + :rtype: `Transformer` + """ + return self | EndTransformation() + #{ Deletion operations def empty(self): @@ -420,7 +442,7 @@ >>> html = HTML('Some Title' ... 'Some body text.') >>> print html | Transformer('title/text()').copy(buffer) \\ - ... .select('body').prepend(tag.h1(buffer)) + ... .end().select('body').prepend(tag.h1(buffer)) Some Title

Some Title

Some body text. @@ -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)) Some Title

body

Some body @@ -454,7 +476,7 @@ >>> html = HTML('Some Title' ... 'Some body text.') >>> print html | Transformer('.//em/text()').cut(buffer) \\ - ... .select('.//em').after(tag.h1(buffer)) + ... .end().select('.//em').after(tag.h1(buffer)) Some TitleSome

body

text. @@ -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."""