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
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
83 yield w()
339
83c3d04bba97 First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents:
diff changeset
84
342
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
119
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
123 def _predecl_defs(stream):
342
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
124 for kind, data, pos in stream:
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
125 if kind is SUB:
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
130 yield w('def %s:', directive.signature)
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
131 w.shift()
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
132 args = ['%r: %s' % (name, name) for name
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
133 in directive.args]
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
136 yield line
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
137 yield w('ctxt.pop()')
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
147 d = directives[0]
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
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
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
150 if isinstance(d, DefDirective):
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
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
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
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
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
156 if isinstance(d, ForDirective):
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
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
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
159 yield w('ctxt.push(%s)', _assign(d.target))
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
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
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
165 elif isinstance(d, IfDirective):
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
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
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
227
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
242 yield w()
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
49aa525b8f83 inline branch: Merged [480:486/trunk].
cmlenz
parents: 359
diff changeset
251 for line in _predecl_defs(template.stream):
342
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 341
diff changeset
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
Copyright (C) 2012-2017 Edgewall Software