annotate genshi/template/directives.py @ 907:bb813ef5fe25 experimental-inline

inline branch: merged r1129 from trunk.
author cmlenz
date Wed, 28 Apr 2010 21:36:59 +0000
parents 09cc3627654c
children
rev   line source
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
2 #
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
3 # Copyright (C) 2006-2009 Edgewall Software
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
4 # All rights reserved.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
5 #
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
8 # are also available at http://genshi.edgewall.org/wiki/License.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
9 #
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://genshi.edgewall.org/log/.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
13
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
14 """Implementation of the various template directives."""
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
15
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
16 from genshi.core import QName, Stream
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
17 from genshi.path import Path
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
18 from genshi.template.base import TemplateRuntimeError, TemplateSyntaxError, \
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
19 EXPR, _apply_directives, _eval_expr
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
20 from genshi.template.eval import Expression, ExpressionASTTransformer, \
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
21 _ast, _parse
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
22
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
23 __all__ = ['AttrsDirective', 'ChooseDirective', 'ContentDirective',
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
24 'DefDirective', 'ForDirective', 'IfDirective', 'MatchDirective',
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
25 'OtherwiseDirective', 'ReplaceDirective', 'StripDirective',
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
26 'WhenDirective', 'WithDirective']
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
27 __docformat__ = 'restructuredtext en'
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
28
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
29
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
30 class DirectiveMeta(type):
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
31 """Meta class for template directives."""
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
32
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
33 def __new__(cls, name, bases, d):
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
34 d['tagname'] = name.lower().replace('directive', '')
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
35 return type.__new__(cls, name, bases, d)
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
36
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
37
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
38 class Directive(object):
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
39 """Abstract base class for template directives.
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
40
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
41 A directive is basically a callable that takes three positional arguments:
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
42 ``ctxt`` is the template data context, ``stream`` is an iterable over the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
43 events that the directive applies to, and ``directives`` is is a list of
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
44 other directives on the same stream that need to be applied.
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
45
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
46 Directives can be "anonymous" or "registered". Registered directives can be
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
47 applied by the template author using an XML attribute with the
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
48 corresponding name in the template. Such directives should be subclasses of
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
49 this base class that can be instantiated with the value of the directive
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
50 attribute as parameter.
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
51
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
52 Anonymous directives are simply functions conforming to the protocol
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
53 described above, and can only be applied programmatically (for example by
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
54 template filters).
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
55 """
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
56 __metaclass__ = DirectiveMeta
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
57 __slots__ = ['expr']
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
58
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
59 def __init__(self, value, template=None, namespaces=None, lineno=-1,
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
60 offset=-1):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
61 self.expr = self._parse_expr(value, template, lineno, offset)
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
62
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
63 @classmethod
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
64 def attach(cls, template, stream, value, namespaces, pos):
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
65 """Called after the template stream has been completely parsed.
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
66
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
67 :param template: the `Template` object
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
68 :param stream: the event stream associated with the directive
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
69 :param value: the argument value for the directive; if the directive was
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
70 specified as an element, this will be an `Attrs` instance
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
71 with all specified attributes, otherwise it will be a
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
72 `unicode` object with just the attribute value
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
73 :param namespaces: a mapping of namespace URIs to prefixes
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
74 :param pos: a ``(filename, lineno, offset)`` tuple describing the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
75 location where the directive was found in the source
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
76
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
77 This class method should return a ``(directive, stream)`` tuple. If
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
78 ``directive`` is not ``None``, it should be an instance of the `Directive`
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
79 class, and gets added to the list of directives applied to the substream
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
80 at runtime. `stream` is an event stream that replaces the original
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
81 stream associated with the directive.
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
82 """
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
83 return cls(value, template, namespaces, *pos[1:]), stream
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
84
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
85 def __call__(self, stream, directives, ctxt, **vars):
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
86 """Apply the directive to the given stream.
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
87
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
88 :param stream: the event stream
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
89 :param directives: a list of the remaining directives that should
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
90 process the stream
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
91 :param ctxt: the context data
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
92 :param vars: additional variables that should be made available when
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
93 Python code is executed
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
94 """
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
95 raise NotImplementedError
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
96
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
97 def __repr__(self):
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
98 expr = ''
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
99 if getattr(self, 'expr', None) is not None:
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
100 expr = ' "%s"' % self.expr.source
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
101 return '<%s%s>' % (type(self).__name__, expr)
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
102
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
103 @classmethod
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
104 def _parse_expr(cls, expr, template, lineno=-1, offset=-1):
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
105 """Parses the given expression, raising a useful error message when a
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
106 syntax error is encountered.
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
107 """
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
108 try:
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
109 return expr and Expression(expr, template.filepath, lineno,
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
110 lookup=template.lookup) or None
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
111 except SyntaxError, err:
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
112 err.msg += ' in expression "%s" of "%s" directive' % (expr,
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
113 cls.tagname)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
114 raise TemplateSyntaxError(err, template.filepath, lineno,
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
115 offset + (err.offset or 0))
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
116
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
117
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
118 def _assignment(ast):
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
119 """Takes the AST representation of an assignment, and returns a
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
120 function that applies the assignment of a given value to a dictionary.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
121 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
122 def _names(node):
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
123 if isinstance(node, _ast.Tuple):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
124 return tuple([_names(child) for child in node.elts])
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
125 elif isinstance(node, _ast.Name):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
126 return node.id
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
127 def _assign(data, value, names=_names(ast)):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
128 if type(names) is tuple:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
129 for idx in range(len(names)):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
130 _assign(data, value[idx], names[idx])
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
131 else:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
132 data[names] = value
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
133 return _assign
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
134
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
135
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
136 class AttrsDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
137 """Implementation of the ``py:attrs`` template directive.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
138
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
139 The value of the ``py:attrs`` attribute should be a dictionary or a sequence
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
140 of ``(name, value)`` tuples. The items in that dictionary or sequence are
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
141 added as attributes to the element:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
142
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
143 >>> from genshi.template import MarkupTemplate
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
144 >>> tmpl = MarkupTemplate('''<ul xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
145 ... <li py:attrs="foo">Bar</li>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
146 ... </ul>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
147 >>> print(tmpl.generate(foo={'class': 'collapse'}))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
148 <ul>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
149 <li class="collapse">Bar</li>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
150 </ul>
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
151 >>> print(tmpl.generate(foo=[('class', 'collapse')]))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
152 <ul>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
153 <li class="collapse">Bar</li>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
154 </ul>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
155
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
156 If the value evaluates to ``None`` (or any other non-truth value), no
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
157 attributes are added:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
158
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
159 >>> print(tmpl.generate(foo=None))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
160 <ul>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
161 <li>Bar</li>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
162 </ul>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
163 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
164 __slots__ = []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
165
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
166 def __call__(self, stream, directives, ctxt, **vars):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
167 def _generate():
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
168 kind, (tag, attrib), pos = stream.next()
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
169 attrs = _eval_expr(self.expr, ctxt, vars)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
170 if attrs:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
171 if isinstance(attrs, Stream):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
172 try:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
173 attrs = iter(attrs).next()
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
174 except StopIteration:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
175 attrs = []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
176 elif not isinstance(attrs, list): # assume it's a dict
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
177 attrs = attrs.items()
907
bb813ef5fe25 inline branch: merged r1129 from trunk.
cmlenz
parents: 902
diff changeset
178 attrib |= [
bb813ef5fe25 inline branch: merged r1129 from trunk.
cmlenz
parents: 902
diff changeset
179 (QName(n), v is not None and unicode(v).strip() or None)
bb813ef5fe25 inline branch: merged r1129 from trunk.
cmlenz
parents: 902
diff changeset
180 for n, v in attrs
bb813ef5fe25 inline branch: merged r1129 from trunk.
cmlenz
parents: 902
diff changeset
181 ]
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
182 yield kind, (tag, attrib), pos
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
183 for event in stream:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
184 yield event
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
185
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
186 return _apply_directives(_generate(), directives, ctxt, vars)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
187
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
188
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
189 class ContentDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
190 """Implementation of the ``py:content`` template directive.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
191
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
192 This directive replaces the content of the element with the result of
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
193 evaluating the value of the ``py:content`` attribute:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
194
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
195 >>> from genshi.template import MarkupTemplate
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
196 >>> tmpl = MarkupTemplate('''<ul xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
197 ... <li py:content="bar">Hello</li>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
198 ... </ul>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
199 >>> print(tmpl.generate(bar='Bye'))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
200 <ul>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
201 <li>Bye</li>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
202 </ul>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
203 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
204 __slots__ = []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
205
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
206 @classmethod
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
207 def attach(cls, template, stream, value, namespaces, pos):
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
208 if type(value) is dict:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
209 raise TemplateSyntaxError('The content directive can not be used '
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
210 'as an element', template.filepath,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
211 *pos[1:])
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
212 expr = cls._parse_expr(value, template, *pos[1:])
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
213 return None, [stream[0], (EXPR, expr, pos), stream[-1]]
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
214
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
215
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
216 class DefDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
217 """Implementation of the ``py:def`` template directive.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
218
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
219 This directive can be used to create "Named Template Functions", which
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
220 are template snippets that are not actually output during normal
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
221 processing, but rather can be expanded from expressions in other places
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
222 in the template.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
223
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
224 A named template function can be used just like a normal Python function
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
225 from template expressions:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
226
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
227 >>> from genshi.template import MarkupTemplate
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
228 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
229 ... <p py:def="echo(greeting, name='world')" class="message">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
230 ... ${greeting}, ${name}!
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
231 ... </p>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
232 ... ${echo('Hi', name='you')}
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
233 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
234 >>> print(tmpl.generate(bar='Bye'))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
235 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
236 <p class="message">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
237 Hi, you!
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
238 </p>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
239 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
240
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
241 If a function does not require parameters, the parenthesis can be omitted
344
eb4ef44ea1ad inline branch: Merged [419:421/trunk].
cmlenz
parents: 342
diff changeset
242 in the definition:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
243
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
244 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
245 ... <p py:def="helloworld" class="message">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
246 ... Hello, world!
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
247 ... </p>
344
eb4ef44ea1ad inline branch: Merged [419:421/trunk].
cmlenz
parents: 342
diff changeset
248 ... ${helloworld()}
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
249 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
250 >>> print(tmpl.generate(bar='Bye'))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
251 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
252 <p class="message">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
253 Hello, world!
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
254 </p>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
255 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
256 """
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
257 __slots__ = ['name', 'args', 'star_args', 'dstar_args', 'defaults',
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
258 'signature']
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
259
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
260 def __init__(self, args, template, namespaces=None, lineno=-1, offset=-1):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
261 Directive.__init__(self, None, template, namespaces, lineno, offset)
342
3d29249e0524 inline branch: support for the def directive.
cmlenz
parents: 339
diff changeset
262 self.signature = args.strip()
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
263 ast = _parse(args).body
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
264 self.args = []
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
265 self.star_args = None
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
266 self.dstar_args = None
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
267 self.defaults = {}
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
268 if isinstance(ast, _ast.Call):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
269 self.name = ast.func.id
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
270 for arg in ast.args:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
271 # only names
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
272 self.args.append(arg.id)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
273 for kwd in ast.keywords:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
274 self.args.append(kwd.arg)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
275 exp = Expression(kwd.value, template.filepath,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
276 lineno, lookup=template.lookup)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
277 self.defaults[kwd.arg] = exp
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
278 if getattr(ast, 'starargs', None):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
279 self.star_args = ast.starargs.id
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
280 if getattr(ast, 'kwargs', None):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
281 self.dstar_args = ast.kwargs.id
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
282 else:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
283 self.name = ast.id
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
284
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
285 @classmethod
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
286 def attach(cls, template, stream, value, namespaces, pos):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
287 if type(value) is dict:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
288 value = value.get('function')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
289 return super(DefDirective, cls).attach(template, stream, value,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
290 namespaces, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
291
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
292 def __call__(self, stream, directives, ctxt, **vars):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
293 stream = list(stream)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
294
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
295 def function(*args, **kwargs):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
296 scope = {}
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
297 args = list(args) # make mutable
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
298 for name in self.args:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
299 if args:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
300 scope[name] = args.pop(0)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
301 else:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
302 if name in kwargs:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
303 val = kwargs.pop(name)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
304 else:
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
305 val = _eval_expr(self.defaults.get(name), ctxt, vars)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
306 scope[name] = val
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
307 if not self.star_args is None:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
308 scope[self.star_args] = args
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
309 if not self.dstar_args is None:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
310 scope[self.dstar_args] = kwargs
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
311 ctxt.push(scope)
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
312 for event in _apply_directives(stream, directives, ctxt, vars):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
313 yield event
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
314 ctxt.pop()
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
315 function.__name__ = self.name
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
316
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
317 # Store the function reference in the bottom context frame so that it
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
318 # doesn't get popped off before processing the template has finished
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
319 # FIXME: this makes context data mutable as a side-effect
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
320 ctxt.frames[-1][self.name] = function
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
321
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
322 return []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
323
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
324 def __repr__(self):
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
325 return '<%s "%s">' % (type(self).__name__, self.name)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
326
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
327
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
328 class ForDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
329 """Implementation of the ``py:for`` template directive for repeating an
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
330 element based on an iterable in the context data.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
331
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
332 >>> from genshi.template import MarkupTemplate
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
333 >>> tmpl = MarkupTemplate('''<ul xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
334 ... <li py:for="item in items">${item}</li>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
335 ... </ul>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
336 >>> print(tmpl.generate(items=[1, 2, 3]))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
337 <ul>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
338 <li>1</li><li>2</li><li>3</li>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
339 </ul>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
340 """
339
83c3d04bba97 First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents: 336
diff changeset
341 __slots__ = ['assign', 'target', 'filename']
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
342
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
343 def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
344 if ' in ' not in value:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
345 raise TemplateSyntaxError('"in" keyword missing in "for" directive',
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
346 template.filepath, lineno, offset)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
347 assign, value = value.split(' in ', 1)
821
abb1f1d2f4f3 inline-branch: Fix for `for` directive.
cmlenz
parents: 820
diff changeset
348 self.target = _parse(assign, 'exec').body[0].value
abb1f1d2f4f3 inline-branch: Fix for `for` directive.
cmlenz
parents: 820
diff changeset
349 self.assign = _assignment(self.target)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
350 value = 'iter(%s)' % value.strip()
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
351 self.filename = template.filepath
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
352 Directive.__init__(self, value, template, namespaces, lineno, offset)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
353
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
354 @classmethod
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
355 def attach(cls, template, stream, value, namespaces, pos):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
356 if type(value) is dict:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
357 value = value.get('each')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
358 return super(ForDirective, cls).attach(template, stream, value,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
359 namespaces, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
360
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
361 def __call__(self, stream, directives, ctxt, **vars):
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
362 iterable = _eval_expr(self.expr, ctxt, vars)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
363 if iterable is None:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
364 return
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
365
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
366 assign = self.assign
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
367 scope = {}
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
368 stream = list(stream)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
369 for item in iterable:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
370 assign(scope, item)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
371 ctxt.push(scope)
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
372 for event in _apply_directives(stream, directives, ctxt, vars):
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
373 yield event
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
374 ctxt.pop()
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
375
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
376 def __repr__(self):
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
377 return '<%s>' % type(self).__name__
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
378
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
379
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
380 class IfDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
381 """Implementation of the ``py:if`` template directive for conditionally
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
382 excluding elements from being output.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
383
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
384 >>> from genshi.template import MarkupTemplate
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
385 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
386 ... <b py:if="foo">${bar}</b>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
387 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
388 >>> print(tmpl.generate(foo=True, bar='Hello'))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
389 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
390 <b>Hello</b>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
391 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
392 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
393 __slots__ = []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
394
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
395 @classmethod
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
396 def attach(cls, template, stream, value, namespaces, pos):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
397 if type(value) is dict:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
398 value = value.get('test')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
399 return super(IfDirective, cls).attach(template, stream, value,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
400 namespaces, pos)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
401
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
402 def __call__(self, stream, directives, ctxt, **vars):
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
403 value = _eval_expr(self.expr, ctxt, vars)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
404 if value:
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
405 return _apply_directives(stream, directives, ctxt, vars)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
406 return []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
407
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
408
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
409 class MatchDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
410 """Implementation of the ``py:match`` template directive.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
411
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
412 >>> from genshi.template import MarkupTemplate
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
413 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
414 ... <span py:match="greeting">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
415 ... Hello ${select('@name')}
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
416 ... </span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
417 ... <greeting name="Dude" />
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
418 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
419 >>> print(tmpl.generate())
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
420 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
421 <span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
422 Hello Dude
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
423 </span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
424 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
425 """
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
426 __slots__ = ['path', 'namespaces', 'hints']
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
427
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
428 def __init__(self, value, template, hints=None, namespaces=None,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
429 lineno=-1, offset=-1):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
430 Directive.__init__(self, None, template, namespaces, lineno, offset)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
431 self.path = Path(value, template.filepath, lineno)
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
432 self.namespaces = namespaces or {}
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
433 self.hints = hints or ()
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
434
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
435 @classmethod
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
436 def attach(cls, template, stream, value, namespaces, pos):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
437 hints = []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
438 if type(value) is dict:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
439 if value.get('buffer', '').lower() == 'false':
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
440 hints.append('not_buffered')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
441 if value.get('once', '').lower() == 'true':
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
442 hints.append('match_once')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
443 if value.get('recursive', '').lower() == 'false':
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
444 hints.append('not_recursive')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
445 value = value.get('path')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
446 return cls(value, template, frozenset(hints), namespaces, *pos[1:]), \
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
447 stream
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
448
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
449 def __call__(self, stream, directives, ctxt, **vars):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
450 ctxt._match_templates.append((self.path.test(ignore_context=True),
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
451 self.path, list(stream), self.hints,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
452 self.namespaces, directives))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
453 return []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
454
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
455 def __repr__(self):
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
456 return '<%s "%s">' % (type(self).__name__, self.path.source)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
457
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
458
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
459 class ReplaceDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
460 """Implementation of the ``py:replace`` template directive.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
461
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
462 This directive replaces the element with the result of evaluating the
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
463 value of the ``py:replace`` attribute:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
464
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
465 >>> from genshi.template import MarkupTemplate
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
466 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
467 ... <span py:replace="bar">Hello</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
468 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
469 >>> print(tmpl.generate(bar='Bye'))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
470 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
471 Bye
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
472 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
473
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
474 This directive is equivalent to ``py:content`` combined with ``py:strip``,
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
475 providing a less verbose way to achieve the same effect:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
476
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
477 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
478 ... <span py:content="bar" py:strip="">Hello</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
479 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
480 >>> print(tmpl.generate(bar='Bye'))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
481 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
482 Bye
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
483 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
484 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
485 __slots__ = []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
486
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
487 @classmethod
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
488 def attach(cls, template, stream, value, namespaces, pos):
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
489 if type(value) is dict:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
490 value = value.get('value')
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
491 if not value:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
492 raise TemplateSyntaxError('missing value for "replace" directive',
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
493 template.filepath, *pos[1:])
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
494 expr = cls._parse_expr(value, template, *pos[1:])
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 355
diff changeset
495 return None, [(EXPR, expr, pos)]
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
496
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
497
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
498 class StripDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
499 """Implementation of the ``py:strip`` template directive.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
500
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
501 When the value of the ``py:strip`` attribute evaluates to ``True``, the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
502 element is stripped from the output
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
503
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
504 >>> from genshi.template import MarkupTemplate
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
505 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
506 ... <div py:strip="True"><b>foo</b></div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
507 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
508 >>> print(tmpl.generate())
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
509 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
510 <b>foo</b>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
511 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
512
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
513 Leaving the attribute value empty is equivalent to a truth value.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
514
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
515 This directive is particulary interesting for named template functions or
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
516 match templates that do not generate a top-level element:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
517
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
518 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
519 ... <div py:def="echo(what)" py:strip="">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
520 ... <b>${what}</b>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
521 ... </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
522 ... ${echo('foo')}
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
523 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
524 >>> print(tmpl.generate())
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
525 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
526 <b>foo</b>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
527 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
528 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
529 __slots__ = []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
530
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
531 def __call__(self, stream, directives, ctxt, **vars):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
532 def _generate():
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
533 if not self.expr or _eval_expr(self.expr, ctxt, vars):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
534 stream.next() # skip start tag
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
535 previous = stream.next()
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
536 for event in stream:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
537 yield previous
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
538 previous = event
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
539 else:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
540 for event in stream:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
541 yield event
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
542 return _apply_directives(_generate(), directives, ctxt, vars)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
543
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
544
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
545 class ChooseDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
546 """Implementation of the ``py:choose`` directive for conditionally selecting
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
547 one of several body elements to display.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
548
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
549 If the ``py:choose`` expression is empty the expressions of nested
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
550 ``py:when`` directives are tested for truth. The first true ``py:when``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
551 body is output. If no ``py:when`` directive is matched then the fallback
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
552 directive ``py:otherwise`` will be used.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
553
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
554 >>> from genshi.template import MarkupTemplate
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
555 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
556 ... py:choose="">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
557 ... <span py:when="0 == 1">0</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
558 ... <span py:when="1 == 1">1</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
559 ... <span py:otherwise="">2</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
560 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
561 >>> print(tmpl.generate())
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
562 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
563 <span>1</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
564 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
565
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
566 If the ``py:choose`` directive contains an expression, the nested
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
567 ``py:when`` directives are tested for equality to the ``py:choose``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
568 expression:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
569
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
570 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
571 ... py:choose="2">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
572 ... <span py:when="1">1</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
573 ... <span py:when="2">2</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
574 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
575 >>> print(tmpl.generate())
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
576 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
577 <span>2</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
578 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
579
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
580 Behavior is undefined if a ``py:choose`` block contains content outside a
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
581 ``py:when`` or ``py:otherwise`` block. Behavior is also undefined if a
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
582 ``py:otherwise`` occurs before ``py:when`` blocks.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
583 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
584 __slots__ = ['matched', 'value']
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
585
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
586 @classmethod
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
587 def attach(cls, template, stream, value, namespaces, pos):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
588 if type(value) is dict:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
589 value = value.get('test')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
590 return super(ChooseDirective, cls).attach(template, stream, value,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
591 namespaces, pos)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
592
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
593 def __call__(self, stream, directives, ctxt, **vars):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
594 info = [False, bool(self.expr), None]
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
595 if self.expr:
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
596 info[2] = _eval_expr(self.expr, ctxt, vars)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
597 ctxt._choice_stack.append(info)
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
598 for event in _apply_directives(stream, directives, ctxt, vars):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
599 yield event
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
600 ctxt._choice_stack.pop()
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
601
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
602
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
603 class WhenDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
604 """Implementation of the ``py:when`` directive for nesting in a parent with
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
605 the ``py:choose`` directive.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
606
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
607 See the documentation of the `ChooseDirective` for usage.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
608 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
609 __slots__ = ['filename']
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
610
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
611 def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
612 Directive.__init__(self, value, template, namespaces, lineno, offset)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
613 self.filename = template.filepath
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
614
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
615 @classmethod
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
616 def attach(cls, template, stream, value, namespaces, pos):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
617 if type(value) is dict:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
618 value = value.get('test')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
619 return super(WhenDirective, cls).attach(template, stream, value,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
620 namespaces, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
621
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
622 def __call__(self, stream, directives, ctxt, **vars):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
623 info = ctxt._choice_stack and ctxt._choice_stack[-1]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
624 if not info:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
625 raise TemplateRuntimeError('"when" directives can only be used '
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
626 'inside a "choose" directive',
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
627 self.filename, *stream.next()[2][1:])
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
628 if info[0]:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
629 return []
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
630 if not self.expr and not info[1]:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
631 raise TemplateRuntimeError('either "choose" or "when" directive '
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
632 'must have a test expression',
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
633 self.filename, *stream.next()[2][1:])
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
634 if info[1]:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
635 value = info[2]
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
636 if self.expr:
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
637 matched = value == _eval_expr(self.expr, ctxt, vars)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
638 else:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
639 matched = bool(value)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
640 else:
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
641 matched = bool(_eval_expr(self.expr, ctxt, vars))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
642 info[0] = matched
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
643 if not matched:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
644 return []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
645
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
646 return _apply_directives(stream, directives, ctxt, vars)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
647
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
648
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
649 class OtherwiseDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
650 """Implementation of the ``py:otherwise`` directive for nesting in a parent
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
651 with the ``py:choose`` directive.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
652
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
653 See the documentation of `ChooseDirective` for usage.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
654 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
655 __slots__ = ['filename']
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
656
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
657 def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
658 Directive.__init__(self, None, template, namespaces, lineno, offset)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
659 self.filename = template.filepath
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
660
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
661 def __call__(self, stream, directives, ctxt, **vars):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
662 info = ctxt._choice_stack and ctxt._choice_stack[-1]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
663 if not info:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
664 raise TemplateRuntimeError('an "otherwise" directive can only be '
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
665 'used inside a "choose" directive',
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
666 self.filename, *stream.next()[2][1:])
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
667 if info[0]:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
668 return []
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
669 info[0] = True
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
670
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
671 return _apply_directives(stream, directives, ctxt, vars)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
672
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
673
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
674 class WithDirective(Directive):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
675 """Implementation of the ``py:with`` template directive, which allows
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
676 shorthand access to variables and expressions.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
677
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
678 >>> from genshi.template import MarkupTemplate
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
679 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
680 ... <span py:with="y=7; z=x+10">$x $y $z</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
681 ... </div>''')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
682 >>> print(tmpl.generate(x=42))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
683 <div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
684 <span>42 7 52</span>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
685 </div>
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
686 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
687 __slots__ = ['vars']
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
688
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
689 def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
690 Directive.__init__(self, None, template, namespaces, lineno, offset)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
691 self.vars = []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
692 value = value.strip()
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
693 try:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
694 ast = _parse(value, 'exec')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
695 for node in ast.body:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
696 if not isinstance(node, _ast.Assign):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
697 raise TemplateSyntaxError('only assignment allowed in '
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
698 'value of the "with" directive',
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
699 template.filepath, lineno, offset)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
700 self.vars.append(([(n, _assignment(n)) for n in node.targets],
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
701 Expression(node.value, template.filepath,
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
702 lineno, lookup=template.lookup)))
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
703 except SyntaxError, err:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
704 err.msg += ' in expression "%s" of "%s" directive' % (value,
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
705 self.tagname)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
706 raise TemplateSyntaxError(err, template.filepath, lineno,
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
707 offset + (err.offset or 0))
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
708
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
709 @classmethod
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
710 def attach(cls, template, stream, value, namespaces, pos):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
711 if type(value) is dict:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
712 value = value.get('vars')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
713 return super(WithDirective, cls).attach(template, stream, value,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
714 namespaces, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
715
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
716 def __call__(self, stream, directives, ctxt, **vars):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
717 frame = {}
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
718 ctxt.push(frame)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
719 for targets, expr in self.vars:
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
720 value = _eval_expr(expr, ctxt, vars)
339
83c3d04bba97 First code for the `inline` branch? only bits and pieces working right now.
cmlenz
parents: 336
diff changeset
721 for _, assign in targets:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
722 assign(frame, value)
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 821
diff changeset
723 for event in _apply_directives(stream, directives, ctxt, vars):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
724 yield event
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
725 ctxt.pop()
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
726
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
727 def __repr__(self):
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
728 return '<%s>' % (type(self).__name__)
Copyright (C) 2012-2017 Edgewall Software