WOOG - my contrib to public domain

Roman Suzi rnd at onego.ru
Mon Apr 30 04:41:19 EDT 2001


Hello!

Some time ago I wrote a module Woog because I was not aware that HTMLgen,
4XSLT and such exist ;-) and wanted it.

Still looking for discussions in this list, I understood that probably the
code which I wrote could be of some value to those who reimplement HTMLgen
;-)

Below are Woog.py, Woog-ex.py (examples) and example.py (refined
version of examples).

And at that time I had no idea of Python Style Guide, sorry.
The code contains ugly hack to add variables. Be careful.

Enjoy reading!

Sincerely yours, Roman Suzi
-- 
_/ Russia _/ Karelia _/ Petrozavodsk _/ rnd at onego.ru _/
_/ Monday, April 30, 2001 _/ Powered by Linux RedHat 6.2 _/
_/ "Do fish get thirsty?" _/

- Woog.py --------------------------------------------------------------
#!/usr/bin/env python

"""
Web-Oriented Object Generator
(requires Python 1.5.2 and Python Imaging library (PIL))

This version was contributed by R.Suzi
into Public Domain in 30.4.2001

Please, do not disturb me by mail:rnd-at-onego.ru
if this code doesn't work!

Disclaimer:
1. It is not useful for anything beyond educational
purposes ;-)
2. I am not sure if the code will work in Python 2.2
after changing namespace rules!

Similar programs/approaches: Zope's DocumentTemplate, HTMLgen
and probably some others, which allow to separate
web-site content, form and logic.
"""

Woog_version = "0.1.3"

import string, re, os, copy
try:
  import Image
except:
  print "WARNING: no WebImage. Can't find Python Imaging Library"

# Web-Oriented Object Generator
single_tags = [ 'meta', 'hr', 'br', 'img', 'p', 'li', 'link', 'input', 'dt' ]
ignor_tags= [ 'script' ]

""" Helps develop templatable web-site with OO approach"""

NBSP = ' '

def shape(l):
  '''shape(l) --> substitutes every list element with 1'''
  if type(l) != type([]):
    return 1
  else:
    return map(shape,l)

def map_dict(f,d):
  '''map_dict(f,d) -- acts like map(f,l), but on dicts'''
  d1={}
  for i in d.keys():
    d1[i] = f(d[i])
  return d1

def filter_dict(f,d):
  '''filter_dict(f,d) -- acts like filter(f,l), but on dicts'''
  d1={}
  for i in d.keys():
    if f(d[i]):
      d1[i] =d[i]
  return d1

def get_csv_data(x):
  '''get_csv_data(x) -- get 2-dim list of data'''
  return map( lambda y: re.split("\s*,\s*", string.strip(y)), re.split( "\n\r?", string.strip(x) ))

def strlv(x,v):
  '''strlv(x,v) -- recursive printing of a list, v for variable'''
  if type(x) == type(""):
    return x
  elif type(x) == type([]):
    return string.join(map(lambda xx,vv=v:strlv(xx,vv), x), "")
  elif callable(x):       #!!! not always good
    return str(x(v))
  else:
    return str(x)

ignor_tags= [ 'script' ]

attre = re.compile( r'[_0-9a-zA-Z][_0-9a-zA-Z]*$' )

class WebRes:
  '''class WebRes -- abstract class for any Web resource
  '''
  necessary = ['location']

  def set ( self, **d ):
    self.__dict__.update(d)
    return self

class A:
  '''class A -- class for HTML attribute
  '''
  def __init__( self, dict={}, **d ) :
    self.dict = {}
    self.vrs = {}
    for i in d.keys(): self.dict[i] = d[i]
    self.dict.update(dict)

  def __getitem__(  self, i ):
    return self.dict[i]

  def __add__(  self, a ):
    aa = copy.copy(self.dict)
    if type(a) == type({}):
      aa.update(map_dict(string.lower,a))
    elif type(a) == type(self):
      aa.update(a.dict)
    else:
      aa.update(a.atts_list())
    return A(aa)

