Mercurial > genshi > mirror
annotate genshi/template/markup.py @ 520:203bd6a3c93d trunk
Applied patch by Dale Sedivec to fix #127. Many thanks!
author | cmlenz |
---|---|
date | Wed, 13 Jun 2007 12:37:58 +0000 |
parents | f56046e4b0de |
children | 619340e2d805 |
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 # |
408 | 3 # Copyright (C) 2006-2007 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 """Markup templating engine.""" |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
15 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
16 from itertools import chain |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
17 import sys |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
18 from textwrap import dedent |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
19 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
20 from genshi.core import Attrs, Namespace, Stream, StreamEventKind |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
21 from genshi.core import START, END, START_NS, END_NS, TEXT, PI, COMMENT |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
22 from genshi.input import XMLParser |
400
e29a94b3ba0c
Renamed `genshi.template.core` to `genshi.template.base`, mainly to avoid confusion with `genshi.core`.
cmlenz
parents:
381
diff
changeset
|
23 from genshi.template.base import BadDirectiveError, Template, \ |
475
b373f80f7763
Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents:
442
diff
changeset
|
24 TemplateSyntaxError, _apply_directives, \ |
b373f80f7763
Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents:
442
diff
changeset
|
25 INCLUDE, SUB |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
26 from genshi.template.eval import Suite |
407
f37d8e6acdf2
Move string interpolation code into separate module (`genshi.template.interpolation`).
cmlenz
parents:
405
diff
changeset
|
27 from genshi.template.interpolation import interpolate |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
28 from genshi.template.directives import * |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
29 |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
30 if sys.version_info < (2, 4): |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
31 _ctxt2dict = lambda ctxt: ctxt.frames[0] |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
32 else: |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
33 _ctxt2dict = lambda ctxt: ctxt |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
34 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
35 __all__ = ['MarkupTemplate'] |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
36 __docformat__ = 'restructuredtext en' |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
37 |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
38 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
39 class MarkupTemplate(Template): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
40 """Implementation of the template language for XML-based templates. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
41 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
42 >>> 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
|
43 ... <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
|
44 ... </ul>''') |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
45 >>> print tmpl.generate(items=[1, 2, 3]) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
46 <ul> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
47 <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
|
48 </ul> |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
49 """ |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
50 EXEC = StreamEventKind('EXEC') |
427 | 51 """Stream event kind representing a Python code suite to execute.""" |
52 | |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
53 DIRECTIVE_NAMESPACE = Namespace('http://genshi.edgewall.org/') |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
54 XINCLUDE_NAMESPACE = Namespace('http://www.w3.org/2001/XInclude') |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
55 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
56 directives = [('def', DefDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
57 ('match', MatchDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
58 ('when', WhenDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
59 ('otherwise', OtherwiseDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
60 ('for', ForDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
61 ('if', IfDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
62 ('choose', ChooseDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
63 ('with', WithDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
64 ('replace', ReplaceDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
65 ('content', ContentDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
66 ('attrs', AttrsDirective), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
67 ('strip', StripDirective)] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
68 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
69 def __init__(self, source, basedir=None, filename=None, loader=None, |
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:
434
diff
changeset
|
70 encoding=None, lookup='lenient'): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
71 Template.__init__(self, source, basedir=basedir, filename=filename, |
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:
434
diff
changeset
|
72 loader=loader, encoding=encoding, lookup=lookup) |
496
f56046e4b0de
Fix bug introduced in [575]: includes weren't being processed inside match templates.
cmlenz
parents:
475
diff
changeset
|
73 # Make sure the include filter comes after the match filter |
f56046e4b0de
Fix bug introduced in [575]: includes weren't being processed inside match templates.
cmlenz
parents:
475
diff
changeset
|
74 if loader: |
f56046e4b0de
Fix bug introduced in [575]: includes weren't being processed inside match templates.
cmlenz
parents:
475
diff
changeset
|
75 self.filters.remove(self._include) |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
76 self.filters += [self._exec, self._match] |
496
f56046e4b0de
Fix bug introduced in [575]: includes weren't being processed inside match templates.
cmlenz
parents:
475
diff
changeset
|
77 if loader: |
f56046e4b0de
Fix bug introduced in [575]: includes weren't being processed inside match templates.
cmlenz
parents:
475
diff
changeset
|
78 self.filters.append(self._include) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
79 |
374
b146277eb54a
`MarkupTemplate`s can now be instantiated from markup streams, in addition to strings and file-like objects. Thanks to David Fraser for the patch. Closes #69.
cmlenz
parents:
364
diff
changeset
|
80 def _parse(self, source, encoding): |
381
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
81 streams = [[]] # stacked lists of events of the "compiled" template |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
82 dirmap = {} # temporary mapping of directives to elements |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
83 ns_prefix = {} |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
84 depth = 0 |
381
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
85 in_fallback = 0 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
86 include_href = None |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
87 |
374
b146277eb54a
`MarkupTemplate`s can now be instantiated from markup streams, in addition to strings and file-like objects. Thanks to David Fraser for the patch. Closes #69.
cmlenz
parents:
364
diff
changeset
|
88 if not isinstance(source, Stream): |
434
5692bc32ba5f
* Better method to propogate the full path to the template file on parse errors. Supersedes r513.
cmlenz
parents:
427
diff
changeset
|
89 source = XMLParser(source, filename=self.filename, |
374
b146277eb54a
`MarkupTemplate`s can now be instantiated from markup streams, in addition to strings and file-like objects. Thanks to David Fraser for the patch. Closes #69.
cmlenz
parents:
364
diff
changeset
|
90 encoding=encoding) |
b146277eb54a
`MarkupTemplate`s can now be instantiated from markup streams, in addition to strings and file-like objects. Thanks to David Fraser for the patch. Closes #69.
cmlenz
parents:
364
diff
changeset
|
91 |
b146277eb54a
`MarkupTemplate`s can now be instantiated from markup streams, in addition to strings and file-like objects. Thanks to David Fraser for the patch. Closes #69.
cmlenz
parents:
364
diff
changeset
|
92 for kind, data, pos in source: |
381
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
93 stream = streams[-1] |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
94 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
95 if kind is START_NS: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
96 # Strip out the namespace declaration for template directives |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
97 prefix, uri = data |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
98 ns_prefix[prefix] = uri |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
99 if uri not in (self.DIRECTIVE_NAMESPACE, |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
100 self.XINCLUDE_NAMESPACE): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
101 stream.append((kind, data, pos)) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
102 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
103 elif kind is END_NS: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
104 uri = ns_prefix.pop(data, None) |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
105 if uri and uri not in (self.DIRECTIVE_NAMESPACE, |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
106 self.XINCLUDE_NAMESPACE): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
107 stream.append((kind, data, pos)) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
108 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
109 elif kind is START: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
110 # Record any directive attributes in start tags |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
111 tag, attrs = data |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
112 directives = [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
113 strip = False |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
114 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
115 if tag in self.DIRECTIVE_NAMESPACE: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
116 cls = self._dir_by_name.get(tag.localname) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
117 if cls is None: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
118 raise BadDirectiveError(tag.localname, self.filepath, |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
119 pos[1]) |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
120 value = attrs.get(getattr(cls, 'ATTRIBUTE', 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:
336
diff
changeset
|
121 directives.append((cls, value, ns_prefix.copy(), pos)) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
122 strip = True |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
123 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
124 new_attrs = [] |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
125 for name, value in attrs: |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
126 if name in self.DIRECTIVE_NAMESPACE: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
127 cls = self._dir_by_name.get(name.localname) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
128 if cls is None: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
129 raise BadDirectiveError(name.localname, |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
130 self.filepath, 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:
336
diff
changeset
|
131 directives.append((cls, value, ns_prefix.copy(), pos)) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
132 else: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
133 if 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:
434
diff
changeset
|
134 value = list(interpolate(value, self.basedir, |
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:
434
diff
changeset
|
135 pos[0], pos[1], pos[2], |
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:
434
diff
changeset
|
136 lookup=self.lookup)) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
137 if len(value) == 1 and value[0][0] is TEXT: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
138 value = value[0][1] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
139 else: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
140 value = [(TEXT, u'', pos)] |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
141 new_attrs.append((name, value)) |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
142 new_attrs = Attrs(new_attrs) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
143 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
144 if directives: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
145 index = self._dir_order.index |
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:
336
diff
changeset
|
146 directives.sort(lambda a, b: cmp(index(a[0]), index(b[0]))) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
147 dirmap[(depth, tag)] = (directives, len(stream), strip) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
148 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
149 if tag in self.XINCLUDE_NAMESPACE: |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
150 if tag.localname == 'include': |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
151 include_href = new_attrs.get('href') |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
152 if not include_href: |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
153 raise TemplateSyntaxError('Include misses required ' |
422
5d08a744636e
More work to include absolute file paths in exceptions.
cmlenz
parents:
421
diff
changeset
|
154 'attribute "href"', |
5d08a744636e
More work to include absolute file paths in exceptions.
cmlenz
parents:
421
diff
changeset
|
155 self.filepath, *pos[1:]) |
381
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
156 streams.append([]) |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
157 elif tag.localname == 'fallback': |
381
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
158 in_fallback += 1 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
159 |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
160 else: |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
161 stream.append((kind, (tag, new_attrs), pos)) |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
162 |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
163 depth += 1 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
164 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
165 elif kind is END: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
166 depth -= 1 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
167 |
381
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
168 if in_fallback and data == self.XINCLUDE_NAMESPACE['fallback']: |
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
169 in_fallback -= 1 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
170 elif data == self.XINCLUDE_NAMESPACE['include']: |
381
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
171 fallback = streams.pop() |
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
172 stream = streams[-1] |
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
173 stream.append((INCLUDE, (include_href, fallback), pos)) |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
174 else: |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
175 stream.append((kind, data, pos)) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
176 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
177 # If there have have directive attributes with the corresponding |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
178 # start tag, move the events inbetween into a "subprogram" |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
179 if (depth, data) in dirmap: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
180 directives, start_offset, strip = dirmap.pop((depth, data)) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
181 substream = stream[start_offset:] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
182 if strip: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
183 substream = substream[1:-1] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
184 stream[start_offset:] = [(SUB, (directives, substream), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
185 pos)] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
186 |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
187 elif kind is PI and data[0] == 'python': |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
188 try: |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
189 # As Expat doesn't report whitespace between the PI target |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
190 # and the data, we have to jump through some hoops here to |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
191 # get correctly indented Python code |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
192 # Unfortunately, we'll still probably not get the line |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
193 # number quite right |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
194 lines = [line.expandtabs() for line in data[1].splitlines()] |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
195 first = lines[0] |
520
203bd6a3c93d
Applied patch by Dale Sedivec to fix #127. Many thanks!
cmlenz
parents:
496
diff
changeset
|
196 rest = dedent('\n'.join(lines[1:])).rstrip() |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
197 if first.rstrip().endswith(':') and not rest[0].isspace(): |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
198 rest = '\n'.join([' ' + line for line |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
199 in rest.splitlines()]) |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
200 source = '\n'.join([first, rest]) |
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:
434
diff
changeset
|
201 suite = Suite(source, self.filepath, pos[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:
434
diff
changeset
|
202 lookup=self.lookup) |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
203 except SyntaxError, err: |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
204 raise TemplateSyntaxError(err, self.filepath, |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
205 pos[1] + (err.lineno or 1) - 1, |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
206 pos[2] + (err.offset or 0)) |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
207 stream.append((EXEC, suite, pos)) |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
208 |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
209 elif kind is TEXT: |
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:
434
diff
changeset
|
210 for kind, data, pos in interpolate(data, self.basedir, pos[0], |
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:
434
diff
changeset
|
211 pos[1], pos[2], |
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:
434
diff
changeset
|
212 lookup=self.lookup): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
213 stream.append((kind, data, pos)) |
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 elif kind is COMMENT: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
216 if not data.lstrip().startswith('!'): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
217 stream.append((kind, data, pos)) |
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 else: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
220 stream.append((kind, data, pos)) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
221 |
381
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
222 assert len(streams) == 1 |
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
223 return streams[0] |
b9fc7a1f76ca
Fix for #80: fallback only shown when the template to include wasn't found. In addition, the nesting of includes and fallback content should work correctly, and directives/expressions/etc inside fallback content are processed. Thanks to Christian Boos for the original patch and unit tests.
cmlenz
parents:
374
diff
changeset
|
224 |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
225 def _exec(self, stream, ctxt): |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
226 """Internal stream filter that executes code in ``<?python ?>`` |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
422
diff
changeset
|
227 processing instructions. |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
228 """ |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
229 for event in stream: |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
230 if event[0] is EXEC: |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
231 event[1].execute(_ctxt2dict(ctxt)) |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
232 else: |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
233 yield event |
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
234 |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
235 def _match(self, stream, ctxt, match_templates=None): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
236 """Internal stream filter that applies any defined match templates |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
237 to the stream. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
238 """ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
239 if match_templates is None: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
240 match_templates = ctxt._match_templates |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
241 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
242 tail = [] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
243 def _strip(stream): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
244 depth = 1 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
245 while 1: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
246 event = stream.next() |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
247 if event[0] is START: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
248 depth += 1 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
249 elif event[0] is END: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
250 depth -= 1 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
251 if depth > 0: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
252 yield event |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
253 else: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
254 tail[:] = [event] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
255 break |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
256 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
257 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
|
258 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
259 # We (currently) only care about start and end events for matching |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
260 # We might care about namespace events in the future, though |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
261 if not match_templates or (event[0] is not START and |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
262 event[0] is not END): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
263 yield event |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
264 continue |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
265 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
266 for idx, (test, path, template, namespaces, directives) in \ |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
267 enumerate(match_templates): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
268 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
269 if test(event, namespaces, ctxt) is True: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
270 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
271 # Let the remaining match templates know about the event so |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
272 # they get a chance to update their internal state |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
273 for test in [mt[0] for mt in match_templates[idx + 1:]]: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
274 test(event, namespaces, ctxt, updateonly=True) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
275 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
276 # Consume and store all events until an end event |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
277 # corresponding to this start event is encountered |
364
7dabedbb53fb
Fix for #77: match templates were matching their own output.
cmlenz
parents:
363
diff
changeset
|
278 content = chain([event], |
7dabedbb53fb
Fix for #77: match templates were matching their own output.
cmlenz
parents:
363
diff
changeset
|
279 self._match(_strip(stream), ctxt, |
7dabedbb53fb
Fix for #77: match templates were matching their own output.
cmlenz
parents:
363
diff
changeset
|
280 [match_templates[idx]]), |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
281 tail) |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
282 content = list(self._include(content, ctxt)) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
283 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
284 for test in [mt[0] for mt in match_templates]: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
285 test(tail[0], namespaces, ctxt, updateonly=True) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
286 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
287 # Make the select() function available in the body of the |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
288 # match template |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
289 def select(path): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
290 return Stream(content).select(path, namespaces, ctxt) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
291 ctxt.push(dict(select=select)) |
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 # Recursively process the output |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
294 template = _apply_directives(template, ctxt, directives) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
295 for event in self._match(self._eval(self._flatten(template, |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
296 ctxt), |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
297 ctxt), ctxt, |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
298 match_templates[:idx] + |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
299 match_templates[idx + 1:]): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
300 yield event |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
301 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
302 ctxt.pop() |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
303 break |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
304 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
305 else: # no matches |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
306 yield event |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
307 |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
362
diff
changeset
|
308 |
405
5340931530e2
Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents:
400
diff
changeset
|
309 EXEC = MarkupTemplate.EXEC |