#! /usr/bin/python
import re, sys
keywords = 'end', 'template', 'if', 'elif', 'else', 'apply-template', 'include'
_templates = {}
class THtml:
def __init__(self, input, loc, parent = {}):
self._liter = iter(input)
self._locals = loc
self._parent = parent
def begin(self):
try:
line = self._liter.next()
while self.recv(line): line = self._liter.next()
except StopIteration:
pass
except:
raise
return self._liter
def recv(self, line):
key, exp = _G_meta(line)
if key:
return self.statement(key, exp)
return self.normal(line)
def statement(self, key, exp):
if key == 'if':
exp = eval(_Repl(exp[:exp.rindex(':')], self))
self._liter = If(exp, self._liter, self).begin()
elif key == 'template':
exp = eval(_Repl(exp[:exp.rindex(':')], self))
txt = []
self._liter = Extract(self._liter, txt).begin()
txt.pop()
_templates[exp] = txt
elif key == 'include':
exp = eval(_Repl(exp, self))
THtml(file(exp).readlines(), self).begin()
elif key == 'apply-template':
exp = eval(_Repl(exp, self))
tval = self.get(exp)
if type(tval) == list:
for d in tval:
THtml(_templates.get(exp, []), d, self).begin()
elif type(tval) == dict:
THtml(_templates.get(exp, []), tval, self).begin()
elif tval != None:
raise ValueError, "'%s': type of '{}/[{}*]' expected" % exp
return 1
def normal(self, line):
sys.stdout.write(_Repl(line, self))
return 1
def __getitem__(self, key):
val = self._locals.get(key)
if val != None:
return val
return self._parent[key]
def get(self, key):
val = self._locals.get(key)
if val != None:
return val
return self._parent.get(key)
class Skip(THtml):
def __init__(self, input):
THtml.__init__(self, input, None)
def statement(self, key, exp):
if key == 'end':
return 0
elif key in ('if', 'template'):
self._liter = Skip(self._liter).begin()
return 1
def normal(self, line):
return 1
class Extract(THtml):
def __init__(self, input, lines):
THtml.__init__(self, input, None)
self._lines = lines
def recv(self, line,):
self._lines.append(line)
return THtml.recv(self, line)
def statement(self, key, exp):
if key == 'end':
return 0
elif key in ('if', 'template'):
self._liter = Extract(self._liter, self._lines).begin()
return 1
def normal(self, line):
return 1
class If(THtml):
def __init__(self, bool, input, env):
THtml.__init__(self, input, env)
self._true = bool
def statement(self, key, exp):
if key == 'end':
return 0
elif key in ('elif', 'else'):
if self._true:
self._liter = Skip(self._liter).begin()
else:
if key == 'elif':
self._true = eval(_Repl(exp[: exp.rindex(':')], self))
else:
self._true = 1
else:
if self._true:
return THtml.statement(self, key, exp)
elif key in ('if', 'template'):
self._liter = Skip(self._liter, None).begin()
return 1
def normal(self, line):
if self._true:
THtml.normal(self, line)
return 1
#_varname = re.compile('%\((\w+)\)s')
def _Repl(txt, dct):
#return re.sub(_varname, lambda g: str(dct.get(g.group(1))), txt)
return txt % dct
_meta = re.compile('^\s*\s*$' % '|'.join(keywords))
def _G_meta(line):
res = re.search(_meta, line)
if res:
return res.group(1, 2)
return 0, 0
def fprintf(outf, inf, glob):
if type(outf) == str:
outf = file(outf, 'w')
bak, sys.stdout = sys.stdout, outf
THtml(inf, glob).begin()
sys.stdout = bak
def printf(inf, glob):
if type(inf) == str:
inf = file(inf)
fprintf(sys.stdout, inf, glob)
import os
def test():
from StringIO import StringIO
content = """\
%(name)s
%(sex)s
%(age)s
%(subject)s
%(score)s
%(name)s
%(age)s
%(city)s
"""
def test_data():
data = """\
Xiaoyu * female * 20 * english 80 maths 88 chinese 92 * song 44 yang 45 * Beijing * ()
wu * male * 20 * c/c++ 8 maths 8 listening 9 * wu 4 wei 5 * ShenZhen * ()
"""
glob = []
for line in data.splitlines():
h = {}
v = [x.strip() for x in line.rstrip().split('*')][:-1]
h['name'], h['sex'], h['age'], result_exam, family, h['city'] = v
h['result_exam'] = []
if result_exam:
r = result_exam.split()
while r:
t = {}
t['score'], t['subject'] = r.pop(), r.pop()
h['result_exam'].append(t)
h['family'] = []
if family:
r = family.split()
while r:
t = { 'family_inc' : 'family.inc' }
t['age'], t['name'] = r.pop(), r.pop()
h['family'].append(t)
glob.append(h)
return glob
glob = test_data()
fprintf(sys.stderr, StringIO(content), { 'glob': glob, 'foo': 'wjy' })
try:
1
#printf(StringIO(content), { 'glob' : glob })
except Exception, e:
print 'Error:', e
if __name__ == '__main__':
test()