# __radd__ = __add__

  def __repr__( self ):
    return self.dict

  def __str__(self):
    atts = `self`
    ak = atts.keys()
    ak.sort()
    s=''
    if atts:
      for i in ak:
        if atts[i]!=None:
          ii = strlv(atts[i],self.vrs)
          if not attre.match( ii ):
            ii = '"'+ii+'"'
          s=s+' '+str(i)+'='+ii
        else:
          s=s+' '+str(i)
    return s

  def __call__ ( self, dict={}, **d ):
    new = copy.copy(self)
    new.vrs = copy.copy(self.vrs)
    new.vrs.update(dict)
    new.vrs.update(d)
    return new

class T:
  '''class T -- class for HTML tag
  single_tags -- tags with optional closing part
  both_tags -- maybe closed or left open
  ignor_tags -- tags in which to ignore other tags
  tag_case = string.upper -- rule for tag case
  indent -- values for indenting certain tags
  '''
  single_tags = [ 'meta', 'hr', 'br', 'img', 'p', 'li', 'link', 'input', 'dt' ]
  both_tags = [ 'p', 'li' ]
  ignor_tags= [ 'script' ]
  tag_case = string.lower # 'lower', 'upper'

  def __init__( self, n, a=A({}), e=""  ) :
    self.tag_case = T.tag_case
    self.n = T.tag_case(n)
    if type(a) == type({}):
      a = A(a)
    if (type(a) == type("") or type(a) == type([])) and e == "":
      e = a
      a = A({})
    self.a = a
    self.e = e
    self.vrs = {}

  def __add__(self, x):
    return MT('',{},[self, x])

  def __radd__(self, x):
    return MT('',{},[x,self])

  def __mul__(self, x):
    return T(self.n, self.a, x)

  def __mod__(self, x):
    return T(self.n, self.a + x, self.e)

  indent = {
            'td':2,
            'tr':1,
            'table':0,
            'ul':0,
            'ol':0,
            'li':1,
            'div':0,
            'br':0,
           }

  def i(self):
    sn = string.lower(self.n)
    if T.indent.has_key(sn):
      return '\n'+' '*T.indent[sn]
    else:
      return ''

  def __repr__(self):
    if self.e:
      out = strlv(self.e,self.vrs)
      if string.lower(self.n) in T.single_tags and not string.lower(self.n) in T.both_tags:
        # raise "TagError: single tag has element!"
        return self.i()+"<"+str(self.n)+str(self.a(self.vrs))+">"+out
      else:
        return self.i()+"<"+str(self.n)+str(self.a(self.vrs))+">"+out+"</"+str(self.n)+">"
    else:
      return self.i()+"<"+str(self.n)+str(self.a(self.vrs))+">"

  def __str__(self):
    return strlv(`self`,self.vrs)

  def __call__ ( self, dict={}, **d ):
    new = copy.copy(self)
    new.vrs = copy.copy(self.vrs)
    new.vrs.update(dict)
    new.vrs.update(d)
    return new

def s_gi(x, i):
  '''s_gi(x, i) -- x[i], with care for i out of range'''
  if type(x) == type([]):
    return x[[i,len(x)-1][i>=len(x)]]
  else:
    return x

def smart_getitem(x, i):
  '''smart_getitem(x, i) -- x[i], with care for i out of range + Ellipsis'''
  if type(x) == type([]):
    return x[[i,len(x)-1][i>=len(x)]]
  else:
    return Ellipsis

