Mercurial > p > roundup > code
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 |
| rev | line source |
|---|---|
| 1049 | 1 ############################################################################## |
| 2 # | |
| 3 # Copyright (c) 2001, 2002 Zope Corporation and Contributors. | |
| 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 | 6 # This software is subject to the provisions of the Zope Public License, |
| 7 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. | |
| 8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | |
| 9 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 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 | 13 ############################################################################## |
| 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 | 17 |
| 18 import re | |
| 19 import cgi | |
| 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 | 34 |
| 35 class TALGenerator: | |
| 36 | |
| 37 inMacroUse = 0 | |
| 38 inMacroDef = 0 | |
| 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 | 41 def __init__(self, expressionCompiler=None, xml=1, source_file=None): |
| 42 if not expressionCompiler: | |
| 43 from DummyEngine import DummyEngine | |
| 44 expressionCompiler = DummyEngine() | |
| 45 self.expressionCompiler = expressionCompiler | |
| 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 | 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 | 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 | 56 self.todoStack = [] |
| 57 self.macros = {} | |
| 58 self.slots = {} | |
| 59 self.slotStack = [] | |
| 60 self.xml = xml | |
| 61 self.emit("version", TAL_VERSION) | |
| 62 self.emit("mode", xml and "xml" or "html") | |
| 63 if source_file is not None: | |
| 64 self.source_file = source_file | |
| 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 | 68 |
| 69 def getCode(self): | |
| 70 assert not self.stack | |
| 71 assert not self.todoStack | |
| 72 return self.optimize(self.program), self.macros | |
| 73 | |
| 74 def optimize(self, program): | |
| 75 output = [] | |
| 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 | 78 if self.xml: |
| 79 endsep = "/>" | |
| 80 else: | |
| 81 endsep = " />" | |
| 82 for cursor in xrange(len(program)+1): | |
| 83 try: | |
| 84 item = program[cursor] | |
| 85 except IndexError: | |
| 86 item = (None, None) | |
| 87 opcode = item[0] | |
| 88 if opcode == "rawtext": | |
| 89 collect.append(item[1]) | |
| 90 continue | |
| 91 if opcode == "endTag": | |
| 92 collect.append("</%s>" % item[1]) | |
| 93 continue | |
| 94 if opcode == "startTag": | |
| 95 if self.optimizeStartTag(collect, item[1], item[2], ">"): | |
| 96 continue | |
| 97 if opcode == "startEndTag": | |
| 98 if self.optimizeStartTag(collect, item[1], item[2], endsep): | |
| 99 continue | |
| 100 if opcode in ("beginScope", "endScope"): | |
| 101 # Push *Scope instructions in front of any text instructions; | |
| 102 # this allows text instructions separated only by *Scope | |
| 103 # instructions to be joined together. | |
| 104 output.append(self.optimizeArgsList(item)) | |
| 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 | 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 | 115 if i >= 0: |
| 116 i = len(text) - (i + 1) | |
| 117 output.append(("rawtextColumn", (text, i))) | |
| 118 else: | |
| 119 output.append(("rawtextOffset", (text, len(text)))) | |
| 120 if opcode != None: | |
| 121 output.append(self.optimizeArgsList(item)) | |
| 122 collect = [] | |
| 123 return self.optimizeCommonTriple(output) | |
| 124 | |
| 125 def optimizeArgsList(self, item): | |
| 126 if len(item) == 2: | |
| 127 return item | |
| 128 else: | |
| 129 return item[0], tuple(item[1:]) | |
| 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 | 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 | 153 if not attrlist: |
| 154 collect.append("<%s%s" % (name, end)) | |
| 155 return 1 | |
| 156 opt = 1 | |
| 157 new = ["<" + name] | |
| 158 for i in range(len(attrlist)): | |
| 159 item = attrlist[i] | |
| 160 if len(item) > 2: | |
| 161 opt = 0 | |
| 162 name, value, action = item[:3] | |
| 163 attrlist[i] = (name, value, action) + item[3:] | |
| 164 else: | |
| 165 if item[1] is None: | |
| 166 s = item[0] | |
| 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 | 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 | 172 if opt: |
| 173 new.append(end) | |
| 174 collect.extend(new) | |
| 175 return opt | |
| 176 | |
| 177 def optimizeCommonTriple(self, program): | |
| 178 if len(program) < 3: | |
| 179 return program | |
| 180 output = program[:2] | |
| 181 prev2, prev1 = output | |
| 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 | 186 position = output.pop()[1] |
| 187 text, column = output.pop()[1] | |
| 188 prev1 = None, None | |
| 189 closeprev = 0 | |
| 190 if output and output[-1][0] == "endScope": | |
| 191 closeprev = 1 | |
| 192 output.pop() | |
| 193 item = ("rawtextBeginScope", | |
| 194 (text, column, position, closeprev, item[1])) | |
| 195 output.append(item) | |
| 196 prev2 = prev1 | |
| 197 prev1 = item | |
| 198 return output | |
| 199 | |
| 200 def todoPush(self, todo): | |
| 201 self.todoStack.append(todo) | |
| 202 | |
| 203 def todoPop(self): | |
| 204 return self.todoStack.pop() | |
| 205 | |
| 206 def compileExpression(self, expr): | |
| 207 try: | |
| 208 return self.expressionCompiler.compile(expr) | |
| 209 except self.CompilerError, err: | |
| 210 raise TALError('%s in expression %s' % (err.args[0], `expr`), | |
| 211 self.position) | |
| 212 | |
| 213 def pushProgram(self): | |
| 214 self.stack.append(self.program) | |
| 215 self.program = [] | |
| 216 | |
| 217 def popProgram(self): | |
| 218 program = self.program | |
| 219 self.program = self.stack.pop() | |
| 220 return self.optimize(program) | |
| 221 | |
| 222 def pushSlots(self): | |
| 223 self.slotStack.append(self.slots) | |
| 224 self.slots = {} | |
| 225 | |
| 226 def popSlots(self): | |
| 227 slots = self.slots | |
| 228 self.slots = self.slotStack.pop() | |
| 229 return slots | |
| 230 | |
| 231 def emit(self, *instruction): | |
| 232 self.program.append(instruction) | |
| 233 | |
| 234 def emitStartTag(self, name, attrlist, isend=0): | |
| 235 if isend: | |
| 236 opcode = "startEndTag" | |
| 237 else: | |
| 238 opcode = "startTag" | |
| 239 self.emit(opcode, name, attrlist) | |
| 240 | |
| 241 def emitEndTag(self, name): | |
| 242 if self.xml and self.program and self.program[-1][0] == "startTag": | |
| 243 # Minimize empty element | |
| 244 self.program[-1] = ("startEndTag",) + self.program[-1][1:] | |
| 245 else: | |
| 246 self.emit("endTag", name) | |
| 247 | |
| 248 def emitOptTag(self, name, optTag, isend): | |
| 249 program = self.popProgram() #block | |
| 250 start = self.popProgram() #start tag | |
| 251 if (isend or not program) and self.xml: | |
| 252 # Minimize empty element | |
| 253 start[-1] = ("startEndTag",) + start[-1][1:] | |
| 254 isend = 1 | |
| 255 cexpr = optTag[0] | |
| 256 if cexpr: | |
| 257 cexpr = self.compileExpression(optTag[0]) | |
| 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 | 260 def emitRawText(self, text): |
| 261 self.emit("rawtext", text) | |
| 262 | |
| 263 def emitText(self, text): | |
| 264 self.emitRawText(cgi.escape(text)) | |
| 265 | |
| 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 | 268 m = re.match( |
| 269 r"(?s)\s*(?:(global|local)\s+)?(%s)\s+(.*)\Z" % NAME_RE, part) | |
| 270 if not m: | |
| 271 raise TALError("invalid define syntax: " + `part`, | |
| 272 self.position) | |
| 273 scope, name, expr = m.group(1, 2, 3) | |
| 274 scope = scope or "local" | |
| 275 cexpr = self.compileExpression(expr) | |
| 276 if scope == "local": | |
| 277 self.emit("setLocal", name, cexpr) | |
| 278 else: | |
| 279 self.emit("setGlobal", name, cexpr) | |
| 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 | 282 block = self.popProgram() |
| 283 key, expr = parseSubstitution(onError) | |
| 284 cexpr = self.compileExpression(expr) | |
| 285 if key == "text": | |
| 286 self.emit("insertText", cexpr, []) | |
| 287 else: | |
| 288 assert key == "structure" | |
| 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 | 294 handler = self.popProgram() |
| 295 self.emit("onError", block, handler) | |
| 296 | |
| 297 def emitCondition(self, expr): | |
| 298 cexpr = self.compileExpression(expr) | |
| 299 program = self.popProgram() | |
| 300 self.emit("condition", cexpr, program) | |
| 301 | |
| 302 def emitRepeat(self, arg): | |
| 303 m = re.match("(?s)\s*(%s)\s+(.*)\Z" % NAME_RE, arg) | |
| 304 if not m: | |
| 305 raise TALError("invalid repeat syntax: " + `arg`, | |
| 306 self.position) | |
| 307 name, expr = m.group(1, 2) | |
| 308 cexpr = self.compileExpression(expr) | |
| 309 program = self.popProgram() | |
| 310 self.emit("loop", name, cexpr, program) | |
| 311 | |
| 312 def emitSubstitution(self, arg, attrDict={}): | |
| 313 key, expr = parseSubstitution(arg) | |
| 314 cexpr = self.compileExpression(expr) | |
| 315 program = self.popProgram() | |
| 316 if key == "text": | |
| 317 self.emit("insertText", cexpr, program) | |
| 318 else: | |
| 319 assert key == "structure" | |
| 320 self.emit("insertStructure", cexpr, attrDict, program) | |
| 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 | 369 def emitDefineMacro(self, macroName): |
| 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 | 372 if self.macros.has_key(macroName): |
| 373 raise METALError("duplicate macro definition: %s" % `macroName`, | |
| 374 self.position) | |
| 375 if not re.match('%s$' % NAME_RE, macroName): | |
| 376 raise METALError("invalid macro name: %s" % `macroName`, | |
| 377 self.position) | |
| 378 self.macros[macroName] = program | |
| 379 self.inMacroDef = self.inMacroDef - 1 | |
| 380 self.emit("defineMacro", macroName, program) | |
| 381 | |
| 382 def emitUseMacro(self, expr): | |
| 383 cexpr = self.compileExpression(expr) | |
| 384 program = self.popProgram() | |
| 385 self.inMacroUse = 0 | |
| 386 self.emit("useMacro", expr, cexpr, self.popSlots(), program) | |
| 387 | |
| 388 def emitDefineSlot(self, slotName): | |
| 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 | 391 if not re.match('%s$' % NAME_RE, slotName): |
| 392 raise METALError("invalid slot name: %s" % `slotName`, | |
| 393 self.position) | |
| 394 self.emit("defineSlot", slotName, program) | |
| 395 | |
| 396 def emitFillSlot(self, slotName): | |
| 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 | 399 if self.slots.has_key(slotName): |
| 400 raise METALError("duplicate fill-slot name: %s" % `slotName`, | |
| 401 self.position) | |
| 402 if not re.match('%s$' % NAME_RE, slotName): | |
| 403 raise METALError("invalid slot name: %s" % `slotName`, | |
| 404 self.position) | |
| 405 self.slots[slotName] = program | |
| 406 self.inMacroUse = 1 | |
| 407 self.emit("fillSlot", slotName, program) | |
| 408 | |
| 409 def unEmitWhitespace(self): | |
| 410 collect = [] | |
| 411 i = len(self.program) - 1 | |
| 412 while i >= 0: | |
| 413 item = self.program[i] | |
| 414 if item[0] != "rawtext": | |
| 415 break | |
| 416 text = item[1] | |
| 417 if not re.match(r"\A\s*\Z", text): | |
| 418 break | |
| 419 collect.append(text) | |
| 420 i = i-1 | |
| 421 del self.program[i+1:] | |
| 422 if i >= 0 and self.program[i][0] == "rawtext": | |
| 423 text = self.program[i][1] | |
| 424 m = re.search(r"\s+\Z", text) | |
| 425 if m: | |
| 426 self.program[i] = ("rawtext", text[:m.start()]) | |
| 427 collect.append(m.group()) | |
| 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 | 430 |
| 431 def unEmitNewlineWhitespace(self): | |
| 432 collect = [] | |
| 433 i = len(self.program) | |
| 434 while i > 0: | |
| 435 i = i-1 | |
| 436 item = self.program[i] | |
| 437 if item[0] != "rawtext": | |
| 438 break | |
| 439 text = item[1] | |
| 440 if re.match(r"\A[ \t]*\Z", text): | |
| 441 collect.append(text) | |
| 442 continue | |
| 443 m = re.match(r"(?s)^(.*)(\n[ \t]*)\Z", text) | |
| 444 if not m: | |
| 445 break | |
| 446 text, rest = m.group(1, 2) | |
| 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 | 449 del self.program[i:] |
| 450 if text: | |
| 451 self.emit("rawtext", text) | |
| 452 return rest | |
| 453 return None | |
| 454 | |
| 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 | 462 if not repldict: |
| 463 return attrlist | |
| 464 newlist = [] | |
| 465 for item in attrlist: | |
| 466 key = item[0] | |
| 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 | 470 del repldict[key] |
| 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 | 475 return newlist |
| 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 | 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 | 480 # Handle the simple, common case |
| 481 self.emitStartTag(name, attrlist, isend) | |
| 482 self.todoPush({}) | |
| 483 if isend: | |
| 484 self.emitEndElement(name, isend) | |
| 485 return | |
| 486 | |
| 487 self.position = position | |
| 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 | 490 raise TALError("bad TAL attribute: " + `key`, position) |
| 491 if not (value or key == 'omit-tag'): | |
| 492 raise TALError("missing value for TAL attribute: " + | |
| 493 `key`, position) | |
| 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 | 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 | 498 if not value: |
| 499 raise TALError("missing value for METAL attribute: " + | |
| 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 | 507 todo = {} |
| 508 defineMacro = metaldict.get("define-macro") | |
| 509 useMacro = metaldict.get("use-macro") | |
| 510 defineSlot = metaldict.get("define-slot") | |
| 511 fillSlot = metaldict.get("fill-slot") | |
| 512 define = taldict.get("define") | |
| 513 condition = taldict.get("condition") | |
| 514 repeat = taldict.get("repeat") | |
| 515 content = taldict.get("content") | |
| 516 replace = taldict.get("replace") | |
| 517 attrsubst = taldict.get("attributes") | |
| 518 onError = taldict.get("on-error") | |
| 519 omitTag = taldict.get("omit-tag") | |
| 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 | 538 if len(metaldict) > 1 and (defineMacro or useMacro): |
| 539 raise METALError("define-macro and use-macro cannot be used " | |
| 540 "together or with define-slot or fill-slot", | |
| 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 | 551 |
| 552 repeatWhitespace = None | |
| 553 if repeat: | |
| 554 # Hack to include preceding whitespace in the loop program | |
| 555 repeatWhitespace = self.unEmitNewlineWhitespace() | |
| 556 if position != (None, None): | |
| 557 # XXX at some point we should insist on a non-trivial position | |
| 558 self.emit("setPosition", position) | |
| 559 if self.inMacroUse: | |
| 560 if fillSlot: | |
| 561 self.pushProgram() | |
| 562 if self.source_file is not None: | |
| 563 self.emit("setSourceFile", self.source_file) | |
| 564 todo["fillSlot"] = fillSlot | |
| 565 self.inMacroUse = 0 | |
| 566 else: | |
| 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 | 570 if not self.inMacroUse: |
| 571 if defineMacro: | |
| 572 self.pushProgram() | |
| 573 self.emit("version", TAL_VERSION) | |
| 574 self.emit("mode", self.xml and "xml" or "html") | |
| 575 if self.source_file is not None: | |
| 576 self.emit("setSourceFile", self.source_file) | |
| 577 todo["defineMacro"] = defineMacro | |
| 578 self.inMacroDef = self.inMacroDef + 1 | |
| 579 if useMacro: | |
| 580 self.pushSlots() | |
| 581 self.pushProgram() | |
| 582 todo["useMacro"] = useMacro | |
| 583 self.inMacroUse = 1 | |
| 584 if defineSlot: | |
| 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 | 587 "define-slot must be within a define-macro", |
| 588 position) | |
| 589 self.pushProgram() | |
| 590 todo["defineSlot"] = defineSlot | |
| 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 | 609 dict = {} |
| 610 for item in attrlist: | |
| 611 key, value = item[:2] | |
| 612 dict[key] = value | |
| 613 self.emit("beginScope", dict) | |
| 614 todo["scope"] = 1 | |
| 615 if onError: | |
| 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 | 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 | 622 self.pushProgram() # block |
| 623 todo["onError"] = onError | |
| 624 if define: | |
| 625 self.emitDefines(define) | |
| 626 todo["define"] = define | |
| 627 if condition: | |
| 628 self.pushProgram() | |
| 629 todo["condition"] = condition | |
| 630 if repeat: | |
| 631 todo["repeat"] = repeat | |
| 632 self.pushProgram() | |
| 633 if repeatWhitespace: | |
| 634 self.emitText(repeatWhitespace) | |
| 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 | 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 | 661 optTag = omitTag is not None or TALtag |
| 662 if optTag: | |
| 663 todo["optional tag"] = omitTag, TALtag | |
| 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 | 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 | 690 else: |
| 691 repldict = {} | |
| 692 if replace: | |
| 693 todo["repldict"] = repldict | |
| 694 repldict = {} | |
| 695 self.emitStartTag(name, self.replaceAttrs(attrlist, repldict), isend) | |
| 696 if optTag: | |
| 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 | 703 self.pushProgram() |
| 704 if todo and position != (None, None): | |
| 705 todo["position"] = position | |
| 706 self.todoPush(todo) | |
| 707 if isend: | |
| 708 self.emitEndElement(name, isend) | |
| 709 | |
| 710 def emitEndElement(self, name, isend=0, implied=0): | |
| 711 todo = self.todoPop() | |
| 712 if not todo: | |
| 713 # Shortcut | |
| 714 if not isend: | |
| 715 self.emitEndTag(name) | |
| 716 return | |
| 717 | |
| 718 self.position = position = todo.get("position", (None, None)) | |
| 719 defineMacro = todo.get("defineMacro") | |
| 720 useMacro = todo.get("useMacro") | |
| 721 defineSlot = todo.get("defineSlot") | |
| 722 fillSlot = todo.get("fillSlot") | |
| 723 repeat = todo.get("repeat") | |
| 724 content = todo.get("content") | |
| 725 replace = todo.get("replace") | |
| 726 condition = todo.get("condition") | |
| 727 onError = todo.get("onError") | |
| 728 define = todo.get("define") | |
| 729 repldict = todo.get("repldict", {}) | |
| 730 scope = todo.get("scope") | |
| 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 | 736 |
| 737 if implied > 0: | |
| 738 if defineMacro or useMacro or defineSlot or fillSlot: | |
| 739 exc = METALError | |
| 740 what = "METAL" | |
| 741 else: | |
| 742 exc = TALError | |
| 743 what = "TAL" | |
| 744 raise exc("%s attributes on <%s> require explicit </%s>" % | |
| 745 (what, name, name), position) | |
| 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 | 749 if content: |
| 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 | 765 if optTag: |
| 766 self.emitOptTag(name, optTag, isend) | |
| 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 | 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 | 778 if replace: |
| 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 | 799 if repeat: |
| 800 self.emitRepeat(repeat) | |
| 801 if condition: | |
| 802 self.emitCondition(condition) | |
| 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 | 805 if scope: |
| 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 | 811 if defineSlot: |
| 812 self.emitDefineSlot(defineSlot) | |
| 813 if fillSlot: | |
| 814 self.emitFillSlot(fillSlot) | |
| 815 if useMacro: | |
| 816 self.emitUseMacro(useMacro) | |
| 817 if defineMacro: | |
| 818 self.emitDefineMacro(defineMacro) | |
| 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 | 868 def test(): |
| 869 t = TALGenerator() | |
| 870 t.pushProgram() | |
| 871 t.emit("bar") | |
| 872 p = t.popProgram() | |
| 873 t.emit("foo", p) | |
| 874 | |
| 875 if __name__ == "__main__": | |
| 876 test() |
