import re def tokenize(text): depth = 0 r = u"" for i in text: if "(" == i: depth += 1 elif ")" == i: depth -= 1 if depth == 0: r += i yield r r = u"" if depth > 0: r += i class BlockNode: def __init__(self, reg, text): m = reg.search(text) self._rawname = m.group(2) self._reg = re.compile("([({][a-z]+ %s)" % self._rawname) r = [] for i in self._rawname.split("."): if '["' in i: r.append(i) else: r.append('["%s"]' % i) self._varname = ''.join(r) self._block = m.group(3) def proccess(self): raise class EachNode(BlockNode): def __init__(self, item, var, text): BlockNode.__init__(self, var, text) self._num = len(eval('item%s' % self._varname)) def proccess(self): def _sub(m): return m.group(1).replace(self._rawname, "%s[%s]" % (self._varname, str(i))) r = [] for i in range(self._num): r.append(self._block.replace(" %s"%self._rawname, " %s[%s]"%(self._varname, str(i)))) return ''.join(r) class DefNode(BlockNode): def __init__(self, item, var, text): BlockNode.__init__(self, var, text) try: self._isdef = eval('item%s' % self._varname) except: self._isdef = None def proccess(self): if self._isdef: return self._block else: return "" class UndefNode(BlockNode): def __init__(self, item, var, text): BlockNode.__init__(self, var, text) try: self._isdef = eval('item%s' % self._varname) except: self._isdef = None def proccess(self): if self._isdef: return "" else: return self._block class GhostParser: def __init__(self, array=None): self._var = re.compile(r"\{(r?var) (\S+?)\}") self._item = array self._block = re.compile(r"\(([a-z]+) (\S+?):(.+)\)", re.S) def proccess(self, text): r = self._block.sub(self._get_block, text) r = self._var.sub(self.__var, r) return r def _get_block(self, match): x = match.group(0) for i in tokenize(match.group(0)): m = self._block.search(i) r = getattr(self, "_%s" % \ m.group(1))(self._item, match.re, i) x = x.replace(i, r) x = x.replace(i, "") if self._block.search(x): return self._block.sub(self._get_block, x) else: return x def _each(self, item, reg, text): return EachNode(item, reg, text).proccess() def _def(self, item, reg, text): return DefNode(item, reg, text).proccess() def _undef(self, item, reg, text): return UndefNode(item, reg, text).proccess() def __var(self, match): return getattr(self, "_get_%s"%match.group(1))(match.group(2)) def _get_rvar(self, text): var = [] tmp = text.split(".") for i in tmp: if '["' in i: var.append(i) else: var.append('["%s"]' % i) exp = 'self._item%s' % ''.join(var) return eval(exp,globals(),locals()) def _get_var(self, text): return self._get_rvar(text).replace('&', '&').replace('"', """).replace('<', '<').replace('>', '>') def parse(filename, array): return GhostParser(array).proccess(unicode(file(filename).read())) def template(arg, array, charset = "utf-8"): if hasattr(arg, "read") == True: data = unicode(arg.read(), charset) else: try: data = unicode(file(arg).read(), charset) except Exception, e: return e return GhostParser(array).proccess(data)