def gen( ns, as, es, fs ):
  '''gen( ns, as, es, fs ) -- generate MT object internals, according to:
  ns -- tag names, as -- attributes, es -- elements,
  fs -- flags (marking which tag to duplicate)
  '''
  if not as.has_key(ns[0]):
    as[ns[0]] = A({})
  x = []
  if type(es) == type(''):
    x = T(ns[0], as[ns[0]], es )
  else:
    if ns[0] in fs:
      for i in xrange(len(es)):
        if type(es[i]) != type([]):
          x = x + [T(ns[0], s_gi(as[ns[0]],i), [es[i]])]
        else:
          x = x + [ T(ns[0], s_gi(as[ns[0]],i),
                 gen( ns[1:],
                      filter_dict( lambda xx:xx!=Ellipsis,
                        map_dict( lambda xx, j=i: smart_getitem(xx,j), as )),
                      es[i],
                      fs ))]
    else:
      for i in xrange(len(es)):
        if type(es[i]) != type([]):
          x = x + [es[i]]
        else:
          x = x + [ gen( ns[1:],
                  filter_dict( lambda xx:xx!=Ellipsis,
                  map_dict( lambda xx, j=i: smart_getitem(xx,j), as )),
                  es[i],
                  fs ) ]
      x = T(ns[0], s_gi(as[ns[0]],0), x )
  return x

class MT:
  '''class MT -- for Multiple Tags
  '''
  def __init__( self, ns, as, es ) :
    if type(ns) == type(''):
      ns = string.split(ns, '/')
    self.fs = []
    for i in xrange(len(ns)):
     if ns[i]:
      if not as.has_key(ns[i]):
       as[ns[i]] = A({})
      if ns[i][-1] == "*":
        ns[i] = ns[i][:-1]
        self.fs.append(ns[i])
    self.ns = ns
    self.as = as
    self.es = es
    self.vrs = {}

  def __repr__(self):
    if self.ns[0]:
      return gen(self.ns, self.as, self.es, self.fs )
    else:
      return self.es

  def __str__( self):
    return strlv(`self`, self.vrs)

  def __add__(self, o2):
    return MT('',{},[self,o2])

  def __radd__(self, o2):
    return MT('',{},[o2,self])

  def __call__ ( self, dict={}, **d ):
    new = copy.copy(self)
    new.vrs = copy.copy(self.vrs)
    new.vrs.update(dict)
    new.vrs.update(d)
    return new

class WebSite:
  '''class WebSite -- class for handling web-site.
  Not very useful yet.
  '''
  necessary = ['local_dir', 'name', 'remote_dir', 'res_list']
  def __init__ ( self, **d ):
    self.res_list=[]
    for i in d.keys(): self.__dict__[i] = d[i]
    for i in self.necessary:
      assert i in self.__dict__.keys()

  def __add__ ( self, wp ):
    if not wp in self.res_list:
      self.res_list=self.res_list + [wp]
      wp.owner = self
    return self

  __radd__ = __add__

  # for debug:
  def __str__ ( self ):
    s=''
    for i in self.res_list:
      s=s+self.local_dir+'/'+i.location+" -> "+self.remote_dir+'/'+i.location+"\n"
    return s

  set = WebRes.set

class WebPage(WebRes):
  """class WebPage(WebRes) -- class for handling web pages.
  Warning! Interface will be changed soon (chunks are bad thing)
  Use MT instead.
  """
  def __init__ ( self, **d ):
    self.chunks = []
    for i in d.keys(): self.__dict__[i] = d[i]
    for i in self.necessary:
      assert i in self.__dict__.keys()

  def __str__( self):
    return string.join(map(str, self.chunks))

  def save(self):
    f=open(self.location, "w" )
    f.write(str(self))
    f.close()


