Mercurial > p > roundup > code
comparison roundup/cgi/TAL/TALDefs.py @ 1049:b9988e118055
moved
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Thu, 05 Sep 2002 00:37:09 +0000 |
| parents | |
| children | fc52d57c6c3e |
comparison
equal
deleted
inserted
replaced
| 1048:1250251f2793 | 1049:b9988e118055 |
|---|---|
| 1 ############################################################################## | |
| 2 # | |
| 3 # Copyright (c) 2001, 2002 Zope Corporation and Contributors. | |
| 4 # All Rights Reserved. | |
| 5 # | |
| 6 # This software is subject to the provisions of the Zope Public License, | |
| 7 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. | |
| 8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | |
| 9 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 10 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | |
| 11 # FOR A PARTICULAR PURPOSE | |
| 12 # | |
| 13 ############################################################################## | |
| 14 """ | |
| 15 Common definitions used by TAL and METAL compilation an transformation. | |
| 16 """ | |
| 17 | |
| 18 from types import ListType, TupleType | |
| 19 | |
| 20 TAL_VERSION = "1.3.2" | |
| 21 | |
| 22 XML_NS = "http://www.w3.org/XML/1998/namespace" # URI for XML namespace | |
| 23 XMLNS_NS = "http://www.w3.org/2000/xmlns/" # URI for XML NS declarations | |
| 24 | |
| 25 ZOPE_TAL_NS = "http://xml.zope.org/namespaces/tal" | |
| 26 ZOPE_METAL_NS = "http://xml.zope.org/namespaces/metal" | |
| 27 | |
| 28 NAME_RE = "[a-zA-Z_][a-zA-Z0-9_]*" | |
| 29 | |
| 30 KNOWN_METAL_ATTRIBUTES = [ | |
| 31 "define-macro", | |
| 32 "use-macro", | |
| 33 "define-slot", | |
| 34 "fill-slot", | |
| 35 "slot" | |
| 36 ] | |
| 37 | |
| 38 KNOWN_TAL_ATTRIBUTES = [ | |
| 39 "define", | |
| 40 "condition", | |
| 41 "content", | |
| 42 "replace", | |
| 43 "repeat", | |
| 44 "attributes", | |
| 45 "on-error", | |
| 46 "omit-tag", | |
| 47 "tal tag", | |
| 48 ] | |
| 49 | |
| 50 class TALError(Exception): | |
| 51 | |
| 52 def __init__(self, msg, position=(None, None)): | |
| 53 assert msg != "" | |
| 54 self.msg = msg | |
| 55 self.lineno = position[0] | |
| 56 self.offset = position[1] | |
| 57 | |
| 58 def __str__(self): | |
| 59 result = self.msg | |
| 60 if self.lineno is not None: | |
| 61 result = result + ", at line %d" % self.lineno | |
| 62 if self.offset is not None: | |
| 63 result = result + ", column %d" % (self.offset + 1) | |
| 64 return result | |
| 65 | |
| 66 class METALError(TALError): | |
| 67 pass | |
| 68 | |
| 69 class TALESError(TALError): | |
| 70 pass | |
| 71 | |
| 72 class ErrorInfo: | |
| 73 | |
| 74 def __init__(self, err, position=(None, None)): | |
| 75 if isinstance(err, Exception): | |
| 76 self.type = err.__class__ | |
| 77 self.value = err | |
| 78 else: | |
| 79 self.type = err | |
| 80 self.value = None | |
| 81 self.lineno = position[0] | |
| 82 self.offset = position[1] | |
| 83 | |
| 84 import re | |
| 85 _attr_re = re.compile(r"\s*([^\s]+)\s+([^\s].*)\Z", re.S) | |
| 86 _subst_re = re.compile(r"\s*(?:(text|structure)\s+)?(.*)\Z", re.S) | |
| 87 del re | |
| 88 | |
| 89 def parseAttributeReplacements(arg): | |
| 90 dict = {} | |
| 91 for part in splitParts(arg): | |
| 92 m = _attr_re.match(part) | |
| 93 if not m: | |
| 94 raise TALError("Bad syntax in attributes:" + `part`) | |
| 95 name, expr = m.group(1, 2) | |
| 96 if dict.has_key(name): | |
| 97 raise TALError("Duplicate attribute name in attributes:" + `part`) | |
| 98 dict[name] = expr | |
| 99 return dict | |
| 100 | |
| 101 def parseSubstitution(arg, position=(None, None)): | |
| 102 m = _subst_re.match(arg) | |
| 103 if not m: | |
| 104 raise TALError("Bad syntax in substitution text: " + `arg`, position) | |
| 105 key, expr = m.group(1, 2) | |
| 106 if not key: | |
| 107 key = "text" | |
| 108 return key, expr | |
| 109 | |
| 110 def splitParts(arg): | |
| 111 # Break in pieces at undoubled semicolons and | |
| 112 # change double semicolons to singles: | |
| 113 import string | |
| 114 arg = string.replace(arg, ";;", "\0") | |
| 115 parts = string.split(arg, ';') | |
| 116 parts = map(lambda s, repl=string.replace: repl(s, "\0", ";"), parts) | |
| 117 if len(parts) > 1 and not string.strip(parts[-1]): | |
| 118 del parts[-1] # It ended in a semicolon | |
| 119 return parts | |
| 120 | |
| 121 def isCurrentVersion(program): | |
| 122 version = getProgramVersion(program) | |
| 123 return version == TAL_VERSION | |
| 124 | |
| 125 def getProgramMode(program): | |
| 126 version = getProgramVersion(program) | |
| 127 if (version == TAL_VERSION and isinstance(program[1], TupleType) and | |
| 128 len(program[1]) == 2): | |
| 129 opcode, mode = program[1] | |
| 130 if opcode == "mode": | |
| 131 return mode | |
| 132 return None | |
| 133 | |
| 134 def getProgramVersion(program): | |
| 135 if (len(program) >= 2 and | |
| 136 isinstance(program[0], TupleType) and len(program[0]) == 2): | |
| 137 opcode, version = program[0] | |
| 138 if opcode == "version": | |
| 139 return version | |
| 140 return None | |
| 141 | |
| 142 import cgi | |
| 143 def quote(s, escape=cgi.escape): | |
| 144 return '"%s"' % escape(s, 1) | |
| 145 del cgi |
