Package qm :: Package external :: Package DocumentTemplate :: Module pDocumentTemplate
[hide private]
[frames] | no frames]

Source Code for Module qm.external.DocumentTemplate.pDocumentTemplate

  1  ############################################################################## 
  2  #  
  3  # Zope Public License (ZPL) Version 1.0 
  4  # ------------------------------------- 
  5  #  
  6  # Copyright (c) Digital Creations.  All rights reserved. 
  7  #  
  8  # This license has been certified as Open Source(tm). 
  9  #  
 10  # Redistribution and use in source and binary forms, with or without 
 11  # modification, are permitted provided that the following conditions are 
 12  # met: 
 13  #  
 14  # 1. Redistributions in source code must retain the above copyright 
 15  #    notice, this list of conditions, and the following disclaimer. 
 16  #  
 17  # 2. Redistributions in binary form must reproduce the above copyright 
 18  #    notice, this list of conditions, and the following disclaimer in 
 19  #    the documentation and/or other materials provided with the 
 20  #    distribution. 
 21  #  
 22  # 3. Digital Creations requests that attribution be given to Zope 
 23  #    in any manner possible. Zope includes a "Powered by Zope" 
 24  #    button that is installed by default. While it is not a license 
 25  #    violation to remove this button, it is requested that the 
 26  #    attribution remain. A significant investment has been put 
 27  #    into Zope, and this effort will continue if the Zope community 
 28  #    continues to grow. This is one way to assure that growth. 
 29  #  
 30  # 4. All advertising materials and documentation mentioning 
 31  #    features derived from or use of this software must display 
 32  #    the following acknowledgement: 
 33  #  
 34  #      "This product includes software developed by Digital Creations 
 35  #      for use in the Z Object Publishing Environment 
 36  #      (http://www.zope.org/)." 
 37  #  
 38  #    In the event that the product being advertised includes an 
 39  #    intact Zope distribution (with copyright and license included) 
 40  #    then this clause is waived. 
 41  #  
 42  # 5. Names associated with Zope or Digital Creations must not be used to 
 43  #    endorse or promote products derived from this software without 
 44  #    prior written permission from Digital Creations. 
 45  #  
 46  # 6. Modified redistributions of any form whatsoever must retain 
 47  #    the following acknowledgment: 
 48  #  
 49  #      "This product includes software developed by Digital Creations 
 50  #      for use in the Z Object Publishing Environment 
 51  #      (http://www.zope.org/)." 
 52  #  
 53  #    Intact (re-)distributions of any official Zope release do not 
 54  #    require an external acknowledgement. 
 55  #  
 56  # 7. Modifications are encouraged but must be packaged separately as 
 57  #    patches to official Zope releases.  Distributions that do not 
 58  #    clearly separate the patches from the original work must be clearly 
 59  #    labeled as unofficial distributions.  Modifications which do not 
 60  #    carry the name Zope may be packaged in any form, as long as they 
 61  #    conform to all of the clauses above. 
 62  #  
 63  #  
 64  # Disclaimer 
 65  #  
 66  #   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY 
 67  #   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 68  #   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 69  #   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS 
 70  #   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 71  #   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 72  #   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
 73  #   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
 74  #   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
 75  #   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
 76  #   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
 77  #   SUCH DAMAGE. 
 78  #  
 79  #  
 80  # This software consists of contributions made by Digital Creations and 
 81  # many individuals on behalf of Digital Creations.  Specific 
 82  # attributions are listed in the accompanying credits file. 
 83  #  
 84  ############################################################################## 
 85  __doc__='''Python implementations of document template some features 
 86   
 87   
 88  $Id: pDocumentTemplate.py 694 2003-04-16 02:53:50Z sc $''' 
 89  __version__='$Revision: 694 $'[11:-2] 
 90   
 91  import string, sys, types 
 92  from string import join 
 93   
 94  StringType=type('') 
 95  TupleType=type(()) 
 96  isFunctionType={} 
 97  for name in ['BuiltinFunctionType', 'BuiltinMethodType', 'ClassType', 
 98               'FunctionType', 'LambdaType', 'MethodType', 'UnboundMethodType']: 
 99      try: isFunctionType[getattr(types,name)]=1 
