1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
1 ##############################################################################
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
2 #
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
4 #
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
5 # This software is subject to the provisions of the Zope Public License,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
6 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
10 # FOR A PARTICULAR PURPOSE
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
11 #
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
12 ##############################################################################
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
13 """TALES
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
14
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
15 An implementation of a generic TALES engine
|
|
1071
|
16
|
|
|
17 Modified for Roundup 0.5 release:
|
|
|
18
|
|
|
19 - changed imports to import from roundup.cgi
|
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
20 """
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
21
|
1409
8dc60d87ab42
Fixed a backlog of bug reports, and worked on python 2.3 compatibility:
Richard Jones <richard@users.sourceforge.net>
diff
changeset
|
22 __version__='$Revision: 1.5 $'[11:-2]
|
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
23
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
24 import re, sys
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
25 from roundup.cgi import ZTUtils
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
26 from MultiMapping import MultiMapping
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
27
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
28 StringType = type('')
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
29
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
30 NAME_RE = r"[a-zA-Z][a-zA-Z0-9_]*"
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
31 _parse_expr = re.compile(r"(%s):" % NAME_RE).match
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
32 _valid_name = re.compile('%s$' % NAME_RE).match
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
33
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
34 class TALESError(Exception):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
35 """Error during TALES expression evaluation"""
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
36
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
37 class Undefined(TALESError):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
38 '''Exception raised on traversal of an undefined path'''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
39
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
40 class RegistrationError(Exception):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
41 '''TALES Type Registration Error'''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
42
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
43 class CompilerError(Exception):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
44 '''TALES Compiler Error'''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
45
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
46 class Default:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
47 '''Retain Default'''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
48 Default = Default()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
49
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
50 _marker = []
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
51
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
52 class SafeMapping(MultiMapping):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
53 '''Mapping with security declarations and limited method exposure.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
54
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
55 Since it subclasses MultiMapping, this class can be used to wrap
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
56 one or more mapping objects. Restricted Python code will not be
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
57 able to mutate the SafeMapping or the wrapped mappings, but will be
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
58 able to read any value.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
59 '''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
60 __allow_access_to_unprotected_subobjects__ = 1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
61 push = pop = None
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
62
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
63 _push = MultiMapping.push
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
64 _pop = MultiMapping.pop
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
65
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
66 def has_get(self, key, _marker=[]):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
67 v = self.get(key, _marker)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
68 return v is not _marker, v
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
69
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
70 class Iterator(ZTUtils.Iterator):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
71 def __init__(self, name, seq, context):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
72 ZTUtils.Iterator.__init__(self, seq)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
73 self.name = name
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
74 self._context = context
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
75
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
76 def next(self):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
77 if ZTUtils.Iterator.next(self):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
78 self._context.setLocal(self.name, self.item)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
79 return 1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
80 return 0
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
81
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
82
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
83 class ErrorInfo:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
84 """Information about an exception passed to an on-error handler."""
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
85 __allow_access_to_unprotected_subobjects__ = 1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
86
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
87 def __init__(self, err, position=(None, None)):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
88 if isinstance(err, Exception):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
89 self.type = err.__class__
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
90 self.value = err
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
91 else:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
92 self.type = err
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
93 self.value = None
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
94 self.lineno = position[0]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
95 self.offset = position[1]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
96
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
97
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
98 class Engine:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
99 '''Expression Engine
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
100
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
101 An instance of this class keeps a mutable collection of expression
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
102 type handlers. It can compile expression strings by delegating to
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
103 these handlers. It can provide an expression Context, which is
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
104 capable of holding state and evaluating compiled expressions.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
105 '''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
106 Iterator = Iterator
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
107
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
108 def __init__(self, Iterator=None):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
109 self.types = {}
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
110 if Iterator is not None:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
111 self.Iterator = Iterator
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
112
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
113 def registerType(self, name, handler):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
114 if not _valid_name(name):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
115 raise RegistrationError, 'Invalid Expression type "%s".' % name
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
116 types = self.types
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
117 if types.has_key(name):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
118 raise RegistrationError, (
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
119 'Multiple registrations for Expression type "%s".' %
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
120 name)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
121 types[name] = handler
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
122
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
123 def getTypes(self):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
124 return self.types
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
125
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
126 def compile(self, expression):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
127 m = _parse_expr(expression)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
128 if m:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
129 type = m.group(1)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
130 expr = expression[m.end():]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
131 else:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
132 type = "standard"
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
133 expr = expression
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
134 try:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
135 handler = self.types[type]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
136 except KeyError:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
137 raise CompilerError, (
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
138 'Unrecognized expression type "%s".' % type)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
139 return handler(type, expr, self)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
140
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
141 def getContext(self, contexts=None, **kwcontexts):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
142 if contexts is not None:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
143 if kwcontexts:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
144 kwcontexts.update(contexts)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
145 else:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
146 kwcontexts = contexts
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
147 return Context(self, kwcontexts)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
148
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
149 def getCompilerError(self):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
150 return CompilerError
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
151
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
152 class Context:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
153 '''Expression Context
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
154
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
155 An instance of this class holds context information that it can
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
156 use to evaluate compiled expressions.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
157 '''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
158
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
159 _context_class = SafeMapping
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
160 position = (None, None)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
161 source_file = None
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
162
|
|
1257
|
163 def __init__(self, compiler, contexts):
|
|
|
164 self._compiler = compiler
|
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
165 self.contexts = contexts
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
166 contexts['nothing'] = None
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
167 contexts['default'] = Default
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
168
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
169 self.repeat_vars = rv = {}
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
170 # Wrap this, as it is visible to restricted code
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
171 contexts['repeat'] = rep = self._context_class(rv)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
172 contexts['loop'] = rep # alias
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
173
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
174 self.global_vars = gv = contexts.copy()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
175 self.local_vars = lv = {}
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
176 self.vars = self._context_class(gv, lv)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
177
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
178 # Keep track of what needs to be popped as each scope ends.
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
179 self._scope_stack = []
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
180
|
|
1257
|
181 def getCompiler(self):
|
|
|
182 return self._compiler
|
|
|
183
|
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
184 def beginScope(self):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
185 self._scope_stack.append([self.local_vars.copy()])
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
186
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
187 def endScope(self):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
188 scope = self._scope_stack.pop()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
189 self.local_vars = lv = scope[0]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
190 v = self.vars
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
191 v._pop()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
192 v._push(lv)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
193 # Pop repeat variables, if any
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
194 i = len(scope) - 1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
195 while i:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
196 name, value = scope[i]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
197 if value is None:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
198 del self.repeat_vars[name]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
199 else:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
200 self.repeat_vars[name] = value
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
201 i = i - 1
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
202
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
203 def setLocal(self, name, value):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
204 self.local_vars[name] = value
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
205
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
206 def setGlobal(self, name, value):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
207 self.global_vars[name] = value
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
208
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
209 def setRepeat(self, name, expr):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
210 expr = self.evaluate(expr)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
211 if not expr:
|
|
1257
|
212 return self._compiler.Iterator(name, (), self)
|
|
|
213 it = self._compiler.Iterator(name, expr, self)
|
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
214 old_value = self.repeat_vars.get(name)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
215 self._scope_stack[-1].append((name, old_value))
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
216 self.repeat_vars[name] = it
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
217 return it
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
218
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
219 def evaluate(self, expression,
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
220 isinstance=isinstance, StringType=StringType):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
221 if isinstance(expression, StringType):
|
|
1257
|
222 expression = self._compiler.compile(expression)
|
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
223 __traceback_supplement__ = (
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
224 TALESTracebackSupplement, self, expression)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
225 v = expression(self)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
226 return v
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
227
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
228 evaluateValue = evaluate
|
|
1219
|
229 evaluateBoolean = evaluate
|
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
230
|
1409
8dc60d87ab42
Fixed a backlog of bug reports, and worked on python 2.3 compatibility:
Richard Jones <richard@users.sourceforge.net>
diff
changeset
|
231 def evaluateText(self, expr):
|
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
232 text = self.evaluate(expr)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
233 if text is Default or text is None:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
234 return text
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
235 return str(text)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
236
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
237 def evaluateStructure(self, expr):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
238 return self.evaluate(expr)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
239 evaluateStructure = evaluate
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
240
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
241 def evaluateMacro(self, expr):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
242 # XXX Should return None or a macro definition
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
243 return self.evaluate(expr)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
244 evaluateMacro = evaluate
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
245
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
246 def createErrorInfo(self, err, position):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
247 return ErrorInfo(err, position)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
248
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
249 def getDefault(self):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
250 return Default
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
251
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
252 def setSourceFile(self, source_file):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
253 self.source_file = source_file
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
254
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
255 def setPosition(self, position):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
256 self.position = position
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
257
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
258
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
259
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
260 class TALESTracebackSupplement:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
261 """Implementation of ITracebackSupplement"""
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
262 def __init__(self, context, expression):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
263 self.context = context
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
264 self.source_url = context.source_file
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
265 self.line = context.position[0]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
266 self.column = context.position[1]
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
267 self.expression = repr(expression)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
268
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
269 def getInfo(self, as_html=0):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
270 import pprint
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
271 data = self.context.contexts.copy()
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
272 s = pprint.pformat(data)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
273 if not as_html:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
274 return ' - Names:\n %s' % string.replace(s, '\n', '\n ')
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
275 else:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
276 from cgi import escape
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
277 return '<b>Names:</b><pre>%s</pre>' % (escape(s))
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
278 return None
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
279
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
280
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
281
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
282 class SimpleExpr:
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
283 '''Simple example of an expression type handler'''
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
284 def __init__(self, name, expr, engine):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
285 self._name = name
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
286 self._expr = expr
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
287 def __call__(self, econtext):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
288 return self._name, self._expr
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
289 def __repr__(self):
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
290 return '<SimpleExpr %s %s>' % (self._name, `self._expr`)
|
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
291
|