Mercurial > p > roundup > code
annotate roundup/cgi/TAL/TALGenerator.py @ 2580:e90d63c7eceb
fixed DateHTMLProperty for invalid date entry [SF#986538]
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Mon, 19 Jul 2004 00:44:01 +0000 |
| 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() |
