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
The 'comment' tag can be used to simply include comments
in DTML source.
''' # '
__rcs_id__='$Id: DT_Comment.py,v 1.1 1998/03/04 18:19:56 jim Exp $'
For example::
<!--#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
......@@ -61,7 +69,7 @@ __rcs_id__='$Id: DT_Comment.py,v 1.1 1998/03/04 18:19:56 jim Exp $'
# (540) 371-6909
#
############################################################################
__version__='$Revision: 1.1 $'[11:-2]
__version__='$Revision: 1.2 $'[11:-2]
from DT_Util import *
......@@ -81,6 +89,28 @@ class Comment:
############################################################################
# $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
# added comment and raise tags
#
......
......@@ -55,6 +55,8 @@ Two source formats are supported:
is used to insert the variable 'total' with the C format
'12.2f'.
%(Expr)s
%(Var)s
Document templates support conditional and sequence insertion
......@@ -98,8 +100,6 @@ Access Control
object will have an attribute, AUTHENTICATED_USER that is the
user object that was found if and when Bobo authenticated a user.
%(Expr)s
Document Templates may be created 4 ways:
DocumentTemplate.String -- Creates a document templated from a
......
"""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
import DT_Doc, DT_String, regex
......@@ -12,20 +12,21 @@ from string import strip, find
class dtml_re_class:
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)
if s < 0: return s
e=find(text,'-->',s)
if e < 0: return e
n=s+5
if text[n:n+1]=='/':
end=text[n:n+1]
n=n+1
elif text[n:n+3]=='end':
end=text[n:n+3]
n=n+3
else:
end=''
l=end_match(text,n)
if l > 0:
end=strip(text[n:n+l])
n=n+l
else: end=''
l=name_match(text,n)
if l < 0: return l
......@@ -59,14 +60,6 @@ class HTML(DT_String.String):
def tagre(self):
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=''):
"""Parse a tag using an already matched re
......@@ -218,6 +211,28 @@ class HTMLFile(FileMixin, HTML):
##########################################################################
#
# $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
# Removed old validation machinery.
#
......
......@@ -117,8 +117,8 @@ __doc__='''Conditional insertion
# (540) 371-6909
#
############################################################################
__rcs_id__='$Id: DT_If.py,v 1.8 1998/01/14 18:23:42 jim Exp $'
__version__='$Revision: 1.8 $'[11:-2]
__rcs_id__='$Id: DT_If.py,v 1.9 1998/04/02 17:37:35 jim Exp $'
__version__='$Revision: 1.9 $'[11:-2]
from DT_Util import *
import sys
......@@ -135,17 +135,20 @@ class If:
args=parse_params(args, name='', expr='')
name,expr=name_param(args,'if',1)
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':
tname, args, section = blocks[-1]
blocks=blocks[:-1]
del blocks[-1]
args=parse_params(args, name='')
if args:
ename,expr=name_param(args,'else',1)
if ename != name:
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:]:
if tname=='else':
......@@ -153,32 +156,14 @@ class If:
'more than one else tag for a single if tag', 'in')
args=parse_params(args, name='', expr='')
name,expr=name_param(args,'elif',1)
self.sections.append((name, expr, section))
def render(self,md):
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)
if self.elses: return self.elses(None, md)
finally: md._pop(1)
return ''
__call__=render
if expr is None: cond=name
else: cond=expr.eval
sections.append(cond)
sections.append(section.blocks)
if elses is not None: sections.append(elses)
self.simple_form=tuple(sections)
class Unless:
name='unless'
......@@ -188,28 +173,9 @@ class Unless:
tname, args, section = blocks[0]
args=parse_params(args, name='', expr='')
name,expr=name_param(args,'unless',1)
self.__name__ = name
self.section=section
self.expr=expr
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
if expr is None: cond=name
else: cond=expr.eval
self.simple_form=(cond,None,section.blocks)
class Else(Unless):
# The else tag is included for backward compatibility and is deprecated.
......@@ -219,6 +185,28 @@ class Else(Unless):
##########################################################################
#
# $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
# Added expr to unless.
#
......
This diff is collapsed.
This diff is collapsed.
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
from DT_Util import *
......@@ -28,6 +28,7 @@ class String:
'var': DT_Var.Var,
'call': DT_Var.Call,
'in': DT_In.In,
'with': DT_With.With,
'if': DT_If.If,
'unless': DT_If.Unless,
'else': DT_If.Else,
......@@ -108,10 +109,10 @@ class String:
tag, l, args, command)
else:
try:
if command is Var:
result.append(command(args, self.varExtra(tagre)))
else:
result.append(command(args))
if command is Var: r=command(args, self.varExtra(tagre))
else: r=command(args)
if hasattr(r,'simple_form'): r=r.simple_form
result.append(r)
except ParseError, m: self.parse_error(m[0],tag,text,l)
l=tagre.search(text,start)
......@@ -166,8 +167,9 @@ class String:
sstart=start
else:
try:
if scommand is not Comment:
result.append(scommand(blocks))
r=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)
return start
......@@ -365,7 +367,7 @@ class String:
md.level=level+1
if client is not None:
push(InstanceDict(client,md,self.validate)) # Circ. Ref. 8-|
push(InstanceDict(client,md)) # Circ. Ref. 8-|
pushed=pushed+1
if self._vars:
......@@ -377,7 +379,7 @@ class String:
pushed=pushed+1
try:
return render_blocks(self,md)
return render_blocks(self.blocks,md)
finally:
if pushed: md._pop(pushed) # Get rid of circular reference!
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
......@@ -52,7 +52,7 @@
# (540) 371-6909
#
############################################################################
__version__='$Revision: 1.30 $'[11:-2]
__version__='$Revision: 1.31 $'[11:-2]
import sys, regex, string, types, math, os
from string import rfind, strip, joinfields, atoi,lower,upper,capitalize
......@@ -327,8 +327,32 @@ def parse_params(text,
try: from cDocumentTemplate 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 $
# 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
# Changed value of ValidationError to Unauthorized.
#
......
......@@ -105,8 +105,16 @@ __doc__='''Variable insertion parameters
is used. For example, if the value of spam is
'"blah blah blah blah"', then the tag
'<!--#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
......@@ -160,7 +168,7 @@ __rcs_id__='$Id: DT_Var.py,v 1.11 1998/03/24 20:21:39 jim Exp $'
# (540) 371-6909
#
############################################################################
__version__='$Revision: 1.11 $'[11:-2]
__version__='$Revision: 1.12 $'[11:-2]
from DT_Util import *
......@@ -189,6 +197,11 @@ class Var:
self.__name__, self.expr = name, expr
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):
name=self.__name__
val=self.expr
......@@ -259,16 +272,10 @@ class Call:
def __init__(self, args):
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
self.simple_form=expr,None
def render(self, md):
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={},
character_entities=(
......@@ -360,6 +367,28 @@ modifiers=map(lambda f: (f.__name__, f), modifiers)
############################################################################
# $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
# 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 @@
"""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
......@@ -56,7 +56,7 @@ __rcs_id__='$Id: DTtest.py,v 1.3 1997/11/11 18:39:00 jim Exp $'
# (540) 371-6909
#
############################################################################
__version__='$Revision: 1.3 $'[11:-2]
__version__='$Revision: 1.4 $'[11:-2]
from DocumentTemplate import *
import sys
......@@ -121,7 +121,7 @@ def test1():
print ss(aa)
print 'num inaccessible:'
ss.names({'args':'args'})
# ss.names({'args':'args'})
print ss(aa)
print 'quoted source:'
......@@ -408,11 +408,11 @@ def test8():
def test9():
html=HTML(
"""
<!--#in spam-->
<!--#in sequence-item-->
<!--#var sequence-item-->
<!--#/in sequence-item-->
<!--#/in spam-->
<!--#in spam-->
<!--#in sequence-item-->
<!--#var sequence-item-->
<!--#/in sequence-item-->
<!--#/in spam-->
""")
print html(spam=[[1,2,3],[4,5,6]])
......@@ -506,12 +506,6 @@ def main():
print 'Test 6', '='*60
try: test6()
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
try: test9()
except: traceback.print_exc()
......@@ -540,6 +534,28 @@ if __name__ == "__main__":
############################################################################
# $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
# Added test for:
# Made sequence-items work when iterating over mapping items.
......
#!/usr/local/bin/python
# $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__ % {
'In': DT_In.__doc__,
'If': DT_If.__doc__,
'Var': DT_Var.__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__ % {
# (540) 371-6909
#
############################################################################
__version__='$Revision: 1.4 $'[11:-2]
__version__='$Revision: 1.5 $'[11:-2]
ParseError='Document Template Parse Error'
......@@ -73,6 +76,28 @@ from DT_Var import html_quote
############################################################################
# $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
# Cleaned up imports.
#
......
"""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
......@@ -11,7 +11,7 @@ __rcs_id__='$Id: VSEval.py,v 1.11 1998/03/12 21:37:01 jim Exp $'
# rights reserved.
#
############################################################################
__version__='$Revision: 1.11 $'[11:-2]
__version__='$Revision: 1.12 $'[11:-2]
from string import join, find, split, translate
import sys, gparse, string
......@@ -73,6 +73,7 @@ class Eval:
globals -- A global namespace.
"""
self.__name__=expr
expr=translate(expr,nltosp)
self.expr=expr
self.globals=globals
......@@ -131,6 +132,28 @@ compiled_getattr=compile(
############################################################################
#
# $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
# Added _getattr.
#
......
......@@ -58,12 +58,14 @@
__doc__='''Python implementations of document template some features
$Id: pDocumentTemplate.py,v 1.7 1997/11/19 15:42:48 jim Exp $'''
__version__='$Revision: 1.7 $'[11:-2]
$Id: pDocumentTemplate.py,v 1.8 1998/04/02 17:37:40 jim Exp $'''
__version__='$Revision: 1.8 $'[11:-2]
import regex, string
from string import join
StringType=type('')
TupleType=type(())
isFunctionType={}
for name in ['BuiltinFunctionType', 'BuiltinMethodType', 'ClassType',
'FunctionType', 'LambdaType', 'MethodType']:
......@@ -86,6 +88,8 @@ class InstanceDict:
self.self=o
self.cache={}
self.namespace=namespace
if validate is None: self.validate=namespace.validate
else: self.validate=validate
def has_key(self,key):
return hasattr(self.self,key)
......@@ -128,7 +132,7 @@ class MultiMapping:
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):
kz = []
......@@ -140,7 +144,7 @@ class TemplateDict:
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 __init__(self):
......@@ -164,19 +168,86 @@ class TemplateDict:
getitem=__getitem__
def render_blocks(self, md):
def render_blocks(blocks, md):
rendered = []
for section in self.blocks:
if type(section) is not StringType:
append=rendered.append
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)
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
##############################################################################
#
# $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
# 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