[Checkins] SVN: z3c.pt/trunk/ XML entities are now allowed even without a correct document type declaration.

Malthe Borch mborch at gmail.com
Tue Sep 2 04:37:25 EDT 2008


Log message for revision 90684:
  XML entities are now allowed even without a correct document type declaration.

Changed:
  U   z3c.pt/trunk/CHANGES.txt
  U   z3c.pt/trunk/src/z3c/pt/template.py
  U   z3c.pt/trunk/src/z3c/pt/testing.py
  U   z3c.pt/trunk/src/z3c/pt/translation.py
  U   z3c.pt/trunk/src/z3c/pt/translation.txt

-=-
Modified: z3c.pt/trunk/CHANGES.txt
===================================================================
--- z3c.pt/trunk/CHANGES.txt	2008-09-02 08:34:04 UTC (rev 90683)
+++ z3c.pt/trunk/CHANGES.txt	2008-09-02 08:37:24 UTC (rev 90684)
@@ -15,6 +15,10 @@
 
   Features
 
+- Added compiler option to specify an implicit doctype; this is
+  currently used by the template classes to let the loose XHTML
+  doctype be the default. [malthe]
+  
 - Added support for translation of tag body. [malthe]
 
 - Added security configuration for the TALES iterator (repeat

Modified: z3c.pt/trunk/src/z3c/pt/template.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/template.py	2008-09-02 08:34:04 UTC (rev 90683)
+++ z3c.pt/trunk/src/z3c/pt/template.py	2008-09-02 08:37:24 UTC (rev 90684)
@@ -1,6 +1,7 @@
 import os
 import macro
 import config
+import doctypes
 import filecache
 import translation
 
@@ -16,16 +17,21 @@
         'text': translation.Compiler.from_text}
 
     format = 'xml'
+    implicit_doctype = doctypes.xhtml
+    explicit_doctype = None
     
     def __init__(self, body, parser, format=None, doctype=None):
         self.body = body
         self.parser = parser        
         self.signature = hash(body)
         self.registry = {}
+
         if format is not None:
             self.format = format
-        self.doctype = doctype
-            
+
+        if doctype is not None:            
+            self.explicit_doctype = doctype
+        
     @property
     def translate(self):
         return NotImplementedError("Must be provided by subclass.")
@@ -36,13 +42,16 @@
 
     @property
     def compiler(self):
-        return self.compilers[self.format](self.body, self.parser, self.doctype)
-    
+        return self.compilers[self.format](
+            self.body, self.parser,
+            implicit_doctype=self.implicit_doctype,
+            explicit_doctype=self.explicit_doctype)
+
     def cook(self, **kwargs):
         return self.compiler(**kwargs)
     
     def cook_check(self, macro, params):
-        key = self.signature, macro, params, self.doctype
+        key = self.signature, macro, params, self.explicit_doctype
         template = self.registry.get(key, None)
         if template is None:
             template = self.cook(macro=macro, params=params)
@@ -99,8 +108,9 @@
         
     def clone(self, filename, format=None):
         cls = type(self)
-        return cls(filename, self.parser, format=format,
-                   doctype=self.doctype, auto_reload=self.auto_reload)
+        return cls(
+            filename, self.parser, format=format,
+            doctype=self.explicit_doctype, auto_reload=self.auto_reload)
         
     def _get_filename(self):
         return getattr(self, '_filename', None)

Modified: z3c.pt/trunk/src/z3c/pt/testing.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/testing.py	2008-09-02 08:34:04 UTC (rev 90683)
+++ z3c.pt/trunk/src/z3c/pt/testing.py	2008-09-02 08:37:24 UTC (rev 90684)
@@ -1,6 +1,7 @@
 import translation
 import generation
 import expressions
+import doctypes
 import macro
 import etree
 import config
@@ -25,22 +26,26 @@
     return out, write, stream
 
 def render_xhtml(body, **kwargs):
-    compiler = translation.Compiler(body, mock_parser)
+    compiler = translation.Compiler(
+        body, mock_parser, implicit_doctype=doctypes.xhtml)
     template = compiler(params=sorted(kwargs.keys()))
     return template.render(**kwargs)    
     
 def render_text(body, **kwargs):
