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

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