[Checkins] SVN: z3c.pt/trunk/z3c/pt/ Implemented expression interpolation in attributes.

Malthe Borch mborch at gmail.com
Sat Feb 23 11:44:26 EST 2008


Log message for revision 84194:
  Implemented expression interpolation in attributes.

Changed:
  U   z3c.pt/trunk/z3c/pt/clauses.py
  U   z3c.pt/trunk/z3c/pt/expressions.py
  U   z3c.pt/trunk/z3c/pt/translation.py
  U   z3c.pt/trunk/z3c/pt/translation.txt

-=-
Modified: z3c.pt/trunk/z3c/pt/clauses.py
===================================================================
--- z3c.pt/trunk/z3c/pt/clauses.py	2008-02-23 16:38:31 UTC (rev 84193)
+++ z3c.pt/trunk/z3c/pt/clauses.py	2008-02-23 16:44:26 UTC (rev 84194)
@@ -504,7 +504,7 @@
         
     def begin(self, stream):
         temp = stream.save()
-                
+
         if self.count == 1:
             expr = self.expressions[0]
         else:
@@ -516,7 +516,7 @@
         stream.write("if _urf is None: _urf = ''")
 
         if unicode_required_flag:
-            stream.write("if isinstance('_urf', unicode):")
+            stream.write("if isinstance(_urf, unicode):")
             stream.indent()
             stream.write("_out.write(_urf.encode('utf-8'))")
             stream.outdent()
@@ -525,7 +525,7 @@
             stream.write("_out.write(str(_urf))")
             stream.outdent()
         else:
-            stream.write("_out.write(str(_urf)")
+            stream.write("_out.write(str(_urf))")
             
     def end(self, stream):
         if self.count != 1:

Modified: z3c.pt/trunk/z3c/pt/expressions.py
===================================================================
--- z3c.pt/trunk/z3c/pt/expressions.py	2008-02-23 16:38:31 UTC (rev 84193)
+++ z3c.pt/trunk/z3c/pt/expressions.py	2008-02-23 16:44:26 UTC (rev 84194)
@@ -125,9 +125,10 @@
         if var in ('repeat',):
             raise ValueError, "Invalid variable name '%s' (reserved)." % variable
 
-        if var.startswith('_'):
-            raise ValueError, \
-                  "Invalid variable name '%s' (starts with an underscore)." % variable            
+        if var.startswith('_') and not var.startswith('_tmp'):
+            raise ValueError(
+                "Invalid variable name '%s' (starts with an underscore)." % var)
+        
         variables.append(var)
 
     return tuple(variables)

Modified: z3c.pt/trunk/z3c/pt/translation.py
===================================================================
--- z3c.pt/trunk/z3c/pt/translation.py	2008-02-23 16:38:31 UTC (rev 84193)
+++ z3c.pt/trunk/z3c/pt/translation.py	2008-02-23 16:44:26 UTC (rev 84194)
@@ -36,8 +36,11 @@
         value = self.attrib.get(ns)
         if value is not None:
             return factory(value)
-    return property(get)
+    def set(self, value):
+        self.attrib[ns] = value
 
+    return property(get, set)
+
 def interpolate(string):
     m = interpolation_regex.search(string)
     if m is None:
@@ -70,7 +73,7 @@
         skip = self.replace or self.content or self.i18n_translate is not None
         if not skip:
             for element in self:
-                element.interpolate()
+                element.interpolate(stream)
             for element in self:
                 element.visit(stream)
                     
@@ -79,7 +82,7 @@
         self.body(stream)
         self.end(stream)
 
-    def interpolate(self):
+    def interpolate(self, stream):
         # interpolate text
         if self.text is not None:
             while self.text:
@@ -109,6 +112,63 @@
                 parent.insert(parent.index(self)+1, t)                
                 self.tail = self.tail[:m.start()+1]
 