-    compiler = translation.Compiler.from_text(body, mock_parser)
+    compiler = translation.Compiler.from_text(
+        body, mock_parser, implicit_doctype=doctypes.xhtml)
     template = compiler(params=sorted(kwargs.keys()))
     return template.render(**kwargs)    
 
 def render_zpt(body, **kwargs):
-    compiler = translation.Compiler(body, zpt.ZopePageTemplateParser())
+    compiler = translation.Compiler(
+        body, zpt.ZopePageTemplateParser(), implicit_doctype=doctypes.xhtml)
     template = compiler(params=sorted(kwargs.keys()))
     return template.render(**kwargs)    
 
 def render_genshi(body, **kwargs):
-    compiler = translation.Compiler(body, genshi.GenshiParser())
+    compiler = translation.Compiler(
+        body, genshi.GenshiParser(), implicit_doctype=doctypes.xhtml)
     template = compiler(params=sorted(kwargs.keys()))
     kwargs.update(template.selectors)
     return template.render(**kwargs)    

Modified: z3c.pt/trunk/src/z3c/pt/translation.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/translation.py	2008-09-02 08:34:04 UTC (rev 90683)
+++ z3c.pt/trunk/src/z3c/pt/translation.py	2008-09-02 08:37:24 UTC (rev 90684)
@@ -435,21 +435,34 @@
                     self.attrib[attributes] = expr
 
 class Compiler(object):
-    """Template compiler."""
+    """Template compiler. ``implicit_doctype`` will be used as the
+    document type if the template does not define one
+    itself. ``explicit_doctype`` may be used to explicitly set a
+    doctype regardless of what the template defines."""
+
+    doctype = None
     
-    def __init__(self, body, parser, doctype=None):
+    def __init__(self, body, parser, implicit_doctype=None, explicit_doctype=None):
+        # if no doctype is defined, prepend the implicit doctype to
+        # the document source
+        no_doctype_declaration = '<!DOCTYPE' not in body
+        if implicit_doctype and no_doctype_declaration:
+            body = implicit_doctype + "\n" + body
+            
         self.root, parsed_doctype = parser.parse(body)
-        if doctype is doctypes.no_doctype:
-            self.doctype = None
-        else:
-            self.doctype = doctype or parsed_doctype
+
+        if explicit_doctype not in (None, doctypes.no_doctype):
+            self.doctype = explicit_doctype
+        elif parsed_doctype and not no_doctype_declaration:
+            self.doctype = parsed_doctype
+            
         self.parser = parser
 
     @classmethod
-    def from_text(cls, body, parser, doctype=None):
+    def from_text(cls, body, parser, implicit_doctype=None, explicit_doctype=None):
         compiler = Compiler(
             "<html xmlns='%s'></html>" % config.XHTML_NS, parser,
-            doctype=doctype)
+            implicit_doctype, explicit_doctype)
         compiler.root.text = body
         compiler.root.attrib[utils.meta_attr('omit-tag')] = ""
         return compiler

Modified: z3c.pt/trunk/src/z3c/pt/translation.txt
===================================================================
--- z3c.pt/trunk/src/z3c/pt/translation.txt	2008-09-02 08:34:04 UTC (rev 90683)
+++ z3c.pt/trunk/src/z3c/pt/translation.txt	2008-09-02 08:37:24 UTC (rev 90684)
@@ -75,6 +75,16 @@
       Hello &nbsp; World!
     </html>
 
+:: Or without doctype.
+    
+  >>> print render_xhtml("""\
+  ... <html xmlns="http://www.w3.org/1999/xhtml">
+  ...   Hello &nbsp; World!
+  ... </html>""")
+    <html>
+      Hello &nbsp; World!
+    </html>
+
 :: Processing instructions output literally
 
   >>> print render_xhtml("""\
@@ -144,7 +154,7 @@
   >>> render_xhtml(body)
   Traceback (most recent call last):
     ...
-  XMLSyntaxError: Couldn't find end of Start Tag div line 1, line 1, column 11
+  XMLSyntaxError: Couldn't find end of Start Tag div...
 
 Missing namespace definition:
     We expect the engine to raise an exception*
@@ -158,4 +168,4 @@
   >>> print render_xhtml(body)
   Traceback (most recent call last):
     ...
-  XMLSyntaxError: Namespace prefix tal for content on div is not defined, line 1, column 23
+  XMLSyntaxError: Namespace prefix tal for content on div is not defined...



More information about the Checkins mailing list