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