changeset 342:aebbf9ae3915 experimental-inline

inline branch: support for the def directive.
author cmlenz
date Thu, 09 Nov 2006 20:06:24 +0000
parents b8ea1485e5d3
children bb881d1b4b5c
files genshi/template/directives.py genshi/template/inline.py
diffstat 2 files changed, 47 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/genshi/template/directives.py
+++ b/genshi/template/directives.py
@@ -170,13 +170,14 @@
       </p>
     </div>
     """
-    __slots__ = ['name', 'args', 'defaults']
+    __slots__ = ['name', 'args', 'defaults', 'signature']
 
     ATTRIBUTE = 'function'
 
     def __init__(self, args, namespaces=None, filename=None, lineno=-1,
                  offset=-1):
         Directive.__init__(self, None, namespaces, filename, lineno, offset)
+        self.signature = args.strip()
         ast = _parse(args).node
         self.args = []
         self.defaults = {}
--- a/genshi/template/inline.py
+++ b/genshi/template/inline.py
@@ -82,15 +82,11 @@
     yield w('from genshi.core import Attrs, QName')
     yield w('from genshi.core import START, START_NS, END, END_NS, DOCTYPE, TEXT')
     yield w('from genshi.path import Path')
-    yield w('from genshi.template.core import Template')
     yield w('from genshi.template.eval import Expression')
     yield w('from genshi.template.inline import _expand, _expand_text')
-    yield w('')
+    yield w()
 
-    yield '# predeclare qnames, attributes, and expressions'
-    p_attrs, p_qnames, p_exprs = {}, {}, {}
-    ai, qi, ei, pi = [0], [0], [0], [0]
-    def _predecl(stream):
+    def _predecl_vars(stream):
         for kind, data, pos in stream:
 
             if kind is START:
@@ -126,27 +122,41 @@
             elif kind is SUB:
                 directives, substream = data
                 for directive in directives:
+
                     if directive.expr:
                         if directive.expr not in p_exprs:
                             ei[0] += 1
                             yield w('E%d = %r', ei[0], directive.expr)
                             p_exprs[directive.expr] = ei[0]
+
                     elif hasattr(directive, 'vars'):
                         for _, expr in directive.vars:
                             if expr not in p_exprs:
                                 ei[0] += 1
                                 yield w('E%d = %r', ei[0], expr)
                                 p_exprs[expr] = ei[0]
+
                     elif hasattr(directive, 'path') and directive.path:
                         yield w('P%d = %r', pi[0], directive.path)
-                for line in _predecl(substream):
+
+                for line in _predecl_vars(substream):
                     yield line
 
-    lines = list(_predecl(template.stream))
-    lines.sort()
-    for line in lines:
-        yield line
-    yield w('')
+    def _predecl_funcs(stream):
+        for kind, data, pos in stream:
+            if kind is SUB:
+                directives, substream = data
+                for directive in directives:
+                    if isinstance(directive, DefDirective):
+                        yield w('def %s:', directive.signature)
+                        w.shift()
+                        args = ['%r: %s' % (name, name) for name
+                                in directive.args]
+                        yield w('ctxt.push({%s})', ', '.join(args))
+                        for line in _generate(substream):
+                            yield line
+                        yield w('ctxt.pop()')
+                        w.unshift()
 
     # Recursively apply directives
     def _apply(directives, stream):
@@ -177,6 +187,9 @@
             yield line
             w.unshift()
 
+        elif isinstance(directive, DefDirective):
+            yield w('ctxt.frames[-1][%r] = %s', directive.name, directive.name)
+
         elif isinstance(directive, ForDirective):
             ei[0] += 1
             yield w('for v in E%d.evaluate(ctxt):', p_exprs[directive.expr])
@@ -236,7 +249,7 @@
         else:
             raise NotImplementedError
 
-        yield w('')
+        yield w()
 
     # Generate code for the given template stream
     def _generate(stream):
@@ -287,9 +300,24 @@
             else:
                 yield w('yield %s, %r, %r', kind, data, pos)
 
+    p_attrs, p_qnames, p_exprs = {}, {}, {}
+    ai, qi, ei, pi = [0], [0], [0], [0]
+
+    yield '# predeclare qnames, attributes, and expressions'
+    lines = list(_predecl_vars(template.stream))
+    lines.sort()
+    for line in lines:
+        yield line
+    yield w()
+
     yield w('def generate(ctxt):')
+    yield w()
     w.shift()
 
+    for line in _predecl_funcs(template.stream):
+        yield line
+    yield w()
+
     ei, pi = [0], [0]
     for line in _generate(template.stream):
         yield line
@@ -306,7 +334,10 @@
       xmlns:py="http://genshi.edgewall.org/"
       lang="en">
  <body>
-    Hello, $hello!
+    <py:def function="sayhi(name='world')">
+      Hello, $name!
+    </py:def>
+    ${sayhi()}
     <ul py:if="items">
       <li py:for="idx, item in enumerate(items)"
           class="${idx % 2 and 'odd' or 'even'}">
Copyright (C) 2012-2017 Edgewall Software