class WebImage(WebRes):
  """class WebImage(WebRes) -- class for handling images.
  !!! should be careful with variable location, etc.
  """

  necessary = WebRes.necessary+['desc']

  def __init__ ( self, **d ):
    for i in d.keys(): self.__dict__[i] = d[i]
    if not d.has_key('atts'):
       self.atts = A({})
    if type(self.atts) == type({}):
       self.atts = A(self.atts)
    if not d.has_key('local_prefix'):
       self.local_prefix = ""
    for i in self.necessary:
      assert i in self.__dict__.keys()
    self.ih = self.image_handler()
    self.vrs = {}

  def __repr__(self):
    return T("img", A( {
                      'src':str(self.location),
                      'alt':strlv(self.desc,self.vrs),
                      'width':self.real_width,
                      'height':self.real_height,
                     })+self.atts
                      )
  def __str__(self):
    return strlv(`self`,self.vrs)

  def image_handler(self):
    self.ih = Image.open( str(self.local_prefix)+str(self.location) )
    (self.real_width,self.real_height) = self.ih.size
    return self.ih

  def is_portrait(self):
    return self.real_width < self.real_height

  def thumb_URL(self, imgurl, tn ):
    return string.join(os.path.splitext(imgurl), tn)

  def image_file_name(self,with_ext=1):
    if with_ext:
      return os.path.split(str(self.location))[1]
    else:
      return os.path.split(os.path.splitext(str(self.location))[0])[1]

  def thumbnail(self, w, h, smartback=1, alt_plus='', tn='-s' ):
    """thumbnail -- making thumbnail.
       smartback =1 -- eh?
       alt_plus = '' -- what to add to 'alt'
       tn -- suffix for filename
    """
    ofn = self.thumb_URL( str(self.local_prefix)+str(self.location), tn )
    self.ih.thumbnail( (w, h) )
    (iw,ih) = self.ih.size
    self.ih.save(ofn)                    # should be optimized
    self.ih = self.image_handler()       # revert to big image

    return WebImage( location=ofn,
                     local_prefix=self.local_prefix,
                     desc=self.desc+alt_plus,
                     atts=A({'border':0}))

  def __add__(self, x):
    return MT('',{},[self, x])

  def __radd__(self, x):
    return MT('',{},[x,self])

  def __call__ ( self, dict={}, **d ):
    new = copy.copy(self)
    new.vrs = copy.copy(self.vrs)
    new.vrs.update(dict)
    new.vrs.update(d)
    return new

class V:
  """class V -- variable class. Variables are binded at the
  time of str()-ing, not when they appear in the expression.
  Vf(x) is used as a shortcut. Look the code below.
  """
  def __init__( self, n, dict={}, **d) :
    self.n = n
    self.vrs = dict
    self.vrs.update(d)

  def __repr__( self ):
    if type(self.n) == type(""):
      exec "_ = " + str(self.n) in self.vrs
      return self.vrs["_"]
    elif callable(self.n):
      return self.n(self.vrs)
    elif type(self.n) == type([]):
      """ _seq_n is a special variable to indicate
          an index in the variable which is list
      """
      res = []
      if self.vrs.has_key('_seq_n'):
        vseqn = self.vrs['_seq_n']
      else:
        vseqn=[]
      sni = len(vseqn)
      for i in xrange(len(self.n)):
        self.vrs.update({'_seq_n':vseqn+[i]})
        res.append( `V(self.n[i])(self.vrs)`)
      del self.vrs['_seq_n']
      return MT('',{},res)
    else:
      return self.n

  def __str__( self):
    try:
      return str(`self`)
    except:
      try:
        return "#ERROR in: " + self.n + "#"
      except:
        return "#ERROR in: (cannot even show it)#"

  def __add__ ( self, s ):
    return MT('', {}, [self,s] )                 #!!!

  def __radd__ ( self, s ):
    return MT('', {}, [s,self] )                 #!!!

  def __call__ ( self, dict={}, **d ):
    new = copy.copy(self)
    new.vrs = copy.copy(self.vrs)
    new.vrs.update(dict)
    new.vrs.update(d)
    return new

def Vf(x):
  return V( "'"+str(x)+"'%vars()" )

# def re_sub_map( what, how, where ):
#   """ re_sub_map( what, how, where ) --
#   what -- re
#   how -- function for processing found value
#   where -- where to substitute
#   """
#   if not isinstance(what,re.RegexObject):
#     what = re.compile(what, re.M | re.S)
#   where = str(where)
#   res = what.search(where)
#   towhere = ''
#   while res:
#     [(b1,e1),(b,e)] = res.regs
#     towhere = towhere + where[:b1] + str( how( where[b:e] ) )
#     where = where[e1:]
#     res = what.search(where)
#   return towhere + where

