[Checkins] SVN: zope.tal/branches/haufe-legacy-integration/ - Launchpad #3742721 - 'structure' directive support within

Andreas Jung andreas at andreas-jung.com
Mon May 11 04:50:08 EDT 2009


Log message for revision 99838:
  - Launchpad #3742721 - 'structure' directive support within
    tal:attributes
  

Changed:
  U   zope.tal/branches/haufe-legacy-integration/CHANGES.txt
  U   zope.tal/branches/haufe-legacy-integration/src/zope/tal/taldefs.py
  U   zope.tal/branches/haufe-legacy-integration/src/zope/tal/talgenerator.py
  U   zope.tal/branches/haufe-legacy-integration/src/zope/tal/talinterpreter.py
  U   zope.tal/branches/haufe-legacy-integration/src/zope/tal/tests/test_htmltalparser.py
  U   zope.tal/branches/haufe-legacy-integration/src/zope/tal/tests/test_talinterpreter.py

-=-
Modified: zope.tal/branches/haufe-legacy-integration/CHANGES.txt
===================================================================
--- zope.tal/branches/haufe-legacy-integration/CHANGES.txt	2009-05-11 08:45:08 UTC (rev 99837)
+++ zope.tal/branches/haufe-legacy-integration/CHANGES.txt	2009-05-11 08:50:08 UTC (rev 99838)
@@ -2,12 +2,14 @@
 CHANGES
 =======
 
-3.5.2 (unreleased)
+3.6.0 (unreleased)
 ------------------
 
-- ...
+- Launchpad #3742721 - 'structure' directive support within
+  tal:attributes
 
 
+
 3.5.1 (2009-03-08)
 ------------------
 

Modified: zope.tal/branches/haufe-legacy-integration/src/zope/tal/taldefs.py
===================================================================
--- zope.tal/branches/haufe-legacy-integration/src/zope/tal/taldefs.py	2009-05-11 08:45:08 UTC (rev 99837)
+++ zope.tal/branches/haufe-legacy-integration/src/zope/tal/taldefs.py	2009-05-11 08:50:08 UTC (rev 99838)
@@ -111,7 +111,7 @@
         self.offset = position[1]
 
 
-_attr_re = re.compile(r"\s*([^\s]+)\s+([^\s].*)\Z", re.S)
+_attr_re = re.compile(r"\s*([^\s]+)\s+(?:(text|structure)\s+)?([^\s].*)\Z", re.S)
 _subst_re = re.compile(r"\s*(?:(text|structure)\s+)?(.*)\Z", re.S)
 
 def parseAttributeReplacements(arg, xml):
@@ -120,12 +120,12 @@
         m = _attr_re.match(part)
         if not m:
             raise TALError("Bad syntax in attributes: %r" % part)
-        name, expr = m.groups()
+        name, rep_type, expr = m.groups()
         if not xml:
             name = name.lower()
         if name in dict:
             raise TALError("Duplicate attribute name in attributes: %r" % part)
-        dict[name] = expr
+        dict[name] = expr, rep_type or 'text'
     return dict
 
 def parseSubstitution(arg, position=(None, None)):

Modified: zope.tal/branches/haufe-legacy-integration/src/zope/tal/talgenerator.py
===================================================================
--- zope.tal/branches/haufe-legacy-integration/src/zope/tal/talgenerator.py	2009-05-11 08:45:08 UTC (rev 99837)
+++ zope.tal/branches/haufe-legacy-integration/src/zope/tal/talgenerator.py	2009-05-11 08:50:08 UTC (rev 99838)
@@ -452,13 +452,13 @@
         for item in attrlist:
             key = item[0]
             if repldict.has_key(key):
-                expr, xlat, msgid = repldict[key]
-                item = item[:2] + ("replace", expr, xlat, msgid)
+                expr, repl_type, xlat, msgid = repldict[key]
+                item = item[:2] + ("replace", expr, repl_type, xlat, msgid)
                 del repldict[key]
             newlist.append(item)
         # Add dynamic-only attributes
-        for key, (expr, xlat, msgid) in repldict.items():
-            newlist.append((key, None, "insert", expr, xlat, msgid))
+        for key, (expr, repl_type, xlat, msgid) in repldict.items():
+            newlist.append((key, None, "insert", expr, repl_type, xlat, msgid))
         return newlist
 
     def emitStartElement(self, name, attrlist, taldict, metaldict, i18ndict,
@@ -681,19 +681,19 @@
                                                  self.xml)
             else:
                 i18nattrs = {}
-            # Convert repldict's name-->expr mapping to a
-            # name-->(compiled_expr, translate) mapping
-            for key, value in repldict.items():
+            # Convert repldict's name-->(expr, repl_type) mapping to a
+            # name-->(compiled_expr, repl_type, translate) mapping
+            for key, (value, repl_type) in repldict.items():
                 if i18nattrs.get(key, None):
                     raise I18NError(
                         "attribute [%s] cannot both be part of tal:attributes"
                         " and have a msgid in i18n:attributes" % key,
                         position)
                 ce = self.compileExpression(value)
-                repldict[key] = ce, key in i18nattrs, i18nattrs.get(key)
+                repldict[key] = ce, repl_type, key in i18nattrs, i18nattrs.get(key)
             for key in i18nattrs:
                 if key not in repldict:
-                    repldict[key] = None, 1, i18nattrs.get(key)
+                    repldict[key] = None, 'text', 1, i18nattrs.get(key)
         else:
             repldict = {}
         if replaced:

