changeset 346:96882a191686 trunk

Whitespace was not getting preserved in HTML `<pre>` elements that contained other HTML elements.
author cmlenz
date Fri, 10 Nov 2006 17:25:52 +0000
parents 2aa7ca37ae6a
children 0cc031745884
files ChangeLog genshi/output.py genshi/tests/output.py
diffstat 3 files changed, 35 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -30,6 +30,9 @@
    are callable.
  * Instances of the `genshi.core.Attrs` class are now immutable (they are
    subclasses of `tuple` instead of `list`).
+ * Preserve whitespace in HTML `<pre>` elements also when they contained any
+   child elements.
+
 
 Version 0.3.4
 http://svn.edgewall.org/repos/genshi/tags/0.3.4/
--- a/genshi/output.py
+++ b/genshi/output.py
@@ -183,7 +183,10 @@
     _BOOLEAN_ATTRS = frozenset(['selected', 'checked', 'compact', 'declare',
                                 'defer', 'disabled', 'ismap', 'multiple',
                                 'nohref', 'noresize', 'noshade', 'nowrap'])
-    _PRESERVE_SPACE = frozenset([QName('pre'), QName('textarea')])
+    _PRESERVE_SPACE = frozenset([
+        QName('pre'), QName('http://www.w3.org/1999/xhtml}pre'),
+        QName('textarea'), QName('http://www.w3.org/1999/xhtml}textarea')
+    ])
 
     def __call__(self, stream):
         namespace = self.NAMESPACE
@@ -461,8 +464,8 @@
         @param noescape: a set or sequence of tag names for which text content
             should not be escaped
         
-        Both the `preserve` and `noescape` sets are expected to refer to
-        elements that cannot contain further child elements.
+        The `noescape` set is expected to refer to elements that cannot contain
+        further child elements (such as <style> or <script> in HTML documents).
         """
         if preserve is None:
             preserve = []
@@ -476,7 +479,7 @@
                  collapse_lines=re.compile('\n{2,}').sub):
         mjoin = Markup('').join
         preserve_elems = self.preserve
-        preserve = False
+        preserve = 0
         noescape_elems = self.noescape
         noescape = False
 
@@ -500,15 +503,17 @@
                     yield TEXT, Markup(text), pos
 
                 if kind is START:
-                    tag, attrib = data
-                    if not preserve and (tag in preserve_elems or
-                                         attrib.get(space) == 'preserve'):
-                        preserve = True
+                    tag, attrs = data
+                    if preserve or (tag in preserve_elems or
+                                    attrs.get(space) == 'preserve'):
+                        preserve += 1
                     if not noescape and tag in noescape_elems:
                         noescape = True
 
                 elif kind is END:
-                    preserve = noescape = False
+                    noescape = False
+                    if preserve:
+                        preserve -= 1
 
                 elif kind is START_CDATA:
                     noescape = True
--- a/genshi/tests/output.py
+++ b/genshi/tests/output.py
@@ -141,6 +141,12 @@
         output = stream.render(XHTMLSerializer)
         self.assertEqual('<textarea name="foo">%s</textarea>' % content, output)
 
+    def test_pre_whitespace(self):
+        content = '\nHey <em>there</em>.  \n\n    I am indented.\n'
+        stream = XML('<pre>%s</pre>' % content)
+        output = stream.render(XHTMLSerializer)
+        self.assertEqual('<pre>%s</pre>' % content, output)
+
     def test_xml_space(self):
         text = '<foo xml:space="preserve"> Do not mess  \n\n with me </foo>'
         output = XML(text).render(XHTMLSerializer)
@@ -254,6 +260,18 @@
 
 class HTMLSerializerTestCase(unittest.TestCase):
 
+    def test_textarea_whitespace(self):
+        content = '\nHey there.  \n\n    I am indented.\n'
+        stream = XML('<textarea name="foo">%s</textarea>' % content)
+        output = stream.render(HTMLSerializer)
+        self.assertEqual('<textarea name="foo">%s</textarea>' % content, output)
+
+    def test_pre_whitespace(self):
+        content = '\nHey <em>there</em>.  \n\n    I am indented.\n'
+        stream = XML('<pre>%s</pre>' % content)
+        output = stream.render(HTMLSerializer)
+        self.assertEqual('<pre>%s</pre>' % content, output)
+
     def test_xml_space(self):
         text = '<foo xml:space="preserve"> Do not mess  \n\n with me </foo>'
         output = XML(text).render(HTMLSerializer)
Copyright (C) 2012-2017 Edgewall Software