[Zope3-checkins] SVN: Zope3/trunk/src/zope/pagetemplate/ Now input encoding of a PageTemplateFile in 'html' mode is determined

Dmitry Vasiliev dima at hlabs.spb.ru
Thu Jul 21 06:07:53 EDT 2005


Log message for revision 37358:
  Now input encoding of a PageTemplateFile in 'html' mode is determined
  by <meta> declaration and then the declaration will stripped.
  
  Open question:
      Shouldn't <meta>/<?xml?> stripping be in PageTemplate.__call__()?
  

Changed:
  U   Zope3/trunk/src/zope/pagetemplate/pagetemplatefile.py
  U   Zope3/trunk/src/zope/pagetemplate/tests/test_ptfile.py

-=-
Modified: Zope3/trunk/src/zope/pagetemplate/pagetemplatefile.py
===================================================================
--- Zope3/trunk/src/zope/pagetemplate/pagetemplatefile.py	2005-07-21 09:09:36 UTC (rev 37357)
+++ Zope3/trunk/src/zope/pagetemplate/pagetemplatefile.py	2005-07-21 10:07:53 UTC (rev 37358)
@@ -17,7 +17,12 @@
 
 $Id$
 """
-import os, sys
+
+__all__ = ("PageTemplateFile",)
+
+import os
+import sys
+import re
 import logging
 
 from zope.pagetemplate.pagetemplate import PageTemplate
@@ -25,6 +30,11 @@
 
 DEFAULT_ENCODING = "utf-8"
 
+meta_pattern = re.compile(
+    r'\s*<meta\s+http-equiv=["\']?Content-Type["\']?'
+    r'\s+content=["\']?([^;]+);\s*charset=([^"\']+)["\']?\s*>\s*',
+    re.IGNORECASE)
+
 def package_home(gdict):
     filename = gdict["__file__"]
     return os.path.dirname(filename)
@@ -34,12 +44,11 @@
 
     _v_last_read = 0
 
-    def __init__(self, filename, _prefix=None, encoding=DEFAULT_ENCODING):
+    def __init__(self, filename, _prefix=None):
         path = self.get_path_from_prefix(_prefix)
         self.filename = os.path.join(path, filename)
         if not os.path.isfile(self.filename):
             raise ValueError("No such file", self.filename)
-        self.encoding = encoding
 
     def get_path_from_prefix(self, _prefix):
         if isinstance(_prefix, str):
@@ -50,6 +59,18 @@
             path = package_home(_prefix)
         return path
 
+    def _prepare_html(self, text):
+        match = meta_pattern.search(text)
+        if match is not None:
+            type, encoding = match.groups()
+            # TODO: Shouldn't <meta>/<?xml?> stripping
+            # be in PageTemplate.__call__()?
+            text = meta_pattern.sub("", text)
+        else:
+            type = None
+            encoding = DEFAULT_ENCODING
+        return unicode(text, encoding), type
+
     def _read_file(self):
         __traceback_info__ = self.filename
         f = open(self.filename, "rb")
@@ -66,7 +87,7 @@
             f.close()
             f = open(self.filename)
             text = f.read()
-            text = unicode(text, self.encoding)
+            text, type = self._prepare_html(text)
         f.close()
         return text, type
 

Modified: Zope3/trunk/src/zope/pagetemplate/tests/test_ptfile.py
===================================================================
--- Zope3/trunk/src/zope/pagetemplate/tests/test_ptfile.py	2005-07-21 09:09:36 UTC (rev 37357)
+++ Zope3/trunk/src/zope/pagetemplate/tests/test_ptfile.py	2005-07-21 10:07:53 UTC (rev 37358)
@@ -140,7 +140,7 @@
     def test_html_default_encoding(self):
         pt = self.get_pt(
             "<html><head><title>"
-            # 'Test' in russian
+            # 'Test' in russian (utf-8)
             "\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82"
             "</title></head></html>")
         rendered = pt()
@@ -150,7 +150,22 @@
             u"\u0422\u0435\u0441\u0442"
             u"</title></head></html>\n")
 
+    def test_html_encoding_by_meta(self):
+        pt = self.get_pt(
+            "<html><head><title>"
+            # 'Test' in russian (windows-1251)
+            "\xd2\xe5\xf1\xf2"
+            '</title><meta http-equiv="Content-Type"'
+            ' content="text/html; charset=windows-1251">'
+            "</head></html>")
+        rendered = pt()
+        self.failUnless(isinstance(rendered, unicode))
+        self.failUnlessEqual(rendered,
+            u"<html><head><title>"
+            u"\u0422\u0435\u0441\u0442"
+            u"</title></head></html>\n")
 
+
 def test_suite():
     return unittest.makeSuite(TypeSniffingTestCase)
 



More information about the Zope3-Checkins mailing list