def re_sub_map ( what, how, where ):
  """ re_sub_map( what, how, where ) --
  what -- re
  how -- function for processing found value
  where -- where to substitute
  """
  if not isinstance(what,re.RegexObject):
    what = re.compile(what, re.M | re.S)

  return what.sub( how, where)


def tag_atts_re(x):
  return r"<\s*"+str(x)+r"\s+(.*?)\s*>"

#####################################################################

if __name__ == "__main__":
   execfile('Woog-ex.py')

-- Woog-ex.py -----------------------------------------------------------

# if 0:  -- uncomment to see errors

t1= T( "TITLE", {'someat':'val','other':'val1','noshade':None}, "Myllarit" )
t2= T( "TITLE", A(someat='val',other='val1',noshade=None), "Myllarit" )
t3= T( "TITLE", "Myllarit" )
t4= T( "BR", "Myllarit" )

print T('font') % A(color='#121212') % A(size='2') * T('center') * ( T('br') + T('p', "parag") ),
'''\n T('font') % A(color='#121212') % A(size='2') * T('center') * ( T('br') + T('p', "parag") )'''
print T('font') % A(color='#121212', size='2') * T('center') * ( T('br') + T('p', "parag") ),
'''\nT('font') % A(color='#121212', size='2') * T('center') * ( T('br') + T('p', "parag") )'''

print T('font', {}, [ t1, t2, t3, t4 ]),
'''\nT('font', {}, [ t1, t2, t3, t4 ])'''

print "\n"+"*"*40,
'''\n"\n"+"*"*40'''

logotab = MT( 'table/tr*/td*',
   {
    'table':{'cellpadding':0,'cellspacing':0,},
       'tr':[{}],
       'td':[[{'rowspan':2,'valign':'bottom','width':117,'height':57},
             {'rowspan':2,'valign':'bottom','width':'10%'},
             {'valign':'bottom'}],
             [{'valign':'bottom'}
      ]]} ,
      [T('caption','he-he'), [[111111, 2222222, 3333333],[4444444]]],
     )
print logotab,
'''\nlogotab'''
lista  = MT( 'ul/li*',
             { 'li':[{}] , 'ul':A({'cc':1})   },
             [[111111, 2222222, 3333333, 4444444]],
           )
print lista,
'''\nlista'''


pstyle = A(c1=1, c2=3)
pstyle1 = A(c1=11, c3=31)
a=MT('div/t2*', { 'div':{}, 't2': [pstyle+pstyle1]}, [T('c',"444"), [1,2,logotab]] )
print a,
'''\na'''
print "*"*78,
'''\n"*"*78'''
print MT( 'ul/li*', {'ul': A(b=123) ,'li':[[ A(ba=1),A(ba=3)]]}, [[1,2,3,4]] ),
'''\nMT( 'ul/li*', {'ul': A(b=123) ,'li':[[ A(ba=1),A(ba=3)]]}, [[1,2,3,4]] )'''

print MT( 'ul/li', {'ul': A(b=123) ,'li':[[ A(ba=1),A(ba=3)]]}, [[1,2,3,4]] ),
'''\nMT( 'ul/li', {'ul': A(b=123) ,'li':[[ A(ba=1),A(ba=3)]]}, [[1,2,3,4]] )'''
print MT( 'ul*/li*', {'ul': A(b=123) ,'li':[[ A(ba=1),A(ba=3)]]}, [[1,2,3,4]] ),
'''\nMT( 'ul*/li*', {'ul': A(b=123) ,'li':[[ A(ba=1),A(ba=3)]]}, [[1,2,3,4]] )'''
print MT( 'ul*/li', {'ul': A(b=123) ,'li':[[ A(ba=1),A(ba=3)]]}, [[1,2,3,4]] ),
'''\nMT( 'ul*/li', {'ul': A(b=123) ,'li':[[ A(ba=1),A(ba=3)]]}, [[1,2,3,4]] )'''

