[ZPT] CVS: Packages/TAL - CHANGES.txt:1.7.2.1 HISTORY.txt:1.3.2.1 TALGenerator.py:1.48.2.1
Evan Simpson
evan@zope.com
Tue, 2 Oct 2001 14:20:08 -0400
Update of /cvs-repository/Packages/TAL
In directory cvs.zope.org:/tmp/cvs-serv30568
Modified Files:
Tag: tal-1_4_0
CHANGES.txt HISTORY.txt TALGenerator.py
Log Message:
Bugfixes from trunk
=== Packages/TAL/CHANGES.txt 1.7 => 1.7.2.1 ===
file HISTORY.txt.
- Version 1.4.0
+ Version 1.4.1
- Features Added
-
- - Added TAL statement: omit_tag="[<boolean expr>]" replaces
- the statement tag with its contents if the boolean
- expression is true or omitted.
+ Bugs Fixed
- - The TAL and METAL namespaces can be applied to tag names,
- tags in these namespaces are removed from rendered output
- (leaving the contents in place, as with omit_tag)
- whenever attributes in these namespaces would be, and
- tag attributes without explicit namespaces default to the
- tag's namespace (per XML spec).
+ - tal:on-error was mangling other attributes
- Bugs Fixed
+ - TAL and METAL attributes with blank values were ignored.
+ - METAL statement nesting was not enforced.
=== Packages/TAL/HISTORY.txt 1.3 => 1.3.2.1 ===
in the file CHANGES.txt.
+ Version 1.4.0
+
+ Features Added
+
+ - Added TAL statement: omit_tag="[<boolean expr>]" replaces
+ the statement tag with its contents if the boolean
+ expression is true or omitted.
+
+ - The TAL and METAL namespaces can be applied to tag names,
+ tags in these namespaces are removed from rendered output
+ (leaving the contents in place, as with omit_tag)
+ whenever attributes in these namespaces would be, and
+ tag attributes without explicit namespaces default to the
+ tag's namespace (per XML spec).
+
Version 1.3.3
Bugs Fixed
=== Packages/TAL/TALGenerator.py 1.48 => 1.48.2.1 ===
class TALGenerator:
+ inMacroUse = 0
+ inMacroDef = 0
+
def __init__(self, expressionCompiler=None, xml=1):
if not expressionCompiler:
from DummyEngine import DummyEngine
@@ -334,27 +337,39 @@
def emitDefineMacro(self, macroName, position=(None, None)):
program = self.popProgram()
+ macroName = string.strip(macroName)
if self.macros.has_key(macroName):
- raise METALError("duplicate macro definition: %s" % macroName,
+ raise METALError("duplicate macro definition: %s" % `macroName`,
position)
+ if not re.match('%s$' % NAME_RE, macroName):
+ raise METALError("invalid macro name: %s" % `macroName`, position)
self.macros[macroName] = program
+ self.inMacroDef = self.inMacroDef - 1
self.emit("defineMacro", macroName, program)
def emitUseMacro(self, expr):
cexpr = self.compileExpression(expr)
program = self.popProgram()
+ self.inMacroUse = 0
self.emit("useMacro", expr, cexpr, self.popSlots(), program)
- def emitDefineSlot(self, slotName):
+ def emitDefineSlot(self, slotName, position=(None, None)):
program = self.popProgram()
+ slotName = string.strip(slotName)
+ if not re.match('%s$' % NAME_RE, slotName):
+ raise METALError("invalid slot name: %s" % `slotName`, position)
self.emit("defineSlot", slotName, program)
def emitFillSlot(self, slotName, position=(None, None)):
program = self.popProgram()
+ slotName = string.strip(slotName)
if self.slots.has_key(slotName):
- raise METALError("duplicate fill-slot name: %s" % slotName,
+ raise METALError("duplicate fill-slot name: %s" % `slotName`,
position)
+ if not re.match('%s$' % NAME_RE, slotName):
+ raise METALError("invalid slot name: %s" % `slotName`, position)
self.slots[slotName] = program
+ self.inMacroUse = 1
self.emit("fillSlot", slotName, program)
def unEmitWhitespace(self):
@@ -428,12 +443,19 @@
self.emitEndElement(name, isend)
return
- for key in taldict.keys():
+ for key, value in taldict.items():
if key not in KNOWN_TAL_ATTRIBUTES:
raise TALError("bad TAL attribute: " + `key`, position)
- for key in metaldict.keys():
+ if not (value or key == 'omit-tag'):
+ raise TALError("missing value for TAL attribute: " +
+ `key`, position)
+ for key, value in metaldict.items():
if key not in KNOWN_METAL_ATTRIBUTES:
- raise METALError("bad METAL attribute: " + `key`, position)
+ raise METALError("bad METAL attribute: " + `key`,
+ position)
+ if not value:
+ raise TALError("missing value for METAL attribute: " +
+ `key`, position)
todo = {}
defineMacro = metaldict.get("define-macro")
useMacro = metaldict.get("use-macro")
@@ -463,21 +485,35 @@
if position != (None, None):
# XXX at some point we should insist on a non-trivial position
self.emit("setPosition", position)
- if defineMacro:
- self.pushProgram()
- self.emit("version", TAL_VERSION)
- self.emit("mode", self.xml and "xml" or "html")
- todo["defineMacro"] = defineMacro
- if useMacro:
- self.pushSlots()
- self.pushProgram()
- todo["useMacro"] = useMacro
- if fillSlot:
- self.pushProgram()
- todo["fillSlot"] = fillSlot
- if defineSlot:
- self.pushProgram()
- todo["defineSlot"] = defineSlot
+ if self.inMacroUse:
+ if fillSlot:
+ self.pushProgram()
+ todo["fillSlot"] = fillSlot
+ self.inMacroUse = 0
+ else:
+ if fillSlot:
+ raise METALError, ("fill-slot must be within a use-macro",
+ position)
+ if not self.inMacroUse:
+ if defineMacro:
+ self.pushProgram()
+ self.emit("version", TAL_VERSION)
+ self.emit("mode", self.xml and "xml" or "html")
+ todo["defineMacro"] = defineMacro
+ self.inMacroDef = self.inMacroDef + 1
+ if useMacro:
+ self.pushSlots()
+ self.pushProgram()
+ todo["useMacro"] = useMacro
+ self.inMacroUse = 1
+ if defineSlot:
+ if not self.inMacroDef:
+ raise METALError, (
+ "define-slot must be within a define-macro",
+ position)
+ self.pushProgram()
+ todo["defineSlot"] = defineSlot
+
if taldict:
dict = {}
for item in attrlist:
@@ -487,7 +523,7 @@
todo["scope"] = 1
if onError:
self.pushProgram() # handler
- self.emitStartTag(name, attrlist)
+ self.emitStartTag(name, list(attrlist)) # Must copy attrlist!
self.pushProgram() # block
todo["onError"] = onError
if define:
@@ -580,7 +616,7 @@
if scope:
self.emit("endScope")
if defineSlot:
- self.emitDefineSlot(defineSlot)
+ self.emitDefineSlot(defineSlot, position)
if fillSlot:
self.emitFillSlot(fillSlot, position)
if useMacro: