Mercurial > genshi > mirror
annotate genshi/template/directives.py @ 1012:cdb5d435d237 trunk
Fix assert with side-effect in xi:fallback directive processing (see #565).
author | hodgestar |
---|---|
date | Mon, 17 Jun 2013 20:52:21 +0000 |
parents | 59463031d904 |
children | 51ab60299647 |
rev | line source |
---|---|
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
1 # -*- coding: utf-8 -*- |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
2 # |
847
e16447a9605f
Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents:
827
diff
changeset
|
3 # Copyright (C) 2006-2009 Edgewall Software |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
4 # All rights reserved. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
5 # |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
9 # |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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/. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
13 |
7763f7aec949
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.""" |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
15 |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
16 from genshi.core import QName, Stream |
336
7763f7aec949
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 |
400
e29a94b3ba0c
Renamed `genshi.template.core` to `genshi.template.base`, mainly to avoid confusion with `genshi.core`.
cmlenz
parents:
380
diff
changeset
|
18 from genshi.template.base import TemplateRuntimeError, TemplateSyntaxError, \ |
817
f2c58252daa3
Minor simplification in the expansion of dynamic attributes.
cmlenz
parents:
794
diff
changeset
|
19 EXPR, _apply_directives, _eval_expr |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
20 from genshi.template.eval import Expression, ExpressionASTTransformer, \ |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
21 _ast, _parse |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
22 |
7763f7aec949
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', |
7763f7aec949
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', |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
25 'OtherwiseDirective', 'ReplaceDirective', 'StripDirective', |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
26 'WhenDirective', 'WithDirective'] |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
27 __docformat__ = 'restructuredtext en' |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
28 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
29 |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
30 class DirectiveMeta(type): |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
31 """Meta class for template directives.""" |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
32 |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
33 def __new__(cls, name, bases, d): |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
34 d['tagname'] = name.lower().replace('directive', '') |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
35 return type.__new__(cls, name, bases, d) |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
36 |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
37 |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
38 class Directive(object): |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
39 """Abstract base class for template directives. |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
40 |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
41 A directive is basically a callable that takes three positional arguments: |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
42 ``ctxt`` is the template data context, ``stream`` is an iterable over the |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
43 events that the directive applies to, and ``directives`` is is a list of |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
44 other directives on the same stream that need to be applied. |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
45 |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
46 Directives can be "anonymous" or "registered". Registered directives can be |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
47 applied by the template author using an XML attribute with the |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
48 corresponding name in the template. Such directives should be subclasses of |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
49 this base class that can be instantiated with the value of the directive |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
50 attribute as parameter. |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
51 |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
52 Anonymous directives are simply functions conforming to the protocol |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
53 described above, and can only be applied programmatically (for example by |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
54 template filters). |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
55 """ |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
56 __metaclass__ = DirectiveMeta |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
57 __slots__ = ['expr'] |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
58 |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
59 def __init__(self, value, template=None, namespaces=None, lineno=-1, |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
60 offset=-1): |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
61 self.expr = self._parse_expr(value, template, lineno, offset) |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
62 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
63 @classmethod |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
64 def attach(cls, template, stream, value, namespaces, pos): |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
65 """Called after the template stream has been completely parsed. |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
66 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
67 :param template: the `Template` object |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
68 :param stream: the event stream associated with the directive |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
69 :param value: the argument value for the directive; if the directive was |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
70 specified as an element, this will be an `Attrs` instance |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
71 with all specified attributes, otherwise it will be a |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
72 `unicode` object with just the attribute value |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
73 :param namespaces: a mapping of namespace URIs to prefixes |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
74 :param pos: a ``(filename, lineno, offset)`` tuple describing the |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
75 location where the directive was found in the source |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
76 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
77 This class method should return a ``(directive, stream)`` tuple. If |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
78 ``directive`` is not ``None``, it should be an instance of the `Directive` |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
79 class, and gets added to the list of directives applied to the substream |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
80 at runtime. `stream` is an event stream that replaces the original |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
81 stream associated with the directive. |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
82 """ |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
83 return cls(value, template, namespaces, *pos[1:]), stream |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
84 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
85 def __call__(self, stream, directives, ctxt, **vars): |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
86 """Apply the directive to the given stream. |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
87 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
88 :param stream: the event stream |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
89 :param directives: a list of the remaining directives that should |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
90 process the stream |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
91 :param ctxt: the context data |
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
92 :param vars: additional variables that should be made available when |
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
93 Python code is executed |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
94 """ |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
95 raise NotImplementedError |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
96 |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
97 def __repr__(self): |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
98 expr = '' |
380
bf2068f5ef74
Fail gracefully in `Directive.__repr__` if the `expr` attribute does not exist for some reason I don't really understand right now (see Trac ticket [http://trac.edgewall.org/ticket/4249 #4249]).
cmlenz
parents:
362
diff
changeset
|
99 if getattr(self, 'expr', None) is not None: |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
100 expr = ' "%s"' % self.expr.source |
860
16d55698006a
A bit of cleanup of the `Markup` Python implementation.
cmlenz
parents:
853
diff
changeset
|
101 return '<%s%s>' % (type(self).__name__, expr) |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
102 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
103 @classmethod |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
104 def _parse_expr(cls, expr, template, lineno=-1, offset=-1): |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
105 """Parses the given expression, raising a useful error message when a |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
106 syntax error is encountered. |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
107 """ |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
108 try: |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
109 return expr and Expression(expr, template.filepath, lineno, |
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
110 lookup=template.lookup) or None |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
111 except SyntaxError, err: |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
112 err.msg += ' in expression "%s" of "%s" directive' % (expr, |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
113 cls.tagname) |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
114 raise TemplateSyntaxError(err, template.filepath, lineno, |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
115 offset + (err.offset or 0)) |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
116 |
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
117 |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
118 def _assignment(ast): |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
119 """Takes the AST representation of an assignment, and returns a |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
120 function that applies the assignment of a given value to a dictionary. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
121 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
122 def _names(node): |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
123 if isinstance(node, _ast.Tuple): |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
124 return tuple([_names(child) for child in node.elts]) |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
125 elif isinstance(node, _ast.Name): |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
126 return node.id |
336
7763f7aec949
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)): |
7763f7aec949
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: |
7763f7aec949
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)): |
7763f7aec949
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]) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
131 else: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
132 data[names] = value |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
133 return _assign |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
134 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
135 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
136 class AttrsDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
137 """Implementation of the ``py:attrs`` template directive. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
138 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
139 The value of the ``py:attrs`` attribute should be a dictionary or a sequence |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
140 of ``(name, value)`` tuples. The items in that dictionary or sequence are |
336
7763f7aec949
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: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
142 |
7763f7aec949
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 |
7763f7aec949
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/"> |
7763f7aec949
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> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
146 ... </ul>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
147 >>> print(tmpl.generate(foo={'class': 'collapse'})) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
148 <ul> |
7763f7aec949
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> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
150 </ul> |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
151 >>> print(tmpl.generate(foo=[('class', 'collapse')])) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
152 <ul> |
7763f7aec949
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> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
154 </ul> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
155 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
156 If the value evaluates to ``None`` (or any other non-truth value), no |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
157 attributes are added: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
158 |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
159 >>> print(tmpl.generate(foo=None)) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
160 <ul> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
161 <li>Bar</li> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
162 </ul> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
163 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
164 __slots__ = [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
165 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
166 def __call__(self, stream, directives, ctxt, **vars): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
167 def _generate(): |
7763f7aec949
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() |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
169 attrs = _eval_expr(self.expr, ctxt, vars) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
170 if attrs: |
7763f7aec949
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): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
172 try: |
7763f7aec949
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() |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
174 except StopIteration: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
175 attrs = [] |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
177 attrs = attrs.items() |
904
82b9b3afe0b8
The `|` operator on `Attrs` objects now removes any existing attributes if the value is `None`.
cmlenz
parents:
860
diff
changeset
|
178 attrib |= [ |
82b9b3afe0b8
The `|` operator on `Attrs` objects now removes any existing attributes if the value is `None`.
cmlenz
parents:
860
diff
changeset
|
179 (QName(n), v is not None and unicode(v).strip() or None) |
82b9b3afe0b8
The `|` operator on `Attrs` objects now removes any existing attributes if the value is `None`.
cmlenz
parents:
860
diff
changeset
|
180 for n, v in attrs |
82b9b3afe0b8
The `|` operator on `Attrs` objects now removes any existing attributes if the value is `None`.
cmlenz
parents:
860
diff
changeset
|
181 ] |
336
7763f7aec949
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 |
7763f7aec949
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: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
184 yield event |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
185 |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
186 return _apply_directives(_generate(), directives, ctxt, vars) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
187 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
188 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
189 class ContentDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
190 """Implementation of the ``py:content`` template directive. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
191 |
7763f7aec949
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 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
193 evaluating the value of the ``py:content`` attribute: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
194 |
7763f7aec949
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 |
7763f7aec949
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/"> |
7763f7aec949
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> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
198 ... </ul>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
199 >>> print(tmpl.generate(bar='Bye')) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
200 <ul> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
201 <li>Bye</li> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
202 </ul> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
203 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
204 __slots__ = [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
205 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
206 @classmethod |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
207 def attach(cls, template, stream, value, namespaces, pos): |
657 | 208 if type(value) is dict: |
209 raise TemplateSyntaxError('The content directive can not be used ' | |
210 'as an element', template.filepath, | |
211 *pos[1:]) | |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
212 expr = cls._parse_expr(value, template, *pos[1:]) |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
213 return None, [stream[0], (EXPR, expr, pos), stream[-1]] |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
214 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
215 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
216 class DefDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
217 """Implementation of the ``py:def`` template directive. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
218 |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
222 in the template. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
223 |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
225 from template expressions: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
226 |
7763f7aec949
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 |
7763f7aec949
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/"> |
7763f7aec949
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"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
230 ... ${greeting}, ${name}! |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
231 ... </p> |
7763f7aec949
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')} |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
233 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
234 >>> print(tmpl.generate(bar='Bye')) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
235 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
236 <p class="message"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
237 Hi, you! |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
238 </p> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
239 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
240 |
7763f7aec949
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 |
343
35189e960252
Remove automatic calling of expression evaluation results if they are callable. See [http://groups.google.com/group/genshi/browse_thread/thread/f515986760918d41 this mailing list thread].
cmlenz
parents:
336
diff
changeset
|
242 in the definition: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
243 |
7763f7aec949
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/"> |
7763f7aec949
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"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
246 ... Hello, world! |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
247 ... </p> |
343
35189e960252
Remove automatic calling of expression evaluation results if they are callable. See [http://groups.google.com/group/genshi/browse_thread/thread/f515986760918d41 this mailing list thread].
cmlenz
parents:
336
diff
changeset
|
248 ... ${helloworld()} |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
249 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
250 >>> print(tmpl.generate(bar='Bye')) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
251 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
252 <p class="message"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
253 Hello, world! |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
254 </p> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
255 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
256 """ |
479 | 257 __slots__ = ['name', 'args', 'star_args', 'dstar_args', 'defaults'] |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
258 |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
259 def __init__(self, args, template, namespaces=None, lineno=-1, offset=-1): |
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
260 Directive.__init__(self, None, template, namespaces, lineno, offset) |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
261 ast = _parse(args).body |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
262 self.args = [] |
479 | 263 self.star_args = None |
264 self.dstar_args = None | |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
265 self.defaults = {} |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
266 if isinstance(ast, _ast.Call): |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
267 self.name = ast.func.id |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
268 for arg in ast.args: |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
269 # only names |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
270 self.args.append(arg.id) |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
271 for kwd in ast.keywords: |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
272 self.args.append(kwd.arg) |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
273 exp = Expression(kwd.value, template.filepath, |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
274 lineno, lookup=template.lookup) |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
275 self.defaults[kwd.arg] = exp |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
276 if getattr(ast, 'starargs', None): |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
277 self.star_args = ast.starargs.id |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
278 if getattr(ast, 'kwargs', None): |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
279 self.dstar_args = ast.kwargs.id |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
280 else: |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
281 self.name = ast.id |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
282 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
283 @classmethod |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
284 def attach(cls, template, stream, value, namespaces, pos): |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
285 if type(value) is dict: |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
286 value = value.get('function') |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
287 return super(DefDirective, cls).attach(template, stream, value, |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
288 namespaces, pos) |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
289 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
290 def __call__(self, stream, directives, ctxt, **vars): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
291 stream = list(stream) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
292 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
293 def function(*args, **kwargs): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
294 scope = {} |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
295 args = list(args) # make mutable |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
296 for name in self.args: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
297 if args: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
298 scope[name] = args.pop(0) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
299 else: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
300 if name in kwargs: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
301 val = kwargs.pop(name) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
302 else: |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
303 val = _eval_expr(self.defaults.get(name), ctxt, vars) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
304 scope[name] = val |
479 | 305 if not self.star_args is None: |
306 scope[self.star_args] = args | |
307 if not self.dstar_args is None: | |
308 scope[self.dstar_args] = kwargs | |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
309 ctxt.push(scope) |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
310 for event in _apply_directives(stream, directives, ctxt, vars): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
311 yield event |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
312 ctxt.pop() |
750 | 313 function.__name__ = self.name |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
314 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
315 # Store the function reference in the bottom context frame so that it |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
316 # doesn't get popped off before processing the template has finished |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
317 # FIXME: this makes context data mutable as a side-effect |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
318 ctxt.frames[-1][self.name] = function |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
319 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
320 return [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
321 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
322 def __repr__(self): |
860
16d55698006a
A bit of cleanup of the `Markup` Python implementation.
cmlenz
parents:
853
diff
changeset
|
323 return '<%s "%s">' % (type(self).__name__, self.name) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
324 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
325 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
326 class ForDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
327 """Implementation of the ``py:for`` template directive for repeating an |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
328 element based on an iterable in the context data. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
329 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
330 >>> from genshi.template import MarkupTemplate |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
331 >>> tmpl = MarkupTemplate('''<ul xmlns:py="http://genshi.edgewall.org/"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
332 ... <li py:for="item in items">${item}</li> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
333 ... </ul>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
334 >>> print(tmpl.generate(items=[1, 2, 3])) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
335 <ul> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
336 <li>1</li><li>2</li><li>3</li> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
337 </ul> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
338 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
339 __slots__ = ['assign', 'filename'] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
340 |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
341 def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
342 if ' in ' not in value: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
343 raise TemplateSyntaxError('"in" keyword missing in "for" directive', |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
344 template.filepath, lineno, offset) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
345 assign, value = value.split(' in ', 1) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
346 ast = _parse(assign, 'exec') |
640 | 347 value = 'iter(%s)' % value.strip() |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
348 self.assign = _assignment(ast.body[0].value) |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
349 self.filename = template.filepath |
640 | 350 Directive.__init__(self, value, template, namespaces, lineno, offset) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
351 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
352 @classmethod |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
353 def attach(cls, template, stream, value, namespaces, pos): |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
354 if type(value) is dict: |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
355 value = value.get('each') |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
356 return super(ForDirective, cls).attach(template, stream, value, |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
357 namespaces, pos) |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
358 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
359 def __call__(self, stream, directives, ctxt, **vars): |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
360 iterable = _eval_expr(self.expr, ctxt, vars) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
361 if iterable is None: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
362 return |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
363 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
364 assign = self.assign |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
365 scope = {} |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
366 stream = list(stream) |
640 | 367 for item in iterable: |
368 assign(scope, item) | |
369 ctxt.push(scope) | |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
370 for event in _apply_directives(stream, directives, ctxt, vars): |
640 | 371 yield event |
372 ctxt.pop() | |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
373 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
374 def __repr__(self): |
860
16d55698006a
A bit of cleanup of the `Markup` Python implementation.
cmlenz
parents:
853
diff
changeset
|
375 return '<%s>' % type(self).__name__ |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
376 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
377 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
378 class IfDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
379 """Implementation of the ``py:if`` template directive for conditionally |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
380 excluding elements from being output. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
381 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
382 >>> from genshi.template import MarkupTemplate |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
383 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
384 ... <b py:if="foo">${bar}</b> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
385 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
386 >>> print(tmpl.generate(foo=True, bar='Hello')) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
387 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
388 <b>Hello</b> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
389 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
390 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
391 __slots__ = [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
392 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
393 @classmethod |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
394 def attach(cls, template, stream, value, namespaces, pos): |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
395 if type(value) is dict: |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
396 value = value.get('test') |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
397 return super(IfDirective, cls).attach(template, stream, value, |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
398 namespaces, pos) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
399 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
400 def __call__(self, stream, directives, ctxt, **vars): |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
401 value = _eval_expr(self.expr, ctxt, vars) |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
402 if value: |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
403 return _apply_directives(stream, directives, ctxt, vars) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
404 return [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
405 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
406 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
407 class MatchDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
408 """Implementation of the ``py:match`` template directive. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
409 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
410 >>> from genshi.template import MarkupTemplate |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
411 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
412 ... <span py:match="greeting"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
413 ... Hello ${select('@name')} |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
414 ... </span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
415 ... <greeting name="Dude" /> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
416 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
417 >>> print(tmpl.generate()) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
418 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
419 <span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
420 Hello Dude |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
421 </span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
422 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
423 """ |
602 | 424 __slots__ = ['path', 'namespaces', 'hints'] |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
425 |
602 | 426 def __init__(self, value, template, hints=None, namespaces=None, |
427 lineno=-1, offset=-1): | |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
428 Directive.__init__(self, None, template, namespaces, lineno, offset) |
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
429 self.path = Path(value, template.filepath, lineno) |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
430 self.namespaces = namespaces or {} |
602 | 431 self.hints = hints or () |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
432 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
433 @classmethod |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
434 def attach(cls, template, stream, value, namespaces, pos): |
602 | 435 hints = [] |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
436 if type(value) is dict: |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
437 if value.get('buffer', '').lower() == 'false': |
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
438 hints.append('not_buffered') |
602 | 439 if value.get('once', '').lower() == 'true': |
440 hints.append('match_once') | |
441 if value.get('recursive', '').lower() == 'false': | |
442 hints.append('not_recursive') | |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
443 value = value.get('path') |
602 | 444 return cls(value, template, frozenset(hints), namespaces, *pos[1:]), \ |
445 stream | |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
446 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
447 def __call__(self, stream, directives, ctxt, **vars): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
448 ctxt._match_templates.append((self.path.test(ignore_context=True), |
602 | 449 self.path, list(stream), self.hints, |
450 self.namespaces, directives)) | |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
451 return [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
452 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
453 def __repr__(self): |
860
16d55698006a
A bit of cleanup of the `Markup` Python implementation.
cmlenz
parents:
853
diff
changeset
|
454 return '<%s "%s">' % (type(self).__name__, self.path.source) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
455 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
456 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
457 class ReplaceDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
458 """Implementation of the ``py:replace`` template directive. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
459 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
460 This directive replaces the element with the result of evaluating the |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
461 value of the ``py:replace`` attribute: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
462 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
463 >>> from genshi.template import MarkupTemplate |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
464 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
465 ... <span py:replace="bar">Hello</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
466 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
467 >>> print(tmpl.generate(bar='Bye')) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
468 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
469 Bye |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
470 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
471 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
472 This directive is equivalent to ``py:content`` combined with ``py:strip``, |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
473 providing a less verbose way to achieve the same effect: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
474 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
475 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
476 ... <span py:content="bar" py:strip="">Hello</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
477 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
478 >>> print(tmpl.generate(bar='Bye')) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
479 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
480 Bye |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
481 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
482 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
483 __slots__ = [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
484 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
485 @classmethod |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
486 def attach(cls, template, stream, value, namespaces, pos): |
657 | 487 if type(value) is dict: |
488 value = value.get('value') | |
436
57e8bd746717
Raise syntax error on empty value for `py:replace` directive.
cmlenz
parents:
425
diff
changeset
|
489 if not value: |
57e8bd746717
Raise syntax error on empty value for `py:replace` directive.
cmlenz
parents:
425
diff
changeset
|
490 raise TemplateSyntaxError('missing value for "replace" directive', |
57e8bd746717
Raise syntax error on empty value for `py:replace` directive.
cmlenz
parents:
425
diff
changeset
|
491 template.filepath, *pos[1:]) |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
492 expr = cls._parse_expr(value, template, *pos[1:]) |
362
fe40d34fb71d
Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents:
351
diff
changeset
|
493 return None, [(EXPR, expr, pos)] |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
494 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
495 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
496 class StripDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
497 """Implementation of the ``py:strip`` template directive. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
498 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
499 When the value of the ``py:strip`` attribute evaluates to ``True``, the |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
500 element is stripped from the output |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
501 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
502 >>> from genshi.template import MarkupTemplate |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
503 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
504 ... <div py:strip="True"><b>foo</b></div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
505 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
506 >>> print(tmpl.generate()) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
507 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
508 <b>foo</b> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
509 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
510 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
511 Leaving the attribute value empty is equivalent to a truth value. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
512 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
513 This directive is particulary interesting for named template functions or |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
514 match templates that do not generate a top-level element: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
515 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
516 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
517 ... <div py:def="echo(what)" py:strip=""> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
518 ... <b>${what}</b> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
519 ... </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
520 ... ${echo('foo')} |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
521 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
522 >>> print(tmpl.generate()) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
523 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
524 <b>foo</b> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
525 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
526 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
527 __slots__ = [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
528 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
529 def __call__(self, stream, directives, ctxt, **vars): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
530 def _generate(): |
847
e16447a9605f
Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents:
827
diff
changeset
|
531 if not self.expr or _eval_expr(self.expr, ctxt, vars): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
532 stream.next() # skip start tag |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
533 previous = stream.next() |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
534 for event in stream: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
535 yield previous |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
536 previous = event |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
537 else: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
538 for event in stream: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
539 yield event |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
540 return _apply_directives(_generate(), directives, ctxt, vars) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
541 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
542 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
543 class ChooseDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
544 """Implementation of the ``py:choose`` directive for conditionally selecting |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
545 one of several body elements to display. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
546 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
547 If the ``py:choose`` expression is empty the expressions of nested |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
548 ``py:when`` directives are tested for truth. The first true ``py:when`` |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
549 body is output. If no ``py:when`` directive is matched then the fallback |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
550 directive ``py:otherwise`` will be used. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
551 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
552 >>> from genshi.template import MarkupTemplate |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
553 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/" |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
554 ... py:choose=""> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
555 ... <span py:when="0 == 1">0</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
556 ... <span py:when="1 == 1">1</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
557 ... <span py:otherwise="">2</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
558 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
559 >>> print(tmpl.generate()) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
560 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
561 <span>1</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
562 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
563 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
564 If the ``py:choose`` directive contains an expression, the nested |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
565 ``py:when`` directives are tested for equality to the ``py:choose`` |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
566 expression: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
567 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
568 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/" |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
569 ... py:choose="2"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
570 ... <span py:when="1">1</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
571 ... <span py:when="2">2</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
572 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
573 >>> print(tmpl.generate()) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
574 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
575 <span>2</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
576 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
577 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
578 Behavior is undefined if a ``py:choose`` block contains content outside a |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
579 ``py:when`` or ``py:otherwise`` block. Behavior is also undefined if a |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
580 ``py:otherwise`` occurs before ``py:when`` blocks. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
581 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
582 __slots__ = ['matched', 'value'] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
583 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
584 @classmethod |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
585 def attach(cls, template, stream, value, namespaces, pos): |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
586 if type(value) is dict: |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
587 value = value.get('test') |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
588 return super(ChooseDirective, cls).attach(template, stream, value, |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
589 namespaces, pos) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
590 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
591 def __call__(self, stream, directives, ctxt, **vars): |
562
b3dc05d88751
In the py:choose stack, store the information of whether a test expression has been supplied separate from the result of its evaluation.
cmlenz
parents:
553
diff
changeset
|
592 info = [False, bool(self.expr), None] |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
593 if self.expr: |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
594 info[2] = _eval_expr(self.expr, ctxt, vars) |
553
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
595 ctxt._choice_stack.append(info) |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
596 for event in _apply_directives(stream, directives, ctxt, vars): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
597 yield event |
553
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
598 ctxt._choice_stack.pop() |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
599 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
600 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
601 class WhenDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
602 """Implementation of the ``py:when`` directive for nesting in a parent with |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
603 the ``py:choose`` directive. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
604 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
605 See the documentation of the `ChooseDirective` for usage. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
606 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
607 __slots__ = ['filename'] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
608 |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
609 def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1): |
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
610 Directive.__init__(self, value, template, namespaces, lineno, offset) |
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
611 self.filename = template.filepath |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
612 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
613 @classmethod |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
614 def attach(cls, template, stream, value, namespaces, pos): |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
615 if type(value) is dict: |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
616 value = value.get('test') |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
617 return super(WhenDirective, cls).attach(template, stream, value, |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
618 namespaces, pos) |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
619 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
620 def __call__(self, stream, directives, ctxt, **vars): |
553
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
621 info = ctxt._choice_stack and ctxt._choice_stack[-1] |
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
622 if not info: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
623 raise TemplateRuntimeError('"when" directives can only be used ' |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
624 'inside a "choose" directive', |
935 | 625 self.filename, *(stream.next())[2][1:]) |
553
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
626 if info[0]: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
627 return [] |
553
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
628 if not self.expr and not info[1]: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
629 raise TemplateRuntimeError('either "choose" or "when" directive ' |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
630 'must have a test expression', |
935 | 631 self.filename, *(stream.next())[2][1:]) |
553
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
632 if info[1]: |
562
b3dc05d88751
In the py:choose stack, store the information of whether a test expression has been supplied separate from the result of its evaluation.
cmlenz
parents:
553
diff
changeset
|
633 value = info[2] |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
634 if self.expr: |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
635 matched = value == _eval_expr(self.expr, ctxt, vars) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
636 else: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
637 matched = bool(value) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
638 else: |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
639 matched = bool(_eval_expr(self.expr, ctxt, vars)) |
553
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
640 info[0] = matched |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
641 if not matched: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
642 return [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
643 |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
644 return _apply_directives(stream, directives, ctxt, vars) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
645 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
646 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
647 class OtherwiseDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
648 """Implementation of the ``py:otherwise`` directive for nesting in a parent |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
649 with the ``py:choose`` directive. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
650 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
651 See the documentation of `ChooseDirective` for usage. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
652 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
653 __slots__ = ['filename'] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
654 |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
655 def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1): |
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
656 Directive.__init__(self, None, template, namespaces, lineno, offset) |
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
657 self.filename = template.filepath |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
658 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
659 def __call__(self, stream, directives, ctxt, **vars): |
553
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
660 info = ctxt._choice_stack and ctxt._choice_stack[-1] |
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
661 if not info: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
662 raise TemplateRuntimeError('an "otherwise" directive can only be ' |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
663 'used inside a "choose" directive', |
935 | 664 self.filename, *(stream.next())[2][1:]) |
553
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
665 if info[0]: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
666 return [] |
553
489a47873950
Store state information for py:choose outside of the regular context data.
cmlenz
parents:
552
diff
changeset
|
667 info[0] = True |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
668 |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
669 return _apply_directives(stream, directives, ctxt, vars) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
670 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
671 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
672 class WithDirective(Directive): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
673 """Implementation of the ``py:with`` template directive, which allows |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
674 shorthand access to variables and expressions. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
675 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
676 >>> from genshi.template import MarkupTemplate |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
677 >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
678 ... <span py:with="y=7; z=x+10">$x $y $z</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
679 ... </div>''') |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
847
diff
changeset
|
680 >>> print(tmpl.generate(x=42)) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
681 <div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
682 <span>42 7 52</span> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
683 </div> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
684 """ |
710
0af8f63514b8
Partially revert [717] to retain compatibility with Python 2.3.
cmlenz
parents:
700
diff
changeset
|
685 __slots__ = ['vars'] |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
686 |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
687 def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1): |
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
688 Directive.__init__(self, None, template, namespaces, lineno, offset) |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
689 self.vars = [] |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
690 value = value.strip() |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
691 try: |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
692 ast = _parse(value, 'exec') |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
693 for node in ast.body: |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
694 if not isinstance(node, _ast.Assign): |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
695 raise TemplateSyntaxError('only assignment allowed in ' |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
696 'value of the "with" directive', |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
697 template.filepath, lineno, offset) |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
698 self.vars.append(([_assignment(n) for n in node.targets], |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
699 Expression(node.value, template.filepath, |
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
700 lineno, lookup=template.lookup))) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
701 except SyntaxError, err: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
702 err.msg += ' in expression "%s" of "%s" directive' % (value, |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
703 self.tagname) |
442
97544725bb7f
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
436
diff
changeset
|
704 raise TemplateSyntaxError(err, template.filepath, lineno, |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
705 offset + (err.offset or 0)) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
706 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
817
diff
changeset
|
707 @classmethod |
552
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
708 def attach(cls, template, stream, value, namespaces, pos): |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
709 if type(value) is dict: |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
710 value = value.get('vars') |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
711 return super(WithDirective, cls).attach(template, stream, value, |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
712 namespaces, pos) |
b59d99d2f631
For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
cmlenz
parents:
479
diff
changeset
|
713 |
700
08f22328303d
Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents:
684
diff
changeset
|
714 def __call__(self, stream, directives, ctxt, **vars): |
710
0af8f63514b8
Partially revert [717] to retain compatibility with Python 2.3.
cmlenz
parents:
700
diff
changeset
|
715 frame = {} |
0af8f63514b8
Partially revert [717] to retain compatibility with Python 2.3.
cmlenz
parents:
700
diff
changeset
|
716 ctxt.push(frame) |
794
f9e23d472a6e
Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents:
750
diff
changeset
|
717 for targets, expr in self.vars: |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
718 value = _eval_expr(expr, ctxt, vars) |
710
0af8f63514b8
Partially revert [717] to retain compatibility with Python 2.3.
cmlenz
parents:
700
diff
changeset
|
719 for assign in targets: |
0af8f63514b8
Partially revert [717] to retain compatibility with Python 2.3.
cmlenz
parents:
700
diff
changeset
|
720 assign(frame, value) |
827
bebc68529176
Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents:
822
diff
changeset
|
721 for event in _apply_directives(stream, directives, ctxt, vars): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
722 yield event |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
723 ctxt.pop() |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
724 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
725 def __repr__(self): |
860
16d55698006a
A bit of cleanup of the `Markup` Python implementation.
cmlenz
parents:
853
diff
changeset
|
726 return '<%s>' % (type(self).__name__) |