img= WebImage( location="lena.jpg",
    desc="probe",
    atts=A({'border':0}) )
print MT( 'p', {}, [img]),
'''\nMT( 'p', {}, [img])'''

print "*"*78,
'''\n"*"*78'''
print MT( 'p', {}, [img]) + img,
'''\nMT( 'p', {}, [img]) + img'''
print T( 'p', {}, img) +  MT( 'pp', {}, [img]),
'''\nT( 'p', {}, img) +  MT( 'pp', {}, [img])'''
print MT( 'p', {}, [img]) +  T( 'pp', {}, img),
'''\nMT( 'p', {}, [img]) +  T( 'pp', {}, img)'''

abra = 1234

p1 = T('t') * ( T('body',{}, V('abra'))      )
p = T('html') * (
       MT('head',{}, [
        T('meta', A(name="Keywords", content=V('abra')), ''),
        T('title', A({}), 'Ser'),
        ]
       )
       + T('body',{}, V('"%(k)s"%vars()'))      )

k=V('abra+abra')

# print p,
# '''\np'''
print p(abra='Carelia'),
'''\np(abra='Carelia')'''

abra = "ABRA"
v = V('abra')
t = T('html')
a = A(color=123)
mt = MT('head',{}, [
        T('meta', A(name="Keywords", content=V('abra')), ''),
        T('title', A({}), 'Ser'),
        ] )(abra=abra)

print v,
'''\nv'''
print t,
'''\nt'''
print mt,
'''\nmt'''
print t % a,
'''\nt % a'''
print t % a * v,
'''\nt % a * v'''
print t * v,
'''\nt * v'''
print t + mt,
'''\nt + mt'''
print mt + t,
'''\nmt + t'''
print mt + v,
'''\nmt + v'''
print t + v,
'''\nt + v'''
#  print v + t,
'''\n#  v + t'''
#  print v + mt,
'''\n#  v + mt'''
print t * mt,
'''\nt * mt'''

if 0:
  mt1 = MT( 'probe', {'probe':A(percent="10%")}, [ 'this is template of %(abra)s' ] )
  v1 = Vf( mt1 )
  print v1,
'''\n  v1'''

mt1 = MT( 'probe', {}, [ 'this is template of %(abra)s' ] )
v1 = Vf( mt1 )
print v1,
'''\nv1'''

print t + {'a':12},
'''\nt + {'a':12}'''
print mt + {'a':12},
'''\nmt + {'a':12}'''

print v + {'a':12},
'''\nv + {'a':12}'''

print mt + t + v,
'''\nmt + t + v'''

print MT('', {}, v),
'''\nMT('', {}, v)'''

print v+t,
'''\nv+t'''

if 0:
  print mt % a,
  '''\n  mt % a'''
  print mt * v,
  '''\n  mt * v'''
  print mt * mt,
  '''\n  mt * mt'''

abra = "++++"
print t(abra=abra).i(),
'''\nt(abra=abra).i()'''
k1 = (v+'def')(abra=abra)
k2 = t * v +   'def'
k3 = mt+'def'
print k1,k2,k3,
'''\nk1,k2,k3'''
abra = "----"

print MT('', {}, ['a','b','c'] ),
'''\nMT('', {}, ['a','b','c'] )'''
print MT('', {}, [k1,k2,k3] ),
'''\nMT('', {}, [k1,k2,k3] )'''
print MT('', {}, ['a','b','c'] ),
'''\nMT('', {}, ['a','b','c'] )'''

#   del k1,k2,k3
vr = V('''\nMT('', {}, [k1,k2,k3] )''' )
vr1 = V(MT('', {}, [k1,k2,k3] ) )
vrf = Vf('%(k1)s')(k1=1)
print vr,
'''\nvr'''
print vr1,
'''\nvr1'''
print vrf,
'''\nvrf'''