Modified: zope.tal/branches/haufe-legacy-integration/src/zope/tal/talinterpreter.py
===================================================================
--- zope.tal/branches/haufe-legacy-integration/src/zope/tal/talinterpreter.py	2009-05-11 08:45:08 UTC (rev 99837)
+++ zope.tal/branches/haufe-legacy-integration/src/zope/tal/talinterpreter.py	2009-05-11 08:50:08 UTC (rev 99838)
@@ -468,7 +468,7 @@
     def attrAction_tal(self, item):
         name, value, action = item[:3]
         ok = 1
-        expr, xlat, msgid = item[3:]
+        expr, repl_type, xlat, msgid = item[3:]
         if self.html and name.lower() in BOOLEAN_HTML_ATTRS:
             evalue = self.engine.evaluateBoolean(item[3])
             if evalue is self.Default:
@@ -499,7 +499,10 @@
                     value = translated
             if value is None:
                 value = name
-            return ["%s=%s" % (name, quote(value))]
+            if repl_type == 'structure':
+                value = '"%s"' % value.replace('"', '"')
+            else: value = quote(value)
+            return ["%s=%s" % (name, value)]
         else:
             return ()
     bytecode_handlers["<attrAction>"] = attrAction

Modified: zope.tal/branches/haufe-legacy-integration/src/zope/tal/tests/test_htmltalparser.py
===================================================================
--- zope.tal/branches/haufe-legacy-integration/src/zope/tal/tests/test_htmltalparser.py	2009-05-11 08:45:08 UTC (rev 99837)
+++ zope.tal/branches/haufe-legacy-integration/src/zope/tal/tests/test_htmltalparser.py	2009-05-11 08:50:08 UTC (rev 99838)
@@ -458,11 +458,11 @@
              {'tal:attributes': 'href string:http://www.zope.org; x string:y',
               'name': 'bar', 'href': 'foo'}),
             ('startTag', ('a',
-             [('href', 'foo', 'replace', '$string:http://www.zope.org$', 0, None),
+             [('href', 'foo', 'replace', '$string:http://www.zope.org$', 'text', 0, None),
               ('name', 'name="bar"'),
               ('tal:attributes',
                'href string:http://www.zope.org; x string:y', 'tal'),
-              ('x', None, 'insert', '$string:y$', 0, None)])),
+              ('x', None, 'insert', '$string:y$', 'text', 0, None)])),
             ('endScope', ()),
             rawtext('link</a>'),
             ])
@@ -485,7 +485,7 @@
                    ('tal:attributes', 'src string:foo.png', 'tal')]))],
                [('insertStructure',
                  ('$string:<img>$',
-                    {'src': ('$string:foo.png$', False, None)},
+                    {'src': ('$string:foo.png$', 'text', False, None)},
                      [('rawtextOffset', ('duh', 3))]))])),
              ('endScope', ())])
 
@@ -578,7 +578,7 @@
             ('setPosition', (1, 0)),
             ('beginScope', {'alt': 'foo', 'i18n:attributes': 'alt'}),
             ('startTag', ('img',
-             [('alt', 'foo', 'replace', None, 1, None),
+             [('alt', 'foo', 'replace', None, 'text', 1, None),
               ('i18n:attributes', 'alt', 'i18n')])),
             ('endScope', ()),
             ])
@@ -586,9 +586,9 @@
             ('setPosition', (1, 0)),
             ('beginScope', {'alt': 'foo', 'i18n:attributes': 'alt foo ; bar'}),
             ('startTag', ('img',
-             [('alt', 'foo', 'replace', None, 1, 'foo'),
+             [('alt', 'foo', 'replace', None, 'text', 1, 'foo'),
               ('i18n:attributes', 'alt foo ; bar', 'i18n'),
-              ('bar', None, 'insert', None, 1, None)])),
+              ('bar', None, 'insert', None, 'text', 1, None)])),
             ('endScope', ()),
             ])
 

Modified: zope.tal/branches/haufe-legacy-integration/src/zope/tal/tests/test_talinterpreter.py
===================================================================
--- zope.tal/branches/haufe-legacy-integration/src/zope/tal/tests/test_talinterpreter.py	2009-05-11 08:45:08 UTC (rev 99837)
+++ zope.tal/branches/haufe-legacy-integration/src/zope/tal/tests/test_talinterpreter.py	2009-05-11 08:50:08 UTC (rev 99838)
@@ -493,6 +493,20 @@
             "Foo <span tal:replace='bar' i18n:name='bar' /></div>")
         self._check(program, u"<div>FOO \u00C0</div>")
 
+    def test_attributes_structure(self):
+        # test that "structure" is recognized in 'tal:attributes'
+        # Note: this test does not belong here (as it has nothing to
+        #  do with translation) -- however, there does not seem to be
+        #  a more appropriate place
+        # Note: the example shows that we need to know which entities
+        #  are replaced by the parser (there must be a single
+        #  ';' after '&quot' (as the parser replaces "&quot;" by '"')
+        #  but a double one after '&uuml' (as this is not replaced by parsing))
+        program, macros = self._compile(
+            '<span tal:attributes="test structure string:A&uuml;;&quot;Z"/>')
+        self._check(program, '<span test="A&uuml;&quot;Z" />')
+
+
 class I18NCornerTestCaseMessage(I18NCornerTestCaseBase):
 
     def factory(self, msgid, default=None, mapping={}, domain=None):



More information about the Checkins mailing list