annotate roundup/cgi/TAL/TALParser.py @ 1447:6118d4498db3

added "foo@" prefix to all but "context" form variable names
author Richard Jones <richard@users.sourceforge.net>
date Tue, 18 Feb 2003 10:58:33 +0000
parents b9988e118055
children fc52d57c6c3e
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.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 #
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
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
11 # FOR A PARTICULAR PURPOSE
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
12 #
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
13 ##############################################################################
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14 """
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
15 Parse XML and compile to TALInterpreter intermediate code.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
16 """
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
17
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
18 import string
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19 from XMLParser import XMLParser
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20 from TALDefs import *
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
21 from TALGenerator import TALGenerator
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
22
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
23 class TALParser(XMLParser):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
24
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
25 ordered_attributes = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
26
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27 def __init__(self, gen=None): # Override
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
28 XMLParser.__init__(self)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29 if gen is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
30 gen = TALGenerator()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31 self.gen = gen
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32 self.nsStack = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
33 self.nsDict = {XML_NS: 'xml'}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34 self.nsNew = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36 def getCode(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37 return self.gen.getCode()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 def getWarnings(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40 return ()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 def StartNamespaceDeclHandler(self, prefix, uri):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43 self.nsStack.append(self.nsDict.copy())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44 self.nsDict[uri] = prefix
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 self.nsNew.append((prefix, uri))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
47 def EndNamespaceDeclHandler(self, prefix):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 self.nsDict = self.nsStack.pop()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50 def StartElementHandler(self, name, attrs):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51 if self.ordered_attributes:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
52 # attrs is a list of alternating names and values
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53 attrlist = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
54 for i in range(0, len(attrs), 2):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
55 key = attrs[i]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 value = attrs[i+1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
57 attrlist.append((key, value))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
58 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
59 # attrs is a dict of {name: value}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
60 attrlist = attrs.items()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
61 attrlist.sort() # For definiteness
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
62 name, attrlist, taldict, metaldict = self.process_ns(name, attrlist)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
63 attrlist = self.xmlnsattrs() + attrlist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
64 self.gen.emitStartElement(name, attrlist, taldict, metaldict)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
66 def process_ns(self, name, attrlist):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
67 taldict = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68 metaldict = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69 fixedattrlist = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70 name, namebase, namens = self.fixname(name)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
71 for key, value in attrlist:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72 key, keybase, keyns = self.fixname(key)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73 ns = keyns or namens # default to tag namespace
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 item = key, value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
75 if ns == 'metal':
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
76 metaldict[keybase] = value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
77 item = item + ("metal",)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
78 elif ns == 'tal':
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 taldict[keybase] = value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80 item = item + ("tal",)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81 fixedattrlist.append(item)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 if namens in ('metal', 'tal'):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 taldict['tal tag'] = namens
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84 return name, fixedattrlist, taldict, metaldict
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 def xmlnsattrs(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87 newlist = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 for prefix, uri in self.nsNew:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 if prefix:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 key = "xmlns:" + prefix
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 key = "xmlns"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 if uri in (ZOPE_METAL_NS, ZOPE_TAL_NS):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94 item = (key, uri, "xmlns")
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 item = (key, uri)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 newlist.append(item)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 self.nsNew = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 return newlist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 def fixname(self, name):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 if ' ' in name:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 uri, name = string.split(name, ' ')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104 prefix = self.nsDict[uri]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 prefixed = name
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106 if prefix:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107 prefixed = "%s:%s" % (prefix, name)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 ns = 'x'
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109 if uri == ZOPE_TAL_NS:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
110 ns = 'tal'
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111 elif uri == ZOPE_METAL_NS:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112 ns = 'metal'
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 return (prefixed, name, ns)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
114 return (name, name, None)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 def EndElementHandler(self, name):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117 name = self.fixname(name)[0]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118 self.gen.emitEndElement(name)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 def DefaultHandler(self, text):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121 self.gen.emitRawText(text)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 def test():
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124 import sys
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125 p = TALParser()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 file = "tests/input/test01.xml"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 if sys.argv[1:]:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 file = sys.argv[1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 p.parseFile(file)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
130 program, macros = p.getCode()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
131 from TALInterpreter import TALInterpreter
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
132 from DummyEngine import DummyEngine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
133 engine = DummyEngine(macros)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
134 TALInterpreter(program, macros, engine, sys.stdout, wrap=0)()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
135
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
136 if __name__ == "__main__":
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
137 test()

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