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