还没有完善的Python模板引擎

暂时还没有完善,仅做记录

  1 # coding:gb2312
  2 
  3 s = """
  4 <?for a in range(5)>
  5     <?for b in range(2)>
  6     abcd
  7     <for?>
  8     ----------------------------
  9 <for?>
 10 
 11 """
 12 
 13 
 14 class TemplateException(Exception):
 15     def __init__(self, message, contents, line, innerException = None):
 16         Exception.__init__(self, "{0} \n\t lien:{1} \n\t content: {2}".format(message, line, contents[line]))
 17         self.innerException = innerException
 18         self.contents = contents
 19         self.line = line
 20         self.msg = message
 21 
 22 import re
 23 
 24 class TagRender(object):
 25     def __init__(self):
 26         pass
 27 
 28     def render(self, tag):
 29         pass
 30 
 31 class ForTagRender(TagRender):
 32     def render(self, tag):
 33         partten = re.compile("\\s*(?P<var>\\S+)\\s+(?:in)\\s+(?P<values>.+)")
 34         match = partten.match(tag["exp"])
 35 
 36         if match:
 37             var = match.groupdict()["var"]
 38             values = match.groupdict()["values"]
 39             expression = "[tag['innerTemplate'].render() for {0} in {1}]".format(var, values)
 40             results = eval(expression)
 41             #results = eval(exp)
 42         else:
 43             raise Exception("error....")
 44         return "\n".join(results)
 45         
 46 class Template(object):
 47     __tagsrender__ = {}
 48     @staticmethod
 49     def reg_tag(name, tagrender):
 50         if Template.__tagsrender__.has_key(name):
 51             raise Exception("Template tag process {0} has existed.".format(name))
 52         else:
 53             Template.__tagsrender__.setdefault(name, tagrender);
 54 
 55     def match(self, text):
 56         return re.compile("^(?:\\s*)<\\?(?P<tag>\\S+)(?P<exp>.*)(?P<end>\\??>)(?:\\s*)$").match(text)
 57 
 58     def single_match(self, text):
 59         return re.compile("^(?:\\s*)<\\?(?P<tag>\\S+)(?P<exp>.*)(?P<end>\\?>)(?:\\s*)$").match(text)
 60 
 61     def end_match(self, text):
 62         return re.compile("^(?:\\s*)<(?P<tag>\\S+)\\?>(?:\\s*)$").match(text)
 63         
 64     def get_render(self):
 65         if self.__render__ is not None:
 66             return self.__render__
 67             
 68     def render(self):
 69         tags = self.__tags[0:]
 70         tags.reverse()
 71         results = []
 72         contents = self.__content.splitlines()
 73         index = 0
 74         while tags:
 75             tag = tags.pop()
 76             results.extend(contents[index:tag["start"]])
 77             tagrender = Template.__tagsrender__.get(tag["tag"], None)
 78             if not tagrender:
 79                 raise Exception("unknow tag...")
 80             subtext = tagrender.render(tag)
 81             if subtext != None:
 82                 results.append(subtext)
 83             index = tag["end"] + 1
 84         results.extend(contents[index:])
 85         return "\n".join(results)
 86     def __init__(self, content, p_line = 0):
 87         self.__content = content
 88         self.__tags = tags = []
 89         _contents = content.splitlines()
 90         tagsstack = []
 91         depth = 0
 92         for i in range(len(_contents)):
 93             text = _contents[i]
 94             if Template.match(self, text):
 95                 # match start
 96                 depth += 1
 97                 if not Template.single_match(self, text):
 98                     tagsstack.append(Template.match(self, text).groupdict()["tag"])
 99                 if depth == 1:
100                     tag = {
101                        "tag": Template.match(self, text).groupdict()["tag"],
102                        "exp": Template.match(self, text).groupdict()["exp"],
103                        "content": None,
104                        "innerTemplate": None,
105                        "start": i,
106                        "end": -1
107                        }
108                     tags.append(tag)
109                     if Template.single_match(self, text):
110                         tag["exp"] = Template.single_match(self, text).groupdict()["exp"]
111                         tag["end"] = i
112                         tag["content"] = text
113                         depth -= 1
114                 else:
115                     if Template.single_match(self, text):
116                         depth -= 1
117             elif Template.end_match(self, text):
118                 # match end
119                 depth -= 1
120                 tagName = Template.end_match(self, text).groupdict()["tag"]
121                 if tagsstack.pop() != tagName:
122                     raise TemplateException("Close tag name is not match.",_contents, i )
123                 if depth == 0:
124                     tags[-1]["end"] = i
125                     tags[-1]["content"] = "\n".join(_contents[tags[-1]["start"]:i+1])
126                     try:
127                         innerContent = "\n".join(_contents[tags[-1]["start"]+1:i])
128                         tags[-1]["innerTemplate"] = Template(innerContent, tags[-1]["start"])
129                     except TemplateException, e:
130                         raise TemplateException(e.msg, _contents, e.line + tags[-1]["start"] + 1, e)
131                 elif depth > 0:
132                     pass
133                 else: #depth < 0
134                     raise TemplateException("There some tags doesn't close.", _contents, i)
135                     
136 Template.reg_tag("for", ForTagRender())
137 t = Template(s)
138 print t.render()
139 raw_input("Enter To Exit")

 

 

posted @ 2013-05-08 23:31  JimmyLai  阅读(382)  评论(0编辑  收藏  举报

Stick on your dream.