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()

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