Commit b907b6dd authored by Guido van Rossum's avatar Guido van Rossum

One step towards refactoring for reuse of the code generation in the

HTML TAL parser.  This moves the "fixing" of the attributes (really
changing them from "<namespace> name" to "<prefix>:name") to the same
loop over the attributes where the presence of unrecognized attributes
is reported, simplifying life later.
parent e353be51
...@@ -89,21 +89,6 @@ Parse XML and compile to TALInterpreter intermediate code. ...@@ -89,21 +89,6 @@ Parse XML and compile to TALInterpreter intermediate code.
import string import string
from XMLParser import XMLParser from XMLParser import XMLParser
from TALDefs import * from TALDefs import *
_metal = ZOPE_METAL_NS + " "
METAL_DEFINE_MACRO = _metal + "define-macro"
METAL_USE_MACRO = _metal + "use-macro"
METAL_DEFINE_SLOT = _metal + "define-slot"
METAL_FILL_SLOT = _metal + "fill-slot"
_tal = ZOPE_TAL_NS + " "
TAL_DEFINE = _tal + "define"
TAL_CONDITION = _tal + "condition"
TAL_INSERT = _tal + "insert"
TAL_REPLACE = _tal + "replace"
TAL_REPEAT = _tal + "repeat"
TAL_ATTRIBUTES = _tal + "attributes"
from TALGenerator import TALGenerator from TALGenerator import TALGenerator
class TALParser(XMLParser): class TALParser(XMLParser):
...@@ -140,30 +125,27 @@ class TALParser(XMLParser): ...@@ -140,30 +125,27 @@ class TALParser(XMLParser):
def StartElementHandler(self, name, attrs): def StartElementHandler(self, name, attrs):
if self.ordered_attributes: if self.ordered_attributes:
# attrs is a list of alternating names and values # attrs is a list of alternating names and values
attrdict = {}
attrlist = [] attrlist = []
for i in range(0, len(attrs), 2): for i in range(0, len(attrs), 2):
key = attrs[i] key = attrs[i]
value = attrs[i+1] value = attrs[i+1]
attrdict[key] = value
attrlist.append((key, value)) attrlist.append((key, value))
else: else:
# attrs is a dict of {name: value} # attrs is a dict of {name: value}
attrdict = attrs
attrlist = attrs.items() attrlist = attrs.items()
attrlist.sort() # For definiteness attrlist.sort() # For definiteness
self.checkattrs(attrlist) attrlist, taldict, metaldict = self.extractattrs(attrlist)
todo = {} todo = {}
defineMacro = attrdict.get(METAL_DEFINE_MACRO) defineMacro = metaldict.get("define-macro")
useMacro = attrdict.get(METAL_USE_MACRO) useMacro = metaldict.get("use-macro")
defineSlot = attrdict.get(METAL_DEFINE_SLOT) defineSlot = metaldict.get("define-slot")
fillSlot = attrdict.get(METAL_FILL_SLOT) fillSlot = metaldict.get("fill-slot")
defines = attrdict.get(TAL_DEFINE) defines = taldict.get("define")
condition = attrdict.get(TAL_CONDITION) condition = taldict.get("condition")
insert = attrdict.get(TAL_INSERT) insert = taldict.get("insert")
replace = attrdict.get(TAL_REPLACE) replace = taldict.get("replace")
repeat = attrdict.get(TAL_REPEAT) repeat = taldict.get("repeat")
attrsubst = attrdict.get(TAL_ATTRIBUTES) attrsubst = taldict.get("attributes")
n = 0 n = 0
if defineMacro: n = n+1 if defineMacro: n = n+1
if useMacro: n = n+1 if useMacro: n = n+1
...@@ -217,31 +199,47 @@ class TALParser(XMLParser): ...@@ -217,31 +199,47 @@ class TALParser(XMLParser):
else: else:
repldict = {} repldict = {}
self.gen.emitStartTag(self.fixname(name), self.gen.emitStartTag(self.fixname(name),
self.fixattrs(attrlist, repldict)) self.replattrs(attrlist, repldict))
if insert: if insert:
self.gen.pushProgram() self.gen.pushProgram()
self.todoPush(todo) self.todoPush(todo)
def checkattrs(self, attrlist): def extractattrs(self, attrlist):
talprefix = _tal talprefix = ZOPE_TAL_NS + " "
ntal = len(talprefix) ntal = len(talprefix)
metalprefix = _metal metalprefix = ZOPE_METAL_NS + " "
nmetal = len(metalprefix) nmetal = len(metalprefix)
taldict = {}
metaldict = {}
fixedattrlist = []
for key, value in attrlist: for key, value in attrlist:
item = self.fixname(key), value
if key[:nmetal] == metalprefix: if key[:nmetal] == metalprefix:
if key[nmetal:] not in KNOWN_METAL_ATTRIBUTES: if key[nmetal:] not in KNOWN_METAL_ATTRIBUTES:
raise METALError( self.attrerror(key, "METAL")
"bad METAL attribute: %s;\nallowed are: %s" % metaldict[key[nmetal:]] = value
(repr(key[nmetal:]), if key[nmetal:] == "define-macro":
string.join(KNOWN_METAL_ATTRIBUTES))) item = item + ("macroHack",)
elif key[:ntal] == talprefix: elif key[:ntal] == talprefix:
if key[ntal:] not in KNOWN_TAL_ATTRIBUTES: if key[ntal:] not in KNOWN_TAL_ATTRIBUTES:
raise TALError( self.attrerror(key, "TAL")
taldict[key[ntal:]] = value
fixedattrlist.append(item)
return fixedattrlist, taldict, metaldict
def attrerror(self, key, mode):
if mode == "METAL":
raise METALError(
"bad METAL attribute: %s;\nallowed are: %s" %
(repr(key[len(ZOPE_METAL_NS)+1:]),
string.join(KNOWN_METAL_ATTRIBUTES)))
if mode == "TAL":
raise TALError(
"bad TAL attribute: %s;\nallowed are: %s" % "bad TAL attribute: %s;\nallowed are: %s" %
(repr(key[ntal:]), (repr(key[len(ZOPE_TAL_NS)+1:]),
string.join(KNOWN_TAL_ATTRIBUTES))) string.join(KNOWN_TAL_ATTRIBUTES)))
def fixattrs(self, attrlist, repldict): def replattrs(self, attrlist, repldict):
newlist = [] newlist = []
for prefix, uri in self.nsNew: for prefix, uri in self.nsNew:
if prefix: if prefix:
...@@ -249,15 +247,13 @@ class TALParser(XMLParser): ...@@ -249,15 +247,13 @@ class TALParser(XMLParser):
else: else:
newlist.append(("xmlns", uri)) newlist.append(("xmlns", uri))
self.nsNew = [] self.nsNew = []
for fullkey, value in attrlist: if not repldict:
key = self.fixname(fullkey) return newlist + attrlist
for item in attrlist:
key = item[0]
if repldict.has_key(key): if repldict.has_key(key):
item = (key, value, "replace", repldict[key]) item = item[:2] + ("replace", repldict[key])
del repldict[key] del repldict[key]
elif fullkey == METAL_DEFINE_MACRO:
item = (key, value, "macroHack")
else:
item = (key, value)
newlist.append(item) newlist.append(item)
for key, value in repldict.items(): # Add dynamic-only attributes for key, value in repldict.items(): # Add dynamic-only attributes
item = (key, "", "replace", value) item = (key, "", "replace", value)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment