Mercurial > p > roundup > code
diff TAL/TALParser.py @ 982:bfd348432420
Adding TAL to the dist
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Fri, 30 Aug 2002 08:23:53 +0000 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TAL/TALParser.py Fri Aug 30 08:23:53 2002 +0000 @@ -0,0 +1,137 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## +""" +Parse XML and compile to TALInterpreter intermediate code. +""" + +import string +from XMLParser import XMLParser +from TALDefs import * +from TALGenerator import TALGenerator + +class TALParser(XMLParser): + + ordered_attributes = 1 + + def __init__(self, gen=None): # Override + XMLParser.__init__(self) + if gen is None: + gen = TALGenerator() + self.gen = gen + self.nsStack = [] + self.nsDict = {XML_NS: 'xml'} + self.nsNew = [] + + def getCode(self): + return self.gen.getCode() + + def getWarnings(self): + return () + + def StartNamespaceDeclHandler(self, prefix, uri): + self.nsStack.append(self.nsDict.copy()) + self.nsDict[uri] = prefix + self.nsNew.append((prefix, uri)) + + def EndNamespaceDeclHandler(self, prefix): + self.nsDict = self.nsStack.pop() + + def StartElementHandler(self, name, attrs): + if self.ordered_attributes: + # attrs is a list of alternating names and values + attrlist = [] + for i in range(0, len(attrs), 2): + key = attrs[i] + value = attrs[i+1] + attrlist.append((key, value)) + else: + # attrs is a dict of {name: value} + attrlist = attrs.items() + attrlist.sort() # For definiteness + name, attrlist, taldict, metaldict = self.process_ns(name, attrlist) + attrlist = self.xmlnsattrs() + attrlist + self.gen.emitStartElement(name, attrlist, taldict, metaldict) + + def process_ns(self, name, attrlist): + taldict = {} + metaldict = {} + fixedattrlist = [] + name, namebase, namens = self.fixname(name) + for key, value in attrlist: + key, keybase, keyns = self.fixname(key) + ns = keyns or namens # default to tag namespace + item = key, value + if ns == 'metal': + metaldict[keybase] = value + item = item + ("metal",) + elif ns == 'tal': + taldict[keybase] = value + item = item + ("tal",) + fixedattrlist.append(item) + if namens in ('metal', 'tal'): + taldict['tal tag'] = namens + return name, fixedattrlist, taldict, metaldict + + def xmlnsattrs(self): + newlist = [] + for prefix, uri in self.nsNew: + if prefix: + key = "xmlns:" + prefix + else: + key = "xmlns" + if uri in (ZOPE_METAL_NS, ZOPE_TAL_NS): + item = (key, uri, "xmlns") + else: + item = (key, uri) + newlist.append(item) + self.nsNew = [] + return newlist + + def fixname(self, name): + if ' ' in name: + uri, name = string.split(name, ' ') + prefix = self.nsDict[uri] + prefixed = name + if prefix: + prefixed = "%s:%s" % (prefix, name) + ns = 'x' + if uri == ZOPE_TAL_NS: + ns = 'tal' + elif uri == ZOPE_METAL_NS: + ns = 'metal' + return (prefixed, name, ns) + return (name, name, None) + + def EndElementHandler(self, name): + name = self.fixname(name)[0] + self.gen.emitEndElement(name) + + def DefaultHandler(self, text): + self.gen.emitRawText(text) + +def test(): + import sys + p = TALParser() + file = "tests/input/test01.xml" + if sys.argv[1:]: + file = sys.argv[1] + p.parseFile(file) + program, macros = p.getCode() + from TALInterpreter import TALInterpreter + from DummyEngine import DummyEngine + engine = DummyEngine(macros) + TALInterpreter(program, macros, engine, sys.stdout, wrap=0)() + +if __name__ == "__main__": + test()
