changeset 261:da3137c427a2 stable-0.3.x

Ported [321:323] to 0.3.x stable branch.
author cmlenz
date Fri, 22 Sep 2006 12:07:23 +0000
parents 5c8125e03b72
children 52d17bd718d9
files ChangeLog genshi/path.py genshi/template.py genshi/tests/filters.py genshi/tests/path.py
diffstat 5 files changed, 66 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Version 0.3.1
+http://svn.edgewall.org/repos/genshi/tags/0.3.1/
+(?, from branches/stable/0.3.x)
+
+ * Includes and user-defined filters were not getting the correct context data
+   when used inside a match template (ticket #56).
+ * XPath patterns using the union operator (`|`) were returning only partial
+   results in some cases.
+
+
 Version 0.3
 http://svn.edgewall.org/repos/genshi/tags/0.3.0/
 (Sep 17 2006, from branches/stable/0.3.x)
--- a/genshi/path.py
+++ b/genshi/path.py
@@ -157,6 +157,7 @@
         paths = [(p, len(p), [0], [], [0] * len(p)) for p in self.paths]
 
         def _test(kind, data, pos, namespaces, variables):
+            retval = None
             for steps, size, cursors, cutoff, counter in paths:
 
                 # Manage the stack that tells us "where we are" in the stream
@@ -166,7 +167,8 @@
                     continue
                 elif kind is START:
                     cursors.append(cursors and cursors[-1] or 0)
-                elif not cursors:
+
+                if retval or not cursors:
                     continue
                 cursor = cursors[-1]
                 depth = len(cursors)
@@ -176,7 +178,7 @@
 
                 ctxtnode = not ignore_context and kind is START \
                                               and depth == 2
-                matched = retval = None
+                matched = None
                 while 1:
                     # Fetch the next location step
                     axis, nodetest, predicates = steps[cursor]
@@ -262,8 +264,7 @@
                         break
                     cursors[-1] = cursor
 
-                if retval:
-                    return retval
+            return retval
 
         return _test
 
--- a/genshi/template.py
+++ b/genshi/template.py
@@ -13,6 +13,7 @@
 
 """Implementation of the template engine."""
 
+from itertools import chain
 try:
     from collections import deque
 except ImportError:
@@ -849,7 +850,7 @@
             stream = filter_(iter(stream), ctxt)
         return Stream(stream)
 
-    def _eval(self, stream, ctxt=None):
+    def _eval(self, stream, ctxt):
         """Internal stream filter that evaluates any expressions in `START` and
         `TEXT` events.
         """
@@ -905,7 +906,7 @@
             else:
                 yield kind, data, pos
 
-    def _flatten(self, stream, ctxt=None):
+    def _flatten(self, stream, ctxt):
         """Internal stream filter that expands `SUB` events in the stream."""
         for kind, data, pos in stream:
             if kind is SUB:
@@ -1049,7 +1050,7 @@
 
         return stream
 
-    def _match(self, stream, ctxt=None, match_templates=None):
+    def _match(self, stream, ctxt, match_templates=None):
         """Internal stream filter that applies any defined match templates
         to the stream.
         """
@@ -1092,8 +1093,12 @@
 
                     # Consume and store all events until an end event
                     # corresponding to this start event is encountered
-                    content = [(kind, data, pos)]
-                    content += list(self._match(_strip(stream), ctxt)) + tail
+                    content = chain([(kind, data, pos)],
+                                    self._match(_strip(stream), ctxt),
+                                    tail)
+                    for filter_ in self.filters[3:]:
+                        content = filter_(content, ctxt)
+                    content = list(content)
 
                     kind, data, pos = tail[0]
                     for test in [mt[0] for mt in match_templates]:
--- a/genshi/tests/filters.py
+++ b/genshi/tests/filters.py
@@ -12,11 +12,15 @@
 # history and logs, available at http://genshi.edgewall.org/log/.
 
 import doctest
+import os
+import shutil
+import tempfile
 import unittest
 
 from genshi.core import Stream
 from genshi.input import HTML, ParseError
 from genshi.filters import HTMLSanitizer
+from genshi.template import TemplateLoader
 
 
 class HTMLSanitizerTestCase(unittest.TestCase):
@@ -116,9 +120,44 @@
         self.assertEquals(u'<img/>', unicode(html | HTMLSanitizer()))
 
 
+class IncludeFilterTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.dirname = tempfile.mkdtemp(suffix='markup_test')
+
+    def tearDown(self):
+        shutil.rmtree(self.dirname)
+
+    def test_select_inluded_elements(self):
+        file1 = open(os.path.join(self.dirname, 'tmpl1.html'), 'w')
+        try:
+            file1.write("""<li>$item</li>""")
+        finally:
+            file1.close()
+
+        file2 = open(os.path.join(self.dirname, 'tmpl2.html'), 'w')
+        try:
+            file2.write("""<html xmlns:xi="http://www.w3.org/2001/XInclude"
+                                 xmlns:py="http://genshi.edgewall.org/">
+              <ul py:match="ul">${select('li')}</ul>
+              <ul py:with="items=(1, 2, 3)">
+                <xi:include href="tmpl1.html" py:for="item in items" />
+              </ul>
+            </html>""")
+        finally:
+            file2.close()
+
+        loader = TemplateLoader([self.dirname])
+        tmpl = loader.load('tmpl2.html')
+        self.assertEqual("""<html>
+              <ul><li>1</li><li>2</li><li>3</li></ul>
+            </html>""", tmpl.generate().render())
+
+
 def suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(HTMLSanitizerTestCase, 'test'))
+    suite.addTest(unittest.makeSuite(IncludeFilterTestCase, 'test'))
     return suite
 
 if __name__ == '__main__':
--- a/genshi/tests/path.py
+++ b/genshi/tests/path.py
@@ -230,10 +230,10 @@
         self.assertEqual('<?php echo("x") ?>', path.select(xml).render())
 
     def test_simple_union(self):
-        xml = XML('<root>Oh <foo>my</foo></root>')
+        xml = XML("""<body>1<br />2<br />3<br /></body>""")
         path = Path('*|text()')
         self.assertEqual('<Path "child::*|child::text()">', repr(path))
-        self.assertEqual('Oh <foo>my</foo>', path.select(xml).render())
+        self.assertEqual('1<br/>2<br/>3<br/>', path.select(xml).render())
 
     def test_predicate_name(self):
         xml = XML('<root><foo/><bar/></root>')
Copyright (C) 2012-2017 Edgewall Software