100      except: pass 
101   
102  try: # Add function and method types from Extension Classes 
103      import ExtensionClass 
104      isFunctionType[ExtensionClass.PythonMethodType]=1 
105      isFunctionType[ExtensionClass.ExtensionMethodType]=1 
106  except: pass 
107   
108  isFunctionType=isFunctionType.has_key 
109   
110  isSimpleType={} 
111  for n in dir(types): 
112      if (n[-4:]=='Type' and n != 'InstanceType' and 
113          not isFunctionType(getattr(types, n))): 
114          isSimpleType[getattr(types, n)]=1 
115   
116  isSimpleType=isSimpleType.has_key 
117   
118 -class InstanceDict:
119 120 validate=None 121
122 - def __init__(self,o,namespace,validate=None):
123 self.self=o 124 self.cache={} 125 self.namespace=namespace 126 if validate is None: self.validate=namespace.validate 127 else: self.validate=validate
128
129 - def has_key(self,key):
130 return hasattr(self.self,key)
131
132 - def keys(self):
133 return self.self.__dict__.keys()
134
135 - def __repr__(self): return 'InstanceDict(%s)' % str(self.self)
136
137 - def __getitem__(self,key):
138 139 cache=self.cache 140 if cache.has_key(key): return cache[key] 141 142 inst=self.self 143 144 if key[:1]=='_': 145 if key != '__str__': 146 raise KeyError, key # Don't divuldge private data 147 r=str(inst) 148 else: 149 try: r=getattr(inst,key) 150 except AttributeError: raise KeyError, key 151 152 v=self.validate 153 if v is not None: v(inst,inst,key,r,self.namespace) 154 155 self.cache[key]=r 156 return r
157
158 -class MultiMapping:
159
160 - def __init__(self): self.dicts=[]
161
162 - def __getitem__(self, key):
163 for d in self.dicts: 164 try: return d[key] 165 except KeyError, AttributeError: pass 166 raise KeyError, key
167
168 - def push(self,d): self.dicts.insert(0,d)
169
170 - def pop(self, n=1):
171 r = self.dicts[-1] 172 del self.dicts[:n] 173 return r
174
175 - def keys(self):
176 kz = [] 177 for d in self.dicts: 178 kz = kz + d.keys() 179 return kz
180
181 -class DictInstance:
182
183 - def __init__(self, mapping):
184 self.__d=mapping
185
186 - def __getattr__(self, name):
187 try: return self.__d[name] 188 except KeyError: raise AttributeError, name
189
190 -class TemplateDict:
191 192 level=0 193
194 - def _pop(self, n=1): return self.dicts.pop(n)
195 - def _push(self, d): return self.dicts.push(d)
196
197 - def __init__(self):
198 m=self.dicts=MultiMapping() 199 self._pop=m.pop 200 self._push=m.push 201 try: self.keys=m.keys 202 except: pass
203
204 - def __getitem__(self,key,call=1, 205 simple=isSimpleType, 206 isFunctionType=isFunctionType, 207 ):
208 209 v = self.dicts[key] 210 if call: 211 if hasattr(v, '__render_with_namespace__'): 212 return v.__render_with_namespace__(self) 213 vbase = getattr(v, 'aq_base', v) 214 if callable(vbase): 215 if getattr(vbase, 'isDocTemp', None): 216 return v(None, self) 217 return v() 218 return v
219
220 - def has_key(self,key):
221 try: 222 v=self.dicts[key] 223 except KeyError: 224 return 0 225 return 1
226 227 getitem=__getitem__ 228
229 - def __call__(self, *args, **kw):
230 if args: 231 if len(args)==1 and not kw: 232 m=args[0] 233 else: 234 m=self.__class__() 235 for a in args: m._push(a) 236 if kw: m._push(kw) 237 else: m=kw 238 return (DictInstance(m),)
239
240 -def render_blocks(blocks, md):
241 rendered = [] 242 append=rendered.append 243 for section in blocks: 244 if type(section) is TupleType: 245 l=len(section) 246 if l==1: 247 # Simple var 248 section=section[0] 249 if type(section) is StringType: section=md[section] 250 else: section=section(md) 251 section=str(section) 252 else: 253 # if 254 cache={} 255 md._push(cache) 256 try: 257 i=0 258 m=l-1 259 while i < m: 260 cond=section[i] 261 if type(cond) is StringType: 262 n=cond 263 try: 264 cond=md[cond] 265 cache[n]=cond 266 except KeyError, v: 267 v=str(v) 268 if n != v: raise KeyError, v, sys.exc_traceback 269 cond=None 270 else: cond=cond(md) 271 if cond: 272 section=section[i+1] 273 if section: section=render_blocks(section,md) 274 else: section='' 275 m=0 276 break 277 i=i+2 278 if m: 279 if i==m: section=render_blocks(section[i],md) 280 else: section='' 281 282 finally: md._pop() 283 284 elif type(section) is not StringType: 285 section=section(md) 286 287 if section: rendered.append(section) 288 289 l=len(rendered) 290 if l==0: return '' 291 elif l==1: return rendered[0] 292 return join(rendered, '') 293 return rendered
294