annotate roundup/cgi/TAL/TALGenerator.py @ 5179:e8b3d3a14563

- issue2550796: Calendar and Classhelp selection tools don't cause onchange event to be triggered. Using the helper popups for modifying lists of users, lists of issues, dates etc.. now trigger the change event on the form's field. This allows onchange javascript to trigger to highlight changes, recalculate other form values etc. See ``upgrading.txt`` for details on applying these changes to your tracker.
author John Rouillard <rouilj@ieee.org>
date Sat, 28 Jan 2017 20:58:19 -0500
parents 8c2402a78bb0
children 198b6e810c67
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 ##############################################################################
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14 """
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
15 Code generator for TALInterpreter intermediate code.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
16 """
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
17
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
18 import re
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19 import cgi
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
21 import TALDefs
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
22
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
23 from TALDefs import NAME_RE, TAL_VERSION
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
24 from TALDefs import I18NError, METALError, TALError
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
25 from TALDefs import parseSubstitution
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
26 from TranslationContext import TranslationContext, DEFAULT_DOMAIN
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
27
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
28 I18N_REPLACE = 1
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
29 I18N_CONTENT = 2
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
30 I18N_EXPRESSION = 3
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
31
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
32 _name_rx = re.compile(NAME_RE)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
33
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35 class TALGenerator:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37 inMacroUse = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 inMacroDef = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 source_file = None
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
40
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41 def __init__(self, expressionCompiler=None, xml=1, source_file=None):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 if not expressionCompiler:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43 from DummyEngine import DummyEngine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44 expressionCompiler = DummyEngine()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 self.expressionCompiler = expressionCompiler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46 self.CompilerError = expressionCompiler.getCompilerError()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
47 # This holds the emitted opcodes representing the input
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 self.program = []
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
49 # The program stack for when we need to do some sub-evaluation for an
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
50 # intermediate result. E.g. in an i18n:name tag for which the
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
51 # contents describe the ${name} value.
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
52 self.stack = []
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
53 # Another stack of postponed actions. Elements on this stack are a
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
54 # dictionary; key/values contain useful information that
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
55 # emitEndElement needs to finish its calculations
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 self.todoStack = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
57 self.macros = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
58 self.slots = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
59 self.slotStack = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
60 self.xml = xml
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
61 self.emit("version", TAL_VERSION)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
62 self.emit("mode", xml and "xml" or "html")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
63 if source_file is not None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
64 self.source_file = source_file
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65 self.emit("setSourceFile", source_file)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
66 self.i18nContext = TranslationContext()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
67 self.i18nLevel = 0
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69 def getCode(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70 assert not self.stack
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
71 assert not self.todoStack
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72 return self.optimize(self.program), self.macros
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 def optimize(self, program):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
75 output = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
76 collect = []
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
77 cursor = 0
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
78 if self.xml:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 endsep = "/>"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81 endsep = " />"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 for cursor in xrange(len(program)+1):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84 item = program[cursor]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85 except IndexError:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 item = (None, None)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87 opcode = item[0]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 if opcode == "rawtext":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 collect.append(item[1])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 continue
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 if opcode == "endTag":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 collect.append("</%s>" % item[1])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 continue
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94 if opcode == "startTag":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95 if self.optimizeStartTag(collect, item[1], item[2], ">"):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 continue
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 if opcode == "startEndTag":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 if self.optimizeStartTag(collect, item[1], item[2], endsep):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 continue
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100 if opcode in ("beginScope", "endScope"):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 # Push *Scope instructions in front of any text instructions;
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 # this allows text instructions separated only by *Scope
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 # instructions to be joined together.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104 output.append(self.optimizeArgsList(item))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 continue
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
106 if opcode == 'noop':
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
107 # This is a spacer for end tags in the face of i18n:name
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
108 # attributes. We can't let the optimizer collect immediately
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
109 # following end tags into the same rawtextOffset.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
110 opcode = None
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
111 pass
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
112 text = "".join(collect)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 if text:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
114 i = text.rfind("\n")
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115 if i >= 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 i = len(text) - (i + 1)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117 output.append(("rawtextColumn", (text, i)))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 output.append(("rawtextOffset", (text, len(text))))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 if opcode != None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121 output.append(self.optimizeArgsList(item))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122 collect = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 return self.optimizeCommonTriple(output)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125 def optimizeArgsList(self, item):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 if len(item) == 2:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 return item
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 return item[0], tuple(item[1:])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
130
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
131 # These codes are used to indicate what sort of special actions
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
132 # are needed for each special attribute. (Simple attributes don't
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
133 # get action codes.)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
134 #
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
135 # The special actions (which are modal) are handled by
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
136 # TALInterpreter.attrAction() and .attrAction_tal().
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
137 #
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
138 # Each attribute is represented by a tuple:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
139 #
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
140 # (name, value) -- a simple name/value pair, with
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
141 # no special processing
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
142 #
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
143 # (name, value, action, *extra) -- attribute with special
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
144 # processing needs, action is a
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
145 # code that indicates which
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
146 # branch to take, and *extra
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
147 # contains additional,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
148 # action-specific information
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
149 # needed by the processing
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
150 #
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
151 def optimizeStartTag(self, collect, name, attrlist, end):
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
152 # return true if the tag can be converted to plain text
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
153 if not attrlist:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
154 collect.append("<%s%s" % (name, end))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
155 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
156 opt = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157 new = ["<" + name]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
158 for i in range(len(attrlist)):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
159 item = attrlist[i]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160 if len(item) > 2:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161 opt = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
162 name, value, action = item[:3]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
163 attrlist[i] = (name, value, action) + item[3:]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165 if item[1] is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 s = item[0]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167 else:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
168 s = '%s="%s"' % (item[0], TALDefs.attrEscape(item[1]))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
169 attrlist[i] = item[0], s
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
170 new.append(" " + s)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
171 # if no non-optimizable attributes were found, convert to plain text
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
172 if opt:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 new.append(end)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174 collect.extend(new)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175 return opt
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 def optimizeCommonTriple(self, program):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178 if len(program) < 3:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179 return program
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
180 output = program[:2]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
181 prev2, prev1 = output
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
182 for item in program[2:]:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
183 if ( item[0] == "beginScope"
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
184 and prev1[0] == "setPosition"
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
185 and prev2[0] == "rawtextColumn"):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 position = output.pop()[1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
187 text, column = output.pop()[1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188 prev1 = None, None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189 closeprev = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190 if output and output[-1][0] == "endScope":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191 closeprev = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
192 output.pop()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
193 item = ("rawtextBeginScope",
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194 (text, column, position, closeprev, item[1]))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195 output.append(item)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
196 prev2 = prev1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
197 prev1 = item
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
198 return output
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
199
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
200 def todoPush(self, todo):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
201 self.todoStack.append(todo)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
202
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
203 def todoPop(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
204 return self.todoStack.pop()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
205
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
206 def compileExpression(self, expr):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
207 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
208 return self.expressionCompiler.compile(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
209 except self.CompilerError, err:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
210 raise TALError('%s in expression %s' % (err.args[0], `expr`),
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
211 self.position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
212
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
213 def pushProgram(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
214 self.stack.append(self.program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
215 self.program = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
216
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
217 def popProgram(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
218 program = self.program
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
219 self.program = self.stack.pop()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
220 return self.optimize(program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
221
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
222 def pushSlots(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
223 self.slotStack.append(self.slots)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
224 self.slots = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
225
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
226 def popSlots(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
227 slots = self.slots
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
228 self.slots = self.slotStack.pop()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
229 return slots
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
230
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
231 def emit(self, *instruction):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
232 self.program.append(instruction)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
233
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
234 def emitStartTag(self, name, attrlist, isend=0):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
235 if isend:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
236 opcode = "startEndTag"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
237 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
238 opcode = "startTag"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
239 self.emit(opcode, name, attrlist)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
240
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
241 def emitEndTag(self, name):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
242 if self.xml and self.program and self.program[-1][0] == "startTag":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
243 # Minimize empty element
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
244 self.program[-1] = ("startEndTag",) + self.program[-1][1:]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
245 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
246 self.emit("endTag", name)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
247
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
248 def emitOptTag(self, name, optTag, isend):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
249 program = self.popProgram() #block
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
250 start = self.popProgram() #start tag
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
251 if (isend or not program) and self.xml:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
252 # Minimize empty element
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
253 start[-1] = ("startEndTag",) + start[-1][1:]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
254 isend = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
255 cexpr = optTag[0]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
256 if cexpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
257 cexpr = self.compileExpression(optTag[0])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
258 self.emit("optTag", name, cexpr, optTag[1], isend, start, program)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
259
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
260 def emitRawText(self, text):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
261 self.emit("rawtext", text)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
262
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
263 def emitText(self, text):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
264 self.emitRawText(cgi.escape(text))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
265
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
266 def emitDefines(self, defines):
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
267 for part in TALDefs.splitParts(defines):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
268 m = re.match(
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
269 r"(?s)\s*(?:(global|local)\s+)?(%s)\s+(.*)\Z" % NAME_RE, part)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
270 if not m:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
271 raise TALError("invalid define syntax: " + `part`,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
272 self.position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
273 scope, name, expr = m.group(1, 2, 3)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
274 scope = scope or "local"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
275 cexpr = self.compileExpression(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
276 if scope == "local":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
277 self.emit("setLocal", name, cexpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
278 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
279 self.emit("setGlobal", name, cexpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
281 def emitOnError(self, name, onError, TALtag, isend):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
282 block = self.popProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
283 key, expr = parseSubstitution(onError)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
284 cexpr = self.compileExpression(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
285 if key == "text":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
286 self.emit("insertText", cexpr, [])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
287 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
288 assert key == "structure"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
289 self.emit("insertStructure", cexpr, {}, [])
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
290 if TALtag:
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
291 self.emitOptTag(name, (None, 1), isend)
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
292 else:
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
293 self.emitEndTag(name)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
294 handler = self.popProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
295 self.emit("onError", block, handler)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
296
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
297 def emitCondition(self, expr):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
298 cexpr = self.compileExpression(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
299 program = self.popProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
300 self.emit("condition", cexpr, program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
301
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
302 def emitRepeat(self, arg):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
303 m = re.match("(?s)\s*(%s)\s+(.*)\Z" % NAME_RE, arg)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
304 if not m:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
305 raise TALError("invalid repeat syntax: " + `arg`,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
306 self.position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
307 name, expr = m.group(1, 2)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
308 cexpr = self.compileExpression(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
309 program = self.popProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
310 self.emit("loop", name, cexpr, program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
311
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
312 def emitSubstitution(self, arg, attrDict={}):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
313 key, expr = parseSubstitution(arg)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
314 cexpr = self.compileExpression(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
315 program = self.popProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
316 if key == "text":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
317 self.emit("insertText", cexpr, program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
318 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
319 assert key == "structure"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
320 self.emit("insertStructure", cexpr, attrDict, program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
321
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
322 def emitI18nVariable(self, stuff):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
323 # Used for i18n:name attributes. arg is extra information describing
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
324 # how the contents of the variable should get filled in, and it will
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
325 # either be a 1-tuple or a 2-tuple. If arg[0] is None, then the
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
326 # i18n:name value is taken implicitly from the contents of the tag,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
327 # e.g. "I live in <span i18n:name="country">the USA</span>". In this
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
328 # case, arg[1] is the opcode sub-program describing the contents of
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
329 # the tag.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
330 #
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
331 # When arg[0] is not None, it contains the tal expression used to
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
332 # calculate the contents of the variable, e.g.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
333 # "I live in <span i18n:name="country"
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
334 # tal:replace="here/countryOfOrigin" />"
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
335 varname, action, expression = stuff
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
336 m = _name_rx.match(varname)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
337 if m is None or m.group() != varname:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
338 raise TALError("illegal i18n:name: %r" % varname, self.position)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
339 key = cexpr = None
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
340 program = self.popProgram()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
341 if action == I18N_REPLACE:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
342 # This is a tag with an i18n:name and a tal:replace (implicit or
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
343 # explicit). Get rid of the first and last elements of the
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
344 # program, which are the start and end tag opcodes of the tag.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
345 program = program[1:-1]
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
346 elif action == I18N_CONTENT:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
347 # This is a tag with an i18n:name and a tal:content
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
348 # (explicit-only). Keep the first and last elements of the
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
349 # program, so we keep the start and end tag output.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
350 pass
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
351 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
352 assert action == I18N_EXPRESSION
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
353 key, expr = parseSubstitution(expression)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
354 cexpr = self.compileExpression(expr)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
355 # XXX Would key be anything but 'text' or None?
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
356 assert key in ('text', None)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
357 self.emit('i18nVariable', varname, program, cexpr)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
358
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
359 def emitTranslation(self, msgid, i18ndata):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
360 program = self.popProgram()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
361 if i18ndata is None:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
362 self.emit('insertTranslation', msgid, program)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
363 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
364 key, expr = parseSubstitution(i18ndata)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
365 cexpr = self.compileExpression(expr)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
366 assert key == 'text'
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
367 self.emit('insertTranslation', msgid, program, cexpr)
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 def emitDefineMacro(self, macroName):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
370 program = self.popProgram()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
371 macroName = macroName.strip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
372 if self.macros.has_key(macroName):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
373 raise METALError("duplicate macro definition: %s" % `macroName`,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
374 self.position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
375 if not re.match('%s$' % NAME_RE, macroName):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
376 raise METALError("invalid macro name: %s" % `macroName`,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
377 self.position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
378 self.macros[macroName] = program
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
379 self.inMacroDef = self.inMacroDef - 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
380 self.emit("defineMacro", macroName, program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
381
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
382 def emitUseMacro(self, expr):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
383 cexpr = self.compileExpression(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
384 program = self.popProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
385 self.inMacroUse = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
386 self.emit("useMacro", expr, cexpr, self.popSlots(), program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
387
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
388 def emitDefineSlot(self, slotName):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
389 program = self.popProgram()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
390 slotName = slotName.strip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
391 if not re.match('%s$' % NAME_RE, slotName):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
392 raise METALError("invalid slot name: %s" % `slotName`,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
393 self.position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
394 self.emit("defineSlot", slotName, program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
395
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
396 def emitFillSlot(self, slotName):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
397 program = self.popProgram()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
398 slotName = slotName.strip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
399 if self.slots.has_key(slotName):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
400 raise METALError("duplicate fill-slot name: %s" % `slotName`,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
401 self.position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
402 if not re.match('%s$' % NAME_RE, slotName):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
403 raise METALError("invalid slot name: %s" % `slotName`,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
404 self.position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
405 self.slots[slotName] = program
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
406 self.inMacroUse = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
407 self.emit("fillSlot", slotName, program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
408
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
409 def unEmitWhitespace(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
410 collect = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
411 i = len(self.program) - 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
412 while i >= 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
413 item = self.program[i]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
414 if item[0] != "rawtext":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
415 break
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
416 text = item[1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
417 if not re.match(r"\A\s*\Z", text):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
418 break
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
419 collect.append(text)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
420 i = i-1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
421 del self.program[i+1:]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
422 if i >= 0 and self.program[i][0] == "rawtext":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
423 text = self.program[i][1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
424 m = re.search(r"\s+\Z", text)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
425 if m:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
426 self.program[i] = ("rawtext", text[:m.start()])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
427 collect.append(m.group())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
428 collect.reverse()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
429 return "".join(collect)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
430
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
431 def unEmitNewlineWhitespace(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
432 collect = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
433 i = len(self.program)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
434 while i > 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
435 i = i-1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
436 item = self.program[i]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
437 if item[0] != "rawtext":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
438 break
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
439 text = item[1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
440 if re.match(r"\A[ \t]*\Z", text):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
441 collect.append(text)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
442 continue
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
443 m = re.match(r"(?s)^(.*)(\n[ \t]*)\Z", text)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
444 if not m:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
445 break
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
446 text, rest = m.group(1, 2)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
447 collect.reverse()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
448 rest = rest + "".join(collect)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
449 del self.program[i:]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
450 if text:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
451 self.emit("rawtext", text)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
452 return rest
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
453 return None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
454
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
455 def replaceAttrs(self, attrlist, repldict):
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
456 # Each entry in attrlist starts like (name, value).
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
457 # Result is (name, value, action, expr, xlat) if there is a
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
458 # tal:attributes entry for that attribute. Additional attrs
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
459 # defined only by tal:attributes are added here.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
460 #
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
461 # (name, value, action, expr, xlat)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
462 if not repldict:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
463 return attrlist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
464 newlist = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
465 for item in attrlist:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
466 key = item[0]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
467 if repldict.has_key(key):
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
468 expr, xlat, msgid = repldict[key]
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
469 item = item[:2] + ("replace", expr, xlat, msgid)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
470 del repldict[key]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
471 newlist.append(item)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
472 # Add dynamic-only attributes
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
473 for key, (expr, xlat, msgid) in repldict.items():
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
474 newlist.append((key, None, "insert", expr, xlat, msgid))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
475 return newlist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
476
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
477 def emitStartElement(self, name, attrlist, taldict, metaldict, i18ndict,
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
478 position=(None, None), isend=0):
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
479 if not taldict and not metaldict and not i18ndict:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
480 # Handle the simple, common case
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
481 self.emitStartTag(name, attrlist, isend)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
482 self.todoPush({})
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
483 if isend:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
484 self.emitEndElement(name, isend)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
485 return
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
486
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
487 self.position = position
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
488 for key, value in taldict.items():
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
489 if key not in TALDefs.KNOWN_TAL_ATTRIBUTES:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
490 raise TALError("bad TAL attribute: " + `key`, position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
491 if not (value or key == 'omit-tag'):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
492 raise TALError("missing value for TAL attribute: " +
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
493 `key`, position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
494 for key, value in metaldict.items():
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
495 if key not in TALDefs.KNOWN_METAL_ATTRIBUTES:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
496 raise METALError("bad METAL attribute: " + `key`,
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
497 position)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
498 if not value:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
499 raise TALError("missing value for METAL attribute: " +
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
500 `key`, position)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
501 for key, value in i18ndict.items():
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
502 if key not in TALDefs.KNOWN_I18N_ATTRIBUTES:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
503 raise I18NError("bad i18n attribute: " + `key`, position)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
504 if not value and key in ("attributes", "data", "id"):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
505 raise I18NError("missing value for i18n attribute: " +
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
506 `key`, position)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
507 todo = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
508 defineMacro = metaldict.get("define-macro")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
509 useMacro = metaldict.get("use-macro")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
510 defineSlot = metaldict.get("define-slot")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
511 fillSlot = metaldict.get("fill-slot")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
512 define = taldict.get("define")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
513 condition = taldict.get("condition")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
514 repeat = taldict.get("repeat")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
515 content = taldict.get("content")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
516 replace = taldict.get("replace")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
517 attrsubst = taldict.get("attributes")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
518 onError = taldict.get("on-error")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
519 omitTag = taldict.get("omit-tag")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
520 TALtag = taldict.get("tal tag")
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
521 i18nattrs = i18ndict.get("attributes")
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
522 # Preserve empty string if implicit msgids are used. We'll generate
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
523 # code with the msgid='' and calculate the right implicit msgid during
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
524 # interpretation phase.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
525 msgid = i18ndict.get("translate")
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
526 varname = i18ndict.get('name')
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
527 i18ndata = i18ndict.get('data')
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
528
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
529 if varname and not self.i18nLevel:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
530 raise I18NError(
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
531 "i18n:name can only occur inside a translation unit",
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
532 position)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
533
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
534 if i18ndata and not msgid:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
535 raise I18NError("i18n:data must be accompanied by i18n:translate",
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
536 position)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
537
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
538 if len(metaldict) > 1 and (defineMacro or useMacro):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
539 raise METALError("define-macro and use-macro cannot be used "
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
540 "together or with define-slot or fill-slot",
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
541 position)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
542 if replace:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
543 if content:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
544 raise TALError(
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
545 "tal:content and tal:replace are mutually exclusive",
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
546 position)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
547 if msgid is not None:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
548 raise I18NError(
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
549 "i18n:translate and tal:replace are mutually exclusive",
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
550 position)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
551
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
552 repeatWhitespace = None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
553 if repeat:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
554 # Hack to include preceding whitespace in the loop program
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
555 repeatWhitespace = self.unEmitNewlineWhitespace()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
556 if position != (None, None):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
557 # XXX at some point we should insist on a non-trivial position
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
558 self.emit("setPosition", position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
559 if self.inMacroUse:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
560 if fillSlot:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
561 self.pushProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
562 if self.source_file is not None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
563 self.emit("setSourceFile", self.source_file)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
564 todo["fillSlot"] = fillSlot
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
565 self.inMacroUse = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
566 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
567 if fillSlot:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
568 raise METALError("fill-slot must be within a use-macro",
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
569 position)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
570 if not self.inMacroUse:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
571 if defineMacro:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
572 self.pushProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
573 self.emit("version", TAL_VERSION)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
574 self.emit("mode", self.xml and "xml" or "html")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
575 if self.source_file is not None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
576 self.emit("setSourceFile", self.source_file)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
577 todo["defineMacro"] = defineMacro
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
578 self.inMacroDef = self.inMacroDef + 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
579 if useMacro:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
580 self.pushSlots()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
581 self.pushProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
582 todo["useMacro"] = useMacro
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
583 self.inMacroUse = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
584 if defineSlot:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
585 if not self.inMacroDef:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
586 raise METALError(
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
587 "define-slot must be within a define-macro",
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
588 position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
589 self.pushProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
590 todo["defineSlot"] = defineSlot
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
591
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
592 if defineSlot or i18ndict:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
593
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
594 domain = i18ndict.get("domain") or self.i18nContext.domain
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
595 source = i18ndict.get("source") or self.i18nContext.source
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
596 target = i18ndict.get("target") or self.i18nContext.target
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
597 if ( domain != DEFAULT_DOMAIN
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
598 or source is not None
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
599 or target is not None):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
600 self.i18nContext = TranslationContext(self.i18nContext,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
601 domain=domain,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
602 source=source,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
603 target=target)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
604 self.emit("beginI18nContext",
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
605 {"domain": domain, "source": source,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
606 "target": target})
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
607 todo["i18ncontext"] = 1
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
608 if taldict or i18ndict:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
609 dict = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
610 for item in attrlist:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
611 key, value = item[:2]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
612 dict[key] = value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
613 self.emit("beginScope", dict)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
614 todo["scope"] = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
615 if onError:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
616 self.pushProgram() # handler
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
617 if TALtag:
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
618 self.pushProgram() # start
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
619 self.emitStartTag(name, list(attrlist)) # Must copy attrlist!
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
620 if TALtag:
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
621 self.pushProgram() # start
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
622 self.pushProgram() # block
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
623 todo["onError"] = onError
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
624 if define:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
625 self.emitDefines(define)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
626 todo["define"] = define
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
627 if condition:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
628 self.pushProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
629 todo["condition"] = condition
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
630 if repeat:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
631 todo["repeat"] = repeat
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
632 self.pushProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
633 if repeatWhitespace:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
634 self.emitText(repeatWhitespace)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
635 if content:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
636 if varname:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
637 todo['i18nvar'] = (varname, I18N_CONTENT, None)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
638 todo["content"] = content
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
639 self.pushProgram()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
640 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
641 todo["content"] = content
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
642 elif replace:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
643 # tal:replace w/ i18n:name has slightly different semantics. What
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
644 # we're actually replacing then is the contents of the ${name}
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
645 # placeholder.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
646 if varname:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
647 todo['i18nvar'] = (varname, I18N_EXPRESSION, replace)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
648 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
649 todo["replace"] = replace
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
650 self.pushProgram()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
651 # i18n:name w/o tal:replace uses the content as the interpolation
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
652 # dictionary values
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
653 elif varname:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
654 todo['i18nvar'] = (varname, I18N_REPLACE, None)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
655 self.pushProgram()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
656 if msgid is not None:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
657 self.i18nLevel += 1
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
658 todo['msgid'] = msgid
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
659 if i18ndata:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
660 todo['i18ndata'] = i18ndata
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
661 optTag = omitTag is not None or TALtag
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
662 if optTag:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
663 todo["optional tag"] = omitTag, TALtag
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
664 self.pushProgram()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
665 if attrsubst or i18nattrs:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
666 if attrsubst:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
667 repldict = TALDefs.parseAttributeReplacements(attrsubst,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
668 self.xml)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
669 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
670 repldict = {}
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
671 if i18nattrs:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
672 i18nattrs = _parseI18nAttributes(i18nattrs, attrlist, repldict,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
673 self.position, self.xml,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
674 self.source_file)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
675 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
676 i18nattrs = {}
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
677 # Convert repldict's name-->expr mapping to a
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
678 # name-->(compiled_expr, translate) mapping
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
679 for key, value in repldict.items():
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
680 if i18nattrs.get(key, None):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
681 raise I18NError(
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
682 ("attribute [%s] cannot both be part of tal:attributes" +
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
683 " and have a msgid in i18n:attributes") % key,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
684 position)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
685 ce = self.compileExpression(value)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
686 repldict[key] = ce, key in i18nattrs, i18nattrs.get(key)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
687 for key in i18nattrs:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
688 if not repldict.has_key(key):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
689 repldict[key] = None, 1, i18nattrs.get(key)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
690 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
691 repldict = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
692 if replace:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
693 todo["repldict"] = repldict
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
694 repldict = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
695 self.emitStartTag(name, self.replaceAttrs(attrlist, repldict), isend)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
696 if optTag:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
697 self.pushProgram()
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
698 if content and not varname:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
699 self.pushProgram()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
700 if msgid is not None:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
701 self.pushProgram()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
702 if content and varname:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
703 self.pushProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
704 if todo and position != (None, None):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
705 todo["position"] = position
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
706 self.todoPush(todo)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
707 if isend:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
708 self.emitEndElement(name, isend)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
709
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
710 def emitEndElement(self, name, isend=0, implied=0):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
711 todo = self.todoPop()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
712 if not todo:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
713 # Shortcut
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
714 if not isend:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
715 self.emitEndTag(name)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
716 return
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
717
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
718 self.position = position = todo.get("position", (None, None))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
719 defineMacro = todo.get("defineMacro")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
720 useMacro = todo.get("useMacro")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
721 defineSlot = todo.get("defineSlot")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
722 fillSlot = todo.get("fillSlot")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
723 repeat = todo.get("repeat")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
724 content = todo.get("content")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
725 replace = todo.get("replace")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
726 condition = todo.get("condition")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
727 onError = todo.get("onError")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
728 define = todo.get("define")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
729 repldict = todo.get("repldict", {})
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
730 scope = todo.get("scope")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
731 optTag = todo.get("optional tag")
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
732 msgid = todo.get('msgid')
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
733 i18ncontext = todo.get("i18ncontext")
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
734 varname = todo.get('i18nvar')
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
735 i18ndata = todo.get('i18ndata')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
736
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
737 if implied > 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
738 if defineMacro or useMacro or defineSlot or fillSlot:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
739 exc = METALError
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
740 what = "METAL"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
741 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
742 exc = TALError
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
743 what = "TAL"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
744 raise exc("%s attributes on <%s> require explicit </%s>" %
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
745 (what, name, name), position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
746
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
747 # If there's no tal:content or tal:replace in the tag with the
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
748 # i18n:name, tal:replace is the default.
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
749 if content:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
750 self.emitSubstitution(content, {})
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
751 # If we're looking at an implicit msgid, emit the insertTranslation
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
752 # opcode now, so that the end tag doesn't become part of the implicit
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
753 # msgid. If we're looking at an explicit msgid, it's better to emit
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
754 # the opcode after the i18nVariable opcode so we can better handle
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
755 # tags with both of them in them (and in the latter case, the contents
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
756 # would be thrown away for msgid purposes).
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
757 #
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
758 # Still, we should emit insertTranslation opcode before i18nVariable
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
759 # in case tal:content, i18n:translate and i18n:name in the same tag
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
760 if msgid is not None:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
761 if (not varname) or (
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
762 varname and (varname[1] == I18N_CONTENT)):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
763 self.emitTranslation(msgid, i18ndata)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
764 self.i18nLevel -= 1
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
765 if optTag:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
766 self.emitOptTag(name, optTag, isend)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
767 elif not isend:
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
768 # If we're processing the end tag for a tag that contained
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
769 # i18n:name, we need to make sure that optimize() won't collect
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
770 # immediately following end tags into the same rawtextOffset, so
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
771 # put a spacer here that the optimizer will recognize.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
772 if varname:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
773 self.emit('noop')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
774 self.emitEndTag(name)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
775 # If i18n:name appeared in the same tag as tal:replace then we're
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
776 # going to do the substitution a little bit differently. The results
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
777 # of the expression go into the i18n substitution dictionary.
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
778 if replace:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
779 self.emitSubstitution(replace, repldict)
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
780 elif varname:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
781 # o varname[0] is the variable name
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
782 # o varname[1] is either
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
783 # - I18N_REPLACE for implicit tal:replace
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
784 # - I18N_CONTENT for tal:content
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
785 # - I18N_EXPRESSION for explicit tal:replace
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
786 # o varname[2] will be None for the first two actions and the
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
787 # replacement tal expression for the third action.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
788 assert (varname[1]
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
789 in [I18N_REPLACE, I18N_CONTENT, I18N_EXPRESSION])
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
790 self.emitI18nVariable(varname)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
791 # Do not test for "msgid is not None", i.e. we only want to test for
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
792 # explicit msgids here. See comment above.
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
793 if msgid is not None:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
794 # in case tal:content, i18n:translate and i18n:name in the
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
795 # same tag insertTranslation opcode has already been
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
796 # emitted
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
797 if varname and (varname[1] <> I18N_CONTENT):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
798 self.emitTranslation(msgid, i18ndata)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
799 if repeat:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
800 self.emitRepeat(repeat)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
801 if condition:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
802 self.emitCondition(condition)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
803 if onError:
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
804 self.emitOnError(name, onError, optTag and optTag[1], isend)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
805 if scope:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
806 self.emit("endScope")
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
807 if i18ncontext:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
808 self.emit("endI18nContext")
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
809 assert self.i18nContext.parent is not None
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
810 self.i18nContext = self.i18nContext.parent
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
811 if defineSlot:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
812 self.emitDefineSlot(defineSlot)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
813 if fillSlot:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
814 self.emitFillSlot(fillSlot)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
815 if useMacro:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
816 self.emitUseMacro(useMacro)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
817 if defineMacro:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
818 self.emitDefineMacro(defineMacro)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
819
2348
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
820
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
821 def _parseI18nAttributes(i18nattrs, attrlist, repldict, position,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
822 xml, source_file):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
823
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
824 def addAttribute(dic, attr, msgid, position, xml):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
825 if not xml:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
826 attr = attr.lower()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
827 if attr in dic:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
828 raise TALError(
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
829 "attribute may only be specified once in i18n:attributes: "
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
830 + attr,
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
831 position)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
832 dic[attr] = msgid
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
833
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
834 d = {}
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
835 if ';' in i18nattrs:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
836 i18nattrlist = i18nattrs.split(';')
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
837 i18nattrlist = [attr.strip().split()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
838 for attr in i18nattrlist if attr.strip()]
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
839 for parts in i18nattrlist:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
840 if len(parts) > 2:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
841 raise TALError("illegal i18n:attributes specification: %r"
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
842 % parts, position)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
843 if len(parts) == 2:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
844 attr, msgid = parts
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
845 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
846 # len(parts) == 1
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
847 attr = parts[0]
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
848 msgid = None
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
849 addAttribute(d, attr, msgid, position, xml)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
850 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
851 i18nattrlist = i18nattrs.split()
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
852 if len(i18nattrlist) == 2:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
853 staticattrs = [attr[0] for attr in attrlist if len(attr) == 2]
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
854 if (not i18nattrlist[1] in staticattrs) and (
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
855 not i18nattrlist[1] in repldict):
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
856 attr, msgid = i18nattrlist
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
857 addAttribute(d, attr, msgid, position, xml)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
858 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
859 msgid = None
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
860 for attr in i18nattrlist:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
861 addAttribute(d, attr, msgid, position, xml)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
862 else:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
863 msgid = None
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
864 for attr in i18nattrlist:
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
865 addAttribute(d, attr, msgid, position, xml)
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
866 return d
8c2402a78bb0 beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
867
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
868 def test():
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
869 t = TALGenerator()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
870 t.pushProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
871 t.emit("bar")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
872 p = t.popProgram()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
873 t.emit("foo", p)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
874
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
875 if __name__ == "__main__":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
876 test()

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