annotate roundup/cgi/TAL/TALInterpreter.py @ 5543:bc3e00a3d24b

MySQL backend fixes for Python 3. With Python 2, text sent to and from MySQL is treated as bytes in Python. The database may be recorded by MySQL as having some other encoding (latin1 being the default in some MySQL versions - Roundup does not set an encoding explicitly, unlike in back_postgresql), but as long as MySQL's notion of the connection encoding agrees with its notion of the database encoding, no conversions actually take place and the bytes are stored and returned as-is. With Python 3, text sent to and from MySQL is treated as Python Unicode strings. When the database and connection encoding is latin1, that means the bytes stored in the database under Python 2 are interpreted as latin1 and converted from that to Unicode, producing incorrect results for any non-ASCII characters; furthermore, if trying to store new non-ASCII data in the database under Python 3, any non-latin1 characters produce errors. This patch arranges for both the connection and database character sets to be UTF-8 when using Python 3, and documents a need to export and import the database when moving from Python 2 to Python 3 with this backend.
author Joseph Myers <jsm@polyomino.org.uk>
date Sun, 16 Sep 2018 16:19:20 +0000
parents c8902d398434
children d79ba7365abb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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, 2002 Zope Corporation and Contributors.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
4 # All Rights Reserved.
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
5 #
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6 # This software is subject to the provisions of the Zope Public License,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
11 # FOR A PARTICULAR PURPOSE.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
12 #
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
13 ##############################################################################
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
14 # Modifications for Roundup:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
15 # 1. implemented ustr as str
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
16 """
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
17 Interpreter for a pre-compiled TAL program.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
18 """
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20 import sys
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
21 import getopt
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
22 import re
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
23 from cgi import escape
5418
55f09ca366c4 Python 3 preparation: StringIO.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5400
diff changeset
24 from roundup.anypy.strings import StringIO
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
25 #from DocumentTemplate.DT_Util import ustr
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
26 ustr = str
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27
5388
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5381
diff changeset
28 from .TALDefs import TAL_VERSION, TALError, METALError, attrEscape
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5381
diff changeset
29 from .TALDefs import isCurrentVersion, getProgramVersion, getProgramMode
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5381
diff changeset
30 from .TALGenerator import TALGenerator
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5381
diff changeset
31 from .TranslationContext import TranslationContext
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
33 BOOLEAN_HTML_ATTRS = [
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34 # List of Boolean attributes in HTML that should be rendered in
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35 # minimized form (e.g. <img ismap> rather than <img ismap="">)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36 # From http://www.w3.org/TR/xhtml1/#guidelines (C.10)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37 # XXX The problem with this is that this is not valid XML and
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 # can't be parsed back!
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 "compact", "nowrap", "ismap", "declare", "noshade", "checked",
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40 "disabled", "readonly", "multiple", "selected", "noresize",
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41 "defer"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 ]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
44 def normalize(text):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
45 # Now we need to normalize the whitespace in implicit message ids and
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
46 # implicit $name substitution values by stripping leading and trailing
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
47 # whitespace, and folding all internal whitespace to a single space.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
48 return ' '.join(text.split())
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
49
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
50
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
51 NAME_RE = r"[a-zA-Z][a-zA-Z0-9_]*"
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
52 _interp_regex = re.compile(r'(?<!\$)(\$(?:%(n)s|{%(n)s}))' %({'n': NAME_RE}))
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
53 _get_var_regex = re.compile(r'%(n)s' %({'n': NAME_RE}))
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
54
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
55 def interpolate(text, mapping):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
56 """Interpolate ${keyword} substitutions.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
57
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
58 This is called when no translation is provided by the translation
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
59 service.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
60 """
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
61 if not mapping:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
62 return text
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
63 # Find all the spots we want to substitute.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
64 to_replace = _interp_regex.findall(text)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
65 # Now substitute with the variables in mapping.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
66 for string in to_replace:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
67 var = _get_var_regex.findall(string)[0]
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
68 if var in mapping:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
69 # Call ustr because we may have an integer for instance.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
70 subst = ustr(mapping[var])
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
71 try:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
72 text = text.replace(string, subst)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
73 except UnicodeError:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
74 # subst contains high-bit chars...
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
75 # As we have no way of knowing the correct encoding,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
76 # substitue something instead of raising an exception.
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 2348
diff changeset
77 subst = repr(subst)[1:-1]
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
78 text = text.replace(string, subst)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
79 return text
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
80
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 class AltTALGenerator(TALGenerator):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84 def __init__(self, repldict, expressionCompiler=None, xml=0):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85 self.repldict = repldict
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 self.enabled = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87 TALGenerator.__init__(self, expressionCompiler, xml)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 def enable(self, enabled):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 self.enabled = enabled
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 def emit(self, *args):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 if self.enabled:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
94 TALGenerator.emit(self, *args)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
96 def emitStartElement(self, name, attrlist, taldict, metaldict, i18ndict,
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 position=(None, None), isend=0):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 metaldict = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 taldict = {}
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
100 i18ndict = {}
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 if self.enabled and self.repldict:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 taldict["attributes"] = "x x"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 TALGenerator.emitStartElement(self, name, attrlist,
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
104 taldict, metaldict, i18ndict,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
105 position, isend)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107 def replaceAttrs(self, attrlist, repldict):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 if self.enabled and self.repldict:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109 repldict = self.repldict
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
110 self.repldict = None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111 return TALGenerator.replaceAttrs(self, attrlist, repldict)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
114 class TALInterpreter:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 def __init__(self, program, macros, engine, stream=None,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117 debug=0, wrap=60, metal=1, tal=1, showtal=-1,
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
118 strictinsert=1, stackLimit=100, i18nInterpolate=1):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 self.program = program
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 self.macros = macros
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
121 self.engine = engine # Execution engine (aka context)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122 self.Default = engine.getDefault()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 self.stream = stream or sys.stdout
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124 self._stream_write = self.stream.write
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125 self.debug = debug
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 self.wrap = wrap
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 self.metal = metal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 self.tal = tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 if tal:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
130 self.dispatch = self.bytecode_handlers_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
131 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
132 self.dispatch = self.bytecode_handlers
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
133 assert showtal in (-1, 0, 1)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
134 if showtal == -1:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
135 showtal = (not tal)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
136 self.showtal = showtal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
137 self.strictinsert = strictinsert
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
138 self.stackLimit = stackLimit
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
139 self.html = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
140 self.endsep = "/>"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
141 self.endlen = len(self.endsep)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
142 self.macroStack = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
143 self.position = None, None # (lineno, offset)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
144 self.col = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
145 self.level = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
146 self.scopeLevel = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
147 self.sourceFile = None
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
148 self.i18nStack = []
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
149 self.i18nInterpolate = i18nInterpolate
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
150 self.i18nContext = TranslationContext()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
151
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
152 def StringIO(self):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
153 # Third-party products wishing to provide a full Unicode-aware
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
154 # StringIO can do so by monkey-patching this method.
5478
c8902d398434 removed FasterStringIO
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5420
diff changeset
155 return StringIO()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
156
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157 def saveState(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
158 return (self.position, self.col, self.stream,
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
159 self.scopeLevel, self.level, self.i18nContext)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161 def restoreState(self, state):
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
162 (self.position, self.col, self.stream, scopeLevel, level, i18n) = state
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
163 self._stream_write = self.stream.write
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 assert self.level == level
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165 while self.scopeLevel > scopeLevel:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 self.engine.endScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167 self.scopeLevel = self.scopeLevel - 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
168 self.engine.setPosition(self.position)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
169 self.i18nContext = i18n
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
170
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
171 def restoreOutputState(self, state):
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
172 (dummy, self.col, self.stream, scopeLevel, level, i18n) = state
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 self._stream_write = self.stream.write
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174 assert self.level == level
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175 assert self.scopeLevel == scopeLevel
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 def pushMacro(self, macroName, slots, entering=1):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178 if len(self.macroStack) >= self.stackLimit:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179 raise METALError("macro nesting limit (%d) exceeded "
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 2348
diff changeset
180 "by %s" % (self.stackLimit, repr(macroName)))
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
181 self.macroStack.append([macroName, slots, entering, self.i18nContext])
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
182
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
183 def popMacro(self):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
184 return self.macroStack.pop()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
185
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 def __call__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
187 assert self.level == 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188 assert self.scopeLevel == 0
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
189 assert self.i18nContext.parent is None
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190 self.interpret(self.program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191 assert self.level == 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
192 assert self.scopeLevel == 0
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
193 assert self.i18nContext.parent is None
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194 if self.col > 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195 self._stream_write("\n")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
196 self.col = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
197
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
198 def stream_write(self, s,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
199 len=len):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
200 self._stream_write(s)
1309
309f125f86cc removed use of string/strop from TAL/TALInterpreter
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
201 i = s.rfind('\n')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
202 if i < 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
203 self.col = self.col + len(s)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
204 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
205 self.col = len(s) - (i + 1)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
206
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
207 bytecode_handlers = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
208
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
209 def interpretWithStream(self, program, stream):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
210 oldstream = self.stream
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
211 self.stream = stream
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
212 self._stream_write = stream.write
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
213 try:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
214 self.interpret(program)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
215 finally:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
216 self.stream = oldstream
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
217 self._stream_write = oldstream.write
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
218
1409
8dc60d87ab42 Fixed a backlog of bug reports, and worked on python 2.3 compatibility:
Richard Jones <richard@users.sourceforge.net>
parents: 1309
diff changeset
219 def interpret(self, program):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
220 oldlevel = self.level
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
221 self.level = oldlevel + 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
222 handlers = self.dispatch
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
223 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
224 if self.debug:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
225 for (opcode, args) in program:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
226 s = "%sdo_%s(%s)\n" % (" "*self.level, opcode,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
227 repr(args))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
228 if len(s) > 80:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
229 s = s[:76] + "...\n"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
230 sys.stderr.write(s)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
231 handlers[opcode](self, args)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
232 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
233 for (opcode, args) in program:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
234 handlers[opcode](self, args)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
235 finally:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
236 self.level = oldlevel
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
237
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
238 def do_version(self, version):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
239 assert version == TAL_VERSION
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
240 bytecode_handlers["version"] = do_version
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
241
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
242 def do_mode(self, mode):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
243 assert mode in ("html", "xml")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
244 self.html = (mode == "html")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
245 if self.html:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
246 self.endsep = " />"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
247 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
248 self.endsep = "/>"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
249 self.endlen = len(self.endsep)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
250 bytecode_handlers["mode"] = do_mode
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
251
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
252 def do_setSourceFile(self, source_file):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
253 self.sourceFile = source_file
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
254 self.engine.setSourceFile(source_file)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
255 bytecode_handlers["setSourceFile"] = do_setSourceFile
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
256
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
257 def do_setPosition(self, position):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
258 self.position = position
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
259 self.engine.setPosition(position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
260 bytecode_handlers["setPosition"] = do_setPosition
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
261
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
262 def do_startEndTag(self, stuff):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
263 self.do_startTag(stuff, self.endsep, self.endlen)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
264 bytecode_handlers["startEndTag"] = do_startEndTag
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
265
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
266 def do_startTag(self, name_attrList,
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
267 end=">", endlen=1, _len=len):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
268 # The bytecode generator does not cause calls to this method
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
269 # for start tags with no attributes; those are optimized down
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
270 # to rawtext events. Hence, there is no special "fast path"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
271 # for that case.
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
272 (name, attrList) = name_attrList
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
273 L = ["<", name]
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
274 append = L.append
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
275 col = self.col + _len(name) + 1
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
276 wrap = self.wrap
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
277 align = col + 1
5400
2120f77554d5 Python 3 preparation: use // and __truediv__ as needed.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5393
diff changeset
278 if align >= wrap//2:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
279 align = 4 # Avoid a narrow column far to the right
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280 attrAction = self.dispatch["<attrAction>"]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
281 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
282 for item in attrList:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
283 if _len(item) == 2:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
284 name, s = item
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
285 else:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
286 # item[2] is the 'action' field:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
287 if item[2] in ('metal', 'tal', 'xmlns', 'i18n'):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
288 if not self.showtal:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
289 continue
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
290 ok, name, s = self.attrAction(item)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
291 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
292 ok, name, s = attrAction(self, item)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
293 if not ok:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
294 continue
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
295 slen = _len(s)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
296 if (wrap and
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
297 col >= align and
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
298 col + 1 + slen > wrap):
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
299 append("\n")
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
300 append(" "*align)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
301 col = align + slen
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
302 else:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
303 append(" ")
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
304 col = col + 1 + slen
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
305 append(s)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
306 append(end)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
307 self._stream_write("".join(L))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
308 col = col + endlen
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
309 finally:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
310 self.col = col
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
311 bytecode_handlers["startTag"] = do_startTag
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
312
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
313 def attrAction(self, item):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
314 name, value, action = item[:3]
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
315 if action == 'insert':
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
316 return 0, name, value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
317 macs = self.macroStack
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
318 if action == 'metal' and self.metal and macs:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
319 if len(macs) > 1 or not macs[-1][2]:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
320 # Drop all METAL attributes at a use-depth above one.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
321 return 0, name, value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
322 # Clear 'entering' flag
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
323 macs[-1][2] = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
324 # Convert or drop depth-one METAL attributes.
1309
309f125f86cc removed use of string/strop from TAL/TALInterpreter
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
325 i = name.rfind(":") + 1
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
326 prefix, suffix = name[:i], name[i:]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
327 if suffix == "define-macro":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
328 # Convert define-macro as we enter depth one.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
329 name = prefix + "use-macro"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
330 value = macs[-1][0] # Macro name
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
331 elif suffix == "define-slot":
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
332 name = prefix + "fill-slot"
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
333 elif suffix == "fill-slot":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
334 pass
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
335 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
336 return 0, name, value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
337
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
338 if value is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
339 value = name
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
340 else:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
341 value = '%s="%s"' % (name, attrEscape(value))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
342 return 1, name, value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
343
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
344 def attrAction_tal(self, item):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
345 name, value, action = item[:3]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
346 ok = 1
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
347 expr, xlat, msgid = item[3:]
1309
309f125f86cc removed use of string/strop from TAL/TALInterpreter
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
348 if self.html and name.lower() in BOOLEAN_HTML_ATTRS:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
349 evalue = self.engine.evaluateBoolean(item[3])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
350 if evalue is self.Default:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
351 if action == 'insert': # Cancelled insert
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
352 ok = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
353 elif evalue:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
354 value = None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
355 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
356 ok = 0
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
357 elif expr is not None:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
358 evalue = self.engine.evaluateText(item[3])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
359 if evalue is self.Default:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
360 if action == 'insert': # Cancelled insert
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
361 ok = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
362 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
363 if evalue is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
364 ok = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
365 value = evalue
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
366 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
367 evalue = None
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
368
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
369 if ok:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
370 if xlat:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
371 translated = self.translate(msgid or value, value, {})
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
372 if translated is not None:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
373 value = translated
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
374 if value is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
375 value = name
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
376 elif evalue is self.Default:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
377 value = attrEscape(value)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
378 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
379 value = escape(value, quote=1)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
380 value = '%s="%s"' % (name, value)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
381 return ok, name, value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
382 bytecode_handlers["<attrAction>"] = attrAction
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
383
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
384 def no_tag(self, start, program):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
385 state = self.saveState()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
386 self.stream = stream = self.StringIO()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
387 self._stream_write = stream.write
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
388 self.interpret(start)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
389 self.restoreOutputState(state)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
390 self.interpret(program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
391
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
392 def do_optTag(self, args_tuple,
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
393 omit=0):
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
394 (name, cexpr, tag_ns, isend, start, program) = args_tuple
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
395 if tag_ns and not self.showtal:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
396 return self.no_tag(start, program)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
397
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
398 self.interpret(start)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
399 if not isend:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
400 self.interpret(program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
401 s = '</%s>' % name
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
402 self._stream_write(s)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
403 self.col = self.col + len(s)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
404
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
405 def do_optTag_tal(self, stuff):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
406 cexpr = stuff[1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
407 if cexpr is not None and (cexpr == '' or
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
408 self.engine.evaluateBoolean(cexpr)):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
409 self.no_tag(stuff[-2], stuff[-1])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
410 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
411 self.do_optTag(stuff)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
412 bytecode_handlers["optTag"] = do_optTag
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
413
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
414 def do_rawtextBeginScope(self, args_tuple):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
415 (s, col, position, closeprev, dict) = args_tuple
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
416 self._stream_write(s)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
417 self.col = col
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
418 self.position = position
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
419 self.engine.setPosition(position)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
420 if closeprev:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
421 engine = self.engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
422 engine.endScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
423 engine.beginScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
424 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
425 self.engine.beginScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
426 self.scopeLevel = self.scopeLevel + 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
427
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
428 def do_rawtextBeginScope_tal(self, args_tuple):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
429 (s, col, position, closeprev, dict) = args_tuple
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
430 self._stream_write(s)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
431 self.col = col
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
432 engine = self.engine
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
433 self.position = position
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
434 engine.setPosition(position)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
435 if closeprev:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
436 engine.endScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
437 engine.beginScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
438 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
439 engine.beginScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
440 self.scopeLevel = self.scopeLevel + 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
441 engine.setLocal("attrs", dict)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
442 bytecode_handlers["rawtextBeginScope"] = do_rawtextBeginScope
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
443
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
444 def do_beginScope(self, dict):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
445 self.engine.beginScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
446 self.scopeLevel = self.scopeLevel + 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
447
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
448 def do_beginScope_tal(self, dict):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
449 engine = self.engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
450 engine.beginScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
451 engine.setLocal("attrs", dict)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
452 self.scopeLevel = self.scopeLevel + 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
453 bytecode_handlers["beginScope"] = do_beginScope
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
454
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
455 def do_endScope(self, notused=None):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
456 self.engine.endScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
457 self.scopeLevel = self.scopeLevel - 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
458 bytecode_handlers["endScope"] = do_endScope
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
459
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
460 def do_setLocal(self, notused):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
461 pass
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
462
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
463 def do_setLocal_tal(self, name_expr):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
464 (name, expr) = name_expr
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
465 self.engine.setLocal(name, self.engine.evaluateValue(expr))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
466 bytecode_handlers["setLocal"] = do_setLocal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
467
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
468 def do_setGlobal_tal(self, name_expr):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
469 (name, expr) = name_expr
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
470 self.engine.setGlobal(name, self.engine.evaluateValue(expr))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
471 bytecode_handlers["setGlobal"] = do_setLocal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
472
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
473 def do_beginI18nContext(self, settings):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
474 get = settings.get
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
475 self.i18nContext = TranslationContext(self.i18nContext,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
476 domain=get("domain"),
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
477 source=get("source"),
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
478 target=get("target"))
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
479 bytecode_handlers["beginI18nContext"] = do_beginI18nContext
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
480
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
481 def do_endI18nContext(self, notused=None):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
482 self.i18nContext = self.i18nContext.parent
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
483 assert self.i18nContext is not None
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
484 bytecode_handlers["endI18nContext"] = do_endI18nContext
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
485
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
486 def do_insertText(self, stuff):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
487 self.interpret(stuff[1])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
488
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
489 def do_insertText_tal(self, stuff):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
490 text = self.engine.evaluateText(stuff[0])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
491 if text is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
492 return
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
493 if text is self.Default:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
494 self.interpret(stuff[1])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
495 return
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
496 s = escape(text)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
497 self._stream_write(s)
1309
309f125f86cc removed use of string/strop from TAL/TALInterpreter
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
498 i = s.rfind('\n')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
499 if i < 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
500 self.col = self.col + len(s)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
501 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
502 self.col = len(s) - (i + 1)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
503 bytecode_handlers["insertText"] = do_insertText
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
504
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
505 def do_i18nVariable(self, stuff):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
506 varname, program, expression = stuff
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
507 if expression is None:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
508 # The value is implicitly the contents of this tag, so we have to
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
509 # evaluate the mini-program to get the value of the variable.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
510 state = self.saveState()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
511 try:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
512 tmpstream = self.StringIO()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
513 self.interpretWithStream(program, tmpstream)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
514 value = normalize(tmpstream.getvalue())
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
515 finally:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
516 self.restoreState(state)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
517 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
518 # Evaluate the value to be associated with the variable in the
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
519 # i18n interpolation dictionary.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
520 value = self.engine.evaluate(expression)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
521 # Either the i18n:name tag is nested inside an i18n:translate in which
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
522 # case the last item on the stack has the i18n dictionary and string
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
523 # representation, or the i18n:name and i18n:translate attributes are
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
524 # in the same tag, in which case the i18nStack will be empty. In that
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
525 # case we can just output the ${name} to the stream
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
526 i18ndict, srepr = self.i18nStack[-1]
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
527 i18ndict[varname] = value
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
528 placeholder = '${%s}' % varname
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
529 srepr.append(placeholder)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
530 self._stream_write(placeholder)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
531 bytecode_handlers['i18nVariable'] = do_i18nVariable
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
532
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
533 def do_insertTranslation(self, stuff):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
534 i18ndict = {}
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
535 srepr = []
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
536 obj = None
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
537 self.i18nStack.append((i18ndict, srepr))
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
538 msgid = stuff[0]
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
539 # We need to evaluate the content of the tag because that will give us
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
540 # several useful pieces of information. First, the contents will
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
541 # include an implicit message id, if no explicit one was given.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
542 # Second, it will evaluate any i18nVariable definitions in the body of
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
543 # the translation (necessary for $varname substitutions).
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
544 #
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
545 # Use a temporary stream to capture the interpretation of the
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
546 # subnodes, which should /not/ go to the output stream.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
547 tmpstream = self.StringIO()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
548 self.interpretWithStream(stuff[1], tmpstream)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
549 default = tmpstream.getvalue()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
550 # We only care about the evaluated contents if we need an implicit
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
551 # message id. All other useful information will be in the i18ndict on
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
552 # the top of the i18nStack.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
553 if msgid == '':
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
554 msgid = normalize(default)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
555 self.i18nStack.pop()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
556 # See if there is was an i18n:data for msgid
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
557 if len(stuff) > 2:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
558 obj = self.engine.evaluate(stuff[2])
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
559 xlated_msgid = self.translate(msgid, default, i18ndict, obj)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
560 assert xlated_msgid is not None, self.position
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
561 self._stream_write(xlated_msgid)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
562 bytecode_handlers['insertTranslation'] = do_insertTranslation
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
563
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
564 def do_insertStructure(self, stuff):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
565 self.interpret(stuff[2])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
566
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
567 def do_insertStructure_tal(self, expr_repldict_block):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
568 (expr, repldict, block) = expr_repldict_block
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
569 structure = self.engine.evaluateStructure(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
570 if structure is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
571 return
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
572 if structure is self.Default:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
573 self.interpret(block)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
574 return
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
575 text = ustr(structure)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
576 if not (repldict or self.strictinsert):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
577 # Take a shortcut, no error checking
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
578 self.stream_write(text)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
579 return
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
580 if self.html:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
581 self.insertHTMLStructure(text, repldict)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
582 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
583 self.insertXMLStructure(text, repldict)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
584 bytecode_handlers["insertStructure"] = do_insertStructure
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
585
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
586 def insertHTMLStructure(self, text, repldict):
5388
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5381
diff changeset
587 from .HTMLTALParser import HTMLTALParser
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
588 gen = AltTALGenerator(repldict, self.engine.getCompiler(), 0)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
589 p = HTMLTALParser(gen) # Raises an exception if text is invalid
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
590 p.parseString(text)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
591 program, macros = p.getCode()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
592 self.interpret(program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
593
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
594 def insertXMLStructure(self, text, repldict):
5388
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5381
diff changeset
595 from .TALParser import TALParser
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
596 gen = AltTALGenerator(repldict, self.engine.getCompiler(), 0)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
597 p = TALParser(gen)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
598 gen.enable(0)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
599 p.parseFragment('<!DOCTYPE foo PUBLIC "foo" "bar"><foo>')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
600 gen.enable(1)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
601 p.parseFragment(text) # Raises an exception if text is invalid
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
602 gen.enable(0)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
603 p.parseFragment('</foo>', 1)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
604 program, macros = gen.getCode()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
605 self.interpret(program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
606
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
607 def do_loop(self, name_expr_block):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
608 (name, expr, block) = name_expr_block
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
609 self.interpret(block)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
610
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
611 def do_loop_tal(self, name_expr_block):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
612 (name, expr, block) = name_expr_block
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
613 iterator = self.engine.setRepeat(name, expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
614 while iterator.next():
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
615 self.interpret(block)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
616 bytecode_handlers["loop"] = do_loop
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
617
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
618 def translate(self, msgid, default, i18ndict, obj=None):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
619 if obj:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
620 i18ndict.update(obj)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
621 if not self.i18nInterpolate:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
622 return msgid
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
623 # XXX We need to pass in one of context or target_language
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
624 return self.engine.translate(self.i18nContext.domain,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
625 msgid, i18ndict, default=default)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
626
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
627 def do_rawtextColumn(self, s_col):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
628 (s, col) = s_col
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
629 self._stream_write(s)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
630 self.col = col
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
631 bytecode_handlers["rawtextColumn"] = do_rawtextColumn
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
632
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
633 def do_rawtextOffset(self, s_offset):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
634 (s, offset) = s_offset
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
635 self._stream_write(s)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
636 self.col = self.col + offset
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
637 bytecode_handlers["rawtextOffset"] = do_rawtextOffset
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
638
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
639 def do_condition(self, condition_block):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
640 (condition, block) = condition_block
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
641 if not self.tal or self.engine.evaluateBoolean(condition):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
642 self.interpret(block)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
643 bytecode_handlers["condition"] = do_condition
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
644
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
645 def do_defineMacro(self, macroName_macro):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
646 (macroName, macro) = macroName_macro
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
647 macs = self.macroStack
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
648 if len(macs) == 1:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
649 entering = macs[-1][2]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
650 if not entering:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
651 macs.append(None)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
652 self.interpret(macro)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
653 assert macs[-1] is None
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
654 macs.pop()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
655 return
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
656 self.interpret(macro)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
657 bytecode_handlers["defineMacro"] = do_defineMacro
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
658
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
659 def do_useMacro(self, args_tuple):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
660 (macroName, macroExpr, compiledSlots, block) = args_tuple
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
661 if not self.metal:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
662 self.interpret(block)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
663 return
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
664 macro = self.engine.evaluateMacro(macroExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
665 if macro is self.Default:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
666 macro = block
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
667 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
668 if not isCurrentVersion(macro):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
669 raise METALError("macro %s has incompatible version %s" %
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 2348
diff changeset
670 (repr(macroName), repr(getProgramVersion(macro))),
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
671 self.position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
672 mode = getProgramMode(macro)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
673 if mode != (self.html and "html" or "xml"):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
674 raise METALError("macro %s has incompatible mode %s" %
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 2348
diff changeset
675 (repr(macroName), repr(mode)), self.position)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
676 self.pushMacro(macroName, compiledSlots)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
677 prev_source = self.sourceFile
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
678 self.interpret(macro)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
679 if self.sourceFile != prev_source:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
680 self.engine.setSourceFile(prev_source)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
681 self.sourceFile = prev_source
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
682 self.popMacro()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
683 bytecode_handlers["useMacro"] = do_useMacro
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
684
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
685 def do_fillSlot(self, slotName_block):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
686 # This is only executed if the enclosing 'use-macro' evaluates
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
687 # to 'default'.
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
688 (slotName, block) = slotName_block
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
689 self.interpret(block)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
690 bytecode_handlers["fillSlot"] = do_fillSlot
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
691
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
692 def do_defineSlot(self, slotName_block):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
693 (slotName, block) = slotName_block
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
694 if not self.metal:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
695 self.interpret(block)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
696 return
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
697 macs = self.macroStack
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
698 if macs and macs[-1] is not None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
699 macroName, slots = self.popMacro()[:2]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
700 slot = slots.get(slotName)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
701 if slot is not None:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
702 prev_source = self.sourceFile
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
703 self.interpret(slot)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
704 if self.sourceFile != prev_source:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
705 self.engine.setSourceFile(prev_source)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
706 self.sourceFile = prev_source
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
707 self.pushMacro(macroName, slots, entering=0)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
708 return
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
709 self.pushMacro(macroName, slots)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
710 # Falling out of the 'if' allows the macro to be interpreted.
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
711 self.interpret(block)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
712 bytecode_handlers["defineSlot"] = do_defineSlot
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
713
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
714 def do_onError(self, block_handler):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
715 (block, handler) = block_handler
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
716 self.interpret(block)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
717
5393
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
718 def do_onError_tal(self, block_handler):
46b2fd6d342e Python 3 preparation: avoid implicit tuple parameter unpacking.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
719 (block, handler) = block_handler
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
720 state = self.saveState()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
721 self.stream = stream = self.StringIO()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
722 self._stream_write = stream.write
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
723 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
724 self.interpret(block)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
725 except:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
726 exc = sys.exc_info()[1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
727 self.restoreState(state)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
728 engine = self.engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
729 engine.beginScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
730 error = engine.createErrorInfo(exc, self.position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
731 engine.setLocal('error', error)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
732 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
733 self.interpret(handler)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
734 finally:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
735 engine.endScope()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
736 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
737 self.restoreOutputState(state)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
738 self.stream_write(stream.getvalue())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
739 bytecode_handlers["onError"] = do_onError
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
740
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
741 bytecode_handlers_tal = bytecode_handlers.copy()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
742 bytecode_handlers_tal["rawtextBeginScope"] = do_rawtextBeginScope_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
743 bytecode_handlers_tal["beginScope"] = do_beginScope_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
744 bytecode_handlers_tal["setLocal"] = do_setLocal_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
745 bytecode_handlers_tal["setGlobal"] = do_setGlobal_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
746 bytecode_handlers_tal["insertStructure"] = do_insertStructure_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
747 bytecode_handlers_tal["insertText"] = do_insertText_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
748 bytecode_handlers_tal["loop"] = do_loop_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
749 bytecode_handlers_tal["onError"] = do_onError_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
750 bytecode_handlers_tal["<attrAction>"] = attrAction_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
751 bytecode_handlers_tal["optTag"] = do_optTag_tal
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
752
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
753
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
754 def _write_ValueError(s):
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5377
diff changeset
755 raise ValueError("I/O operation on closed file")

Roundup Issue Tracker: http://roundup-tracker.org/