+        # interpolate attributes
+        for name in self._static_attributes():
+            value = self.attrib[name]
+
+            i = 0
+            format = ''
+            terms = []
+
+            defines = []
+
+            while value:
+                string = value[i:]
+                m = interpolate(string)
+                if m is None:
+                    break
+
+                start = m.start()
+                if start > 0:
+                    text = string[:m.start()+1]
+                else:
+                    text = ''
+                i += m.end()
+
+                format += '%s%s'
+                exp = m.group('expression')
+
+                if len(expressions.value(exp)) == 1:
+                    terms.extend(("'%s'" % text.replace("'", "\\'"), exp))
+                else:
+                    var = stream.save()
+                    defines.append((var, m.group('expression')))
+                    terms.extend(("'%s'" % text.replace("'", "\\'"), var))
+
+            if not terms:
+                continue
+
+            if i < len(value):
+                format += '%s'
+                terms.append("'%s'" % value[i:].replace("'", "\\'"))
+
+            value = "'%s'" % format + '%%(%s,)' % ",".join(terms)
+
+            del self.attrib[name]
+
+            attributes = '{http://xml.zope.org/namespaces/tal}attributes'
+            if attributes in self.attrib:
+                self.attrib[attributes] += '; %s %s' % (name, value)
+            else:
+                self.attrib[attributes] = '%s %s' % (name, value)
+
+            define = '{http://xml.zope.org/namespaces/tal}define'
+            for name, expression in defines:
+                if define in self.attrib:
+                    self.attrib[define] += '; %s %s' % (name, expression)
+                else:
+                    self.attrib[define] = '%s %s' % (name, expression)
+                
     def clauses(self):
         _ = []
 
@@ -328,15 +388,21 @@
     define = attribute("define", expressions.definitions)
     replace = attribute("replace", expressions.value)
     repeat = attribute("repeat", expressions.definition)
+    attributes = attribute("attributes", expressions.value)
     content = attribute("content", expressions.value)
     omit = attribute("omit-tag", expressions.value)
-
+    
     def _static_attributes(self):
         attributes = {}
 
         for key in self.keys():
             if key not in \
-                   ('define', 'replace', 'repeat', 'content', 'omit-tag'):
+                   ('define',
+                    'replace',
+                    'repeat',
+                    'attributes',
+                    'content',
+                    'omit-tag'):
                 raise ValueError(
                     u"Attribute '%s' not allowed in the namespace '%s'" %
                     (key, self.nsmap[self.prefix]))

Modified: z3c.pt/trunk/z3c/pt/translation.txt
===================================================================
--- z3c.pt/trunk/z3c/pt/translation.txt	2008-02-23 16:38:31 UTC (rev 84193)
+++ z3c.pt/trunk/z3c/pt/translation.txt	2008-02-23 16:44:26 UTC (rev 84194)
@@ -36,13 +36,21 @@
   ...   <p tal:omit-tag="True">No paragraph here either.</p>
   ...   <p tal:omit-tag="False">A paragraph here.</p>
   ...   <span tal:replace="'Hello World!'">Hello Universe!</span>
-  ...   <span tal:content="'%s'" />
   ...   <span tal:content="None" />
   ...   <span tal:attributes="class lambda: 'Hello'"
   ...         tal:content="lambda: 'World'" />
-  ...   <span>Inter${'pol' + 'ati'}on</span>is ${int('test') | 'convenient'}!
+  ...   <span tal:content="unicode('La Pe\xc3\xb1a', 'utf-8')" />
+  ...   <span>inter${'pol' + 'ati'}on</span>is ${int('test') | 'convenient'}!
+  ...   <span tal:define="hello 'Hello'" class="${hello} World!" />
+  ...   <span class="my-${'class'} item${'Last'}" />
+  ...   <span style="position: ${'abs'}olute"
+  ...         class="my-${int('test') | 'class'} item${'Last'}" />
+  ...   <img alt="La Peña, oh ${'La Peña'}" />
+  ...   ${unicode('La Pe\xc3\xb1a', 'utf-8')}
+  ...   <img alt="${unicode('La Pe\xc3\xb1a', 'utf-8')}" />
+  ...   <img alt="Hello ${unicode('La Pe\xc3\xb1a', 'utf-8').encode('utf-8')}!" />  
   ... </div>
-  ... """ % (u'La Pe\xf1a').encode('utf-8')
+  ... """
 
   >>> print render(body)
   <div>
@@ -76,11 +84,19 @@
     No paragraph here either.
     <p>A paragraph here.</p>
     Hello World!
-    <span>La Peña</span>
     <span></span>
     <span class="Hello">World</span>
-    <span>Interpolation</span>is convenient!
+    <span>La Peña</span>
+    <span>interpolation</span>is convenient!
+    <span class="Hello World!" />
+    <span class="my-class itemLast" />
+    <span style="position: absolute" class="my-class itemLast" />
+    <img alt="La Peña, oh La Peña" />
+    La Peña
+    <img alt="La Peña" />
+    <img alt="Hello La Peña!" />  
   </div>
+
     
 Error handling
 --------------



More information about the Checkins mailing list