Mercurial > genshi > genshi-test
annotate genshi/template/inline.py @ 820:1837f39efd6f experimental-inline
Sync (old) experimental inline branch with trunk@1027.
author | cmlenz |
---|---|
date | Wed, 11 Mar 2009 17:51:06 +0000 |
parents | 49aa525b8f83 |
children | abb1f1d2f4f3 |
rev | line source |
---|---|
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
1 # -*- coding: utf-8 -*- |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
2 # |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
3 # Copyright (C) 2006 Edgewall Software |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
4 # All rights reserved. |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
5 # |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
6 # This software is licensed as described in the file COPYING, which |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
7 # you should have received as part of this distribution. The terms |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
8 # are also available at http://genshi.edgewall.org/wiki/License. |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
9 # |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
10 # This software consists of voluntary contributions made by many |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
11 # individuals. For the exact contribution history, see the revision |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
12 # history and logs, available at http://genshi.edgewall.org/log/. |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
13 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
14 import compiler |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
15 import imp |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
16 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
17 from genshi.core import Attrs, Stream, _ensure, START, END, TEXT |
820
1837f39efd6f
Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents:
398
diff
changeset
|
18 from genshi.template.base import EXPR, SUB |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
19 from genshi.template.directives import * |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
20 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
21 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
22 class CodeWriter(object): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
23 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
24 def __init__(self): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
25 self.indent = 0 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
26 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
27 def __call__(self, line='', *args): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
28 if not line: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
29 return '' |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
30 if args: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
31 line %= args |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
32 return ' ' * self.indent + line |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
33 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
34 def shift(self): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
35 self.indent += 4 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
36 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
37 def unshift(self): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
38 self.indent -= 4 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
39 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
40 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
41 def _expand(obj, pos): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
42 if obj is not None: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
43 # First check for a string, otherwise the iterable test below |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
44 # succeeds, and the string will be chopped up into individual |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
45 # characters |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
46 if isinstance(obj, basestring): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
47 yield TEXT, obj, pos |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
48 elif hasattr(obj, '__iter__'): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
49 for event in _ensure(obj): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
50 yield event |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
51 else: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
52 yield TEXT, unicode(obj), pos |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
53 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
54 def _expand_text(obj): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
55 if obj is not None: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
56 if isinstance(obj, basestring): |
356
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
57 return [obj] |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
58 elif hasattr(obj, '__iter__'): |
356
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
59 return [e[1] for e in _ensure(obj) if e[0] is TEXT] |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
60 else: |
356
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
61 return [unicode(obj)] |
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
62 return [] |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
63 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
64 def _assign(ast): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
65 buf = [] |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
66 def _build(node, indices): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
67 if isinstance(node, (compiler.ast.AssTuple, compiler.ast.Tuple)): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
68 for idx, child in enumerate(node.nodes): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
69 _build(child, indices + (idx,)) |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
70 elif isinstance(node, (compiler.ast.AssName, compiler.ast.Name)): |
398 | 71 buf.append('%r: v%s' % (node.name, ''.join(['[%s]' % i for i in indices]))) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
72 _build(ast, ()) |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
73 return '{%s}' % ', '.join(buf) |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
74 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
75 def inline(template): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
76 w = CodeWriter() |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
77 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
78 yield w('from genshi.core import Attrs, QName') |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
79 yield w('from genshi.core import START, START_NS, END, END_NS, DOCTYPE, TEXT') |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
80 yield w('from genshi.path import Path') |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
81 yield w('from genshi.template.eval import Expression') |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
82 yield w('from genshi.template.inline import _expand, _expand_text') |
342 | 83 yield w() |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
84 |
342 | 85 def _predecl_vars(stream): |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
86 for kind, data, pos in stream: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
87 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
88 if kind is START: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
89 tagname, attrs = data |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
90 yield 'Q', tagname, tagname |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
91 |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
92 sattrs = Attrs([(n, v) for n, v in attrs |
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
93 if isinstance(v, basestring)]) |
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
94 for name, val in [(n, v) for n, v in attrs |
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
95 if not isinstance(v, basestring)]: |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
96 yield 'Q', name, name |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
97 for subkind, subdata, subpos in val: |
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
98 if subkind is EXPR: |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
99 yield 'E', subdata, subdata |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
100 |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
101 yield 'A', tuple(sattrs), sattrs |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
102 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
103 elif kind is EXPR: |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
104 yield 'E', data, data |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
105 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
106 elif kind is SUB: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
107 directives, substream = data |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
108 for directive in directives: |
342 | 109 |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
110 if directive.expr: |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
111 yield 'E', directive.expr, directive.expr |
342 | 112 |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
113 elif hasattr(directive, 'vars'): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
114 for _, expr in directive.vars: |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
115 yield 'E', expr, expr |
342 | 116 |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
117 elif hasattr(directive, 'path') and directive.path: |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
118 yield 'P', directive.path, directive.path |
342 | 119 |
120 for line in _predecl_vars(substream): | |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
121 yield line |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
122 |
398 | 123 def _predecl_defs(stream): |
342 | 124 for kind, data, pos in stream: |
125 if kind is SUB: | |
126 directives, substream = data | |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
127 for idx, directive in enumerate(directives): |
342 | 128 if isinstance(directive, DefDirective): |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
129 defs.append(directive.name) |
342 | 130 yield w('def %s:', directive.signature) |
131 w.shift() | |
132 args = ['%r: %s' % (name, name) for name | |
133 in directive.args] | |
134 yield w('ctxt.push({%s})', ', '.join(args)) | |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
135 for line in _apply(directives[idx + 1:], substream): |
342 | 136 yield line |
137 yield w('ctxt.pop()') | |
138 w.unshift() | |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
139 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
140 # Recursively apply directives |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
141 def _apply(directives, stream): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
142 if not directives: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
143 for line in _generate(stream): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
144 yield line |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
145 return |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
146 |
398 | 147 d = directives[0] |
148 rest = directives[1:] | |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
149 |
398 | 150 if isinstance(d, DefDirective): |
151 return # already added | |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
152 |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
153 yield w() |
398 | 154 yield w('# Applying %r', d) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
155 |
398 | 156 if isinstance(d, ForDirective): |
157 yield w('for v in e[%d].evaluate(ctxt):', index['E'][d.expr]) | |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
158 w.shift() |
398 | 159 yield w('ctxt.push(%s)', _assign(d.target)) |
160 for line in _apply(rest, stream): | |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
161 yield line |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
162 yield w('ctxt.pop()') |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
163 w.unshift() |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
164 |
398 | 165 elif isinstance(d, IfDirective): |
166 yield w('if e[%d].evaluate(ctxt):', index['E'][d.expr]) | |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
167 w.shift() |
398 | 168 for line in _apply(rest, stream): |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
169 yield line |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
170 w.unshift() |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
171 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
172 else: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
173 raise NotImplementedError |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
174 |
342 | 175 yield w() |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
176 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
177 # Generate code for the given template stream |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
178 def _generate(stream): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
179 for kind, data, pos in stream: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
180 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
181 if kind is EXPR: |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
182 yield w('for evt in _expand(e[%d].evaluate(ctxt), (f, %d, %d)): yield evt', |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
183 index['E'][data], *pos[1:]) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
184 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
185 elif kind is START: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
186 tagname, attrs = data |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
187 qn = index['Q'][tagname] |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
188 |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
189 sattrs = Attrs([(n, v) for n, v in attrs |
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
190 if isinstance(v, basestring)]) |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
191 at = index['A'][tuple(sattrs)] |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
192 if filter(None, [not isinstance(v, basestring) for n,v in attrs]): |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
193 yield w('at = [(an, "".join(av)) for an, av in ([') |
356
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
194 w.shift() |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
195 for name, value in [(n, v) for n, v in attrs |
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
196 if not isinstance(v, basestring)]: |
356
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
197 values = [] |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
198 for subkind, subdata, subpos in value: |
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
199 if subkind is EXPR: |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
200 values.append('_expand_text(e[%d].evaluate(ctxt))' % |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
201 index['E'][subdata]) |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
202 elif subkind is TEXT: |
356
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
203 values.append('[%r]' % subdata) |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
204 yield w('(q[%d], [v for v in %s if v is not None]),' % ( |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
205 index['Q'][name], ' + '.join(values) |
356
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
206 )) |
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
207 w.unshift() |
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
208 yield w(']) if av]') |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
209 yield w('yield START, (q[%d], a[%d] | at), (f, %d, %d)', qn, at, |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
210 *pos[1:]) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
211 else: |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
212 yield w('yield START, (q[%d], a[%d]), (f, %d, %d)', qn, at, *pos[1:]) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
213 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
214 elif kind is END: |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
215 yield w('yield END, q[%d], (f, %d, %d)', index['Q'][data], *pos[1:]) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
216 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
217 elif kind is SUB: |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
218 directives, substream = data |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
219 for line in _apply(directives, substream): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
220 yield line |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
221 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
222 else: |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
223 yield w('yield %s, %r, (f, %d, %d)', kind, data, *pos[1:]) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
224 |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
225 yield w('_F = %r', template.filename) |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
226 yield w() |
342 | 227 |
228 yield '# predeclare qnames, attributes, and expressions' | |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
229 index, counter, values = {}, {}, {} |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
230 for prefix, key, value in _predecl_vars(template.stream): |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
231 if not prefix in counter: |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
232 counter[prefix] = 0 |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
233 if key not in index.get(prefix, ()): |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
234 index.setdefault(prefix, {})[key] = counter[prefix] |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
235 counter[prefix] += 1 |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
236 values.setdefault(prefix, []).append(value) |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
237 for prefix in sorted(values.keys()): |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
238 yield w('_%s = (', prefix) |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
239 for value in values[prefix]: |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
240 yield w(' ' + repr(value) + ',') |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
241 yield w(')') |
342 | 242 yield w() |
243 | |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
244 yield w('def generate(ctxt, %s):', |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
245 ', '.join(['f=_F'] + ['%s=_%s' % (n.lower(), n) for n in index])) |
342 | 246 yield w() |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
247 w.shift() |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
248 |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
249 # Define macro functions |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
250 defs = [] |
398 | 251 for line in _predecl_defs(template.stream): |
342 | 252 yield line |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
253 if defs: |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
254 yield w() |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
255 yield w('ctxt.push({%s})', ', '.join(['%r: %s' % (n, n) for n in defs])) |
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
256 yield w() |
342 | 257 |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
258 ei, pi = [0], [0] |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
259 for line in _generate(template.stream): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
260 yield line |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
261 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
262 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
263 if __name__ == '__main__': |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
264 import timeit |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
265 from genshi.template import Context, MarkupTemplate |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
266 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
267 text = """<!DOCTYPE html |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
268 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
269 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
270 <html xmlns="http://www.w3.org/1999/xhtml" |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
271 xmlns:py="http://genshi.edgewall.org/" |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
272 lang="en"> |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
273 <body> |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
274 <h1 py:def="sayhi(name='world')" py:strip=""> |
342 | 275 Hello, $name! |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
276 </h1> |
342 | 277 ${sayhi()} |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
278 <ul py:if="items"> |
356
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
279 <li py:for="idx, item in enumerate(items)" |
ada22378f12c
inline branch: minor tweaks, removed currently unsupported directives
cmlenz
parents:
355
diff
changeset
|
280 class="${idx % 2 and 'odd' or 'even'}"> |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
281 <span py:replace="item + 1">NUM</span> |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
282 </li> |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
283 </ul> |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
284 </body> |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
285 </html>""" |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
286 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
287 ctxt = Context(hello='world', items=range(10)) |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
288 tmpl = MarkupTemplate(text) |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
289 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
290 print 'Generated source:' |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
291 for idx, line in enumerate(inline(tmpl)): |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
292 print '%3d %s' % (idx + 1, line) |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
293 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
294 print |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
295 print 'Interpreted template:' |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
296 print tmpl.generate(ctxt) |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
297 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
298 print |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
299 print 'Executed module:' |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
300 module = tmpl.compile() |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
301 print Stream(module.generate(ctxt)) |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
302 |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
303 print |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
304 print |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
305 t = timeit.Timer('list(tmpl.generate(**data))', ''' |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
306 from genshi.template import Context, MarkupTemplate |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
307 data = dict(hello='world', items=range(10)) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
308 tmpl = MarkupTemplate("""%s""")''' % text) |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
309 print 'Interpreted: %.2f msec/pass' % (1000 * t.timeit(number=1000) / 1000) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
310 print |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
311 |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
312 t = timeit.Timer('list(module.generate(Context(**data)))', ''' |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
313 from genshi.core import Stream |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
314 from genshi.template import Context, MarkupTemplate |
348
72937f87d519
inline branch: adapted to the immutble `Attrs` change, and various other fixes.
cmlenz
parents:
342
diff
changeset
|
315 data = dict(hello='world', items=range(10)) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
316 tmpl = MarkupTemplate("""%s""") |
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
317 module = tmpl.compile()''' % text) |
359
f53be1b18b82
inline branch: use array to predeclare qnames, attrs, and expressions.
cmlenz
parents:
356
diff
changeset
|
318 print 'Compiled: %.2f msec/pass' % (1000 * t.timeit(number=1000) / 1000) |
339
83c3d04bba97
First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff
changeset
|
319 print |