Mercurial > p > roundup > code
annotate TAL/TALParser.py @ 1029:c3e391d9c4e9
more FieldStorage fun
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Tue, 03 Sep 2002 07:42:38 +0000 |
| parents | bfd348432420 |
| children |
| rev | line source |
|---|---|
|
982
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
1 ############################################################################## |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
2 # |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
3 # Copyright (c) 2001, 2002 Zope Corporation and Contributors. |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
4 # All Rights Reserved. |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
5 # |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
6 # This software is subject to the provisions of the Zope Public License, |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
7 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
9 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
10 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
11 # FOR A PARTICULAR PURPOSE |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
12 # |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
13 ############################################################################## |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
14 """ |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
15 Parse XML and compile to TALInterpreter intermediate code. |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
16 """ |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
17 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
18 import string |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
19 from XMLParser import XMLParser |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
20 from TALDefs import * |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
21 from TALGenerator import TALGenerator |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
22 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
23 class TALParser(XMLParser): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
24 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
25 ordered_attributes = 1 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
26 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
27 def __init__(self, gen=None): # Override |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
28 XMLParser.__init__(self) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
29 if gen is None: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
30 gen = TALGenerator() |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
31 self.gen = gen |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
32 self.nsStack = [] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
33 self.nsDict = {XML_NS: 'xml'} |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
34 self.nsNew = [] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
35 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
36 def getCode(self): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
37 return self.gen.getCode() |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
38 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
39 def getWarnings(self): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
40 return () |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
41 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
42 def StartNamespaceDeclHandler(self, prefix, uri): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
43 self.nsStack.append(self.nsDict.copy()) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
44 self.nsDict[uri] = prefix |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
45 self.nsNew.append((prefix, uri)) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
46 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
47 def EndNamespaceDeclHandler(self, prefix): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
48 self.nsDict = self.nsStack.pop() |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
49 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
50 def StartElementHandler(self, name, attrs): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
51 if self.ordered_attributes: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
52 # attrs is a list of alternating names and values |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
53 attrlist = [] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
54 for i in range(0, len(attrs), 2): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
55 key = attrs[i] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
56 value = attrs[i+1] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
57 attrlist.append((key, value)) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
58 else: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
59 # attrs is a dict of {name: value} |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
60 attrlist = attrs.items() |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
61 attrlist.sort() # For definiteness |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
62 name, attrlist, taldict, metaldict = self.process_ns(name, attrlist) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
63 attrlist = self.xmlnsattrs() + attrlist |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
64 self.gen.emitStartElement(name, attrlist, taldict, metaldict) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
65 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
66 def process_ns(self, name, attrlist): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
67 taldict = {} |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
68 metaldict = {} |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
69 fixedattrlist = [] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
70 name, namebase, namens = self.fixname(name) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
71 for key, value in attrlist: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
72 key, keybase, keyns = self.fixname(key) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
73 ns = keyns or namens # default to tag namespace |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
74 item = key, value |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
75 if ns == 'metal': |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
76 metaldict[keybase] = value |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
77 item = item + ("metal",) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
78 elif ns == 'tal': |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
79 taldict[keybase] = value |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
80 item = item + ("tal",) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
81 fixedattrlist.append(item) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
82 if namens in ('metal', 'tal'): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
83 taldict['tal tag'] = namens |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
84 return name, fixedattrlist, taldict, metaldict |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
85 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
86 def xmlnsattrs(self): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
87 newlist = [] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
88 for prefix, uri in self.nsNew: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
89 if prefix: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
90 key = "xmlns:" + prefix |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
91 else: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
92 key = "xmlns" |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
93 if uri in (ZOPE_METAL_NS, ZOPE_TAL_NS): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
94 item = (key, uri, "xmlns") |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
95 else: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
96 item = (key, uri) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
97 newlist.append(item) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
98 self.nsNew = [] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
99 return newlist |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
100 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
101 def fixname(self, name): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
102 if ' ' in name: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
103 uri, name = string.split(name, ' ') |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
104 prefix = self.nsDict[uri] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
105 prefixed = name |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
106 if prefix: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
107 prefixed = "%s:%s" % (prefix, name) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
108 ns = 'x' |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
109 if uri == ZOPE_TAL_NS: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
110 ns = 'tal' |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
111 elif uri == ZOPE_METAL_NS: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
112 ns = 'metal' |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
113 return (prefixed, name, ns) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
114 return (name, name, None) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
115 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
116 def EndElementHandler(self, name): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
117 name = self.fixname(name)[0] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
118 self.gen.emitEndElement(name) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
119 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
120 def DefaultHandler(self, text): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
121 self.gen.emitRawText(text) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
122 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
123 def test(): |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
124 import sys |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
125 p = TALParser() |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
126 file = "tests/input/test01.xml" |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
127 if sys.argv[1:]: |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
128 file = sys.argv[1] |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
129 p.parseFile(file) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
130 program, macros = p.getCode() |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
131 from TALInterpreter import TALInterpreter |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
132 from DummyEngine import DummyEngine |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
133 engine = DummyEngine(macros) |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
134 TALInterpreter(program, macros, engine, sys.stdout, wrap=0)() |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
135 |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
136 if __name__ == "__main__": |
|
bfd348432420
Adding TAL to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
137 test() |