abra = "++++"
print vr,
'''\nvr'''
print vr1,
'''\nvr1'''
print vrf,
'''\nvrf'''

ilist = {'1':'1.gif','2':'2.gif','3':'3.gif'}
somehtml = """tra-ta-ta <mytag>mydata</mytag>
<fig 1>
<fig 2>
<fig 3>
[C
<remark >
<remark >
<remark >
<remark a>
"""

print re_sub_map( "<mytag>(.*?)</mytag>", lambda x: '<i>'+str(x.group(1)) +'</i>', somehtml ),
'''\nre_sub_map( "<mytag>(.*?)</mytag>", lambda x: '<i>'+x+'</i>', somehtml )'''
print '-'*20,
'''\n'-'*20'''



print re_sub_map( tag_atts_re("fig"),
  lambda x: str(T('img',A(src=ilist[x.group(1)]) )),
  somehtml ),
print '''\nre_sub_map( tag_atts_re("fig"),'''

global cntrs
cntrs={}
def cnt(k):
  global cntrs
  if cntrs.has_key(k):
    cntrs[k] = cntrs[k] + 1
  else:
    cntrs[k] = 1
  return cntrs[k]

print re_sub_map( tag_atts_re("remark"),
  lambda x: str(cnt(x.group(1))),
  somehtml )
-----------------------------------------------------------------------

-- example.py ---------------------------------------------------------

#!/usr/bin/env python

from Woog  import *

print "EXAMPLE 1 ######################################################"
### Several images with variable width ################################

imag= WebImage( location="lena.jpg",
             desc="Lena "+V('n'),
             atts=A({'border':0, 'width':V('n*10+50')}) )

images = map( lambda x,f=imag,T=T: f(n=x) + T('br'), range(1,10) )

print MT('',{},images)

print "EXAMPLE 2 ######################################################"
### Several images with variable width ################################

imag= V(WebImage( location="lena.jpg",
             desc="Lena "+V('n'),
             atts=A({'border':0, 'width':V('n*10+50')}) ) )

images = map( lambda x,f=imag,T=T: f(n=x) + T('br'), range(1,10) )

print MT('',{},images)

print "EXAMPLE 3 ######################################################"
### Several images with variable width ################################

imag= WebImage( location="lena.jpg",
             desc="Lena "+V('n'),
             atts=A({'border':0, 'width':V('n*10+50')}) )

images = V(map( lambda x,f=imag,T=T: f(n=x) + T('br'), range(1,10) ))

print MT('',{},images)

print "EXAMPLE 4 ######################################################"
### Sequences via variables ###########################################

print V([V('str(_seq_n[0]+1)+" "')]*3)      # use of _seq_n inside V
print V([V([V('str(_seq_n[0]+1)+","+str(_seq_n[1]+1)+" "')]*3)]*4)

print "EXAMPLE 5 ######################################################"
### List to template ##################################################

somelist = [ 'a', 'b', 'c' ]
p = T('p', {},  [V('i'), ' - to change to better handling in the future'])
for i in somelist:
  print p(i=i)

# Tfill( T( 'p', V('i') ), somelist, 'i')      ?????
# or ForIn( 'i', somelist, T( 'p', V('i') ) )

print "EXAMPLE 6 ######################################################"
### Custom tags processing quick version ##############################

img_list = {'1':'1.jpg','2':'2.jpg','3':'3.jpg'}
somehtml = """tra-ta-ta <mytag>mydata</mytag><fig 1>
<fig 2> <fig 3>
"""

print re_sub_map ( tag_atts_re("fig"),
  lambda x: str(T('img',A(src=img_list[x.group(1)]) ))    ,
  somehtml ),

print re_sub_map( "<mytag>(.*?)</mytag>",
      lambda x: '<i>'+str(x.group(1)) +'</i>', somehtml )

-----------------------------------------------------------------------





More information about the Python-list mailing list