annotate TAL/TALInterpreter.py @ 1029:c3e391d9c4e9

more FieldStorage fun
author Richard Jones <richard@users.sourceforge.net>
date Tue, 03 Sep 2002 07:42:38 +0000
parents bfd348432420
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
982
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1 ##############################################################################
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 #
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3 # Copyright (c) 2001, 2002 Zope Corporation and Contributors.
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
4 # All Rights Reserved.
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 #
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6 # This software is subject to the provisions of the Zope Public License,
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
11 # FOR A PARTICULAR PURPOSE
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
12 #
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
13 ##############################################################################
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14 """
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
15 Interpreter for a pre-compiled TAL program.
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
16 """
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
17
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
18 import sys
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19 import getopt
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
21 from cgi import escape
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
22 from string import join, lower, rfind
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
23 try:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
24 from strop import lower, rfind
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
25 except ImportError:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
26 pass
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
28 try:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29 from cStringIO import StringIO
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
30 except ImportError:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31 from StringIO import StringIO
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
33 from TALDefs import quote, TAL_VERSION, TALError, METALError
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34 from TALDefs import isCurrentVersion, getProgramVersion, getProgramMode
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35 from TALGenerator import TALGenerator
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37 BOOLEAN_HTML_ATTRS = [
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 # List of Boolean attributes in HTML that should be rendered in
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 # minimized form (e.g. <img ismap> rather than <img ismap="">)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40 # From http://www.w3.org/TR/xhtml1/#guidelines (C.10)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41 # XXX The problem with this is that this is not valid XML and
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 # can't be parsed back!
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43 "compact", "nowrap", "ismap", "declare", "noshade", "checked",
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44 "disabled", "readonly", "multiple", "selected", "noresize",
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 "defer"
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46 ]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
47
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 EMPTY_HTML_TAGS = [
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49 # List of HTML tags with an empty content model; these are
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50 # rendered in minimized form, e.g. <img />.
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51 # From http://www.w3.org/TR/xhtml1/#dtds
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
52 "base", "meta", "link", "hr", "br", "param", "img", "area",
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53 "input", "col", "basefont", "isindex", "frame",
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
54 ]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
55
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 class AltTALGenerator(TALGenerator):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
57
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
58 def __init__(self, repldict, expressionCompiler=None, xml=0):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
59 self.repldict = repldict
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
60 self.enabled = 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
61 TALGenerator.__init__(self, expressionCompiler, xml)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
62
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
63 def enable(self, enabled):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
64 self.enabled = enabled
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
66 def emit(self, *args):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
67 if self.enabled:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68 apply(TALGenerator.emit, (self,) + args)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70 def emitStartElement(self, name, attrlist, taldict, metaldict,
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
71 position=(None, None), isend=0):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72 metaldict = {}
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73 taldict = {}
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 if self.enabled and self.repldict:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
75 taldict["attributes"] = "x x"
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
76 TALGenerator.emitStartElement(self, name, attrlist,
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
77 taldict, metaldict, position, isend)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
78
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 def replaceAttrs(self, attrlist, repldict):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80 if self.enabled and self.repldict:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81 repldict = self.repldict
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 self.repldict = None
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 return TALGenerator.replaceAttrs(self, attrlist, repldict)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 class TALInterpreter:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 def __init__(self, program, macros, engine, stream=None,
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 debug=0, wrap=60, metal=1, tal=1, showtal=-1,
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 strictinsert=1, stackLimit=100):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 self.program = program
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 self.macros = macros
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 self.engine = engine
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94 self.Default = engine.getDefault()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95 self.stream = stream or sys.stdout
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 self._stream_write = self.stream.write
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 self.debug = debug
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 self.wrap = wrap
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 self.metal = metal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100 self.tal = tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 if tal:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 self.dispatch = self.bytecode_handlers_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104 self.dispatch = self.bytecode_handlers
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 assert showtal in (-1, 0, 1)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106 if showtal == -1:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107 showtal = (not tal)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 self.showtal = showtal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109 self.strictinsert = strictinsert
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
110 self.stackLimit = stackLimit
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111 self.html = 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112 self.endsep = "/>"
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 self.endlen = len(self.endsep)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
114 self.macroStack = []
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115 self.popMacro = self.macroStack.pop
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 self.position = None, None # (lineno, offset)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117 self.col = 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118 self.level = 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 self.scopeLevel = 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 self.sourceFile = None
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122 def saveState(self):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 return (self.position, self.col, self.stream,
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124 self.scopeLevel, self.level)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 def restoreState(self, state):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 (self.position, self.col, self.stream, scopeLevel, level) = state
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 self._stream_write = self.stream.write
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 assert self.level == level
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
130 while self.scopeLevel > scopeLevel:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
131 self.engine.endScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
132 self.scopeLevel = self.scopeLevel - 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
133 self.engine.setPosition(self.position)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
134
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
135 def restoreOutputState(self, state):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
136 (dummy, self.col, self.stream, scopeLevel, level) = state
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
137 self._stream_write = self.stream.write
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
138 assert self.level == level
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
139 assert self.scopeLevel == scopeLevel
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
140
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
141 def pushMacro(self, macroName, slots, entering=1):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
142 if len(self.macroStack) >= self.stackLimit:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
143 raise METALError("macro nesting limit (%d) exceeded "
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
144 "by %s" % (self.stackLimit, `macroName`))
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
145 self.macroStack.append([macroName, slots, entering])
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
146
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
147 def macroContext(self, what):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
148 macroStack = self.macroStack
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
149 i = len(macroStack)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
150 while i > 0:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
151 i = i-1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
152 if macroStack[i][0] == what:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
153 return i
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
154 return -1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
155
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
156 def __call__(self):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157 assert self.level == 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
158 assert self.scopeLevel == 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
159 self.interpret(self.program)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160 assert self.level == 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161 assert self.scopeLevel == 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
162 if self.col > 0:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
163 self._stream_write("\n")
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 self.col = 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 def stream_write(self, s,
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167 len=len, rfind=rfind):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
168 self._stream_write(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
169 i = rfind(s, '\n')
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
170 if i < 0:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
171 self.col = self.col + len(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
172 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 self.col = len(s) - (i + 1)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175 bytecode_handlers = {}
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 def interpret(self, program, None=None):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178 oldlevel = self.level
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179 self.level = oldlevel + 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
180 handlers = self.dispatch
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
181 try:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
182 if self.debug:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
183 for (opcode, args) in program:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
184 s = "%sdo_%s%s\n" % (" "*self.level, opcode,
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
185 repr(args))
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 if len(s) > 80:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
187 s = s[:76] + "...\n"
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188 sys.stderr.write(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189 handlers[opcode](self, args)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191 for (opcode, args) in program:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
192 handlers[opcode](self, args)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
193 finally:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194 self.level = oldlevel
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
196 def do_version(self, version):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
197 assert version == TAL_VERSION
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
198 bytecode_handlers["version"] = do_version
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
199
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
200 def do_mode(self, mode):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
201 assert mode in ("html", "xml")
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
202 self.html = (mode == "html")
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
203 if self.html:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
204 self.endsep = " />"
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
205 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
206 self.endsep = "/>"
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
207 self.endlen = len(self.endsep)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
208 bytecode_handlers["mode"] = do_mode
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
209
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
210 def do_setSourceFile(self, source_file):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
211 self.sourceFile = source_file
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
212 self.engine.setSourceFile(source_file)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
213 bytecode_handlers["setSourceFile"] = do_setSourceFile
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
214
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
215 def do_setPosition(self, position):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
216 self.position = position
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
217 self.engine.setPosition(position)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
218 bytecode_handlers["setPosition"] = do_setPosition
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
219
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
220 def do_startEndTag(self, stuff):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
221 self.do_startTag(stuff, self.endsep, self.endlen)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
222 bytecode_handlers["startEndTag"] = do_startEndTag
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
223
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
224 def do_startTag(self, (name, attrList),
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
225 end=">", endlen=1, _len=len):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
226 # The bytecode generator does not cause calls to this method
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
227 # for start tags with no attributes; those are optimized down
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
228 # to rawtext events. Hence, there is no special "fast path"
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
229 # for that case.
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
230 _stream_write = self._stream_write
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
231 _stream_write("<" + name)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
232 namelen = _len(name)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
233 col = self.col + namelen + 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
234 wrap = self.wrap
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
235 align = col + 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
236 if align >= wrap/2:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
237 align = 4 # Avoid a narrow column far to the right
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
238 attrAction = self.dispatch["<attrAction>"]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
239 try:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
240 for item in attrList:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
241 if _len(item) == 2:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
242 name, s = item
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
243 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
244 ok, name, s = attrAction(self, item)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
245 if not ok:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
246 continue
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
247 slen = _len(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
248 if (wrap and
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
249 col >= align and
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
250 col + 1 + slen > wrap):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
251 _stream_write("\n" + " "*align)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
252 col = align + slen
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
253 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
254 s = " " + s
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
255 col = col + 1 + slen
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
256 _stream_write(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
257 _stream_write(end)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
258 col = col + endlen
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
259 finally:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
260 self.col = col
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
261 bytecode_handlers["startTag"] = do_startTag
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
262
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
263 def attrAction(self, item):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
264 name, value, action = item[:3]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
265 if action == 1 or (action > 1 and not self.showtal):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
266 return 0, name, value
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
267 macs = self.macroStack
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
268 if action == 2 and self.metal and macs:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
269 if len(macs) > 1 or not macs[-1][2]:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
270 # Drop all METAL attributes at a use-depth above one.
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
271 return 0, name, value
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
272 # Clear 'entering' flag
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
273 macs[-1][2] = 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
274 # Convert or drop depth-one METAL attributes.
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
275 i = rfind(name, ":") + 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
276 prefix, suffix = name[:i], name[i:]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
277 if suffix == "define-macro":
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
278 # Convert define-macro as we enter depth one.
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
279 name = prefix + "use-macro"
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280 value = macs[-1][0] # Macro name
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
281 elif suffix == "define-slot":
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
282 name = prefix + "slot"
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
283 elif suffix == "fill-slot":
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
284 pass
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
285 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
286 return 0, name, value
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
287
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
288 if value is None:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
289 value = name
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
290 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
291 value = "%s=%s" % (name, quote(value))
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
292 return 1, name, value
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
293
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
294 def attrAction_tal(self, item):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
295 name, value, action = item[:3]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
296 if action > 1:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
297 return self.attrAction(item)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
298 ok = 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
299 if self.html and lower(name) in BOOLEAN_HTML_ATTRS:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
300 evalue = self.engine.evaluateBoolean(item[3])
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
301 if evalue is self.Default:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
302 if action == 1: # Cancelled insert
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
303 ok = 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
304 elif evalue:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
305 value = None
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
306 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
307 ok = 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
308 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
309 evalue = self.engine.evaluateText(item[3])
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
310 if evalue is self.Default:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
311 if action == 1: # Cancelled insert
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
312 ok = 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
313 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
314 if evalue is None:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
315 ok = 0
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
316 value = evalue
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
317 if ok:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
318 if value is None:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
319 value = name
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
320 value = "%s=%s" % (name, quote(value))
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
321 return ok, name, value
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
322
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
323 bytecode_handlers["<attrAction>"] = attrAction
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
324
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
325 def no_tag(self, start, program):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
326 state = self.saveState()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
327 self.stream = stream = StringIO()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
328 self._stream_write = stream.write
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
329 self.interpret(start)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
330 self.restoreOutputState(state)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
331 self.interpret(program)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
332
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
333 def do_optTag(self, (name, cexpr, tag_ns, isend, start, program),
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
334 omit=0):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
335 if tag_ns and not self.showtal:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
336 return self.no_tag(start, program)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
337
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
338 self.interpret(start)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
339 if not isend:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
340 self.interpret(program)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
341 s = '</%s>' % name
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
342 self._stream_write(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
343 self.col = self.col + len(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
344
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
345 def do_optTag_tal(self, stuff):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
346 cexpr = stuff[1]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
347 if cexpr is not None and (cexpr == '' or
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
348 self.engine.evaluateBoolean(cexpr)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
349 self.no_tag(stuff[-2], stuff[-1])
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
350 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
351 self.do_optTag(stuff)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
352 bytecode_handlers["optTag"] = do_optTag
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
353
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
354 def dumpMacroStack(self, prefix, suffix, value):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
355 sys.stderr.write("+---- %s%s = %s\n" % (prefix, suffix, value))
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
356 for i in range(len(self.macroStack)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
357 what, macroName, slots = self.macroStack[i]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
358 sys.stderr.write("| %2d. %-12s %-12s %s\n" %
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
359 (i, what, macroName, slots and slots.keys()))
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
360 sys.stderr.write("+--------------------------------------\n")
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
361
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
362 def do_rawtextBeginScope(self, (s, col, position, closeprev, dict)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
363 self._stream_write(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
364 self.col = col
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
365 self.do_setPosition(position)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
366 if closeprev:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
367 engine = self.engine
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
368 engine.endScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
369 engine.beginScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
370 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
371 self.engine.beginScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
372 self.scopeLevel = self.scopeLevel + 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
373
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
374 def do_rawtextBeginScope_tal(self, (s, col, position, closeprev, dict)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
375 self._stream_write(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
376 self.col = col
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
377 self.do_setPosition(position)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
378 engine = self.engine
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
379 if closeprev:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
380 engine.endScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
381 engine.beginScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
382 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
383 engine.beginScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
384 self.scopeLevel = self.scopeLevel + 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
385 engine.setLocal("attrs", dict)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
386 bytecode_handlers["rawtextBeginScope"] = do_rawtextBeginScope
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
387
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
388 def do_beginScope(self, dict):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
389 self.engine.beginScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
390 self.scopeLevel = self.scopeLevel + 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
391
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
392 def do_beginScope_tal(self, dict):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
393 engine = self.engine
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
394 engine.beginScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
395 engine.setLocal("attrs", dict)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
396 self.scopeLevel = self.scopeLevel + 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
397 bytecode_handlers["beginScope"] = do_beginScope
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
398
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
399 def do_endScope(self, notused=None):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
400 self.engine.endScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
401 self.scopeLevel = self.scopeLevel - 1
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
402 bytecode_handlers["endScope"] = do_endScope
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
403
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
404 def do_setLocal(self, notused):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
405 pass
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
406
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
407 def do_setLocal_tal(self, (name, expr)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
408 self.engine.setLocal(name, self.engine.evaluateValue(expr))
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
409 bytecode_handlers["setLocal"] = do_setLocal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
410
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
411 def do_setGlobal_tal(self, (name, expr)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
412 self.engine.setGlobal(name, self.engine.evaluateValue(expr))
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
413 bytecode_handlers["setGlobal"] = do_setLocal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
414
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
415 def do_insertText(self, stuff):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
416 self.interpret(stuff[1])
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
417
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
418 def do_insertText_tal(self, stuff):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
419 text = self.engine.evaluateText(stuff[0])
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
420 if text is None:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
421 return
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
422 if text is self.Default:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
423 self.interpret(stuff[1])
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
424 return
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
425 s = escape(text)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
426 self._stream_write(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
427 i = rfind(s, '\n')
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
428 if i < 0:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
429 self.col = self.col + len(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
430 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
431 self.col = len(s) - (i + 1)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
432 bytecode_handlers["insertText"] = do_insertText
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
433
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
434 def do_insertStructure(self, stuff):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
435 self.interpret(stuff[2])
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
436
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
437 def do_insertStructure_tal(self, (expr, repldict, block)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
438 structure = self.engine.evaluateStructure(expr)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
439 if structure is None:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
440 return
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
441 if structure is self.Default:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
442 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
443 return
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
444 text = str(structure)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
445 if not (repldict or self.strictinsert):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
446 # Take a shortcut, no error checking
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
447 self.stream_write(text)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
448 return
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
449 if self.html:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
450 self.insertHTMLStructure(text, repldict)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
451 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
452 self.insertXMLStructure(text, repldict)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
453 bytecode_handlers["insertStructure"] = do_insertStructure
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
454
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
455 def insertHTMLStructure(self, text, repldict):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
456 from HTMLTALParser import HTMLTALParser
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
457 gen = AltTALGenerator(repldict, self.engine, 0)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
458 p = HTMLTALParser(gen) # Raises an exception if text is invalid
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
459 p.parseString(text)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
460 program, macros = p.getCode()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
461 self.interpret(program)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
462
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
463 def insertXMLStructure(self, text, repldict):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
464 from TALParser import TALParser
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
465 gen = AltTALGenerator(repldict, self.engine, 0)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
466 p = TALParser(gen)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
467 gen.enable(0)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
468 p.parseFragment('<!DOCTYPE foo PUBLIC "foo" "bar"><foo>')
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
469 gen.enable(1)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
470 p.parseFragment(text) # Raises an exception if text is invalid
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
471 gen.enable(0)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
472 p.parseFragment('</foo>', 1)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
473 program, macros = gen.getCode()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
474 self.interpret(program)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
475
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
476 def do_loop(self, (name, expr, block)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
477 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
478
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
479 def do_loop_tal(self, (name, expr, block)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
480 iterator = self.engine.setRepeat(name, expr)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
481 while iterator.next():
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
482 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
483 bytecode_handlers["loop"] = do_loop
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
484
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
485 def do_rawtextColumn(self, (s, col)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
486 self._stream_write(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
487 self.col = col
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
488 bytecode_handlers["rawtextColumn"] = do_rawtextColumn
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
489
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
490 def do_rawtextOffset(self, (s, offset)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
491 self._stream_write(s)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
492 self.col = self.col + offset
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
493 bytecode_handlers["rawtextOffset"] = do_rawtextOffset
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
494
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
495 def do_condition(self, (condition, block)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
496 if not self.tal or self.engine.evaluateBoolean(condition):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
497 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
498 bytecode_handlers["condition"] = do_condition
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
499
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
500 def do_defineMacro(self, (macroName, macro)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
501 macs = self.macroStack
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
502 if len(macs) == 1:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
503 entering = macs[-1][2]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
504 if not entering:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
505 macs.append(None)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
506 self.interpret(macro)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
507 macs.pop()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
508 return
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
509 self.interpret(macro)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
510 bytecode_handlers["defineMacro"] = do_defineMacro
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
511
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
512 def do_useMacro(self, (macroName, macroExpr, compiledSlots, block)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
513 if not self.metal:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
514 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
515 return
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
516 macro = self.engine.evaluateMacro(macroExpr)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
517 if macro is self.Default:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
518 macro = block
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
519 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
520 if not isCurrentVersion(macro):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
521 raise METALError("macro %s has incompatible version %s" %
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
522 (`macroName`, `getProgramVersion(macro)`),
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
523 self.position)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
524 mode = getProgramMode(macro)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
525 if mode != (self.html and "html" or "xml"):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
526 raise METALError("macro %s has incompatible mode %s" %
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
527 (`macroName`, `mode`), self.position)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
528 self.pushMacro(macroName, compiledSlots)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
529 saved_source = self.sourceFile
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
530 saved_position = self.position # Used by Boa Constructor
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
531 self.interpret(macro)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
532 if self.sourceFile != saved_source:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
533 self.engine.setSourceFile(saved_source)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
534 self.sourceFile = saved_source
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
535 self.popMacro()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
536 bytecode_handlers["useMacro"] = do_useMacro
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
537
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
538 def do_fillSlot(self, (slotName, block)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
539 # This is only executed if the enclosing 'use-macro' evaluates
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
540 # to 'default'.
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
541 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
542 bytecode_handlers["fillSlot"] = do_fillSlot
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
543
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
544 def do_defineSlot(self, (slotName, block)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
545 if not self.metal:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
546 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
547 return
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
548 macs = self.macroStack
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
549 if macs and macs[-1] is not None:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
550 saved_source = self.sourceFile
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
551 saved_position = self.position # Used by Boa Constructor
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
552 macroName, slots = self.popMacro()[:2]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
553 slot = slots.get(slotName)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
554 if slot is not None:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
555 self.interpret(slot)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
556 if self.sourceFile != saved_source:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
557 self.engine.setSourceFile(saved_source)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
558 self.sourceFile = saved_source
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
559 self.pushMacro(macroName, slots, entering=0)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
560 return
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
561 self.pushMacro(macroName, slots)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
562 if len(macs) == 1:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
563 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
564 return
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
565 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
566 bytecode_handlers["defineSlot"] = do_defineSlot
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
567
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
568 def do_onError(self, (block, handler)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
569 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
570
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
571 def do_onError_tal(self, (block, handler)):
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
572 state = self.saveState()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
573 self.stream = stream = StringIO()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
574 self._stream_write = stream.write
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
575 try:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
576 self.interpret(block)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
577 except:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
578 exc = sys.exc_info()[1]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
579 self.restoreState(state)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
580 engine = self.engine
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
581 engine.beginScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
582 error = engine.createErrorInfo(exc, self.position)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
583 engine.setLocal('error', error)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
584 try:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
585 self.interpret(handler)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
586 finally:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
587 engine.endScope()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
588 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
589 self.restoreOutputState(state)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
590 self.stream_write(stream.getvalue())
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
591 bytecode_handlers["onError"] = do_onError
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
592
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
593 bytecode_handlers_tal = bytecode_handlers.copy()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
594 bytecode_handlers_tal["rawtextBeginScope"] = do_rawtextBeginScope_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
595 bytecode_handlers_tal["beginScope"] = do_beginScope_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
596 bytecode_handlers_tal["setLocal"] = do_setLocal_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
597 bytecode_handlers_tal["setGlobal"] = do_setGlobal_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
598 bytecode_handlers_tal["insertStructure"] = do_insertStructure_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
599 bytecode_handlers_tal["insertText"] = do_insertText_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
600 bytecode_handlers_tal["loop"] = do_loop_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
601 bytecode_handlers_tal["onError"] = do_onError_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
602 bytecode_handlers_tal["<attrAction>"] = attrAction_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
603 bytecode_handlers_tal["optTag"] = do_optTag_tal
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
604
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
605
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
606 def test():
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
607 from driver import FILE, parsefile
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
608 from DummyEngine import DummyEngine
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
609 try:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
610 opts, args = getopt.getopt(sys.argv[1:], "")
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
611 except getopt.error, msg:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
612 print msg
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
613 sys.exit(2)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
614 if args:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
615 file = args[0]
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
616 else:
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
617 file = FILE
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
618 doc = parsefile(file)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
619 compiler = TALCompiler(doc)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
620 program, macros = compiler()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
621 engine = DummyEngine()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
622 interpreter = TALInterpreter(program, macros, engine)
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
623 interpreter()
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
624
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
625 if __name__ == "__main__":
bfd348432420 Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
626 test()

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