annotate genshi/template/text.py @ 1030:c5c5cbadde37 stable-0.7.x

Merge r1255 from trunk (fix slash escaping of CRLF newlines).
author hodgestar
date Wed, 19 Mar 2014 13:41:53 +0000
parents 59463031d904
children
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: 790
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
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
14 """Plain text templating engine.
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
15
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
16 This module implements two template language syntaxes, at least for a certain
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
17 transitional period. `OldTextTemplate` (aliased to just `TextTemplate`) defines
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
18 a syntax that was inspired by Cheetah/Velocity. `NewTextTemplate` on the other
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
19 hand is inspired by the syntax of the Django template language, which has more
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
20 explicit delimiting of directives, and is more flexible with regards to
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
21 white space and line breaks.
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
22
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
23 In a future release, `OldTextTemplate` will be phased out in favor of
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
24 `NewTextTemplate`, as the names imply. Therefore the new syntax is strongly
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
25 recommended for new projects, and existing projects may want to migrate to the
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
26 new syntax to remain compatible with future Genshi releases.
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
27 """
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 import re
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
30
693
35e143388705 Enable use of expressions in include directives of text templates. Closes #194. Thanks to Oliver Cope for reporting the issue.
cmlenz
parents: 629
diff changeset
31 from genshi.core import TEXT
610
5e358de79e4c * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
32 from genshi.template.base import BadDirectiveError, Template, \
5e358de79e4c * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
33 TemplateSyntaxError, EXEC, INCLUDE, SUB
609
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
34 from genshi.template.eval import Suite
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
35 from genshi.template.directives import *
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 693
diff changeset
36 from genshi.template.directives import Directive
407
f37d8e6acdf2 Move string interpolation code into separate module (`genshi.template.interpolation`).
cmlenz
parents: 400
diff changeset
37 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
38
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
39 __all__ = ['NewTextTemplate', 'OldTextTemplate', 'TextTemplate']
425
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
40 __docformat__ = 'restructuredtext en'
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
41
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
42
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
43 class NewTextTemplate(Template):
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
44 r"""Implementation of a simple text-based template engine. This class will
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
45 replace `OldTextTemplate` in a future release.
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
46
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
47 It uses a more explicit delimiting style for directives: instead of the old
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
48 style which required putting directives on separate lines that were prefixed
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
49 with a ``#`` sign, directives and commenbtsr are enclosed in delimiter pairs
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
50 (by default ``{% ... %}`` and ``{# ... #}``, respectively).
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
51
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
52 Variable substitution uses the same interpolation syntax as for markup
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
53 languages: simple references are prefixed with a dollar sign, more complex
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
54 expression enclosed in curly braces.
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
55
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
56 >>> tmpl = NewTextTemplate('''Dear $name,
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
57 ...
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
58 ... {# This is a comment #}
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
59 ... We have the following items for you:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
60 ... {% for item in items %}
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
61 ... * ${'Item %d' % item}
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
62 ... {% end %}
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
63 ... ''')
865
1adf86694e01 Also skip the encoding step in the template tests.
cmlenz
parents: 858
diff changeset
64 >>> print(tmpl.generate(name='Joe', items=[1, 2, 3]).render(encoding=None))
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
65 Dear Joe,
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
66 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
67 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
68 We have the following items for you:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
69 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
70 * Item 1
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
71 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
72 * Item 2
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
73 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
74 * Item 3
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
75 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
76 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
77
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
78 By default, no spaces or line breaks are removed. If a line break should
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
79 not be included in the output, prefix it with a backslash:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
80
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
81 >>> tmpl = NewTextTemplate('''Dear $name,
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
82 ...
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
83 ... {# This is a comment #}\
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
84 ... We have the following items for you:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
85 ... {% for item in items %}\
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
86 ... * $item
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
87 ... {% end %}\
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
88 ... ''')
865
1adf86694e01 Also skip the encoding step in the template tests.
cmlenz
parents: 858
diff changeset
89 >>> print(tmpl.generate(name='Joe', items=[1, 2, 3]).render(encoding=None))
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
90 Dear Joe,
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
91 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
92 We have the following items for you:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
93 * 1
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
94 * 2
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
95 * 3
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
96 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
97
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
98 Backslashes are also used to escape the start delimiter of directives and
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
99 comments:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
100
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
101 >>> tmpl = NewTextTemplate('''Dear $name,
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
102 ...
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
103 ... \{# This is a comment #}
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
104 ... We have the following items for you:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
105 ... {% for item in items %}\
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
106 ... * $item
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
107 ... {% end %}\
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
108 ... ''')
865
1adf86694e01 Also skip the encoding step in the template tests.
cmlenz
parents: 858
diff changeset
109 >>> print(tmpl.generate(name='Joe', items=[1, 2, 3]).render(encoding=None))
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
110 Dear Joe,
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
111 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
112 {# This is a comment #}
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
113 We have the following items for you:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
114 * 1
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
115 * 2
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
116 * 3
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
117 <BLANKLINE>
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
118
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
119 :since: version 0.5
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
120 """
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
121 directives = [('def', DefDirective),
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
122 ('when', WhenDirective),
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
123 ('otherwise', OtherwiseDirective),
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
124 ('for', ForDirective),
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
125 ('if', IfDirective),
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
126 ('choose', ChooseDirective),
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
127 ('with', WithDirective)]
605
d0345c64da65 Text templates now default to rendering as plain text; it is no longer necessary to explicitly specify the "text" method to the `render()` or `serialize()` method of the generated markup stream. See tickets #62 and #118.
cmlenz
parents: 592
diff changeset
128 serializer = 'text'
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
129
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
130 _DIRECTIVE_RE = r'((?<!\\)%s\s*(\w+)\s*(.*?)\s*%s|(?<!\\)%s.*?%s)'
1030
c5c5cbadde37 Merge r1255 from trunk (fix slash escaping of CRLF newlines).
hodgestar
parents: 935
diff changeset
131 _ESCAPE_RE = r'\\\n|\\\r\n|\\(\\)|\\(%s)|\\(%s)'
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
132
714
fc6d9d2a3527 The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
133 def __init__(self, source, filepath=None, filename=None, loader=None,
606
37ff75bb4301 Changed the default error handling mode to "strict".
cmlenz
parents: 605
diff changeset
134 encoding=None, lookup='strict', allow_exec=False,
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
135 delims=('{%', '%}', '{#', '#}')):
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
136 self.delimiters = delims
714
fc6d9d2a3527 The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
137 Template.__init__(self, source, filepath=filepath, filename=filename,
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
138 loader=loader, encoding=encoding, lookup=lookup)
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
139
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
140 def _get_delims(self):
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
141 return self._delims
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
142 def _set_delims(self, delims):
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
143 if len(delims) != 4:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
144 raise ValueError('delimiers tuple must have exactly four elements')
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
145 self._delims = delims
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
146 self._directive_re = re.compile(self._DIRECTIVE_RE % tuple(
854
4d9bef447df9 More work on reducing the size of the diff produced by 2to3.
cmlenz
parents: 853
diff changeset
147 [re.escape(d) for d in delims]
609
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
148 ), re.DOTALL)
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
149 self._escape_re = re.compile(self._ESCAPE_RE % tuple(
854
4d9bef447df9 More work on reducing the size of the diff produced by 2to3.
cmlenz
parents: 853
diff changeset
150 [re.escape(d) for d in delims[::2]]
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
151 ))
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
152 delimiters = property(_get_delims, _set_delims, """\
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
153 The delimiters for directives and comments. This should be a four item tuple
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
154 of the form ``(directive_start, directive_end, comment_start,
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
155 comment_end)``, where each item is a string.
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
156 """)
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
157
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
158 def _parse(self, source, encoding):
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
159 """Parse the template from text input."""
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
160 stream = [] # list of events of the "compiled" template
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
161 dirmap = {} # temporary mapping of directives to elements
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
162 depth = 0
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
163
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
164 source = source.read()
935
59463031d904 Merge r1143 from py3k:
hodgestar
parents: 865
diff changeset
165 if not isinstance(source, unicode):
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
166 source = source.decode(encoding or 'utf-8', 'replace')
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
167 offset = 0
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
168 lineno = 1
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
169
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
170 _escape_sub = self._escape_re.sub
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
171 def _escape_repl(mo):
858
7811327c536a Yet more 2to3 diff size reduction.
cmlenz
parents: 854
diff changeset
172 groups = [g for g in mo.groups() if g]
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
173 if not groups:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
174 return ''
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
175 return groups[0]
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
176
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
177 for idx, mo in enumerate(self._directive_re.finditer(source)):
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
178 start, end = mo.span(1)
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
179 if start > offset:
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
180 text = _escape_sub(_escape_repl, source[offset:start])
714
fc6d9d2a3527 The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
181 for kind, data, pos in interpolate(text, self.filepath, lineno,
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
182 lookup=self.lookup):
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
183 stream.append((kind, data, pos))
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
184 lineno += len(text.splitlines())
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
185
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
186 lineno += len(source[start:end].splitlines())
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
187 command, value = mo.group(2, 3)
609
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
188
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
189 if command == 'include':
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
190 pos = (self.filename, lineno, 0)
714
fc6d9d2a3527 The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
191 value = list(interpolate(value, self.filepath, lineno, 0,
fc6d9d2a3527 The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
192 lookup=self.lookup))
693
35e143388705 Enable use of expressions in include directives of text templates. Closes #194. Thanks to Oliver Cope for reporting the issue.
cmlenz
parents: 629
diff changeset
193 if len(value) == 1 and value[0][0] is TEXT:
35e143388705 Enable use of expressions in include directives of text templates. Closes #194. Thanks to Oliver Cope for reporting the issue.
cmlenz
parents: 629
diff changeset
194 value = value[0][1]
35e143388705 Enable use of expressions in include directives of text templates. Closes #194. Thanks to Oliver Cope for reporting the issue.
cmlenz
parents: 629
diff changeset
195 stream.append((INCLUDE, (value, None, []), pos))
609
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
196
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
197 elif command == 'python':
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
198 if not self.allow_exec:
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
199 raise TemplateSyntaxError('Python code blocks not allowed',
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
200 self.filepath, lineno)
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
201 try:
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
202 suite = Suite(value, self.filepath, lineno,
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
203 lookup=self.lookup)
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
204 except SyntaxError, err:
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
205 raise TemplateSyntaxError(err, self.filepath,
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
206 lineno + (err.lineno or 1) - 1)
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
207 pos = (self.filename, lineno, 0)
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
208 stream.append((EXEC, suite, pos))
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
209
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
210 elif command == 'end':
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
211 depth -= 1
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
212 if depth in dirmap:
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
213 directive, start_offset = dirmap.pop(depth)
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
214 substream = stream[start_offset:]
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
215 stream[start_offset:] = [(SUB, ([directive], substream),
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
216 (self.filepath, lineno, 0))]
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
217
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
218 elif command:
790
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 719
diff changeset
219 cls = self.get_directive(command)
609
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
220 if cls is None:
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
221 raise BadDirectiveError(command)
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: 790
diff changeset
222 directive = 0, cls, value, None, (self.filepath, lineno, 0)
609
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
223 dirmap[depth] = (directive, len(stream))
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
224 depth += 1
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
225
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
226 offset = end
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
227
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
228 if offset < len(source):
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
229 text = _escape_sub(_escape_repl, source[offset:])
714
fc6d9d2a3527 The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
230 for kind, data, pos in interpolate(text, self.filepath, lineno,
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
231 lookup=self.lookup):
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
232 stream.append((kind, data, pos))
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
233
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
234 return stream
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
235
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
236
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
237 class OldTextTemplate(Template):
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
238 """Legacy implementation of the old syntax text-based templates. This class
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
239 is provided in a transition phase for backwards compatibility. New code
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
240 should use the `NewTextTemplate` class and the improved syntax it provides.
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
241
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
242 >>> tmpl = OldTextTemplate('''Dear $name,
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 ... We have the following items for you:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
245 ... #for item in items
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
246 ... * $item
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
247 ... #end
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
248 ...
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
249 ... All the best,
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
250 ... Foobar''')
865
1adf86694e01 Also skip the encoding step in the template tests.
cmlenz
parents: 858
diff changeset
251 >>> print(tmpl.generate(name='Joe', items=[1, 2, 3]).render(encoding=None))
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
252 Dear Joe,
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
253 <BLANKLINE>
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
254 We have the following items for you:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
255 * 1
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
256 * 2
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
257 * 3
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
258 <BLANKLINE>
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
259 All the best,
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
260 Foobar
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
261 """
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
262 directives = [('def', DefDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
263 ('when', WhenDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
264 ('otherwise', OtherwiseDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
265 ('for', ForDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
266 ('if', IfDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
267 ('choose', ChooseDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
268 ('with', WithDirective)]
605
d0345c64da65 Text templates now default to rendering as plain text; it is no longer necessary to explicitly specify the "text" method to the `render()` or `serialize()` method of the generated markup stream. See tickets #62 and #118.
cmlenz
parents: 592
diff changeset
269 serializer = 'text'
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
270
365
4f431931d64e Fix for #62: preserve whitespace in front of directives.
cmlenz
parents: 362
diff changeset
271 _DIRECTIVE_RE = re.compile(r'(?:^[ \t]*(?<!\\)#(end).*\n?)|'
4f431931d64e Fix for #62: preserve whitespace in front of directives.
cmlenz
parents: 362
diff changeset
272 r'(?:^[ \t]*(?<!\\)#((?:\w+|#).*)\n?)',
4f431931d64e Fix for #62: preserve whitespace in front of directives.
cmlenz
parents: 362
diff changeset
273 re.MULTILINE)
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
274
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: 365
diff changeset
275 def _parse(self, source, encoding):
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
276 """Parse the template from text input."""
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
277 stream = [] # list of events of the "compiled" template
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
278 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
279 depth = 0
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
280
512
ed9f1300f3bf Fix for #125 (text template handling unicode source). Thanks to Christian Boos for the patch.
cmlenz
parents: 475
diff changeset
281 source = source.read()
935
59463031d904 Merge r1143 from py3k:
hodgestar
parents: 865
diff changeset
282 if not isinstance(source, unicode):
512
ed9f1300f3bf Fix for #125 (text template handling unicode source). Thanks to Christian Boos for the patch.
cmlenz
parents: 475
diff changeset
283 source = source.decode(encoding or 'utf-8', 'replace')
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
284 offset = 0
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
285 lineno = 1
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 for idx, mo in enumerate(self._DIRECTIVE_RE.finditer(source)):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
288 start, end = mo.span()
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
289 if start > offset:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
290 text = source[offset:start]
714
fc6d9d2a3527 The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
291 for kind, data, pos in interpolate(text, self.filepath, lineno,
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: 425
diff changeset
292 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
293 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
294 lineno += len(text.splitlines())
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
295
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
296 text = source[start:end].lstrip()[1:]
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
297 lineno += len(text.splitlines())
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
298 directive = text.split(None, 1)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
299 if len(directive) > 1:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
300 command, value = directive
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
301 else:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
302 command, value = directive[0], None
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
303
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
304 if command == 'end':
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
305 depth -= 1
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
306 if depth in dirmap:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
307 directive, start_offset = dirmap.pop(depth)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
308 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
309 stream[start_offset:] = [(SUB, ([directive], substream),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
310 (self.filepath, lineno, 0))]
475
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
311 elif command == 'include':
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
312 pos = (self.filename, lineno, 0)
610
5e358de79e4c * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
313 stream.append((INCLUDE, (value.strip(), None, []), pos))
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
314 elif command != '#':
790
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 719
diff changeset
315 cls = self.get_directive(command)
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
316 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
317 raise BadDirectiveError(command)
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: 790
diff changeset
318 directive = 0, cls, value, None, (self.filepath, lineno, 0)
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
319 dirmap[depth] = (directive, len(stream))
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
320 depth += 1
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 offset = end
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
323
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
324 if offset < len(source):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
325 text = source[offset:].replace('\\#', '#')
714
fc6d9d2a3527 The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
326 for kind, data, pos in interpolate(text, self.filepath, lineno,
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: 425
diff changeset
327 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
328 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
329
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
330 return stream
592
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
331
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
332
1da8de3e5e51 Add a new syntax for text templates, which is available alongside the old syntax for now. The new syntax is more poweful and flexible, using Django-style directive notation.
cmlenz
parents: 512
diff changeset
333 TextTemplate = OldTextTemplate
Copyright (C) 2012-2017 Edgewall Software