Commit cbd3d223 authored by Jim Fulton's avatar Jim Fulton

untabified

parent cad7d8e1
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
"""HTML formated DocumentTemplates """HTML formated DocumentTemplates
$Id: DT_HTML.py,v 1.12 1998/09/14 20:48:39 jim Exp $""" $Id: DT_HTML.py,v 1.13 1998/09/14 22:03:31 jim Exp $"""
from DT_String import String, FileMixin from DT_String import String, FileMixin
import DT_String, regex import DT_String, regex
...@@ -64,48 +64,48 @@ from string import strip, find, split, join, rfind ...@@ -64,48 +64,48 @@ from string import strip, find, split, join, rfind
class dtml_re_class: class dtml_re_class:
def search(self, text, start=0, def search(self, text, start=0,
name_match=regex.compile('[\0- ]*[a-zA-Z]+[\0- ]*').match, name_match=regex.compile('[\0- ]*[a-zA-Z]+[\0- ]*').match,
end_match=regex.compile('[\0- ]*\(/\|end\)', end_match=regex.compile('[\0- ]*\(/\|end\)',
regex.casefold).match, 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
l=end_match(text,n) l=end_match(text,n)
if l > 0: if l > 0:
end=strip(text[n:n+l]) end=strip(text[n:n+l])
n=n+l n=n+l
else: end='' else: end=''
l=name_match(text,n) l=name_match(text,n)
if l < 0: return l if l < 0: return l
a=n+l a=n+l
name=strip(text[n:a]) name=strip(text[n:a])
args=strip(text[a:e]) args=strip(text[a:e])
d=self.__dict__ d=self.__dict__
d[0]=text[s:e+3] d[0]=text[s:e+3]
d[1]=end d[1]=end
d['end']= end d['end']= end
d[2]=name d[2]=name
d['name']=name d['name']=name
d[3]=args d[3]=args
d['args']=args d['args']=args
return s return s
def group(self,*args): def group(self,*args):
g=self.__dict__ g=self.__dict__
if len(args)==1: return g[args[0]] if len(args)==1: return g[args[0]]
r=[] r=[]
for arg in args: for arg in args:
r.append(g[arg]) r.append(g[arg])
return tuple(r) return tuple(r)
class HTML(DT_String.String): class HTML(DT_String.String):
"""HTML Document Templates """HTML Document Templates
...@@ -123,83 +123,83 @@ class HTML(DT_String.String): ...@@ -123,83 +123,83 @@ class HTML(DT_String.String):
""" """
def tagre(self): def tagre(self):
return dtml_re_class() return dtml_re_class()
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
Return: tag, args, command, coname Return: tag, args, command, coname
where: tag is the tag, where: tag is the tag,
args is the tag\'s argument string, args is the tag\'s argument string,
command is a corresponding command info structure if the command is a corresponding command info structure if the
tag is a start tag, or None otherwise, and tag is a start tag, or None otherwise, and
coname is the name of a continue tag (e.g. else) coname is the name of a continue tag (e.g. else)
or None otherwise or None otherwise
""" """
tag, end, name, args, =tagre.group(0, 'end', 'name', 'args') tag, end, name, args, =tagre.group(0, 'end', 'name', 'args')
args=strip(args) args=strip(args)
if end: if end:
if not command or name != command.name: if not command or name != command.name:
raise ParseError, ('unexpected end tag', tag) raise ParseError, ('unexpected end tag', tag)
return tag, args, None, None return tag, args, None, None
if command and name in command.blockContinuations: if command and name in command.blockContinuations:
if name=='else' and args: if name=='else' and args:
# Waaaaaah! Have to special case else because of # Waaaaaah! Have to special case else because of
# old else start tag usage. Waaaaaaah! # old else start tag usage. Waaaaaaah!
l=len(args) l=len(args)
if not (args==sargs or if not (args==sargs or
args==sargs[:l] and sargs[l:l+1] in ' \t\n'): args==sargs[:l] and sargs[l:l+1] in ' \t\n'):
return tag, args, self.commands[name], None return tag, args, self.commands[name], None
return tag, args, None, name return tag, args, None, name
try: return tag, args, self.commands[name], None try: return tag, args, self.commands[name], None
except KeyError: except KeyError:
raise ParseError, ('Unexpected tag', tag) raise ParseError, ('Unexpected tag', tag)
def SubTemplate(self, name): return HTML('', __name__=name) def SubTemplate(self, name): return HTML('', __name__=name)
def varExtra(self,tagre): return 's' def varExtra(self,tagre): return 's'
def manage_edit(self,data,REQUEST=None): def manage_edit(self,data,REQUEST=None):
'edit a template' 'edit a template'
self.munge(data) self.munge(data)
if REQUEST: return self.editConfirmation(self,REQUEST) if REQUEST: return self.editConfirmation(self,REQUEST)
def quotedHTML(self, def quotedHTML(self,
text=None, text=None,
character_entities=( character_entities=(
(('&'), '&amp;'), (('&'), '&amp;'),
(("<"), '&lt;' ), (("<"), '&lt;' ),
((">"), '&gt;' ), ((">"), '&gt;' ),
(('"'), '&quot;'))): #" (('"'), '&quot;'))): #"
if text is None: text=self.read_raw() if text is None: text=self.read_raw()
for re,name in character_entities: for re,name in character_entities:
if find(text, re) >= 0: text=join(split(text,re),name) if find(text, re) >= 0: text=join(split(text,re),name)
return text return text
errQuote=quotedHTML errQuote=quotedHTML
def __str__(self): def __str__(self):
return self.quotedHTML() return self.quotedHTML()
def management_interface(self): def management_interface(self):
'''Hook to allow public execution of management interface with '''Hook to allow public execution of management interface with
everything else private.''' everything else private.'''
return self return self
def manage_editForm(self, PARENT_URL, REQUEST): def manage_editForm(self, PARENT_URL, REQUEST):
'''Display doc template editing form''' #" '''Display doc template editing form''' #"
return self._manage_editForm( return self._manage_editForm(
self, self,
mapping=REQUEST, mapping=REQUEST,
__str__=str(self), __str__=str(self),
PARENT_URL=PARENT_URL PARENT_URL=PARENT_URL
) )
manage_editDocument=manage=manage_editForm manage_editDocument=manage=manage_editForm
...@@ -213,10 +213,10 @@ class HTMLDefault(HTML): ...@@ -213,10 +213,10 @@ class HTMLDefault(HTML):
copy_class=HTML copy_class=HTML
def manage_edit(self,data,PARENTS,URL1,REQUEST): def manage_edit(self,data,PARENTS,URL1,REQUEST):
'edit a template' 'edit a template'
newHTML=self.copy_class(data,self.globals,self.__name__) newHTML=self.copy_class(data,self.globals,self.__name__)
setattr(PARENTS[1],URL1[rfind(URL1,'/')+1:],newHTML) setattr(PARENTS[1],URL1[rfind(URL1,'/')+1:],newHTML)
return self.editConfirmation(self,REQUEST) return self.editConfirmation(self,REQUEST)
class HTMLFile(FileMixin, HTML): class HTMLFile(FileMixin, HTML):
...@@ -231,45 +231,45 @@ class HTMLFile(FileMixin, HTML): ...@@ -231,45 +231,45 @@ class HTMLFile(FileMixin, HTML):
""" """
def manage_default(self, REQUEST=None): def manage_default(self, REQUEST=None):
'Revert to factory defaults' 'Revert to factory defaults'
if self.edited_source: if self.edited_source:
self.edited_source='' self.edited_source=''
self.cooked=self.cook() self.cooked=self.cook()
if REQUEST: return self.editConfirmation(self,REQUEST) if REQUEST: return self.editConfirmation(self,REQUEST)
def manage_editForm(self, PARENT_URL, REQUEST): def manage_editForm(self, PARENT_URL, REQUEST):
'''Display doc template editing form''' '''Display doc template editing form'''
return self._manage_editForm(mapping=REQUEST, return self._manage_editForm(mapping=REQUEST,
document_template_edit_width= document_template_edit_width=
self.document_template_edit_width, self.document_template_edit_width,
document_template_edit_header= document_template_edit_header=
self.document_template_edit_header, self.document_template_edit_header,
document_template_form_header= document_template_form_header=
self.document_template_form_header, self.document_template_form_header,
document_template_edit_footer= document_template_edit_footer=
self.document_template_edit_footer, self.document_template_edit_footer,
PARENT_URL=PARENT_URL, PARENT_URL=PARENT_URL,
__str__=str(self), __str__=str(self),
FactoryDefaultString=FactoryDefaultString, FactoryDefaultString=FactoryDefaultString,
) )
manage_editDocument=manage=manage_editForm manage_editDocument=manage=manage_editForm
def manage_edit(self,data, def manage_edit(self,data,
PARENTS=[],URL1='',URL2='',REQUEST='', SUBMIT=''): PARENTS=[],URL1='',URL2='',REQUEST='', SUBMIT=''):
'edit a template' 'edit a template'
if SUBMIT==FactoryDefaultString: return self.manage_default(REQUEST) if SUBMIT==FactoryDefaultString: return self.manage_default(REQUEST)
if find(data,'\r'): if find(data,'\r'):
data=join(split(data,'\r\n'),'\n\r') data=join(split(data,'\r\n'),'\n\r')
data=join(split(data,'\n\r'),'\n') data=join(split(data,'\n\r'),'\n')
if self.edited_source: if self.edited_source:
self.edited_source=data self.edited_source=data
self.cooked=self.cook() self.cooked=self.cook()
else: else:
__traceback_info__=self.__class__ __traceback_info__=self.__class__
newHTML=self.__class__() newHTML=self.__class__()
newHTML.__setstate__(self.__getstate__()) newHTML.__setstate__(self.__getstate__())
newHTML.edited_source=data newHTML.edited_source=data
setattr(PARENTS[1],URL1[rfind(URL1,'/')+1:],newHTML) setattr(PARENTS[1],URL1[rfind(URL1,'/')+1:],newHTML)
if REQUEST: return self.editConfirmation(self,REQUEST) if REQUEST: return self.editConfirmation(self,REQUEST)
...@@ -117,8 +117,8 @@ __doc__='''Conditional insertion ...@@ -117,8 +117,8 @@ __doc__='''Conditional insertion
variable is not reevaluated. variable is not reevaluated.
''' '''
__rcs_id__='$Id: DT_If.py,v 1.13 1998/09/14 20:48:39 jim Exp $' __rcs_id__='$Id: DT_If.py,v 1.14 1998/09/14 22:03:31 jim Exp $'
__version__='$Revision: 1.13 $'[11:-2] __version__='$Revision: 1.14 $'[11:-2]
from DT_Util import ParseError, parse_params, name_param, str from DT_Util import ParseError, parse_params, name_param, str
...@@ -130,53 +130,52 @@ class If: ...@@ -130,53 +130,52 @@ class If:
def __init__(self, blocks): def __init__(self, blocks):
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,'if',1) name,expr=name_param(args,'if',1)
self.__name__= name self.__name__= name
if expr is None: cond=name if expr is None: cond=name
else: cond=expr.eval else: cond=expr.eval
sections=[cond, section.blocks] sections=[cond, section.blocks]
if blocks[-1][0]=='else': if blocks[-1][0]=='else':
tname, args, section = blocks[-1] tname, args, section = blocks[-1]
del 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')
elses=section.blocks elses=section.blocks
else: elses=None else: elses=None
for tname, args, section in blocks[1:]: for tname, args, section in blocks[1:]:
if tname=='else': if tname=='else':
raise ParseError, ( raise ParseError, (
'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)
if expr is None: cond=name if expr is None: cond=name
else: cond=expr.eval else: cond=expr.eval
sections.append(cond) sections.append(cond)
sections.append(section.blocks) sections.append(section.blocks)
if elses is not None: sections.append(elses) if elses is not None: sections.append(elses)
self.simple_form=tuple(sections) self.simple_form=tuple(sections)
class Unless: class Unless:
name='unless' name='unless'
blockContinuations=() blockContinuations=()
def __init__(self, blocks): def __init__(self, blocks):
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)
if expr is None: cond=name if expr is None: cond=name
else: cond=expr.eval else: cond=expr.eval
self.simple_form=(cond,None,section.blocks) self.simple_form=(cond,None,section.blocks)
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.
name='else' name='else'
...@@ -86,8 +86,8 @@ ...@@ -86,8 +86,8 @@
A more complete case is used as follows:: A more complete case is used as follows::
<!--#in sequence sort=age--> <!--#in sequence sort=age-->
<!--#var sequence-number-->) <!--#var age--> <!--#var sequence-number-->) <!--#var age-->
<!--#/in--> <!--#/in-->
Attributes Attributes
...@@ -100,15 +100,15 @@ ...@@ -100,15 +100,15 @@
'sequence-item' -- The element. 'sequence-item' -- The element.
'sequence-var-nnn' -- The value of a specific named attribute 'sequence-var-nnn' -- The value of a specific named attribute
of the item, where 'nnn' is the name. For example, to get of the item, where 'nnn' is the name. For example, to get
an items 'title' attribute, use 'sequence-var-title'. This an items 'title' attribute, use 'sequence-var-title'. This
construct is most useful in an 'if' tag to test whether an construct is most useful in an 'if' tag to test whether an
attribute is present, because the attribute lookup will be attribute is present, because the attribute lookup will be
extended to the full document template namespace. extended to the full document template namespace.
'sequence-key' -- The key associated with the element in an 'sequence-key' -- The key associated with the element in an
items list. See below. items list. See below.
'sequence-index' -- The index, starting from 0, of the 'sequence-index' -- The index, starting from 0, of the
element within the sequence. element within the sequence.
...@@ -190,9 +190,9 @@ ...@@ -190,9 +190,9 @@
attribute removed. This is extremely useful when attribute removed. This is extremely useful when
building URLs to fetch another batch. building URLs to fetch another batch.
To see how this is used, consider the following example:: To see how this is used, consider the following example::
<!--#in search_results size=20 start=batch_start--> <!--#in search_results size=20 start=batch_start-->
... display rows ... display rows
...@@ -204,18 +204,18 @@ ...@@ -204,18 +204,18 @@
</a> </a>
<!--#/if--> <!--#/if--> <!--#/if--> <!--#/if-->
<!--#/in--> <!--#/in-->
If the original URL is: 'foo/bar?x=1&y=2', then the If the original URL is: 'foo/bar?x=1&y=2', then the
rendered text (after row data are displated) will be:: rendered text (after row data are displated) will be::
<a href="foo/bar?x=1&y=2&batch_start=20"> <a href="foo/bar?x=1&y=2&batch_start=20">
(Next 20 results) (Next 20 results)
</a> </a>
If the original URL is: 'foo/bar?batch_start=10&x=1&y=2', If the original URL is: 'foo/bar?batch_start=10&x=1&y=2',
then the rendered text (after row data are displated) then the rendered text (after row data are displated)
will be:: will be::
<a href="foo/bar?x=1&y=2&batch_start=30"> <a href="foo/bar?x=1&y=2&batch_start=30">
(Next 20 results) (Next 20 results)
...@@ -307,29 +307,29 @@ ...@@ -307,29 +307,29 @@
Currently supported statistic names are: Currently supported statistic names are:
total -- The total of numeric values. total -- The total of numeric values.
count -- The total number of non-missing values. count -- The total number of non-missing values.
min -- The minimum of non-missing values. min -- The minimum of non-missing values.
max -- The maximum of non-missing values. max -- The maximum of non-missing values.
median -- The median of non-missing values. median -- The median of non-missing values.
mean -- The mean of numeric values values. mean -- The mean of numeric values values.
variance -- The variance of numeric values computed with a variance -- The variance of numeric values computed with a
degrees of freedom qeual to the count - 1. degrees of freedom qeual to the count - 1.
variance-n -- The variance of numeric values computed with a variance-n -- The variance of numeric values computed with a
degrees of freedom qeual to the count. degrees of freedom qeual to the count.
standard-deviation -- The standard deviation of numeric values standard-deviation -- The standard deviation of numeric values
computed with a degrees of freedom qeual to the count - 1. computed with a degrees of freedom qeual to the count - 1.
standard-deviation-n -- The standard deviation of numeric standard-deviation-n -- The standard deviation of numeric
values computed with a degrees of freedom qeual to the count. values computed with a degrees of freedom qeual to the count.
Missing values are either 'None' or the attribute 'Value' Missing values are either 'None' or the attribute 'Value'
of the module 'Missing', if present. of the module 'Missing', if present.
...@@ -342,15 +342,15 @@ ...@@ -342,15 +342,15 @@
- The sequence given to the 'in' tag is of zero length, or - The sequence given to the 'in' tag is of zero length, or
- The 'previous' attribute was used and their are no - The 'previous' attribute was used and their are no
previous batches, or previous batches, or
- The 'next' attribute was used and their are no - The 'next' attribute was used and their are no
next batches, or next batches, or
''' #' ''' #'
__rcs_id__='$Id: DT_In.py,v 1.29 1998/09/14 20:48:40 jim Exp $' __rcs_id__='$Id: DT_In.py,v 1.30 1998/09/14 22:03:32 jim Exp $'
__version__='$Revision: 1.29 $'[11:-2] __version__='$Revision: 1.30 $'[11:-2]
from DT_Util import ParseError, parse_params, name_param, str from DT_Util import ParseError, parse_params, name_param, str
from DT_Util import render_blocks, InstanceDict from DT_Util import render_blocks, InstanceDict
...@@ -364,9 +364,9 @@ class InFactory: ...@@ -364,9 +364,9 @@ class InFactory:
name='in' name='in'
def __call__(self, blocks): def __call__(self, blocks):
i=InClass(blocks) i=InClass(blocks)
if i.batch: return i.renderwb if i.batch: return i.renderwb
else: return i.renderwob else: return i.renderwob
In=InFactory() In=InFactory()
...@@ -376,143 +376,143 @@ class InClass: ...@@ -376,143 +376,143 @@ class InClass:
start_name_re=None start_name_re=None
def __init__(self, blocks): def __init__(self, blocks):
tname, args, section = blocks[0] tname, args, section = blocks[0]
args=parse_params(args, name='', start='1',end='-1',size='10', args=parse_params(args, name='', start='1',end='-1',size='10',
orphan='3',overlap='1',mapping=1, orphan='3',overlap='1',mapping=1,
skip_unauthorized=1, skip_unauthorized=1,
previous=1, next=1, expr='', sort='') previous=1, next=1, expr='', sort='')
self.args=args self.args=args
has_key=args.has_key has_key=args.has_key
if has_key('sort'): self.sort=args['sort'] if has_key('sort'): self.sort=args['sort']
if has_key('mapping'): self.mapping=args['mapping'] if has_key('mapping'): self.mapping=args['mapping']
for n in 'start', 'size', 'end': for n in 'start', 'size', 'end':
if has_key(n): self.batch=1 if has_key(n): self.batch=1
for n in 'orphan','overlap','previous','next': for n in 'orphan','overlap','previous','next':
if has_key(n) and not self.batch: if has_key(n) and not self.batch:
raise ParseError, ( raise ParseError, (
""" """
The %s attribute was used but neither of the The %s attribute was used but neither of the
<code>start</code>, <code>end</code>, or <code>size</code> <code>start</code>, <code>end</code>, or <code>size</code>
attributes were used. attributes were used.
""" % n, 'in') """ % n, 'in')
if has_key('start'): if has_key('start'):
v=args['start'] v=args['start']
if type(v)==type(''): if type(v)==type(''):
try: atoi(v) try: atoi(v)
except: except:
self.start_name_re=ts_regex.compile( self.start_name_re=ts_regex.compile(
'&+'+ '&+'+
join(map(lambda c: "[%s]" % c, v),'')+ join(map(lambda c: "[%s]" % c, v),'')+
'=[0-9]+&+') '=[0-9]+&+')
name,expr=name_param(args,'in',1) name,expr=name_param(args,'in',1)
if expr is not None: expr=expr.eval if expr is not None: expr=expr.eval
self.__name__, self.expr = name, expr self.__name__, self.expr = name, expr
self.section=section.blocks self.section=section.blocks
if len(blocks) > 1: if len(blocks) > 1:
if len(blocks) != 2: raise ParseError, ( if len(blocks) != 2: raise ParseError, (
'too many else blocks', 'in') 'too many else blocks', 'in')
tname, args, section = blocks[1] tname, args, section = blocks[1]
args=parse_params(args, name='') args=parse_params(args, name='')
if args: if args:
ename=name_param(args) ename=name_param(args)
if ename != name: if ename != name:
raise ParseError, ( raise ParseError, (
'name in else does not match in', 'in') 'name in else does not match in', 'in')
self.elses=section.blocks self.elses=section.blocks
def renderwb(self, md): def renderwb(self, md):
expr=self.expr expr=self.expr
name=self.__name__ name=self.__name__
if expr is None: if expr is None:
sequence=md[name] sequence=md[name]
cache={ name: sequence } cache={ name: sequence }
else: else:
sequence=expr(md) sequence=expr(md)
cache=None cache=None
if not sequence: if not sequence:
if self.elses: return render_blocks(self.elses, md) if self.elses: return render_blocks(self.elses, md)
return '' return ''
section=self.section section=self.section
params=self.args params=self.args
mapping=self.mapping mapping=self.mapping
if self.sort is not None: sequence=self.sort_sequence(sequence) if self.sort is not None: sequence=self.sort_sequence(sequence)
next=previous=0 next=previous=0
try: start=int_param(params,md,'start',0) try: start=int_param(params,md,'start',0)
except: start=1 except: start=1
end=int_param(params,md,'end',0) end=int_param(params,md,'end',0)
size=int_param(params,md,'size',0) size=int_param(params,md,'size',0)
overlap=int_param(params,md,'overlap',0) overlap=int_param(params,md,'overlap',0)
orphan=int_param(params,md,'orphan','3') orphan=int_param(params,md,'orphan','3')
start,end,sz=opt(start,end,size,orphan,sequence) start,end,sz=opt(start,end,size,orphan,sequence)
if params.has_key('next'): next=1 if params.has_key('next'): next=1
if params.has_key('previous'): previous=1 if params.has_key('previous'): previous=1
last=end-1 last=end-1
first=start-1 first=start-1
try: query_string=md['QUERY_STRING'] try: query_string=md['QUERY_STRING']
except: query_string='' except: query_string=''
vars=sequence_variables(sequence,'?'+query_string,self.start_name_re) vars=sequence_variables(sequence,'?'+query_string,self.start_name_re)
kw=vars.data kw=vars.data
kw['mapping']=mapping kw['mapping']=mapping
kw['sequence-step-size']=sz kw['sequence-step-size']=sz
kw['sequence-step-overlap']=overlap kw['sequence-step-overlap']=overlap
kw['sequence-step-start']=start kw['sequence-step-start']=start
kw['sequence-step-end']=end kw['sequence-step-end']=end
kw['sequence-step-start-index']=start-1 kw['sequence-step-start-index']=start-1
kw['sequence-step-end-index']=end-1 kw['sequence-step-end-index']=end-1
kw['sequence-step-orphan']=orphan kw['sequence-step-orphan']=orphan
push=md._push push=md._push
pop=md._pop pop=md._pop
render=render_blocks render=render_blocks
if cache: push(cache) if cache: push(cache)
push(vars) push(vars)
try: try:
if previous: if previous:
if first > 0: if first > 0:
pstart,pend,psize=opt(None,first+overlap, pstart,pend,psize=opt(None,first+overlap,
sz,orphan,sequence) sz,orphan,sequence)
kw['previous-sequence']=1 kw['previous-sequence']=1
kw['previous-sequence-start-index']=pstart-1 kw['previous-sequence-start-index']=pstart-1
kw['previous-sequence-end-index']=pend-1 kw['previous-sequence-end-index']=pend-1
kw['previous-sequence-size']=pend+1-pstart kw['previous-sequence-size']=pend+1-pstart
result=render(section,md) result=render(section,md)
elif self.elses: result=render(self.elses, md) elif self.elses: result=render(self.elses, md)
else: result='' else: result=''
elif next: elif next:
try: try:
# The following line is a sneaky way to test whether # The following line is a sneaky way to test whether
# there are more items, without actually # there are more items, without actually
# computing a length: # computing a length:
sequence[end] sequence[end]
pstart,pend,psize=opt(end+1-overlap,None, pstart,pend,psize=opt(end+1-overlap,None,
sz,orphan,sequence) sz,orphan,sequence)
kw['next-sequence']=1 kw['next-sequence']=1
kw['next-sequence-start-index']=pstart-1 kw['next-sequence-start-index']=pstart-1
kw['next-sequence-end-index']=pend-1 kw['next-sequence-end-index']=pend-1
kw['next-sequence-size']=pend+1-pstart kw['next-sequence-size']=pend+1-pstart
result=render(section,md) result=render(section,md)
except: except:
if self.elses: result=render(self.elses, md) if self.elses: result=render(self.elses, md)
else: result='' else: result=''
else: else:
result = [] result = []
append=result.append append=result.append
validate=md.validate validate=md.validate
for index in range(first,end): for index in range(first,end):
if index==first and index > 0: if index==first and index > 0:
pstart,pend,psize=opt(None,index+overlap, pstart,pend,psize=opt(None,index+overlap,
...@@ -537,154 +537,153 @@ class InClass: ...@@ -537,154 +537,153 @@ class InClass:
kw['next-sequence-end-index']=pend-1 kw['next-sequence-end-index']=pend-1
kw['next-sequence-size']=pend+1-pstart kw['next-sequence-size']=pend+1-pstart
except: pass except: pass
if index==last: kw['sequence-end']=1 if index==last: kw['sequence-end']=1
client=sequence[index] client=sequence[index]
if validate is not None: if validate is not None:
try: vv=validate(sequence,sequence,index,client,md) try: vv=validate(sequence,sequence,index,client,md)
except: vv=0 except: vv=0
if not vv: if not vv:
if (params.has_key('skip_unauthorized') and if (params.has_key('skip_unauthorized') and
params['skip_unauthorized']): params['skip_unauthorized']):
if index==first: kw['sequence-start']=0 if index==first: kw['sequence-start']=0
continue continue
raise ValidationError, index raise ValidationError, index
kw['sequence-index']=index kw['sequence-index']=index
if type(client)==TupleType and len(client)==2: if type(client)==TupleType and len(client)==2:
client=client[1] client=client[1]
if mapping: push(client) if mapping: push(client)
else: push(InstanceDict(client, md)) else: push(InstanceDict(client, md))
try: append(render(section, md)) try: append(render(section, md))
finally: pop(1) finally: pop(1)
if index==first: kw['sequence-start']=0 if index==first: kw['sequence-start']=0
result=join(result, '') result=join(result, '')
finally: finally:
if cache: pop() if cache: pop()
pop() pop()
return result return result
def renderwob(self, md): def renderwob(self, md):
expr=self.expr expr=self.expr
name=self.__name__ name=self.__name__
if expr is None: if expr is None:
sequence=md[name] sequence=md[name]
cache={ name: sequence } cache={ name: sequence }
else: else:
sequence=expr(md) sequence=expr(md)
cache=None cache=None
if not sequence: if not sequence:
if self.elses: return render_blocks(self.elses, md) if self.elses: return render_blocks(self.elses, md)
return '' return ''
section=self.section section=self.section
mapping=self.mapping mapping=self.mapping
if self.sort is not None: sequence=self.sort_sequence(sequence) if self.sort is not None: sequence=self.sort_sequence(sequence)
vars=sequence_variables(sequence) vars=sequence_variables(sequence)
kw=vars.data kw=vars.data
kw['mapping']=mapping kw['mapping']=mapping
l=len(sequence) l=len(sequence)
last=l-1 last=l-1
push=md._push push=md._push
pop=md._pop pop=md._pop
render=render_blocks render=render_blocks
if cache: push(cache) if cache: push(cache)
push(vars) push(vars)
try: try:
result = [] result = []
append=result.append append=result.append
validate=md.validate validate=md.validate
for index in range(l): for index in range(l):
if index==last: kw['sequence-end']=1 if index==last: kw['sequence-end']=1
client=sequence[index] client=sequence[index]
if validate is not None: if validate is not None:
try: vv=validate(sequence,sequence,index,client,md) try: vv=validate(sequence,sequence,index,client,md)
except: vv=0 except: vv=0
if not vv: if not vv:
if (self.args.has_key('skip_unauthorized') and if (self.args.has_key('skip_unauthorized') and
self.args['skip_unauthorized']): self.args['skip_unauthorized']):
if index==1: kw['sequence-start']=0 if index==1: kw['sequence-start']=0
continue continue
raise ValidationError, index raise ValidationError, index
kw['sequence-index']=index kw['sequence-index']=index
if type(client)==TupleType and len(client)==2: if type(client)==TupleType and len(client)==2:
client=client[1] client=client[1]
if mapping: push(client) if mapping: push(client)
else: push(InstanceDict(client, md)) else: push(InstanceDict(client, md))
try: append(render(section, md)) try: append(render(section, md))
finally: pop() finally: pop()
if index==0: kw['sequence-start']=0 if index==0: kw['sequence-start']=0
result=join(result, '') result=join(result, '')
finally: finally:
if cache: pop() if cache: pop()
pop() pop()
return result return result
def sort_sequence(self, sequence): def sort_sequence(self, sequence):
sort=self.sort sort=self.sort
mapping=self.mapping mapping=self.mapping
isort=not sort isort=not sort
k=None k=None
s=[] s=[]
for client in sequence: for client in sequence:
if type(client)==TupleType and len(client)==2: if type(client)==TupleType and len(client)==2:
if isort: k=client[0] if isort: k=client[0]
v=client[1] v=client[1]
else: else:
if isort: k=client if isort: k=client
v=client v=client
if sort: if sort:
if mapping: k=v[sort] if mapping: k=v[sort]
else: k=getattr(v, sort) else: k=getattr(v, sort)
if not basic_type(k): if not basic_type(k):
try: k=k() try: k=k()
except: pass except: pass
s.append((k,client)) s.append((k,client))
s.sort() s.sort()
sequence=[] sequence=[]
for k, client in s: sequence.append(client) for k, client in s: sequence.append(client)
return sequence return sequence
basic_type={type(''): 1, type(0): 1, type(0.0): 1, type(()): 1, type([]): 1 basic_type={type(''): 1, type(0): 1, type(0.0): 1, type(()): 1, type([]): 1
}.has_key }.has_key
def int_param(params,md,name,default=0, st=type('')): def int_param(params,md,name,default=0, st=type('')):
try: v=params[name] try: v=params[name]
except: v=default except: v=default
if v: if v:
try: v=atoi(v) try: v=atoi(v)
except: except:
v=md[v] v=md[v]
if type(v) is st: v=atoi(v) if type(v) is st: v=atoi(v)
return v return v
...@@ -54,8 +54,8 @@ ...@@ -54,8 +54,8 @@
__doc__='''Sequence variables support __doc__='''Sequence variables support
$Id: DT_InSV.py,v 1.7 1998/09/14 20:48:40 jim Exp $''' $Id: DT_InSV.py,v 1.8 1998/09/14 22:03:32 jim Exp $'''
__version__='$Revision: 1.7 $'[11:-2] __version__='$Revision: 1.8 $'[11:-2]
from string import lower, rfind from string import lower, rfind
from math import sqrt from math import sqrt
...@@ -69,17 +69,17 @@ except: mv=None ...@@ -69,17 +69,17 @@ except: mv=None
class sequence_variables: class sequence_variables:
def __init__(self,items=None,query_string='',start_name_re=None): def __init__(self,items=None,query_string='',start_name_re=None):
self.items=items self.items=items
self.query_string=query_string self.query_string=query_string
self.start_name_re=start_name_re self.start_name_re=start_name_re
self.data=data={ self.data=data={
'previous-sequence': 0, 'previous-sequence': 0,
'next-sequence': 0, 'next-sequence': 0,
'sequence-start': 1, 'sequence-start': 1,
'sequence-end': 0, 'sequence-end': 0,
} }
def number(self,index): return index+1 def number(self,index): return index+1
...@@ -89,84 +89,84 @@ class sequence_variables: ...@@ -89,84 +89,84 @@ class sequence_variables:
def Letter(self,index): return chr(ord('A')+index) def Letter(self,index): return chr(ord('A')+index)
def key(self,index): return self.items[index][0] def key(self,index): return self.items[index][0]
def item(self,index, tt=type(())): def item(self,index, tt=type(())):
i=self.items[index] i=self.items[index]
if type(i) is tt and len(i)==2: return i[1] if type(i) is tt and len(i)==2: return i[1]
return i return i
def roman(self,index): return lower(self.Roman(index)) def roman(self,index): return lower(self.Roman(index))
def Roman(self,num): def Roman(self,num):
# Force number to be an integer value # Force number to be an integer value
num = int(num)+1 num = int(num)+1
# Initialize roman as an empty string # Initialize roman as an empty string
roman = '' roman = ''
while num >= 1000: while num >= 1000:
num = num - 1000 num = num - 1000
roman = '%sM' % roman roman = '%sM' % roman
while num >= 500: while num >= 500:
num = num - 500 num = num - 500
roman = '%sD' % roman roman = '%sD' % roman
while num >= 100: while num >= 100:
num = num - 100 num = num - 100
roman = '%sC' % roman roman = '%sC' % roman
while num >= 50: while num >= 50:
num = num - 50 num = num - 50
roman = '%sL' % roman roman = '%sL' % roman
while num >= 10: while num >= 10:
num = num - 10 num = num - 10
roman = '%sX' % roman roman = '%sX' % roman
while num >= 5: while num >= 5:
num = num - 5 num = num - 5
roman = '%sV' % roman roman = '%sV' % roman
while num < 5 and num >= 1: while num < 5 and num >= 1:
num = num - 1 num = num - 1
roman = '%sI' % roman roman = '%sI' % roman
# Replaces special cases in Roman Numerals # Replaces special cases in Roman Numerals
roman = sub('DCCCC', 'CM', roman) roman = sub('DCCCC', 'CM', roman)
roman = sub('CCCC', 'CD', roman) roman = sub('CCCC', 'CD', roman)
roman = sub('LXXXX', 'XC', roman) roman = sub('LXXXX', 'XC', roman)
roman = sub('XXXX', 'XL', roman) roman = sub('XXXX', 'XL', roman)
roman = sub('VIIII', 'IX', roman) roman = sub('VIIII', 'IX', roman)
roman = sub('IIII', 'IV', roman) roman = sub('IIII', 'IV', roman)
return roman return roman
def value(self,index,name): def value(self,index,name):
data=self.data data=self.data
item=self.items[index] item=self.items[index]
if type(item)==TupleType and len(item)==2: if type(item)==TupleType and len(item)==2:
item=item[1] item=item[1]
if data['mapping']: return item[name] if data['mapping']: return item[name]
return getattr(item,name) return getattr(item,name)
def first(self,name,key=''): def first(self,name,key=''):
data=self.data data=self.data
if data['sequence-start']: return 1 if data['sequence-start']: return 1
index=data['sequence-index'] index=data['sequence-index']
return self.value(index,name) != self.value(index-1,name) return self.value(index,name) != self.value(index-1,name)
def last(self,name,key=''): def last(self,name,key=''):
data=self.data data=self.data
if data['sequence-end']: return 1 if data['sequence-end']: return 1
index=data['sequence-index'] index=data['sequence-index']
return self.value(index,name) != self.value(index+1,name) return self.value(index,name) != self.value(index+1,name)
def length(self, ignored): def length(self, ignored):
l=self.data['sequence-length']=len(self.items) l=self.data['sequence-length']=len(self.items)
return l return l
def query(self, *ignored): def query(self, *ignored):
if self.start_name_re is None: raise KeyError, 'sequence-query' if self.start_name_re is None: raise KeyError, 'sequence-query'
query_string=self.query_string query_string=self.query_string
while query_string and query_string[:1] in '?&': while query_string and query_string[:1] in '?&':
query_string=query_string[1:] query_string=query_string[1:]
...@@ -184,180 +184,180 @@ class sequence_variables: ...@@ -184,180 +184,180 @@ class sequence_variables:
else: query_string='?' else: query_string='?'
self.data['sequence-query']=query_string self.data['sequence-query']=query_string
return query_string return query_string
statistic_names=( statistic_names=(
'total', 'count', 'min', 'max', 'median', 'mean', 'total', 'count', 'min', 'max', 'median', 'mean',
'variance', 'variance-n','standard-deviation', 'standard-deviation-n', 'variance', 'variance-n','standard-deviation', 'standard-deviation-n',
) )
def statistics(self,name,key): def statistics(self,name,key):
items=self.items items=self.items
data=self.data data=self.data
mapping=data['mapping'] mapping=data['mapping']
count=sum=sumsq=0 count=sum=sumsq=0
min=max=None min=max=None
scount=smin=smax=None scount=smin=smax=None
values=[] values=[]
svalues=[] svalues=[]
for item in items: for item in items:
try: try:
if mapping: item=item[name] if mapping: item=item[name]
else: item=getattr(item,name) else: item=getattr(item,name)
try: try:
s=item*item s=item*item
sum=sum+item sum=sum+item
sumsq=sumsq+s sumsq=sumsq+s
values.append(item) values.append(item)
if min is None: if min is None:
min=max=item min=max=item
else: else:
if item < min: min=item if item < min: min=item
if item > max: max=item if item > max: max=item
except: except:
if item is not None and item is not mv: if item is not None and item is not mv:
if smin is None: smin=smax=item if smin is None: smin=smax=item
else: else:
if item < smin: smin=item if item < smin: smin=item
if item > smax: smax=item if item > smax: smax=item
svalues.append(item) svalues.append(item)
except: pass except: pass
# Initialize all stats to empty strings: # Initialize all stats to empty strings:
for stat in self.statistic_names: data['%s-%s' % (stat,name)]='' for stat in self.statistic_names: data['%s-%s' % (stat,name)]=''
count=len(values) count=len(values)
try: # Numeric statistics try: # Numeric statistics
n=float(count) n=float(count)
mean=sum/n mean=sum/n
sumsq=sumsq/n - mean*mean sumsq=sumsq/n - mean*mean
data['mean-%s' % name]=mean data['mean-%s' % name]=mean
data['total-%s' % name]=sum data['total-%s' % name]=sum
data['variance-n-%s' % name]=sumsq data['variance-n-%s' % name]=sumsq
data['standard-deviation-n-%s' % name]=sqrt(sumsq) data['standard-deviation-n-%s' % name]=sqrt(sumsq)
if count > 1: if count > 1:
sumsq=sumsq*n/(n-1) sumsq=sumsq*n/(n-1)
data['variance-%s' % name]=sumsq data['variance-%s' % name]=sumsq
data['standard-deviation-%s' % name]=sqrt(sumsq) data['standard-deviation-%s' % name]=sqrt(sumsq)
else: else:
data['variance-%s' % name]='' data['variance-%s' % name]=''
data['standard-deviation-%s' % name]='' data['standard-deviation-%s' % name]=''
except: except:
if min is None: min,max,values=smin,smax,svalues if min is None: min,max,values=smin,smax,svalues
else: else:
if smin < min: min=smin if smin < min: min=smin
if smax > max: max=smax if smax > max: max=smax
values=values+svalues values=values+svalues
count=len(values) count=len(values)
data['count-%s' % name]=count data['count-%s' % name]=count
# data['_values']=values # data['_values']=values
if min is not None: if min is not None:
data['min-%s' % name]=min data['min-%s' % name]=min
data['max-%s' % name]=max data['max-%s' % name]=max
values.sort() values.sort()
if count==1: if count==1:
data['median-%s' % name]=min data['median-%s' % name]=min
else: else:
n=count+1 n=count+1
if n/2*2==n: data['median-%s' % name]=values[n/2-1] if n/2*2==n: data['median-%s' % name]=values[n/2-1]
else: else:
n=n/2 n=n/2
try: data['median-%s' % name]=(values[n]+values[n-1])/2 try: data['median-%s' % name]=(values[n]+values[n-1])/2
except: except:
try: data['median-%s' % name]=( try: data['median-%s' % name]=(
"between %s and %s" % (values[n],values[n-1])) "between %s and %s" % (values[n],values[n-1]))
except: pass except: pass
return data[key] return data[key]
def next_batches(self, suffix='batches',key=''): def next_batches(self, suffix='batches',key=''):
if suffix != 'batches': raise KeyError, key if suffix != 'batches': raise KeyError, key
data=self.data data=self.data
sequence=self.items sequence=self.items
try: try:
if not data['next-sequence']: return () if not data['next-sequence']: return ()
sz=data['sequence-step-size'] sz=data['sequence-step-size']
start=data['sequence-step-start'] start=data['sequence-step-start']
end=data['sequence-step-end'] end=data['sequence-step-end']
l=len(sequence) l=len(sequence)
orphan=data['sequence-step-orphan'] orphan=data['sequence-step-orphan']
overlap=data['sequence-step-overlap'] overlap=data['sequence-step-overlap']
except: AttributeError, 'next-batches' except: AttributeError, 'next-batches'
r=[] r=[]
while end < l: while end < l:
start,end,spam=opt(end+1-overlap,None,sz,orphan,sequence) start,end,spam=opt(end+1-overlap,None,sz,orphan,sequence)
v=sequence_variables(self.items, v=sequence_variables(self.items,
self.query_string,self.start_name_re) self.query_string,self.start_name_re)
d=v.data d=v.data
d['batch-start-index']=start-1 d['batch-start-index']=start-1
d['batch-end-index']=end-1 d['batch-end-index']=end-1
d['batch-size']=end+1-start d['batch-size']=end+1-start
d['mapping']=data['mapping'] d['mapping']=data['mapping']
r.append(v) r.append(v)
data['next-batches']=r data['next-batches']=r
return r return r
def previous_batches(self, suffix='batches',key=''): def previous_batches(self, suffix='batches',key=''):
if suffix != 'batches': raise KeyError, key if suffix != 'batches': raise KeyError, key
data=self.data data=self.data
sequence=self.items sequence=self.items
try: try:
if not data['previous-sequence']: return () if not data['previous-sequence']: return ()
sz=data['sequence-step-size'] sz=data['sequence-step-size']
start=data['sequence-step-start'] start=data['sequence-step-start']
end=data['sequence-step-end'] end=data['sequence-step-end']
l=len(sequence) l=len(sequence)
orphan=data['sequence-step-orphan'] orphan=data['sequence-step-orphan']
overlap=data['sequence-step-overlap'] overlap=data['sequence-step-overlap']
except: AttributeError, 'previous-batches' except: AttributeError, 'previous-batches'
r=[] r=[]
while start > 1: while start > 1:
start,end,spam=opt(None,start-1+overlap,sz,orphan,sequence) start,end,spam=opt(None,start-1+overlap,sz,orphan,sequence)
v=sequence_variables(self.items, v=sequence_variables(self.items,
self.query_string,self.start_name_re) self.query_string,self.start_name_re)
d=v.data d=v.data
d['batch-start-index']=start-1 d['batch-start-index']=start-1
d['batch-end-index']=end-1 d['batch-end-index']=end-1
d['batch-size']=end+1-start d['batch-size']=end+1-start
d['mapping']=data['mapping'] d['mapping']=data['mapping']
r.append(v) r.append(v)
r.reverse() r.reverse()
data['previous-batches']=r data['previous-batches']=r
return r return r
special_prefixes={ special_prefixes={
'first': first, 'first': first,
'last': last, 'last': last,
'previous': previous_batches, 'previous': previous_batches,
'next': next_batches, 'next': next_batches,
# These two are for backward compatability with a missfeature: # These two are for backward compatability with a missfeature:
'sequence-index': lambda self, suffix, key: self['sequence-'+suffix], 'sequence-index': lambda self, suffix, key: self['sequence-'+suffix],
'sequence-index-is': lambda self, suffix, key: self['sequence-'+suffix], 'sequence-index-is': lambda self, suffix, key: self['sequence-'+suffix],
} }
for n in statistic_names: special_prefixes[n]=statistics for n in statistic_names: special_prefixes[n]=statistics
def __getitem__(self,key, def __getitem__(self,key,
special_prefixes=special_prefixes, special_prefixes=special_prefixes,
special_prefix=special_prefixes.has_key special_prefix=special_prefixes.has_key
): ):
data=self.data data=self.data
if data.has_key(key): return data[key] if data.has_key(key): return data[key]
l=rfind(key,'-') l=rfind(key,'-')
if l < 0: raise KeyError, key if l < 0: raise KeyError, key
suffix=key[l+1:] suffix=key[l+1:]
prefix=key[:l] prefix=key[:l]
if hasattr(self, suffix): if hasattr(self, suffix):
try: v=data[prefix+'-index'] try: v=data[prefix+'-index']
except: pass except: pass
else: return getattr(self,suffix)(v) else: return getattr(self,suffix)(v)
if special_prefix(prefix): if special_prefix(prefix):
return special_prefixes[prefix](self, suffix, key) return special_prefixes[prefix](self, suffix, key)
if prefix[-4:]=='-var': if prefix[-4:]=='-var':
prefix=prefix[:-4] prefix=prefix[:-4]
...@@ -371,33 +371,32 @@ class sequence_variables: ...@@ -371,33 +371,32 @@ class sequence_variables:
def opt(start,end,size,orphan,sequence): def opt(start,end,size,orphan,sequence):
if size < 1: if size < 1:
if start > 0 and end > 0 and end >= start: if start > 0 and end > 0 and end >= start:
size=end+1-start size=end+1-start
else: size=7 else: size=7
if start > 0: if start > 0:
try: sequence[start-1] try: sequence[start-1]
except: start=len(sequence) except: start=len(sequence)
# if start > l: start=l # if start > l: start=l
if end > 0: if end > 0:
if end > start: end=start if end > start: end=start
else: else:
end=start+size-1 end=start+size-1
try: sequence[end+orphan-1] try: sequence[end+orphan-1]
except: end=len(sequence) except: end=len(sequence)
# if l - end < orphan: end=l # if l - end < orphan: end=l
elif end > 0: elif end > 0:
try: sequence[end-1] try: sequence[end-1]
except: end=len(sequence) except: end=len(sequence)
# if end > l: end=l # if end > l: end=l
start=end+1-size start=end+1-size
if start - 1 < orphan: start=1 if start - 1 < orphan: start=1
else: else:
start=1 start=1
end=start+size-1 end=start+size-1
try: sequence[end+orphan-1] try: sequence[end+orphan-1]
except: end=len(sequence) except: end=len(sequence)
# if l - end < orphan: end=l # if l - end < orphan: end=l
return start,end,size return start,end,size
...@@ -65,8 +65,8 @@ ...@@ -65,8 +65,8 @@
<!--#/if--> <!--#/if-->
''' '''
__rcs_id__='$Id: DT_Raise.py,v 1.8 1998/09/14 20:48:40 jim Exp $' __rcs_id__='$Id: DT_Raise.py,v 1.9 1998/09/14 22:03:32 jim Exp $'
__version__='$Revision: 1.8 $'[11:-2] __version__='$Revision: 1.9 $'[11:-2]
from DT_Util import parse_params, name_param, render_blocks, str from DT_Util import parse_params, name_param, render_blocks, str
...@@ -77,25 +77,24 @@ class Raise: ...@@ -77,25 +77,24 @@ class Raise:
def __init__(self, blocks): def __init__(self, blocks):
tname, args, section = blocks[0] tname, args, section = blocks[0]
self.section=section.blocks self.section=section.blocks
args=parse_params(args, type='', expr='') args=parse_params(args, type='', expr='')
self.__name__, self.expr = name_param(args, 'raise', 1, attr='type') self.__name__, self.expr = name_param(args, 'raise', 1, attr='type')
def render(self,md): def render(self,md):
expr=self.expr expr=self.expr
if expr is None: if expr is None:
t=self.__name__ t=self.__name__
if t[-5:]=='Error' and __builtins__.has_key(t): if t[-5:]=='Error' and __builtins__.has_key(t):
t=__builtins__[t] t=__builtins__[t]
else: else:
try: t=expr.eval(md) try: t=expr.eval(md)
except: t='Invalid Error Type Expression' except: t='Invalid Error Type Expression'
try: v=render_blocks(self.section,md) try: v=render_blocks(self.section,md)
except: v='Invalid Error Value' except: v='Invalid Error Value'
raise t, v raise t, v
__call__=render __call__=render
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
# (540) 371-6909 # (540) 371-6909
# #
############################################################################## ##############################################################################
"$Id: DT_String.py,v 1.18 1998/09/14 20:48:41 jim Exp $" "$Id: DT_String.py,v 1.19 1998/09/14 22:03:32 jim Exp $"
from string import split, strip from string import split, strip
import regex, ts_regex import regex, ts_regex
...@@ -90,34 +90,34 @@ class String: ...@@ -90,34 +90,34 @@ class String:
def errQuote(self, s): return s def errQuote(self, s): return s
def parse_error(self, mess, tag, text, start): def parse_error(self, mess, tag, text, start):
raise ParseError, "%s, for tag %s, on line %s of %s<p>" % ( raise ParseError, "%s, for tag %s, on line %s of %s<p>" % (
mess, self.errQuote(tag), len(split(text[:start],'\n')), mess, self.errQuote(tag), len(split(text[:start],'\n')),
self.errQuote(self.__name__)) self.errQuote(self.__name__))
commands={ commands={
'var': Var, 'var': Var,
'call': Call, 'call': Call,
'in': ('in', 'DT_In','In'), 'in': ('in', 'DT_In','In'),
'with': ('with', 'DT_With','With'), 'with': ('with', 'DT_With','With'),
'if': ('if', 'DT_If','If'), 'if': ('if', 'DT_If','If'),
'unless': ('unless', 'DT_If','Unless'), 'unless': ('unless', 'DT_If','Unless'),
'else': ('else', 'DT_If','Else'), 'else': ('else', 'DT_If','Else'),
'comment': Comment, 'comment': Comment,
'raise': ('raise', 'DT_Raise','Raise'), 'raise': ('raise', 'DT_Raise','Raise'),
} }
def SubTemplate(self, name): return String('', __name__=name) def SubTemplate(self, name): return String('', __name__=name)
def tagre(self): def tagre(self):
return ts_regex.symcomp( return ts_regex.symcomp(
'%(' # beginning '%(' # beginning
'\(<name>[a-zA-Z0-9_/.-]+\)' # tag name '\(<name>[a-zA-Z0-9_/.-]+\)' # tag name
'\(' '\('
'[\0- ]+' # space after tag name '[\0- ]+' # space after tag name
'\(<args>\([^)"]+\("[^"]*"\)?\)*\)' # arguments '\(<args>\([^)"]+\("[^"]*"\)?\)*\)' # arguments
'\)?' '\)?'
')\(<fmt>[0-9]*[.]?[0-9]*[a-z]\|[]![]\)' # end ')\(<fmt>[0-9]*[.]?[0-9]*[a-z]\|[]![]\)' # end
, regex.casefold) , regex.casefold)
def _parseTag(self, tagre, command=None, sargs='', tt=type(())): def _parseTag(self, tagre, command=None, sargs='', tt=type(())):
tag, args, command, coname = self.parseTag(tagre,command,sargs) tag, args, command, coname = self.parseTag(tagre,command,sargs)
...@@ -133,159 +133,159 @@ class String: ...@@ -133,159 +133,159 @@ class String:
return tag, args, command, coname return tag, args, command, coname
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
Return: tag, args, command, coname Return: tag, args, command, coname
where: tag is the tag, where: tag is the tag,
args is the tag\'s argument string, args is the tag\'s argument string,
command is a corresponding command info structure if the command is a corresponding command info structure if the
tag is a start tag, or None otherwise, and tag is a start tag, or None otherwise, and
coname is the name of a continue tag (e.g. else) coname is the name of a continue tag (e.g. else)
or None otherwise or None otherwise
""" """
tag, name, args, fmt =tagre.group(0, 'name', 'args', 'fmt') tag, name, args, fmt =tagre.group(0, 'name', 'args', 'fmt')
args=args and strip(args) or '' args=args and strip(args) or ''
if fmt==']': if fmt==']':
if not command or name != command.name: if not command or name != command.name:
raise ParseError, ('unexpected end tag', tag) raise ParseError, ('unexpected end tag', tag)
return tag, args, None, None return tag, args, None, None
elif fmt=='[' or fmt=='!': elif fmt=='[' or fmt=='!':
if command and name in command.blockContinuations: if command and name in command.blockContinuations:
if name=='else' and args: if name=='else' and args:
# Waaaaaah! Have to special case else because of # Waaaaaah! Have to special case else because of
# old else start tag usage. Waaaaaaah! # old else start tag usage. Waaaaaaah!
l=len(args) l=len(args)
if not (args==sargs or if not (args==sargs or
args==sargs[:l] and sargs[l:l+1] in ' \t\n'): args==sargs[:l] and sargs[l:l+1] in ' \t\n'):
return tag, args, self.commands[name], None return tag, args, self.commands[name], None
return tag, args, None, name return tag, args, None, name
try: return tag, args, self.commands[name], None try: return tag, args, self.commands[name], None
except KeyError: except KeyError:
raise ParseError, ('Unexpected tag', tag) raise ParseError, ('Unexpected tag', tag)
else: else:
# Var command # Var command
args=args and ("%s %s" % (name, args)) or name args=args and ("%s %s" % (name, args)) or name
return tag, args, Var, None return tag, args, Var, None
def varExtra(self,tagre): return tagre.group('fmt') def varExtra(self,tagre): return tagre.group('fmt')
def parse(self,text,start=0,result=None,tagre=None): def parse(self,text,start=0,result=None,tagre=None):
if result is None: result=[] if result is None: result=[]
if tagre is None: tagre=self.tagre() if tagre is None: tagre=self.tagre()
l=tagre.search(text,start) l=tagre.search(text,start)
while l >= 0: while l >= 0:
try: tag, args, command, coname = self._parseTag(tagre) try: tag, args, command, coname = self._parseTag(tagre)
except ParseError, m: self.parse_error(m[0],m[1],text,l) except ParseError, m: self.parse_error(m[0],m[1],text,l)
s=text[start:l] s=text[start:l]
if s: result.append(s) if s: result.append(s)
start=l+len(tag) start=l+len(tag)
if hasattr(command,'blockContinuations'): if hasattr(command,'blockContinuations'):
start=self.parse_block(text, start, result, tagre, start=self.parse_block(text, start, result, tagre,
tag, l, args, command) tag, l, args, command)
else: else:
try: try:
if command is Var: r=command(args, self.varExtra(tagre)) if command is Var: r=command(args, self.varExtra(tagre))
else: r=command(args) else: r=command(args)
if hasattr(r,'simple_form'): r=r.simple_form if hasattr(r,'simple_form'): r=r.simple_form
result.append(r) 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)
text=text[start:] text=text[start:]
if text: result.append(text) if text: result.append(text)
return result return result
def skip_eol(self, text, start, eol=regex.compile('[ \t]*\n')): def skip_eol(self, text, start, eol=regex.compile('[ \t]*\n')):
# if block open is followed by newline, then skip past newline # if block open is followed by newline, then skip past newline
l=eol.match(text,start) l=eol.match(text,start)
if l > 0: start=start+l if l > 0: start=start+l
return start return start
def parse_block(self, text, start, result, tagre, def parse_block(self, text, start, result, tagre,
stag, sloc, sargs, scommand): stag, sloc, sargs, scommand):
start=self.skip_eol(text,start) start=self.skip_eol(text,start)
blocks=[] blocks=[]
tname=scommand.name tname=scommand.name
sname=stag sname=stag
sstart=start sstart=start
sa=sargs sa=sargs
while 1: while 1:
l=tagre.search(text,start) l=tagre.search(text,start)
if l < 0: self.parse_error('No closing tag', stag, text, sloc) if l < 0: self.parse_error('No closing tag', stag, text, sloc)
try: tag, args, command, coname= self._parseTag(tagre,scommand,sa) try: tag, args, command, coname= self._parseTag(tagre,scommand,sa)
except ParseError, m: self.parse_error(m[0],m[1], text, l) except ParseError, m: self.parse_error(m[0],m[1], text, l)
if command: if command:
start=l+len(tag) start=l+len(tag)
if hasattr(command, 'blockContinuations'): if hasattr(command, 'blockContinuations'):
# New open tag. Need to find closing tag. # New open tag. Need to find closing tag.
start=self.parse_close(text, start, tagre, tag, l, start=self.parse_close(text, start, tagre, tag, l,
command, args) command, args)
else: else:
# Either a continuation tag or an end tag # Either a continuation tag or an end tag
section=self.SubTemplate(sname) section=self.SubTemplate(sname)
section.blocks=self.parse(text[:l],sstart) section.blocks=self.parse(text[:l],sstart)
section.cooked=None section.cooked=None
blocks.append((tname,sargs,section)) blocks.append((tname,sargs,section))
start=self.skip_eol(text,l+len(tag)) start=self.skip_eol(text,l+len(tag))
if coname: if coname:
tname=coname tname=coname
sname=tag sname=tag
sargs=args sargs=args
sstart=start sstart=start
else: else:
try: try:
r=scommand(blocks) r=scommand(blocks)
if hasattr(r,'simple_form'): r=r.simple_form if hasattr(r,'simple_form'): r=r.simple_form
result.append(r) 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
def parse_close(self, text, start, tagre, stag, sloc, scommand, sa): def parse_close(self, text, start, tagre, stag, sloc, scommand, sa):
while 1: while 1:
l=tagre.search(text,start) l=tagre.search(text,start)
if l < 0: self.parse_error('No closing tag', stag, text, sloc) if l < 0: self.parse_error('No closing tag', stag, text, sloc)
try: tag, args, command, coname= self._parseTag(tagre,scommand,sa) try: tag, args, command, coname= self._parseTag(tagre,scommand,sa)
except ParseError, m: self.parse_error(m[0],m[1], text, l) except ParseError, m: self.parse_error(m[0],m[1], text, l)
start=l+len(tag) start=l+len(tag)
if command: if command:
if hasattr(command, 'blockContinuations'): if hasattr(command, 'blockContinuations'):
# New open tag. Need to find closing tag. # New open tag. Need to find closing tag.
start=self.parse_close(text, start, tagre, tag, l, start=self.parse_close(text, start, tagre, tag, l,
command,args) command,args)
elif not coname: return start elif not coname: return start
shared_globals={} shared_globals={}
def __init__(self, source_string='', mapping=None, __name__='<string>', def __init__(self, source_string='', mapping=None, __name__='<string>',
**vars): **vars):
"""\ """\
Create a document template from a string. Create a document template from a string.
The optional parameter, 'mapping', may be used to provide a The optional parameter, 'mapping', may be used to provide a
mapping object containing defaults for values to be inserted. mapping object containing defaults for values to be inserted.
""" """
self.raw=source_string self.raw=source_string
self.initvars(mapping, vars) self.initvars(mapping, vars)
self.setName(__name__) self.setName(__name__)
def name(self): return self.__name__ def name(self): return self.__name__
id=name id=name
...@@ -293,49 +293,49 @@ class String: ...@@ -293,49 +293,49 @@ class String:
def setName(self,v): self.__dict__['__name__']=v def setName(self,v): self.__dict__['__name__']=v
def default(self,name=None,**kw): def default(self,name=None,**kw):
"""\ """\
Change or query default values in a document template. Change or query default values in a document template.
If a name is specified, the value of the named default value If a name is specified, the value of the named default value
before the operation is returned. before the operation is returned.
Keyword arguments are used to provide default values. Keyword arguments are used to provide default values.
""" """
if name: name=self.globals[name] if name: name=self.globals[name]
for key in kw.keys(): self.globals[key]=kw[key] for key in kw.keys(): self.globals[key]=kw[key]
return name return name
def var(self,name=None,**kw): def var(self,name=None,**kw):
"""\ """\
Change or query a variable in a document template. Change or query a variable in a document template.
If a name is specified, the value of the named variable before If a name is specified, the value of the named variable before
the operation is returned. the operation is returned.
Keyword arguments are used to provide variable values. Keyword arguments are used to provide variable values.
""" """
if name: name=self._vars[name] if name: name=self._vars[name]
for key in kw.keys(): self._vars[key]=kw[key] for key in kw.keys(): self._vars[key]=kw[key]
return name return name
def munge(self,source_string=None,mapping=None,**vars): def munge(self,source_string=None,mapping=None,**vars):
"""\ """\
Change the text or default values for a document template. Change the text or default values for a document template.
""" """
if mapping is not None or vars: if mapping is not None or vars:
self.initvars(mapping, vars) self.initvars(mapping, vars)
if source_string is not None: if source_string is not None:
self.raw=source_string self.raw=source_string
self.cook() self.cook()
def manage_edit(self,data,REQUEST=None): def manage_edit(self,data,REQUEST=None):
self.munge(data) self.munge(data)
def read_raw(self,raw=None): def read_raw(self,raw=None):
return self.raw return self.raw
def read(self,raw=None): def read(self,raw=None):
return self.read_raw() return self.read_raw()
def cook(self, def cook(self,
cooklock=ts_regex.allocate_lock(), cooklock=ts_regex.allocate_lock(),
...@@ -348,158 +348,158 @@ class String: ...@@ -348,158 +348,158 @@ class String:
cooklock.release() cooklock.release()
def initvars(self, globals, vars): def initvars(self, globals, vars):
if globals: if globals:
for k in globals.keys(): for k in globals.keys():
if k[:1] != '_' and not vars.has_key(k): vars[k]=globals[k] if k[:1] != '_' and not vars.has_key(k): vars[k]=globals[k]
self.globals=vars self.globals=vars
self._vars={} self._vars={}
__state_names__=('raw', 'globals', '__name__', '_vars') __state_names__=('raw', 'globals', '__name__', '_vars')
def __getstate__(self): def __getstate__(self):
r={} r={}
for k in self.__state_names__: for k in self.__state_names__:
try: r[k]=getattr(self,k) try: r[k]=getattr(self,k)
except: pass except: pass
return r return r
def __setstate__(self,s,hack=('',{},'<string>',{},'')): def __setstate__(self,s,hack=('',{},'<string>',{},'')):
try: try:
for k in s.keys(): self.__dict__[k]=s[k] for k in s.keys(): self.__dict__[k]=s[k]
except: except:
self.raw,self.globals,self.__dict__['name'],self._vars,dummy=( self.raw,self.globals,self.__dict__['name'],self._vars,dummy=(
s+hack[len(s)-len(hack):]) s+hack[len(s)-len(hack):])
def __call__(self,client=None,mapping={},**kw): def __call__(self,client=None,mapping={},**kw):
'''\ '''\
Generate a document from a document template. Generate a document from a document template.
The document will be generated by inserting values into the The document will be generated by inserting values into the
format string specified when the document template was format string specified when the document template was
created. Values are inserted using standard python named created. Values are inserted using standard python named
string formats. string formats.
The optional argument 'client' is used to specify a object The optional argument 'client' is used to specify a object
containing values to be looked up. Values will be looked up containing values to be looked up. Values will be looked up
using getattr, so inheritence of values is supported. Note using getattr, so inheritence of values is supported. Note
that names beginning with '_' will not be looked up from the that names beginning with '_' will not be looked up from the
client. client.
The optional argument, 'mapping' is used to specify a mapping The optional argument, 'mapping' is used to specify a mapping
object containing values to be inserted. object containing values to be inserted.
Values to be inserted may also be specified using keyword Values to be inserted may also be specified using keyword
arguments. arguments.
Values will be inserted from one of several sources. The Values will be inserted from one of several sources. The
sources, in the order in which they are consulted, are: sources, in the order in which they are consulted, are:
o Keyword arguments, o Keyword arguments,
o The 'client' argument, o The 'client' argument,
o The 'mapping' argument, o The 'mapping' argument,
o The keyword arguments provided when the object was o The keyword arguments provided when the object was
created, and created, and
o The 'mapping' argument provided when the template was o The 'mapping' argument provided when the template was
created. created.
''' '''
# print '============================================================' # print '============================================================'
# print '__called__' # print '__called__'
# print self.raw # print self.raw
# print kw # print kw
# print client # print client
# print mapping # print mapping
# print '============================================================' # print '============================================================'
if mapping is None: mapping = {} if mapping is None: mapping = {}
if not hasattr(self,'cooked'): if not hasattr(self,'cooked'):
try: changed=self.__changed__() try: changed=self.__changed__()
except: changed=1 except: changed=1
self.cook() self.cook()
if not changed: self.__changed__(0) if not changed: self.__changed__(0)
pushed=None pushed=None
try: try:
if mapping.__class__ is TemplateDict: pushed=0 if mapping.__class__ is TemplateDict: pushed=0
except: pass except: pass
globals=self.globals globals=self.globals
if pushed is not None: if pushed is not None:
# We were passed a TemplateDict, so we must be a sub-template # We were passed a TemplateDict, so we must be a sub-template
md=mapping md=mapping
push=md._push push=md._push
if globals: if globals:
push(self.globals) push(self.globals)
pushed=pushed+1 pushed=pushed+1
else: else:
md=TemplateDict() md=TemplateDict()
push=md._push push=md._push
shared_globals=self.shared_globals shared_globals=self.shared_globals
if shared_globals: push(shared_globals) if shared_globals: push(shared_globals)
if globals: push(globals) if globals: push(globals)
if mapping: if mapping:
push(mapping) push(mapping)
if hasattr(mapping,'AUTHENTICATED_USER'): if hasattr(mapping,'AUTHENTICATED_USER'):
md.AUTHENTICATED_USER=mapping['AUTHENTICATED_USER'] md.AUTHENTICATED_USER=mapping['AUTHENTICATED_USER']
md.validate=self.validate md.validate=self.validate
if client is not None: md.this=client if client is not None: md.this=client
pushed=0 pushed=0
level=md.level level=md.level
if level > 200: raise SystemError, ( if level > 200: raise SystemError, (
'infinite recursion in document template') 'infinite recursion in document template')
md.level=level+1 md.level=level+1
if client is not None: if client is not None:
push(InstanceDict(client,md)) # Circ. Ref. 8-| push(InstanceDict(client,md)) # Circ. Ref. 8-|
pushed=pushed+1 pushed=pushed+1
if self._vars: if self._vars:
push(self._vars) push(self._vars)
pushed=pushed+1 pushed=pushed+1
if kw: if kw:
push(kw) push(kw)
pushed=pushed+1 pushed=pushed+1
try: try:
return render_blocks(self.blocks,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
validate=None validate=None
def __str__(self): def __str__(self):
return self.read() return self.read()
class FileMixin: class FileMixin:
# Mix-in class to abstract certain file-related attributes # Mix-in class to abstract certain file-related attributes
edited_source='' edited_source=''
__state_names__=( __state_names__=(
String.__state_names__ + String.__state_names__ +
('edited_source',)) ('edited_source',))
def __init__(self, file_name='', mapping=None, **vars): def __init__(self, file_name='', mapping=None, **vars):
"""\ """\
Create a document template based on a named file. Create a document template based on a named file.
The optional parameter, 'mapping', may be used to provide a The optional parameter, 'mapping', may be used to provide a
mapping object containing defaults for values to be inserted. mapping object containing defaults for values to be inserted.
""" """
self.raw=file_name self.raw=file_name
self.initvars(mapping, vars) self.initvars(mapping, vars)
self.setName(file_name) self.setName(file_name)
def read_raw(self): def read_raw(self):
if self.edited_source: return self.edited_source if self.edited_source: return self.edited_source
if self.raw: return open(self.raw,'r').read() if self.raw: return open(self.raw,'r').read()
return '' return ''
class File(FileMixin, String): class File(FileMixin, String):
"""\ """\
...@@ -512,4 +512,3 @@ class File(FileMixin, String): ...@@ -512,4 +512,3 @@ class File(FileMixin, String):
template is used the first time. template is used the first time.
""" """
def manage_edit(self,data): raise TypeError, 'cannot edit files' def manage_edit(self,data): raise TypeError, 'cannot edit files'
...@@ -54,8 +54,8 @@ ...@@ -54,8 +54,8 @@
__doc__='''Machinery to support through-the-web editing __doc__='''Machinery to support through-the-web editing
$Id: DT_UI.py,v 1.6 1998/09/14 20:48:41 jim Exp $''' $Id: DT_UI.py,v 1.7 1998/09/14 22:03:33 jim Exp $'''
__version__='$Revision: 1.6 $'[11:-2] __version__='$Revision: 1.7 $'[11:-2]
from DT_HTML import HTML from DT_HTML import HTML
...@@ -97,12 +97,12 @@ HTML._manage_editForm = HTML( ...@@ -97,12 +97,12 @@ HTML._manage_editForm = HTML(
<!--#/if FactoryDefaultString--> <!--#/if FactoryDefaultString-->
<INPUT NAME=SUBMIT TYPE="SUBMIT" VALUE="Cancel"> <INPUT NAME=SUBMIT TYPE="SUBMIT" VALUE="Cancel">
<!--#if HTTP_REFERER--> <!--#if HTTP_REFERER-->
<INPUT NAME="CANCEL_ACTION" TYPE="HIDDEN" <INPUT NAME="CANCEL_ACTION" TYPE="HIDDEN"
VALUE="<!--#var HTTP_REFERER-->"> VALUE="<!--#var HTTP_REFERER-->">
<!--#else HTTP_REFERER--> <!--#else HTTP_REFERER-->
<!--#if PARENT_URL--> <!--#if PARENT_URL-->
<INPUT NAME="CANCEL_ACTION" TYPE="HIDDEN" <INPUT NAME="CANCEL_ACTION" TYPE="HIDDEN"
VALUE="<!--#var PARENT_URL-->"> VALUE="<!--#var PARENT_URL-->">
<!--#/if PARENT_URL--> <!--#/if PARENT_URL-->
<!--#/if HTTP_REFERER--> <!--#/if HTTP_REFERER-->
</center> </center>
...@@ -118,13 +118,13 @@ HTML.editConfirmation=HTML( ...@@ -118,13 +118,13 @@ HTML.editConfirmation=HTML(
"""<html><head><title>Change Successful</title></head><body> """<html><head><title>Change Successful</title></head><body>
<!--#if CANCEL_ACTION--> <!--#if CANCEL_ACTION-->
<form action="<!--#var CANCEL_ACTION-->" method="POST"> <form action="<!--#var CANCEL_ACTION-->" method="POST">
<center> <center>
<em><!--#var dt_edit_name--></em><br>has been changed.<br><br> <em><!--#var dt_edit_name--></em><br>has been changed.<br><br>
<input type=submit name="SUBMIT" value="OK"> <input type=submit name="SUBMIT" value="OK">
</center> </center>
</form></body></html> </form></body></html>
<!--#else CANCEL_ACTION--> <!--#else CANCEL_ACTION-->
<center> <center>
<em><!--#var dt_edit_name--></em><br>has been changed. <em><!--#var dt_edit_name--></em><br>has been changed.
</center> </center>
<!--#/if CANCEL_ACTION-->""") <!--#/if CANCEL_ACTION-->""")
...@@ -51,8 +51,8 @@ ...@@ -51,8 +51,8 @@
# (540) 371-6909 # (540) 371-6909
# #
############################################################################## ##############################################################################
'''$Id: DT_Util.py,v 1.46 1998/09/14 20:48:41 jim Exp $''' '''$Id: DT_Util.py,v 1.47 1998/09/14 22:03:33 jim Exp $'''
__version__='$Revision: 1.46 $'[11:-2] __version__='$Revision: 1.47 $'[11:-2]
import regex, string, math, os import regex, string, math, os
from string import strip, join, atoi, lower, split, find from string import strip, join, atoi, lower, split, find
...@@ -65,37 +65,37 @@ ValidationError='Unauthorized' ...@@ -65,37 +65,37 @@ ValidationError='Unauthorized'
def html_quote(v, name='(Unknown name)', md={}, def html_quote(v, name='(Unknown name)', md={},
character_entities=( character_entities=(
(('&'), '&amp;'), (('&'), '&amp;'),
(("<"), '&lt;' ), (("<"), '&lt;' ),
((">"), '&gt;' ), ((">"), '&gt;' ),
(('"'), '&quot;'))): #" (('"'), '&quot;'))): #"
text=str(v) text=str(v)
for re,name in character_entities: for re,name in character_entities:
if find(text, re) >= 0: text=join(split(text,re),name) if find(text, re) >= 0: text=join(split(text,re),name)
return text return text
def int_param(params,md,name,default=0, st=type('')): def int_param(params,md,name,default=0, st=type('')):
try: v=params[name] try: v=params[name]
except: v=default except: v=default
if v: if v:
try: v=atoi(v) try: v=atoi(v)
except: except:
v=md[v] v=md[v]
if type(v) is st: v=atoi(v) if type(v) is st: v=atoi(v)
return v return v
def careful_getattr(md, inst, name): def careful_getattr(md, inst, name):
if name[:1]!='_': if name[:1]!='_':
validate=md.validate validate=md.validate
if validate is None: return getattr(inst, name) if validate is None: return getattr(inst, name)
if hasattr(inst,'aq_acquire'): if hasattr(inst,'aq_acquire'):
return inst.aq_acquire(name, validate, md) return inst.aq_acquire(name, validate, md)
v=getattr(inst, name) v=getattr(inst, name)
if validate(inst,inst,name,v,md): return v if validate(inst,inst,name,v,md): return v
raise ValidationError, name raise ValidationError, name
...@@ -127,18 +127,18 @@ def careful_getitem(md, mapping, key): ...@@ -127,18 +127,18 @@ def careful_getitem(md, mapping, key):
def careful_getslice(md, seq, *indexes): def careful_getslice(md, seq, *indexes):
v=len(indexes) v=len(indexes)
if v==2: if v==2:
v=seq[indexes[0]:indexes[1]] v=seq[indexes[0]:indexes[1]]
elif v==1: elif v==1:
v=seq[indexes[0]:] v=seq[indexes[0]:]
else: v=seq[:] else: v=seq[:]
if type(seq) is type(''): return v # Short-circuit common case if type(seq) is type(''): return v # Short-circuit common case
validate=md.validate validate=md.validate
if validate is not None: if validate is not None:
for e in v: for e in v:
if not validate(seq,seq,'',e,md): if not validate(seq,seq,'',e,md):
raise ValidationError, 'unauthorized access to slice member' raise ValidationError, 'unauthorized access to slice member'
return v return v
...@@ -149,7 +149,7 @@ except: from pDocumentTemplate import InstanceDict, TemplateDict, render_blocks ...@@ -149,7 +149,7 @@ except: from pDocumentTemplate import InstanceDict, TemplateDict, render_blocks
d=TemplateDict.__dict__ d=TemplateDict.__dict__
for name in ('None', 'abs', 'chr', 'divmod', 'float', 'hash', 'hex', 'int', for name in ('None', 'abs', 'chr', 'divmod', 'float', 'hash', 'hex', 'int',
'len', 'max', 'min', 'oct', 'ord', 'pow', 'round', 'str'): 'len', 'max', 'min', 'oct', 'ord', 'pow', 'round', 'str'):
d[name]=__builtins__[name] d[name]=__builtins__[name]
d['string']=string d['string']=string
d['math']=math d['math']=math
...@@ -158,7 +158,7 @@ d['whrandom']=whrandom ...@@ -158,7 +158,7 @@ d['whrandom']=whrandom
def test(self, *args): def test(self, *args):
l=len(args) l=len(args)
for i in range(1, l, 2): for i in range(1, l, 2):
if args[i-1]: return args[i] if args[i-1]: return args[i]
if l%2: return args[-1] if l%2: return args[-1]
...@@ -211,16 +211,16 @@ class Eval(VSEval.Eval): ...@@ -211,16 +211,16 @@ class Eval(VSEval.Eval):
def eval(self, mapping): def eval(self, mapping):
d={'_vars': mapping, '_': mapping} d={'_vars': mapping, '_': mapping}
code=self.code code=self.code
globals=self.globals globals=self.globals
for name in self.used: for name in self.used:
try: d[name]=mapping.getitem(name,0) try: d[name]=mapping.getitem(name,0)
except KeyError: except KeyError:
if name=='_getattr': if name=='_getattr':
d['__builtins__']=globals d['__builtins__']=globals
exec compiled_getattr in d exec compiled_getattr in d
return eval(code,globals,d) return eval(code,globals,d)
def name_param(params,tag='',expr=0, attr='name', default_unnamed=1): def name_param(params,tag='',expr=0, attr='name', default_unnamed=1):
...@@ -228,10 +228,10 @@ def name_param(params,tag='',expr=0, attr='name', default_unnamed=1): ...@@ -228,10 +228,10 @@ def name_param(params,tag='',expr=0, attr='name', default_unnamed=1):
__traceback_info__=params, tag, expr, attr __traceback_info__=params, tag, expr, attr
#if expr and used('expr') and used('') and not used(params['']): #if expr and used('expr') and used('') and not used(params['']):
# # Fix up something like: <!--#in expr="whatever" mapping--> # # Fix up something like: <!--#in expr="whatever" mapping-->
# params[params['']]=default_unnamed # params[params['']]=default_unnamed
# del params[''] # del params['']
if used(''): if used(''):
v=params[''] v=params['']
...@@ -266,16 +266,16 @@ def name_param(params,tag='',expr=0, attr='name', default_unnamed=1): ...@@ -266,16 +266,16 @@ def name_param(params,tag='',expr=0, attr='name', default_unnamed=1):
return params[''] return params['']
elif used(attr): elif used(attr):
if expr: if expr:
if used('expr'): if used('expr'):
raise ParseError, ('%s and expr given' % attr, tag) raise ParseError, ('%s and expr given' % attr, tag)
return params[attr],None return params[attr],None
return params[attr] return params[attr]
elif expr and used('expr'): elif expr and used('expr'):
name=params['expr'] name=params['expr']
expr=Eval(name, expr_globals) expr=Eval(name, expr_globals)
return name, expr return name, expr
raise ParseError, ('No %s given' % attr, tag) raise ParseError, ('No %s given' % attr, tag)
Expr_doc=""" Expr_doc="""
...@@ -337,17 +337,17 @@ Python expression support ...@@ -337,17 +337,17 @@ Python expression support
ListType=type([]) ListType=type([])
def parse_params(text, def parse_params(text,
result=None, result=None,
tag='', tag='',
unparmre=regex.compile( unparmre=regex.compile(
'\([\0- ]*\([^\0- =\"]+\)\)'), '\([\0- ]*\([^\0- =\"]+\)\)'),
qunparmre=regex.compile( qunparmre=regex.compile(
'\([\0- ]*\("[^"]*"\)\)'), '\([\0- ]*\("[^"]*"\)\)'),
parmre=regex.compile( parmre=regex.compile(
'\([\0- ]*\([^\0- =\"]+\)=\([^\0- =\"]+\)\)'), '\([\0- ]*\([^\0- =\"]+\)=\([^\0- =\"]+\)\)'),
qparmre=regex.compile( qparmre=regex.compile(
'\([\0- ]*\([^\0- =\"]+\)="\([^"]*\)\"\)'), '\([\0- ]*\([^\0- =\"]+\)="\([^"]*\)\"\)'),
**parms): **parms):
"""Parse tag parameters """Parse tag parameters
...@@ -373,41 +373,41 @@ def parse_params(text, ...@@ -373,41 +373,41 @@ def parse_params(text,
result=result or {} result=result or {}
if parmre.match(text) >= 0: if parmre.match(text) >= 0:
name=lower(parmre.group(2)) name=lower(parmre.group(2))
value=parmre.group(3) value=parmre.group(3)
l=len(parmre.group(1)) l=len(parmre.group(1))
elif qparmre.match(text) >= 0: elif qparmre.match(text) >= 0:
name=lower(qparmre.group(2)) name=lower(qparmre.group(2))
value=qparmre.group(3) value=qparmre.group(3)
l=len(qparmre.group(1)) l=len(qparmre.group(1))
elif unparmre.match(text) >= 0: elif unparmre.match(text) >= 0:
name=unparmre.group(2) name=unparmre.group(2)
l=len(unparmre.group(1)) l=len(unparmre.group(1))
if result: if result:
if parms.has_key(name): if parms.has_key(name):
if parms[name] is None: raise ParseError, ( if parms[name] is None: raise ParseError, (
'Attribute %s requires a value' % name, tag) 'Attribute %s requires a value' % name, tag)
result[name]=parms[name] result[name]=parms[name]
else: raise ParseError, ( else: raise ParseError, (
'Invalid attribute name, "%s"' % name, tag) 'Invalid attribute name, "%s"' % name, tag)
else: else:
result['']=name result['']=name
return apply(parse_params,(text[l:],result),parms) return apply(parse_params,(text[l:],result),parms)
elif qunparmre.match(text) >= 0: elif qunparmre.match(text) >= 0:
name=qunparmre.group(2) name=qunparmre.group(2)
l=len(qunparmre.group(1)) l=len(qunparmre.group(1))
if result: raise ParseError, ( if result: raise ParseError, (
'Invalid attribute name, "%s"' % name, tag) 'Invalid attribute name, "%s"' % name, tag)
else: result['']=name else: result['']=name
return apply(parse_params,(text[l:],result),parms) return apply(parse_params,(text[l:],result),parms)
else: else:
if not text or not strip(text): return result if not text or not strip(text): return result
raise ParseError, ('invalid parameter: "%s"' % text, tag) raise ParseError, ('invalid parameter: "%s"' % text, tag)
if not parms.has_key(name): if not parms.has_key(name):
raise ParseError, ( raise ParseError, (
'Invalid attribute name, "%s"' % name, tag) 'Invalid attribute name, "%s"' % name, tag)
if result.has_key(name): if result.has_key(name):
p=parms[name] p=parms[name]
......
...@@ -100,8 +100,8 @@ __doc__='''Variable insertion parameters ...@@ -100,8 +100,8 @@ __doc__='''Variable insertion parameters
- Cannot be formatted with the specified format, and - Cannot be formatted with the specified format, and
- Are either the special Python value 'None' or - Are either the special Python value 'None' or
are false and yield an empty string when converted to are false and yield an empty string when converted to
a string. a string.
For example, when showing a monitary value retrieved from a For example, when showing a monitary value retrieved from a
database that is either a number or a missing value, the database that is either a number or a missing value, the
...@@ -164,8 +164,8 @@ Evaluating expressions without rendering results ...@@ -164,8 +164,8 @@ Evaluating expressions without rendering results
''' # ' ''' # '
__rcs_id__='$Id: DT_Var.py,v 1.22 1998/09/14 20:48:42 jim Exp $' __rcs_id__='$Id: DT_Var.py,v 1.23 1998/09/14 22:03:33 jim Exp $'
__version__='$Revision: 1.22 $'[11:-2] __version__='$Revision: 1.23 $'[11:-2]
from DT_Util import parse_params, name_param, html_quote, str from DT_Util import parse_params, name_param, html_quote, str
import regex, string, sys, regex import regex, string, sys, regex
...@@ -176,92 +176,92 @@ class Var: ...@@ -176,92 +176,92 @@ class Var:
expr=None expr=None
def __init__(self, args, fmt='s'): def __init__(self, args, fmt='s'):
args = parse_params(args, name='', lower=1, upper=1, expr='', args = parse_params(args, name='', lower=1, upper=1, expr='',
capitalize=1, spacify=1, null='', fmt='s', capitalize=1, spacify=1, null='', fmt='s',
size=0, etc='...', thousands_commas=1, size=0, etc='...', thousands_commas=1,
html_quote=1, url_quote=1, sql_quote=1, html_quote=1, url_quote=1, sql_quote=1,
newline_to_br=1) newline_to_br=1)
self.args=args self.args=args
self.modifiers=tuple( self.modifiers=tuple(
map(lambda t: t[1], map(lambda t: t[1],
filter(lambda m, args=args, used=args.has_key: filter(lambda m, args=args, used=args.has_key:
used(m[0]) and args[m[0]], used(m[0]) and args[m[0]],
modifiers))) modifiers)))
name, expr = name_param(args,'var',1) name, expr = name_param(args,'var',1)
self.__name__, self.expr = name, expr self.__name__, self.expr = name, expr
self.fmt = fmt self.fmt = fmt
if len(args)==1 and fmt=='s': if len(args)==1 and fmt=='s':
if expr is None: expr=name if expr is None: expr=name
else: expr=expr.eval else: expr=expr.eval
self.simple_form=expr, self.simple_form=expr,
def render(self, md): def render(self, md):
name=self.__name__ name=self.__name__
val=self.expr val=self.expr
if val is None: if val is None:
val = md[name] val = md[name]
else: else:
val=val.eval(md) val=val.eval(md)
args=self.args args=self.args
have_arg=args.has_key have_arg=args.has_key
__traceback_info__=name, val, args __traceback_info__=name, val, args
# handle special formats defined using fmt= first # handle special formats defined using fmt= first
if have_arg('fmt'): if have_arg('fmt'):
fmt=args['fmt'] fmt=args['fmt']
if have_arg('null') and not val and val != 0: if have_arg('null') and not val and val != 0:
try: try:
if hasattr(val, fmt): if hasattr(val, fmt):
val = getattr(val,fmt)() val = getattr(val,fmt)()
elif special_formats.has_key(fmt): elif special_formats.has_key(fmt):
val = special_formats[fmt](val, name, md) val = special_formats[fmt](val, name, md)
elif fmt=='': val='' elif fmt=='': val=''
else: val = fmt % val else: val = fmt % val
except: except:
t, v = sys.exc_type, sys.exc_value t, v = sys.exc_type, sys.exc_value
if val is None or not str(val): return args['null'] if val is None or not str(val): return args['null']
raise t, v raise t, v
else: else:
# We duplicate the code here to avoid exception handler # We duplicate the code here to avoid exception handler
# which tends to screw up stack or leak # which tends to screw up stack or leak
if hasattr(val, fmt): if hasattr(val, fmt):
val = getattr(val,fmt)() val = getattr(val,fmt)()
elif special_formats.has_key(fmt): elif special_formats.has_key(fmt):
val = special_formats[fmt](val, name, md) val = special_formats[fmt](val, name, md)
elif fmt=='': val='' elif fmt=='': val=''
else: val = fmt % val else: val = fmt % val
# finally, pump it through the actual string format... # finally, pump it through the actual string format...
fmt=self.fmt fmt=self.fmt
if fmt=='s': val=str(val) if fmt=='s': val=str(val)
else: val = ('%'+self.fmt) % (val,) else: val = ('%'+self.fmt) % (val,)
# next, look for upper, lower, etc # next, look for upper, lower, etc
for f in self.modifiers: val=f(val) for f in self.modifiers: val=f(val)
if have_arg('size'): if have_arg('size'):
size=args['size'] size=args['size']
try: size=atoi(size) try: size=atoi(size)
except: raise 'Document Error',( except: raise 'Document Error',(
'''a <code>size</code> attribute was used in a <code>var</code> '''a <code>size</code> attribute was used in a <code>var</code>
tag with a non-integer value.''') tag with a non-integer value.''')
if len(val) > size: if len(val) > size:
val=val[:size] val=val[:size]
l=rfind(val,' ') l=rfind(val,' ')
if l > size/2: if l > size/2:
val=val[:l+1] val=val[:l+1]
if have_arg('etc'): l=args['etc'] if have_arg('etc'): l=args['etc']
else: l='...' else: l='...'
val=val+l val=val+l
return val return val
__call__=render __call__=render
...@@ -270,11 +270,11 @@ class Call: ...@@ -270,11 +270,11 @@ class Call:
expr=None expr=None
def __init__(self, args): def __init__(self, args):
args = parse_params(args, name='', expr='') args = parse_params(args, name='', expr='')
name, expr = name_param(args,'call',1) name, expr = name_param(args,'call',1)
if expr is None: expr=name if expr is None: expr=name
else: expr=expr.eval else: expr=expr.eval
self.simple_form=expr,None self.simple_form=expr,None
def url_quote(v, name='(Unknown name)', md={}): def url_quote(v, name='(Unknown name)', md={}):
...@@ -363,7 +363,7 @@ def spacify(val): ...@@ -363,7 +363,7 @@ def spacify(val):
return val return val
modifiers=(html_quote, url_quote, newline_to_br, string.lower, string.upper, modifiers=(html_quote, url_quote, newline_to_br, string.lower, string.upper,
string.capitalize, spacify, thousands_commas, sql_quote) string.capitalize, spacify, thousands_commas, sql_quote)
modifiers=map(lambda f: (f.__name__, f), modifiers) modifiers=map(lambda f: (f.__name__, f), modifiers)
class Comment: class Comment:
...@@ -386,7 +386,6 @@ class Comment: ...@@ -386,7 +386,6 @@ class Comment:
def __init__(self, args, fmt=''): pass def __init__(self, args, fmt=''): pass
def render(self, md): def render(self, md):
return '' return ''
__call__=render __call__=render
...@@ -75,8 +75,8 @@ ...@@ -75,8 +75,8 @@
''' '''
__rcs_id__='$Id: DT_With.py,v 1.5 1998/09/14 20:48:42 jim Exp $' __rcs_id__='$Id: DT_With.py,v 1.6 1998/09/14 22:03:33 jim Exp $'
__version__='$Revision: 1.5 $'[11:-2] __version__='$Revision: 1.6 $'[11:-2]
from DT_Util import parse_params, name_param, InstanceDict, render_blocks, str from DT_Util import parse_params, name_param, InstanceDict, render_blocks, str
...@@ -86,26 +86,26 @@ class With: ...@@ -86,26 +86,26 @@ class With:
mapping=None mapping=None
def __init__(self, blocks): def __init__(self, blocks):
tname, args, section = blocks[0] tname, args, section = blocks[0]
args=parse_params(args, name='', expr='', mapping=1) args=parse_params(args, name='', expr='', mapping=1)
name,expr=name_param(args,'with',1) name,expr=name_param(args,'with',1)
if expr is None: expr=name if expr is None: expr=name
else: expr=expr.eval else: expr=expr.eval
self.__name__, self.expr = name, expr self.__name__, self.expr = name, expr
self.section=section.blocks self.section=section.blocks
if args.has_key('mapping') and args['mapping']: self.mapping=1 if args.has_key('mapping') and args['mapping']: self.mapping=1
def render(self, md): def render(self, md):
expr=self.expr expr=self.expr
if type(expr) is type(''): v=md[expr] if type(expr) is type(''): v=md[expr]
else: v=expr(md) else: v=expr(md)
if self.mapping: md._push(v) if self.mapping: md._push(v)
else: else:
if type(v) is type(()) and len(v)==1: v=v[0] if type(v) is type(()) and len(v)==1: v=v[0]
md._push(InstanceDict(v,md)) md._push(InstanceDict(v,md))
try: return render_blocks(self.section, md) try: return render_blocks(self.section, md)
finally: md._pop(1) finally: md._pop(1)
__call__=render __call__=render
...@@ -55,8 +55,8 @@ ...@@ -55,8 +55,8 @@
"""Document Template Tests """Document Template Tests
""" """
__rcs_id__='$Id: DTtest.py,v 1.8 1998/09/14 20:48:42 jim Exp $' __rcs_id__='$Id: DTtest.py,v 1.9 1998/09/14 22:03:34 jim Exp $'
__version__='$Revision: 1.8 $'[11:-2] __version__='$Revision: 1.9 $'[11:-2]
from DocumentTemplate import * from DocumentTemplate import *
import sys import sys
...@@ -71,7 +71,7 @@ class Bruce: ...@@ -71,7 +71,7 @@ class Bruce:
def __len__(self): return 7 def __len__(self): return 7
def __getitem__(self,index): def __getitem__(self,index):
if (type(index) is type(1) and if (type(index) is type(1) and
(index < 0 or index > 6)): raise IndexError, index (index < 0 or index > 6)): raise IndexError, index
return self return self
isDocTemp=0 isDocTemp=0
def __getattr__(self,name): def __getattr__(self,name):
...@@ -85,12 +85,12 @@ class arg: ...@@ -85,12 +85,12 @@ class arg:
class argv: class argv:
def __init__(self): def __init__(self):
import sys import sys
args=self.args=[] args=self.args=[]
for aa in sys.argv[1:]: args.append(arg(len(args)+1,aa)) for aa in sys.argv[1:]: args.append(arg(len(args)+1,aa))
def items(self): def items(self):
return map(lambda a: ('spam%d' % a.num, a), self.args) return map(lambda a: ('spam%d' % a.num, a), self.args)
def values(self): return self.args def values(self): return self.args
...@@ -99,25 +99,25 @@ def test1(): ...@@ -99,25 +99,25 @@ def test1():
aa=argv() aa=argv()
ss=String( ss=String(
"""\ """\
%(comment)[ blah %(comment)] %(comment)[ blah %(comment)]
<html><head><title>Test of documentation templates</title></head> <html><head><title>Test of documentation templates</title></head>
<body> <body>
%(if args)[ %(if args)[
<dl><dt>The arguments to this test program were:<p> <dl><dt>The arguments to this test program were:<p>
<dd> <dd>
<ul> <ul>
%(in args)[ %(in args)[
<li>Argument number %(num)d was %(arg)s <li>Argument number %(num)d was %(arg)s
%(in args)] %(in args)]
</ul></dl><p> </ul></dl><p>
%(if args)] %(if args)]
%(else args)[ %(else args)[
No arguments were given.<p> No arguments were given.<p>
%(else args)] %(else args)]
And thats da trooth. And thats da trooth.
</body></html> </body></html>
""") """)
print ss(aa) print ss(aa)
...@@ -129,8 +129,8 @@ def test1(): ...@@ -129,8 +129,8 @@ def test1():
print str(ss) print str(ss)
try: try:
ss(hello=1,world=2) ss(hello=1,world=2)
print 'test if test failed' print 'test if test failed'
except: pass except: pass
# Test nested templates # Test nested templates
...@@ -144,24 +144,24 @@ def test2(): ...@@ -144,24 +144,24 @@ def test2():
aa=argv() aa=argv()
print HTML( print HTML(
'''\ '''\
<html><head><title>Test of documentation templates</title></head> <html><head><title>Test of documentation templates</title></head>
<body> <body>
<!--#if values--> <!--#if values-->
The arguments were: The arguments were:
<!--#in <!--#in
values--> values-->
<!--#var <!--#var
sequence-roman-->. sequence-roman-->.
Argument <!--#var Argument <!--#var
num fmt=d--> was <!--#var arg--> num fmt=d--> was <!--#var arg-->
<!--#/in values--> <!--#/in values-->
<!--#else values--> <!--#else values-->
No arguments were given.<p> No arguments were given.<p>
<!--#/if values--> <!--#/if values-->
And I\'m 100% sure! And I\'m 100% sure!
</body></html> </body></html>
''')(aa) ''')(aa)
def test3(): def test3():
test2() test2()
...@@ -169,39 +169,39 @@ def test3(): ...@@ -169,39 +169,39 @@ def test3():
aa=argv() aa=argv()
h=HTML( h=HTML(
'''\ '''\
<html><head><title>Test of documentation templates</title></head> <html><head><title>Test of documentation templates</title></head>
<body> <body>
<!--#if args--> <!--#if args-->
The arguments were: The arguments were:
<!--#in args size=size end=end--> <!--#in args size=size end=end-->
<!--#if previous-sequence--> <!--#if previous-sequence-->
(<!--#var previous-sequence-start-arg-->- (<!--#var previous-sequence-start-arg-->-
<!--#var previous-sequence-end-arg-->) <!--#var previous-sequence-end-arg-->)
<!--#/if previous-sequence--> <!--#/if previous-sequence-->
<!--#if sequence-start--> <!--#if sequence-start-->
<dl> <dl>
<!--#/if sequence-start--> <!--#/if sequence-start-->
<dt><!--#var sequence-arg-->.</dt> <dt><!--#var sequence-arg-->.</dt>
<dd>Argument <!--#var num fmt=d--> was <!--#var arg--></dd> <dd>Argument <!--#var num fmt=d--> was <!--#var arg--></dd>
<!--#if next-sequence--> <!--#if next-sequence-->
(<!--#var next-sequence-start-arg-->- (<!--#var next-sequence-start-arg-->-
<!--#var next-sequence-end-arg-->) <!--#var next-sequence-end-arg-->)
<!--#/if next-sequence--> <!--#/if next-sequence-->
<!--#/in args--> <!--#/in args-->
</dl> </dl>
<!--#else args--> <!--#else args-->
No arguments were given.<p> No arguments were given.<p>
<!--#/if args--> <!--#/if args-->
And I\'m 100% sure! And I\'m 100% sure!
</body></html> </body></html>
''') ''')
size,orphan=5,0 size,orphan=5,0
for end in range(20): for end in range(20):
end=end+1 end=end+1
print '='*60, '\n' print '='*60, '\n'
print h(aa,size=size, orphan=orphan, end=end) print h(aa,size=size, orphan=orphan, end=end)
def test3_okay(key, val): def test3_okay(key, val):
print 'Testing', key print 'Testing', key
...@@ -213,178 +213,178 @@ def test4(): ...@@ -213,178 +213,178 @@ def test4():
def item2(key,**kw): return kw def item2(key,**kw): return kw
class item_class: class item_class:
def __init__(self,key,**kw): def __init__(self,key,**kw):
for k in kw.keys(): self.__dict__[k]=kw[k] for k in kw.keys(): self.__dict__[k]=kw[k]
items=( items=(
item( 1,dealer='Bay Chevy', make='Chevrolet', model='Caprice', year=96), item( 1,dealer='Bay Chevy', make='Chevrolet', model='Caprice', year=96),
item( 2,dealer='Bay Chevy', make='Chevrolet', model='Nova', year=96), item( 2,dealer='Bay Chevy', make='Chevrolet', model='Nova', year=96),
item( 4,dealer='Bay Chevy', make='Chevrolet', model='Nova', year=96), item( 4,dealer='Bay Chevy', make='Chevrolet', model='Nova', year=96),
item( 5,dealer='Bay Chevy', make='Chevrolet', model='Nova', year=96), item( 5,dealer='Bay Chevy', make='Chevrolet', model='Nova', year=96),
item( 3,dealer='Bay Chevy', make='Chevrolet', model='Corvett', year=96), item( 3,dealer='Bay Chevy', make='Chevrolet', model='Corvett', year=96),
item( 6,dealer='Bay Chevy', make='Chevrolet', model='Lumina', year=96), item( 6,dealer='Bay Chevy', make='Chevrolet', model='Lumina', year=96),
item( 7,dealer='Bay Chevy', make='Chevrolet', model='Lumina', year=96), item( 7,dealer='Bay Chevy', make='Chevrolet', model='Lumina', year=96),
item( 8,dealer='Bay Chevy', make='Chevrolet', model='Lumina', year=95), item( 8,dealer='Bay Chevy', make='Chevrolet', model='Lumina', year=95),
item( 9,dealer='Bay Chevy', make='Chevrolet', model='Corsica', year=96), item( 9,dealer='Bay Chevy', make='Chevrolet', model='Corsica', year=96),
item(10,dealer='Bay Chevy', make='Chevrolet', model='Corsica', year=96), item(10,dealer='Bay Chevy', make='Chevrolet', model='Corsica', year=96),
item(11,dealer='Bay Chevy', make='Toyota', model='Camry', year=95), item(11,dealer='Bay Chevy', make='Toyota', model='Camry', year=95),
item(12,dealer='Colman Olds', make='Olds', model='Ciera', year=96), item(12,dealer='Colman Olds', make='Olds', model='Ciera', year=96),
item(12,dealer='Colman Olds', make='Olds', model='Ciera', year=96), item(12,dealer='Colman Olds', make='Olds', model='Ciera', year=96),
item(12,dealer='Colman Olds', make='Olds', model='Ciera', year=96), item(12,dealer='Colman Olds', make='Olds', model='Ciera', year=96),
item(12,dealer='Colman Olds', make='Olds', model='Cutlass', year=96), item(12,dealer='Colman Olds', make='Olds', model='Cutlass', year=96),
item(12,dealer='Colman Olds', make='Olds', model='Cutlas', year=95), item(12,dealer='Colman Olds', make='Olds', model='Cutlas', year=95),
item(12,dealer='Colman Olds', make='Dodge', model='Shadow', year=93), item(12,dealer='Colman Olds', make='Dodge', model='Shadow', year=93),
item(12,dealer='Colman Olds', make='Jeep', model='Cheroke', year=94), item(12,dealer='Colman Olds', make='Jeep', model='Cheroke', year=94),
item(12,dealer='Colman Olds', make='Toyota', model='Previa', year=92), item(12,dealer='Colman Olds', make='Toyota', model='Previa', year=92),
item(12,dealer='Colman Olds', make='Toyota', model='Celica', year=93), item(12,dealer='Colman Olds', make='Toyota', model='Celica', year=93),
item(12,dealer='Colman Olds', make='Toyota', model='Camry', year=93), item(12,dealer='Colman Olds', make='Toyota', model='Camry', year=93),
item(12,dealer='Colman Olds', make='Honda', model='Accord', year=94), item(12,dealer='Colman Olds', make='Honda', model='Accord', year=94),
item(12,dealer='Colman Olds', make='Honda', model='Accord', year=92), item(12,dealer='Colman Olds', make='Honda', model='Accord', year=92),
item(12,dealer='Colman Olds', make='Honda', model='Civic', year=94), item(12,dealer='Colman Olds', make='Honda', model='Civic', year=94),
item(12,dealer='Colman Olds', make='Honda', model='Civix', year=93), item(12,dealer='Colman Olds', make='Honda', model='Civix', year=93),
item( 1,dealer='Spam Chev', make='Chevrolet', model='Caprice', year=96), item( 1,dealer='Spam Chev', make='Chevrolet', model='Caprice', year=96),
item( 2,dealer='Spam Chev', make='Chevrolet', model='Nova', year=96), item( 2,dealer='Spam Chev', make='Chevrolet', model='Nova', year=96),
item( 4,dealer='Spam Chev', make='Chevrolet', model='Nova', year=96), item( 4,dealer='Spam Chev', make='Chevrolet', model='Nova', year=96),
item( 5,dealer='Spam Chev', make='Chevrolet', model='Nova', year=96), item( 5,dealer='Spam Chev', make='Chevrolet', model='Nova', year=96),
item( 3,dealer='Spam Chev', make='Chevrolet', model='Corvett', year=96), item( 3,dealer='Spam Chev', make='Chevrolet', model='Corvett', year=96),
item( 6,dealer='Spam Chev', make='Chevrolet', model='Lumina', year=96), item( 6,dealer='Spam Chev', make='Chevrolet', model='Lumina', year=96),
item( 7,dealer='Spam Chev', make='Chevrolet', model='Lumina', year=96), item( 7,dealer='Spam Chev', make='Chevrolet', model='Lumina', year=96),
item( 8,dealer='Spam Chev', make='Chevrolet', model='Lumina', year=95), item( 8,dealer='Spam Chev', make='Chevrolet', model='Lumina', year=95),
item( 9,dealer='Spam Chev', make='Chevrolet', model='Corsica', year=96), item( 9,dealer='Spam Chev', make='Chevrolet', model='Corsica', year=96),
item(10,dealer='Spam Chev', make='Chevrolet', model='Corsica', year=96), item(10,dealer='Spam Chev', make='Chevrolet', model='Corsica', year=96),
item(11,dealer='Spam Chevy', make='Toyota', model='Camry', year=95), item(11,dealer='Spam Chevy', make='Toyota', model='Camry', year=95),
item(12,dealer='Spam Olds', make='Olds', model='Ciera', year=96), item(12,dealer='Spam Olds', make='Olds', model='Ciera', year=96),
item(12,dealer='Spam Olds', make='Olds', model='Ciera', year=96), item(12,dealer='Spam Olds', make='Olds', model='Ciera', year=96),
item(12,dealer='Spam Olds', make='Olds', model='Ciera', year=96), item(12,dealer='Spam Olds', make='Olds', model='Ciera', year=96),
item(12,dealer='Spam Olds', make='Olds', model='Cutlass', year=96), item(12,dealer='Spam Olds', make='Olds', model='Cutlass', year=96),
item(12,dealer='Spam Olds', make='Olds', model='Cutlas', year=95), item(12,dealer='Spam Olds', make='Olds', model='Cutlas', year=95),
item(12,dealer='Spam Olds', make='Dodge', model='Shadow', year=93), item(12,dealer='Spam Olds', make='Dodge', model='Shadow', year=93),
item(12,dealer='Spam Olds', make='Jeep', model='Cheroke', year=94), item(12,dealer='Spam Olds', make='Jeep', model='Cheroke', year=94),
item(12,dealer='Spam Olds', make='Toyota', model='Previa', year=92), item(12,dealer='Spam Olds', make='Toyota', model='Previa', year=92),
item(12,dealer='Spam Olds', make='Toyota', model='Celica', year=93), item(12,dealer='Spam Olds', make='Toyota', model='Celica', year=93),
item(12,dealer='Spam Olds', make='Toyota', model='Camry', year=93), item(12,dealer='Spam Olds', make='Toyota', model='Camry', year=93),
item(12,dealer='Spam Olds', make='Honda', model='Accord', year=94), item(12,dealer='Spam Olds', make='Honda', model='Accord', year=94),
item(12,dealer='Spam Olds', make='Honda', model='Accord', year=92), item(12,dealer='Spam Olds', make='Honda', model='Accord', year=92),
item(12,dealer='Spam Olds', make='Honda', model='Civic', year=94), item(12,dealer='Spam Olds', make='Honda', model='Civic', year=94),
item(12,dealer='Spam Olds', make='Honda', model='Civix', year=93), item(12,dealer='Spam Olds', make='Honda', model='Civix', year=93),
) )
html=HTML( html=HTML(
'''\ '''\
<html><head><title>Inventory by Dealer</title></head><body> <html><head><title>Inventory by Dealer</title></head><body>
<dl> <dl>
<!--#in inventory mapping size=5 start=first_ad--> <!--#in inventory mapping size=5 start=first_ad-->
<!--#if previous-sequence--> <!--#if previous-sequence-->
<!--#in <!--#in
previous-batches mapping--> previous-batches mapping-->
(<!--#var batch-start-var-dealer--> (<!--#var batch-start-var-dealer-->
<!--#var batch-start-var-year--> <!--#var batch-start-var-year-->
<!--#var batch-start-var-make--> <!--#var batch-start-var-make-->
<!--#var batch-start-var-model--> <!--#var batch-start-var-model-->
- -
<!--#var batch-end-var-dealer--> <!--#var batch-end-var-dealer-->
<!--#var batch-end-var-year--> <!--#var batch-end-var-year-->
<!--#var batch-end-var-make--> <!--#var batch-end-var-make-->
<!--#var batch-end-var-model--> <!--#var batch-end-var-model-->
) )
<!--#/in previous-batches--> <!--#/in previous-batches-->
<!--#/if previous-sequence--> <!--#/if previous-sequence-->
<!--#if first-dealer--> <!--#if first-dealer-->
<dt><!--#var dealer--></dt><dd> <dt><!--#var dealer--></dt><dd>
<!--#/if first-dealer--> <!--#/if first-dealer-->
<!--#var year--> <!--#var make--> <!--#var model--> <p> <!--#var year--> <!--#var make--> <!--#var model--> <p>
<!--#if last-dealer--> <!--#if last-dealer-->
</dd> </dd>
<!--#/if last-dealer--> <!--#/if last-dealer-->
<!--#if next-sequence--> <!--#if next-sequence-->
<!--#in next-batches mapping--> <!--#in next-batches mapping-->
(<!--#var batch-start-var-dealer--> (<!--#var batch-start-var-dealer-->
<!--#var batch-start-var-year--> <!--#var batch-start-var-year-->
<!--#var batch-start-var-make--> <!--#var batch-start-var-make-->
<!--#var batch-start-var-model--> <!--#var batch-start-var-model-->
- -
<!--#var batch-end-var-dealer--> <!--#var batch-end-var-dealer-->
<!--#var batch-end-var-year--> <!--#var batch-end-var-year-->
<!--#var batch-end-var-make--> <!--#var batch-end-var-make-->
<!--#var batch-end-var-model--> <!--#var batch-end-var-model-->
) )
<!--#/in next-batches--> <!--#/in next-batches-->
<!--#/if next-sequence--> <!--#/if next-sequence-->
<!--#/in inventory--> <!--#/in inventory-->
</dl> </dl>
</body></html> </body></html>
''') ''')
print html(inventory=items, first_ad=15) print html(inventory=items, first_ad=15)
def test5(): def test5():
html=HTML( html=HTML(
'''\ '''\
<html><head><title>Affiliate Manager Affiliate Menu</title></head><body> <html><head><title>Affiliate Manager Affiliate Menu</title></head><body>
<CENTER> <CENTER>
<FONT SIZE="+2">Affiliate Manager Menu</FONT> <FONT SIZE="+2">Affiliate Manager Menu</FONT>
<p> <p>
<!--#if affiliates--> <!--#if affiliates-->
Select an affiliate to visit:<br> Select an affiliate to visit:<br>
<UL> <UL>
<!--#in affiliates--> <!--#in affiliates-->
<LI><A HREF="<!--#var PARENT_URL-->/<!--#var ID-->/"> <LI><A HREF="<!--#var PARENT_URL-->/<!--#var ID-->/">
<!--#var name--></A></LI> <!--#var name--></A></LI>
<!--#/in affiliates--> <!--#/in affiliates-->
</UL> </UL>
<!--#/if affiliates--> <!--#/if affiliates-->
<p> <p>
<A HREF="<!--#var PARENT_URL-->/add_affiliate_form">Add an affiliate</A> <A HREF="<!--#var PARENT_URL-->/add_affiliate_form">Add an affiliate</A>
<!--#if affiliates--> <!--#if affiliates-->
* <A HREF="<!--#var PARENT_URL-->/delete_affiliates_form"> * <A HREF="<!--#var PARENT_URL-->/delete_affiliates_form">
Delete affiliates</A> Delete affiliates</A>
<!--#/if affiliates--> <!--#/if affiliates-->
</p> </p>
</CENTER> </CENTER>
</body> </body>
</html>''') </html>''')
print html(affiliates=[], PARENT_URL='www') print html(affiliates=[], PARENT_URL='www')
def test6(): def test6():
def d(**kw): return kw def d(**kw): return kw
data=(d(name='jim', age=38), data=(d(name='jim', age=38),
# d(name='kak', age=40), # d(name='kak', age=40),
d(name='will', age=7), d(name='will', age=7),
d(name='drew', age=4), d(name='drew', age=4),
d(name='ches', age=1), d(name='ches', age=1),
) )
html=HTML( html=HTML(
"""Ages:\n """Ages:\n
<!--#in data mapping--> <!--#in data mapping-->
<!--#if sequence-end--> <!--#if sequence-end-->
--------------- ---------------
for variable name: for variable name:
min: <!--#var min-name--> min: <!--#var min-name-->
max: <!--#var max-name--> max: <!--#var max-name-->
count: <!--#var count-name--> count: <!--#var count-name-->
total: <!--#var total-name--> total: <!--#var total-name-->
median: <!--#var median-name--> median: <!--#var median-name-->
--------------- ---------------
for variable age: for variable age:
min: <!--#var min-age--> min: <!--#var min-age-->
max: <!--#var max-age--> max: <!--#var max-age-->
count: <!--#var count-age--> count: <!--#var count-age-->
total: <!--#var total-age--> total: <!--#var total-age-->
median: <!--#var median-age--> median: <!--#var median-age-->
mean: <!--#var mean-age--> mean: <!--#var mean-age-->
s.d. <!--#var standard-deviation-age--> s.d. <!--#var standard-deviation-age-->
--------------- ---------------
<!--#/if sequence-end--> <!--#/if sequence-end-->
<!--#/in data--> <!--#/in data-->
""") """)
print html(data=data) print html(data=data)
def test7(): def test7():
...@@ -395,7 +395,7 @@ def test7(): ...@@ -395,7 +395,7 @@ def test7():
""") """)
html.names({'name':'name', 'date':'date'}) html.names({'name':'name', 'date':'date'})
print html(date=DateTime.DateTime(), print html(date=DateTime.DateTime(),
name='todays_date') name='todays_date')
def test8(): def test8():
import DateTime import DateTime
...@@ -404,36 +404,36 @@ def test8(): ...@@ -404,36 +404,36 @@ def test8():
%(date fmt=year)s/%(date fmt=month)s/%(date fmt=day)s %(date fmt=year)s/%(date fmt=month)s/%(date fmt=day)s
""") """)
print html(date=DateTime.DateTime(), print html(date=DateTime.DateTime(),
name='todays_date') name='todays_date')
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]])
def test9a(): def test9a():
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]])
def test10(): def test10():
#import Missing #import Missing
html=HTML( html=HTML(
""" """
<!--#var spam fmt="$%.2f bob's your uncle" null="spam%eggs!|"--> <!--#var spam fmt="$%.2f bob's your uncle" null="spam%eggs!|"-->
""") #' """) #'
print html(spam=42) print html(spam=42)
print html(spam=None) print html(spam=None)
#print html(spam=Missing.Value) #print html(spam=Missing.Value)
...@@ -442,17 +442,17 @@ def test10(): ...@@ -442,17 +442,17 @@ def test10():
def test11(): def test11():
#import Missing #import Missing
html=HTML( html=HTML(
""" """
<!--#var spam --> <!--#var spam -->
html: <!--#var spam fmt=html-quote--> html: <!--#var spam fmt=html-quote-->
url: <!--#var spam fmt=url-quote--> url: <!--#var spam fmt=url-quote-->
multi: <!--#var spam fmt=multi-line--> multi: <!--#var spam fmt=multi-line-->
dollars: <!--#var spam fmt=whole-dollars--> dollars: <!--#var spam fmt=whole-dollars-->
cents: <!--#var spam fmt=dollars-and-cents--> cents: <!--#var spam fmt=dollars-and-cents-->
dollars,: <!--#var spam fmt=dollars-with-commas--> dollars,: <!--#var spam fmt=dollars-with-commas-->
cents,: <!--#var spam fmt=dollars-and-cents-with-commas--> cents,: <!--#var spam fmt=dollars-and-cents-with-commas-->
""") """)
print html(spam=4200000) print html(spam=4200000)
print html(spam=None) print html(spam=None)
...@@ -462,30 +462,30 @@ def test11(): ...@@ -462,30 +462,30 @@ def test11():
class test12ob: class test12ob:
def __init__(self,**kw): def __init__(self,**kw):
for k,v in kw.items(): self.__dict__[k]=v for k,v in kw.items(): self.__dict__[k]=v
def puke(self): def puke(self):
raise 'Puke', 'raaalf' raise 'Puke', 'raaalf'
def test12(): def test12():
class foo: class foo:
def __len__(self): return 9 def __len__(self): return 9
def __getitem__(self,i): def __getitem__(self,i):
if i >= 9: raise IndexError, i if i >= 9: raise IndexError, i
return test12ob(index=i, value='item %s' % i) return test12ob(index=i, value='item %s' % i)
html=HTML( html=HTML(
""" """
<!--#if spam--> <!--#if spam-->
<!--#in spam--> <!--#in spam-->
<!--#var value--> <!--#var value-->
<!--#var puke--> <!--#var puke-->
<!--#/in spam--> <!--#/in spam-->
<!--#/if spam--> <!--#/if spam-->
""") """)
try: print html(spam=foo()) try: print html(spam=foo())
except: return except: return
raise 'DocumentTemplate bug', ( raise 'DocumentTemplate bug', (
'Puke error not properly propigated in test 12') 'Puke error not properly propigated in test 12')
def test13(): def test13():
"Test automatic rendering of callable obnjects" "Test automatic rendering of callable obnjects"
...@@ -523,47 +523,46 @@ def test15(): ...@@ -523,47 +523,46 @@ def test15():
print v print v
def main(): def main():
import traceback import traceback
print 'Test 1', '='*60 print 'Test 1', '='*60
try: test1() try: test1()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 2', '='*60 print 'Test 2', '='*60
try: test2() try: test2()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 3', '='*60 print 'Test 3', '='*60
try: test3() try: test3()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 4', '='*60 print 'Test 4', '='*60
try: test4() try: test4()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 5', '='*60 print 'Test 5', '='*60
try: test5() try: test5()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 6', '='*60 print 'Test 6', '='*60
try: test6() try: test6()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 9', '='*60 print 'Test 9', '='*60
try: test9() try: test9()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 9a', '='*60 print 'Test 9a', '='*60
try: test9a() try: test9a()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 10', '='*60 print 'Test 10', '='*60
try: test10() try: test10()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 11', '='*60 print 'Test 11', '='*60
try: test11() try: test11()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 14', '='*60 print 'Test 14', '='*60
try: test14() try: test14()
except: traceback.print_exc() except: traceback.print_exc()
print 'Test 15', '='*60 print 'Test 15', '='*60
try: test15() try: test15()
except: traceback.print_exc() except: traceback.print_exc()
if __name__ == "__main__": if __name__ == "__main__":
try: command=sys.argv[1] try: command=sys.argv[1]
except: command='main' except: command='main'
globals()[command]() globals()[command]()
...@@ -57,7 +57,7 @@ def d(**kw): return kw ...@@ -57,7 +57,7 @@ def d(**kw): return kw
class D: class D:
def __init__(self, **kw): def __init__(self, **kw):
for k, v in kw.items(): self.__dict__[k]=v for k, v in kw.items(): self.__dict__[k]=v
def __repr__(self): return "D(%s)" % `self.__dict__` def __repr__(self): return "D(%s)" % `self.__dict__`
......
...@@ -54,8 +54,8 @@ ...@@ -54,8 +54,8 @@
"""Very Safe Python Expressions """Very Safe Python Expressions
""" """
__rcs_id__='$Id: VSEval.py,v 1.18 1998/09/14 20:48:43 jim Exp $' __rcs_id__='$Id: VSEval.py,v 1.19 1998/09/14 22:03:34 jim Exp $'
__version__='$Revision: 1.18 $'[11:-2] __version__='$Revision: 1.19 $'[11:-2]
from string import translate from string import translate
import string import string
...@@ -73,12 +73,12 @@ def careful_mul(env, *factors): ...@@ -73,12 +73,12 @@ def careful_mul(env, *factors):
s=None s=None
r=1 r=1
for factor in factors: for factor in factors:
try: try:
l=len(factor) l=len(factor)
s=1 s=1
except: l=factor except: l=factor
if s and (l*r) > 1000: raise TypeError, 'Illegal sequence repeat' if s and (l*r) > 1000: raise TypeError, 'Illegal sequence repeat'
r=r*factor r=r*factor
return r return r
...@@ -109,68 +109,68 @@ class Eval: ...@@ -109,68 +109,68 @@ class Eval:
""" """
def __init__(self, expr, globals=default_globals): def __init__(self, expr, globals=default_globals):
"""Create a 'safe' expression """Create a 'safe' expression
where: where:
expr -- a string containing the expression to be evaluated. expr -- a string containing the expression to be evaluated.
globals -- A global namespace. globals -- A global namespace.
""" """
global gparse global gparse
if gparse is None: import gparse if gparse is None: import gparse
self.__name__=expr self.__name__=expr
expr=translate(expr,nltosp) expr=translate(expr,nltosp)
self.expr=expr self.expr=expr
self.globals=globals self.globals=globals
co=compile(expr,'<string>','eval') co=compile(expr,'<string>','eval')
names=list(co.co_names) names=list(co.co_names)
# Check for valid names, disallowing names that begin with '_' or # Check for valid names, disallowing names that begin with '_' or
# 'manage'. This is a DC specific rule and probably needs to be # 'manage'. This is a DC specific rule and probably needs to be
# made customizable! # made customizable!
for name in names: for name in names:
if name[:1]=='_' and name not in ('_', '_vars', '_getattr'): if name[:1]=='_' and name not in ('_', '_vars', '_getattr'):
raise TypeError, 'illegal name used in expression' raise TypeError, 'illegal name used in expression'
used={} used={}
i=0 i=0
code=co.co_code code=co.co_code
l=len(code) l=len(code)
LOAD_NAME=101 LOAD_NAME=101
HAVE_ARGUMENT=90 HAVE_ARGUMENT=90
def HAS_ARG(op): ((op) >= HAVE_ARGUMENT) def HAS_ARG(op): ((op) >= HAVE_ARGUMENT)
while(i < l): while(i < l):
c=ord(code[i]) c=ord(code[i])
if c==LOAD_NAME: if c==LOAD_NAME:
name=names[ord(code[i+1])+256*ord(code[i+2])] name=names[ord(code[i+1])+256*ord(code[i+2])]
used[name]=1 used[name]=1
i=i+3 i=i+3
elif c >= HAVE_ARGUMENT: i=i+3 elif c >= HAVE_ARGUMENT: i=i+3
else: i=i+1 else: i=i+1
self.code=gparse.compile(expr,'<string>','eval') self.code=gparse.compile(expr,'<string>','eval')
self.used=tuple(used.keys()) self.used=tuple(used.keys())
def eval(self, mapping): def eval(self, mapping):
d={'_vars': mapping} d={'_vars': mapping}
code=self.code code=self.code
globals=self.globals globals=self.globals
for name in self.used: for name in self.used:
try: d[name]=mapping.getitem(name,0) try: d[name]=mapping.getitem(name,0)
except KeyError: except KeyError:
if name=='_getattr': if name=='_getattr':
d['__builtins__']=globals d['__builtins__']=globals
exec compiled_getattr in d exec compiled_getattr in d
return eval(code,globals,d) return eval(code,globals,d)
def __call__(self, **kw): def __call__(self, **kw):
return eval(self.code, self.globals, kw) return eval(self.code, self.globals, kw)
compiled_getattr=compile( compiled_getattr=compile(
'def _getattr(o,n): return __guarded_getattr__(_vars,o,n)', 'def _getattr(o,n): return __guarded_getattr__(_vars,o,n)',
......
DocumentTemplate releases DocumentTemplate releases
2.2
This release has a number of new features and bug fixes.
Features
- There is a new user's guide in HTML and PDF formats with - There is a new user's guide in HTML and PDF formats with
table of contents and index. table of contents and index.
- Import of some modules is delayed providing 30% faster imports. - AFAIK DocumentTemplate is now thread-safe.
- Several occurrences of 'from some_module import *' have been - There is a new open-source copyright.
eliminated.
- No longer enable the through-the-web-editing interface by default. - Import of some modules is delayed providing 30% faster imports.
- Made regex use thread safe. - No longer enable the through-the-web-editing interface by default.
- Added short-hand expr usage: - Added short-hand expr usage:
...@@ -20,6 +25,11 @@ DocumentTemplate releases ...@@ -20,6 +25,11 @@ DocumentTemplate releases
<!--#some_tag expr="foo.bar"--> <!--#some_tag expr="foo.bar"-->
Bugs fixed
- Several occurrences of 'from some_module import *' have been
eliminated.
- Fixed bugs in error reporting. - Fixed bugs in error reporting.
- Handle valueless attributes a bit better. - Handle valueless attributes a bit better.
...@@ -120,5 +130,5 @@ DocumentTemplate releases ...@@ -120,5 +130,5 @@ DocumentTemplate releases
- New 'in' tag variables for getting information about the start and - New 'in' tag variables for getting information about the start and
end indexes of the current batch. end indexes of the current batch.
"Download DocumentTemplate 2.1":DocumentTemplate-2.1.tar.gz. "Download DocumentTemplate 2.2":DocumentTemplate-2.2.tar.gz.
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