Commit 62f52e45 authored by Jim Fulton's avatar Jim Fulton

Major redesign of block rendering. The code inside a block tag is

compiled as a template but only the templates blocks are saved, and
later rendered directly with render_blocks.

Added with tag.

Also, for the HTML syntax, we now allow spaces after # and after end
or '/'.  So, the tags::

  <!--#
    with spam
    -->

and::

  <!--#
    end with
    -->

are valid.
parent 1533bb64
...@@ -6,8 +6,16 @@ __doc__='''Comments ...@@ -6,8 +6,16 @@ __doc__='''Comments
The 'comment' tag can be used to simply include comments The 'comment' tag can be used to simply include comments
in DTML source. in DTML source.
''' # ' For example::
__rcs_id__='$Id: DT_Comment.py,v 1.1 1998/03/04 18:19:56 jim Exp $'
<!--#comment-->
This text is not rendered.
<!--#/comment-->
'''
__rcs_id__='$Id: DT_Comment.py,v 1.2 1998/04/02 17:37:34 jim Exp $'
############################################################################ ############################################################################
# Copyright # Copyright
...@@ -61,7 +69,7 @@ __rcs_id__='$Id: DT_Comment.py,v 1.1 1998/03/04 18:19:56 jim Exp $' ...@@ -61,7 +69,7 @@ __rcs_id__='$Id: DT_Comment.py,v 1.1 1998/03/04 18:19:56 jim Exp $'
# (540) 371-6909 # (540) 371-6909
# #
############################################################################ ############################################################################
__version__='$Revision: 1.1 $'[11:-2] __version__='$Revision: 1.2 $'[11:-2]
from DT_Util import * from DT_Util import *
...@@ -81,6 +89,28 @@ class Comment: ...@@ -81,6 +89,28 @@ class Comment:
############################################################################ ############################################################################
# $Log: DT_Comment.py,v $ # $Log: DT_Comment.py,v $
# Revision 1.2 1998/04/02 17:37:34 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.1 1998/03/04 18:19:56 jim # Revision 1.1 1998/03/04 18:19:56 jim
# added comment and raise tags # added comment and raise tags
# #
......
...@@ -55,6 +55,8 @@ Two source formats are supported: ...@@ -55,6 +55,8 @@ Two source formats are supported:
is used to insert the variable 'total' with the C format is used to insert the variable 'total' with the C format
'12.2f'. '12.2f'.
%(Expr)s
%(Var)s %(Var)s
Document templates support conditional and sequence insertion Document templates support conditional and sequence insertion
...@@ -98,8 +100,6 @@ Access Control ...@@ -98,8 +100,6 @@ Access Control
object will have an attribute, AUTHENTICATED_USER that is the object will have an attribute, AUTHENTICATED_USER that is the
user object that was found if and when Bobo authenticated a user. user object that was found if and when Bobo authenticated a user.
%(Expr)s
Document Templates may be created 4 ways: Document Templates may be created 4 ways:
DocumentTemplate.String -- Creates a document templated from a DocumentTemplate.String -- Creates a document templated from a
......
"""HTML formated DocumentTemplates """HTML formated DocumentTemplates
$Id: DT_HTML.py,v 1.5 1997/10/27 17:35:32 jim Exp $""" $Id: DT_HTML.py,v 1.6 1998/04/02 17:37:35 jim Exp $"""
from DT_String import String, FileMixin from DT_String import String, FileMixin
import DT_Doc, DT_String, regex import DT_Doc, DT_String, regex
...@@ -12,20 +12,21 @@ from string import strip, find ...@@ -12,20 +12,21 @@ from string import strip, find
class dtml_re_class: class dtml_re_class:
def search(self, text, start=0, def search(self, text, start=0,
name_match=regex.compile('[a-zA-Z]+[\0- ]*').match): name_match=regex.compile('[\0- ]*[a-zA-Z]+[\0- ]*').match,
end_match=regex.compile('[\0- ]*\(/\|end\)',
regex.casefold).match,
):
s=find(text,'<!--#',start) s=find(text,'<!--#',start)
if s < 0: return s if s < 0: return s
e=find(text,'-->',s) e=find(text,'-->',s)
if e < 0: return e if e < 0: return e
n=s+5 n=s+5
if text[n:n+1]=='/': l=end_match(text,n)
end=text[n:n+1] if l > 0:
n=n+1 end=strip(text[n:n+l])
elif text[n:n+3]=='end': n=n+l
end=text[n:n+3] else: end=''
n=n+3
else:
end=''
l=name_match(text,n) l=name_match(text,n)
if l < 0: return l if l < 0: return l
...@@ -59,14 +60,6 @@ class HTML(DT_String.String): ...@@ -59,14 +60,6 @@ class HTML(DT_String.String):
def tagre(self): def tagre(self):
return dtml_re_class() return dtml_re_class()
return regex.symcomp(
'<!--#' # beginning
'\(<end>/\|end\)?' # end tag marker
'\(<name>[a-z]+\)' # tag name
'[\0- ]*' # space after tag name
'\(<args>\([^>"]+\("[^"]*"\)?\)*\)' # arguments
'-->' # end
, regex.casefold)
def parseTag(self, tagre, command=None, sargs=''): def parseTag(self, tagre, command=None, sargs=''):
"""Parse a tag using an already matched re """Parse a tag using an already matched re
...@@ -218,6 +211,28 @@ class HTMLFile(FileMixin, HTML): ...@@ -218,6 +211,28 @@ class HTMLFile(FileMixin, HTML):
########################################################################## ##########################################################################
# #
# $Log: DT_HTML.py,v $ # $Log: DT_HTML.py,v $
# Revision 1.6 1998/04/02 17:37:35 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.5 1997/10/27 17:35:32 jim # Revision 1.5 1997/10/27 17:35:32 jim
# Removed old validation machinery. # Removed old validation machinery.
# #
......
...@@ -117,8 +117,8 @@ __doc__='''Conditional insertion ...@@ -117,8 +117,8 @@ __doc__='''Conditional insertion
# (540) 371-6909 # (540) 371-6909
# #
############################################################################ ############################################################################
__rcs_id__='$Id: DT_If.py,v 1.8 1998/01/14 18:23:42 jim Exp $' __rcs_id__='$Id: DT_If.py,v 1.9 1998/04/02 17:37:35 jim Exp $'
__version__='$Revision: 1.8 $'[11:-2] __version__='$Revision: 1.9 $'[11:-2]
from DT_Util import * from DT_Util import *
import sys import sys
...@@ -135,17 +135,20 @@ class If: ...@@ -135,17 +135,20 @@ class If:
args=parse_params(args, name='', expr='') args=parse_params(args, name='', expr='')
name,expr=name_param(args,'if',1) name,expr=name_param(args,'if',1)
self.__name__= name self.__name__= name
self.sections=[(name, expr, section)] if expr is None: cond=name
else: cond=expr.eval
sections=[cond, section.blocks]
if blocks[-1][0]=='else': if blocks[-1][0]=='else':
tname, args, section = blocks[-1] tname, args, section = blocks[-1]
blocks=blocks[:-1] del blocks[-1]
args=parse_params(args, name='') args=parse_params(args, name='')
if args: if args:
ename,expr=name_param(args,'else',1) ename,expr=name_param(args,'else',1)
if ename != name: if ename != name:
raise ParseError, ('name in else does not match if', 'in') raise ParseError, ('name in else does not match if', 'in')
self.elses=section elses=section.blocks
else: elses=None
for tname, args, section in blocks[1:]: for tname, args, section in blocks[1:]:
if tname=='else': if tname=='else':
...@@ -153,32 +156,14 @@ class If: ...@@ -153,32 +156,14 @@ class If:
'more than one else tag for a single if tag', 'in') 'more than one else tag for a single if tag', 'in')
args=parse_params(args, name='', expr='') args=parse_params(args, name='', expr='')
name,expr=name_param(args,'elif',1) name,expr=name_param(args,'elif',1)
self.sections.append((name, expr, section)) if expr is None: cond=name
else: cond=expr.eval
sections.append(cond)
sections.append(section.blocks)
def render(self,md): if elses is not None: sections.append(elses)
cache={}
md._push(cache)
try:
for name, expr, section in self.sections:
if expr is None:
try: v=md[name]
except KeyError, ev:
if ev is not name:
raise KeyError, name, sys.exc_traceback
v=None
cache[name]=v
else:
v=expr.eval(md)
if v: return section(None,md) self.simple_form=tuple(sections)
if self.elses: return self.elses(None, md)
finally: md._pop(1)
return ''
__call__=render
class Unless: class Unless:
name='unless' name='unless'
...@@ -188,28 +173,9 @@ class Unless: ...@@ -188,28 +173,9 @@ class Unless:
tname, args, section = blocks[0] tname, args, section = blocks[0]
args=parse_params(args, name='', expr='') args=parse_params(args, name='', expr='')
name,expr=name_param(args,'unless',1) name,expr=name_param(args,'unless',1)
self.__name__ = name if expr is None: cond=name
self.section=section else: cond=expr.eval
self.expr=expr self.simple_form=(cond,None,section.blocks)
def render(self,md):
name=self.__name__
expr=self.expr
if expr is None:
try: v=md[name]
except KeyError, ev:
if ev is not name: raise KeyError, name, sys.exc_traceback
v=None
if not v:
md._push({name:v})
try: return self.section(None,md)
finally: md._pop(1)
else:
if not expr.eval(md): return self.section(None,md)
return ''
__call__=render
class Else(Unless): class Else(Unless):
# The else tag is included for backward compatibility and is deprecated. # The else tag is included for backward compatibility and is deprecated.
...@@ -219,6 +185,28 @@ class Else(Unless): ...@@ -219,6 +185,28 @@ class Else(Unless):
########################################################################## ##########################################################################
# #
# $Log: DT_If.py,v $ # $Log: DT_If.py,v $
# Revision 1.9 1998/04/02 17:37:35 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.8 1998/01/14 18:23:42 jim # Revision 1.8 1998/01/14 18:23:42 jim
# Added expr to unless. # Added expr to unless.
# #
......
This diff is collapsed.
This diff is collapsed.
from string import * from string import *
import DT_Doc, DT_Var, DT_In, DT_If, regex, DT_Raise import DT_Doc, DT_Var, DT_In, DT_If, regex, DT_Raise, DT_With
Var=DT_Var.Var Var=DT_Var.Var
from DT_Util import * from DT_Util import *
...@@ -28,6 +28,7 @@ class String: ...@@ -28,6 +28,7 @@ class String:
'var': DT_Var.Var, 'var': DT_Var.Var,
'call': DT_Var.Call, 'call': DT_Var.Call,
'in': DT_In.In, 'in': DT_In.In,
'with': DT_With.With,
'if': DT_If.If, 'if': DT_If.If,
'unless': DT_If.Unless, 'unless': DT_If.Unless,
'else': DT_If.Else, 'else': DT_If.Else,
...@@ -108,10 +109,10 @@ class String: ...@@ -108,10 +109,10 @@ class String:
tag, l, args, command) tag, l, args, command)
else: else:
try: try:
if command is Var: if command is Var: r=command(args, self.varExtra(tagre))
result.append(command(args, self.varExtra(tagre))) else: r=command(args)
else: if hasattr(r,'simple_form'): r=r.simple_form
result.append(command(args)) result.append(r)
except ParseError, m: self.parse_error(m[0],tag,text,l) except ParseError, m: self.parse_error(m[0],tag,text,l)
l=tagre.search(text,start) l=tagre.search(text,start)
...@@ -166,8 +167,9 @@ class String: ...@@ -166,8 +167,9 @@ class String:
sstart=start sstart=start
else: else:
try: try:
if scommand is not Comment: r=scommand(blocks)
result.append(scommand(blocks)) if hasattr(r,'simple_form'): r=r.simple_form
result.append(r)
except ParseError, m: self.parse_error(m[0],stag,text,l) except ParseError, m: self.parse_error(m[0],stag,text,l)
return start return start
...@@ -365,7 +367,7 @@ class String: ...@@ -365,7 +367,7 @@ class String:
md.level=level+1 md.level=level+1
if client is not None: if client is not None:
push(InstanceDict(client,md,self.validate)) # Circ. Ref. 8-| push(InstanceDict(client,md)) # Circ. Ref. 8-|
pushed=pushed+1 pushed=pushed+1
if self._vars: if self._vars:
...@@ -377,7 +379,7 @@ class String: ...@@ -377,7 +379,7 @@ class String:
pushed=pushed+1 pushed=pushed+1
try: try:
return render_blocks(self,md) return render_blocks(self.blocks,md)
finally: finally:
if pushed: md._pop(pushed) # Get rid of circular reference! if pushed: md._pop(pushed) # Get rid of circular reference!
md.level=level # Restore previous level md.level=level # Restore previous level
......
'''$Id: DT_Util.py,v 1.30 1998/03/26 22:02:16 jim Exp $''' '''$Id: DT_Util.py,v 1.31 1998/04/02 17:37:37 jim Exp $'''
############################################################################ ############################################################################
# Copyright # Copyright
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
# (540) 371-6909 # (540) 371-6909
# #
############################################################################ ############################################################################
__version__='$Revision: 1.30 $'[11:-2] __version__='$Revision: 1.31 $'[11:-2]
import sys, regex, string, types, math, os import sys, regex, string, types, math, os
from string import rfind, strip, joinfields, atoi,lower,upper,capitalize from string import rfind, strip, joinfields, atoi,lower,upper,capitalize
...@@ -327,8 +327,32 @@ def parse_params(text, ...@@ -327,8 +327,32 @@ def parse_params(text,
try: from cDocumentTemplate import InstanceDict, TemplateDict, render_blocks try: from cDocumentTemplate import InstanceDict, TemplateDict, render_blocks
except: from pDocumentTemplate import InstanceDict, TemplateDict, render_blocks except: from pDocumentTemplate import InstanceDict, TemplateDict, render_blocks
#from cDocumentTemplate import InstanceDict, TemplateDict, render_blocks
############################################################################ ############################################################################
# $Log: DT_Util.py,v $ # $Log: DT_Util.py,v $
# Revision 1.31 1998/04/02 17:37:37 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.30 1998/03/26 22:02:16 jim # Revision 1.30 1998/03/26 22:02:16 jim
# Changed value of ValidationError to Unauthorized. # Changed value of ValidationError to Unauthorized.
# #
......
...@@ -105,8 +105,16 @@ __doc__='''Variable insertion parameters ...@@ -105,8 +105,16 @@ __doc__='''Variable insertion parameters
is used. For example, if the value of spam is is used. For example, if the value of spam is
'"blah blah blah blah"', then the tag '"blah blah blah blah"', then the tag
'<!--#var spam size=10-->' inserts '"blah blah ..."'. '<!--#var spam size=10-->' inserts '"blah blah ..."'.
Evaluating expressions without rendering results
A 'call' tag is provided for evaluating named objects or expressions
without rendering the result.
''' # ' ''' # '
__rcs_id__='$Id: DT_Var.py,v 1.11 1998/03/24 20:21:39 jim Exp $' __rcs_id__='$Id: DT_Var.py,v 1.12 1998/04/02 17:37:38 jim Exp $'
############################################################################ ############################################################################
# Copyright # Copyright
...@@ -160,7 +168,7 @@ __rcs_id__='$Id: DT_Var.py,v 1.11 1998/03/24 20:21:39 jim Exp $' ...@@ -160,7 +168,7 @@ __rcs_id__='$Id: DT_Var.py,v 1.11 1998/03/24 20:21:39 jim Exp $'
# (540) 371-6909 # (540) 371-6909
# #
############################################################################ ############################################################################
__version__='$Revision: 1.11 $'[11:-2] __version__='$Revision: 1.12 $'[11:-2]
from DT_Util import * from DT_Util import *
...@@ -189,6 +197,11 @@ class Var: ...@@ -189,6 +197,11 @@ class Var:
self.__name__, self.expr = name, expr self.__name__, self.expr = name, expr
self.fmt = fmt self.fmt = fmt
if len(args)==1:
if expr is None: expr=name
else: expr=expr.eval
self.simple_form=expr,
def render(self, md): def render(self, md):
name=self.__name__ name=self.__name__
val=self.expr val=self.expr
...@@ -259,16 +272,10 @@ class Call: ...@@ -259,16 +272,10 @@ class Call:
def __init__(self, args): def __init__(self, args):
args = parse_params(args, name='', expr='') args = parse_params(args, name='', expr='')
self.__name__, self.expr = name_param(args,'call',1) name, expr = name_param(args,'call',1)
if expr is None: expr=None
def render(self, md): self.simple_form=expr,None
name=self.__name__
val=self.expr
if val is None: md[name]
else: val.eval(md)
return ''
__call__=render
def html_quote(v, name='(Unknown name)', md={}, def html_quote(v, name='(Unknown name)', md={},
character_entities=( character_entities=(
...@@ -360,6 +367,28 @@ modifiers=map(lambda f: (f.__name__, f), modifiers) ...@@ -360,6 +367,28 @@ modifiers=map(lambda f: (f.__name__, f), modifiers)
############################################################################ ############################################################################
# $Log: DT_Var.py,v $ # $Log: DT_Var.py,v $
# Revision 1.12 1998/04/02 17:37:38 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.11 1998/03/24 20:21:39 jim # Revision 1.11 1998/03/24 20:21:39 jim
# Added 'call' tag. # Added 'call' tag.
# #
......
'''Nested namespace access
The 'with' tag is used to introduce nested namespaces.
The text enclosed in the with tag is rendered using information
from the given variable or expression.
For example, if the variable 'person' is bound to an object that
has attributes 'name' and 'age', then a 'with' tag like the
following can be used to access these attributes::
<!--#with person-->
<!--#var name-->,
<!--#var age-->
<!--#/with-->
Eather a 'name' or an 'expr' attribute may be used to specify data.
A 'mapping' attribute may be used to indicate that the given data
should be treated as mapping object, rather than as an object with
named attributes.
'''
__rcs_id__='$Id: DT_With.py,v 1.1 1998/04/02 17:37:38 jim Exp $'
############################################################################
# Copyright
#
# Copyright 1996 Digital Creations, L.C., 910 Princess Anne
# Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
# rights reserved. Copyright in this software is owned by DCLC,
# unless otherwise indicated. Permission to use, copy and
# distribute this software is hereby granted, provided that the
# above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear. Note that
# any product, process or technology described in this software
# may be the subject of other Intellectual Property rights
# reserved by Digital Creations, L.C. and are not licensed
# hereunder.
#
# Trademarks
#
# Digital Creations & DCLC, are trademarks of Digital Creations, L.C..
# All other trademarks are owned by their respective companies.
#
# No Warranty
#
# The software is provided "as is" without warranty of any kind,
# either express or implied, including, but not limited to, the
# implied warranties of merchantability, fitness for a particular
# purpose, or non-infringement. This software could include
# technical inaccuracies or typographical errors. Changes are
# periodically made to the software; these changes will be
# incorporated in new editions of the software. DCLC may make
# improvements and/or changes in this software at any time
# without notice.
#
# Limitation Of Liability
#
# In no event will DCLC be liable for direct, indirect, special,
# incidental, economic, cover, or consequential damages arising
# out of the use of or inability to use this software even if
# advised of the possibility of such damages. Some states do not
# allow the exclusion or limitation of implied warranties or
# limitation of liability for incidental or consequential
# damages, so the above limitation or exclusion may not apply to
# you.
#
#
# If you have questions regarding this software,
# contact:
#
# Jim Fulton, jim@digicool.com
#
# (540) 371-6909
#
############################################################################
__version__='$Revision: 1.1 $'[11:-2]
from DT_Util import *
class With:
blockContinuations=()
name='with'
mapping=None
def __init__(self, blocks):
tname, args, section = blocks[0]
args=parse_params(args, name='', expr='', mapping=1)
name,expr=name_param(args,'with',1)
if expr is None: expr=name
else: expr=expr.eval
self.__name__, self.expr = name, expr
self.section=section.blocks
if args.has_key('mapping') and args['mapping']: self.mapping=1
def render(self, md):
expr=self.expr
if type(expr) is type(''): v=md[expr]
else: v=expr(md)
if self.mapping: md._push(v)
else:
if type(v) is type(()) and len(v)==1: v=v[0]
md._push(InstanceDict(v,md))
try: return render_blocks(self.section, md)
finally: md._pop(1)
__call__=render
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"""Document Template Tests """Document Template Tests
""" """
__rcs_id__='$Id: DTtest.py,v 1.3 1997/11/11 18:39:00 jim Exp $' __rcs_id__='$Id: DTtest.py,v 1.4 1998/04/02 17:37:38 jim Exp $'
############################################################################ ############################################################################
# Copyright # Copyright
...@@ -56,7 +56,7 @@ __rcs_id__='$Id: DTtest.py,v 1.3 1997/11/11 18:39:00 jim Exp $' ...@@ -56,7 +56,7 @@ __rcs_id__='$Id: DTtest.py,v 1.3 1997/11/11 18:39:00 jim Exp $'
# (540) 371-6909 # (540) 371-6909
# #
############################################################################ ############################################################################
__version__='$Revision: 1.3 $'[11:-2] __version__='$Revision: 1.4 $'[11:-2]
from DocumentTemplate import * from DocumentTemplate import *
import sys import sys
...@@ -121,7 +121,7 @@ def test1(): ...@@ -121,7 +121,7 @@ def test1():
print ss(aa) print ss(aa)
print 'num inaccessible:' print 'num inaccessible:'
ss.names({'args':'args'}) # ss.names({'args':'args'})
print ss(aa) print ss(aa)
print 'quoted source:' print 'quoted source:'
...@@ -408,11 +408,11 @@ def test8(): ...@@ -408,11 +408,11 @@ def test8():
def test9(): def test9():
html=HTML( html=HTML(
""" """
<!--#in spam--> <!--#in spam-->
<!--#in sequence-item--> <!--#in sequence-item-->
<!--#var sequence-item--> <!--#var sequence-item-->
<!--#/in sequence-item--> <!--#/in sequence-item-->
<!--#/in spam--> <!--#/in spam-->
""") """)
print html(spam=[[1,2,3],[4,5,6]]) print html(spam=[[1,2,3],[4,5,6]])
...@@ -506,12 +506,6 @@ def main(): ...@@ -506,12 +506,6 @@ def main():
print 'Test 6', '='*60 print 'Test 6', '='*60
try: test6() try: test6()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 7', '='*60
try: test7()
except: traceback.print_exc()
print 'Test 8', '='*60
try: test8()
except: traceback.print_exc()
print 'Test 9', '='*60 print 'Test 9', '='*60
try: test9() try: test9()
except: traceback.print_exc() except: traceback.print_exc()
...@@ -540,6 +534,28 @@ if __name__ == "__main__": ...@@ -540,6 +534,28 @@ if __name__ == "__main__":
############################################################################ ############################################################################
# $Log: DTtest.py,v $ # $Log: DTtest.py,v $
# Revision 1.4 1998/04/02 17:37:38 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.3 1997/11/11 18:39:00 jim # Revision 1.3 1997/11/11 18:39:00 jim
# Added test for: # Added test for:
# Made sequence-items work when iterating over mapping items. # Made sequence-items work when iterating over mapping items.
......
#!/usr/local/bin/python #!/usr/local/bin/python
# $What$ # $What$
import DT_Doc, DT_Var, DT_In, DT_If, DT_Util import DT_Doc, DT_Var, DT_In, DT_If, DT_Util, DT_Comment, DT_Raise, DT_With
__doc__=DT_Doc.__doc__ % { __doc__=DT_Doc.__doc__ % {
'In': DT_In.__doc__, 'In': DT_In.__doc__,
'If': DT_If.__doc__, 'If': DT_If.__doc__,
'Var': DT_Var.__doc__, 'Var': DT_Var.__doc__,
'Expr': DT_Util.Expr_doc, 'Expr': DT_Util.Expr_doc,
'id': '$Id: DocumentTemplate.py,v 1.4 1997/10/29 22:06:32 jim Exp $' 'Comment': DT_Comment.__doc__,
'Raise': DT_Raise.__doc__,
'With': DT_With.__doc__,
'id': '$Id: DocumentTemplate.py,v 1.5 1998/04/02 17:37:39 jim Exp $'
} }
############################################################################ ############################################################################
...@@ -62,7 +65,7 @@ __doc__=DT_Doc.__doc__ % { ...@@ -62,7 +65,7 @@ __doc__=DT_Doc.__doc__ % {
# (540) 371-6909 # (540) 371-6909
# #
############################################################################ ############################################################################
__version__='$Revision: 1.4 $'[11:-2] __version__='$Revision: 1.5 $'[11:-2]
ParseError='Document Template Parse Error' ParseError='Document Template Parse Error'
...@@ -73,6 +76,28 @@ from DT_Var import html_quote ...@@ -73,6 +76,28 @@ from DT_Var import html_quote
############################################################################ ############################################################################
# $Log: DocumentTemplate.py,v $ # $Log: DocumentTemplate.py,v $
# Revision 1.5 1998/04/02 17:37:39 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.4 1997/10/29 22:06:32 jim # Revision 1.4 1997/10/29 22:06:32 jim
# Cleaned up imports. # Cleaned up imports.
# #
......
"""Very Safe Python Expressions """Very Safe Python Expressions
""" """
__rcs_id__='$Id: VSEval.py,v 1.11 1998/03/12 21:37:01 jim Exp $' __rcs_id__='$Id: VSEval.py,v 1.12 1998/04/02 17:37:39 jim Exp $'
############################################################################ ############################################################################
# Copyright # Copyright
...@@ -11,7 +11,7 @@ __rcs_id__='$Id: VSEval.py,v 1.11 1998/03/12 21:37:01 jim Exp $' ...@@ -11,7 +11,7 @@ __rcs_id__='$Id: VSEval.py,v 1.11 1998/03/12 21:37:01 jim Exp $'
# rights reserved. # rights reserved.
# #
############################################################################ ############################################################################
__version__='$Revision: 1.11 $'[11:-2] __version__='$Revision: 1.12 $'[11:-2]
from string import join, find, split, translate from string import join, find, split, translate
import sys, gparse, string import sys, gparse, string
...@@ -73,6 +73,7 @@ class Eval: ...@@ -73,6 +73,7 @@ class Eval:
globals -- A global namespace. globals -- A global namespace.
""" """
self.__name__=expr
expr=translate(expr,nltosp) expr=translate(expr,nltosp)
self.expr=expr self.expr=expr
self.globals=globals self.globals=globals
...@@ -131,6 +132,28 @@ compiled_getattr=compile( ...@@ -131,6 +132,28 @@ compiled_getattr=compile(
############################################################################ ############################################################################
# #
# $Log: VSEval.py,v $ # $Log: VSEval.py,v $
# Revision 1.12 1998/04/02 17:37:39 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.11 1998/03/12 21:37:01 jim # Revision 1.11 1998/03/12 21:37:01 jim
# Added _getattr. # Added _getattr.
# #
......
...@@ -58,12 +58,14 @@ ...@@ -58,12 +58,14 @@
__doc__='''Python implementations of document template some features __doc__='''Python implementations of document template some features
$Id: pDocumentTemplate.py,v 1.7 1997/11/19 15:42:48 jim Exp $''' $Id: pDocumentTemplate.py,v 1.8 1998/04/02 17:37:40 jim Exp $'''
__version__='$Revision: 1.7 $'[11:-2] __version__='$Revision: 1.8 $'[11:-2]
import regex, string import regex, string
from string import join
StringType=type('') StringType=type('')
TupleType=type(())
isFunctionType={} isFunctionType={}
for name in ['BuiltinFunctionType', 'BuiltinMethodType', 'ClassType', for name in ['BuiltinFunctionType', 'BuiltinMethodType', 'ClassType',
'FunctionType', 'LambdaType', 'MethodType']: 'FunctionType', 'LambdaType', 'MethodType']:
...@@ -86,6 +88,8 @@ class InstanceDict: ...@@ -86,6 +88,8 @@ class InstanceDict:
self.self=o self.self=o
self.cache={} self.cache={}
self.namespace=namespace self.namespace=namespace
if validate is None: self.validate=namespace.validate
else: self.validate=validate
def has_key(self,key): def has_key(self,key):
return hasattr(self.self,key) return hasattr(self.self,key)
...@@ -128,7 +132,7 @@ class MultiMapping: ...@@ -128,7 +132,7 @@ class MultiMapping:
def push(self,d): self.dicts.insert(0,d) def push(self,d): self.dicts.insert(0,d)
def pop(self,n): del self.dicts[:n] def pop(self,n=1): del self.dicts[:n]
def keys(self): def keys(self):
kz = [] kz = []
...@@ -140,7 +144,7 @@ class TemplateDict: ...@@ -140,7 +144,7 @@ class TemplateDict:
level=0 level=0
def _pop(self, n): return self.dicts.pop(n) def _pop(self, n=1): return self.dicts.pop(n)
def _push(self, d): return self.dicts.push(d) def _push(self, d): return self.dicts.push(d)
def __init__(self): def __init__(self):
...@@ -164,19 +168,86 @@ class TemplateDict: ...@@ -164,19 +168,86 @@ class TemplateDict:
getitem=__getitem__ getitem=__getitem__
def render_blocks(self, md): def render_blocks(blocks, md):
rendered = [] rendered = []
for section in self.blocks: append=rendered.append
if type(section) is not StringType: for section in blocks:
if type(section) is TupleType:
l=len(section)
if l==1:
# Simple var
section=section[0]
if type(section) is StringType: section=md[section]
else: section=section(md)
section=str(section)
else:
# if
cache={}
md._push(cache)
try:
i=0
m=l-1
while i < m:
cond=section[i]
if type(cond) is StringType:
n=cond
try:
cond=md[cond]
cache[n]=cond
except KeyError, v:
if n != v: raise KeyError, v, sys.exc_traceback
cond=None
else: cond=section(md)
if cond:
section=section[i+1]
if section: section=render_blocks(section,md)
else: section=''
m=0
break
i=i+2
if m:
if i==m: section=render_blocks(section[i],md)
else: section=''
finally: md._pop()
elif type(section) is not StringType:
section=section(md) section=section(md)
if section: rendered.append(section) if section: rendered.append(section)
rendered=string.join(rendered, '')
l=len(rendered)
if l==0: return ''
elif l==1: return rendered[0]
return join(rendered, '')
return rendered return rendered
############################################################################## ##############################################################################
# #
# $Log: pDocumentTemplate.py,v $ # $Log: pDocumentTemplate.py,v $
# Revision 1.8 1998/04/02 17:37:40 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.7 1997/11/19 15:42:48 jim # Revision 1.7 1997/11/19 15:42:48 jim
# added _ prefix to push and pop methods to make them private # added _ prefix to push and pop methods to make them private
# #
......
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