暂时还没有完善,仅做记录
1 # coding:gb2312 2 3 s = """ 4 5 6 abcd 78 ---------------------------- 9 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 \\S+)\\s+(?:in)\\s+(?P .+)") 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 \\S+)(?P .*)(?P \\??>)(?:\\s*)$").match(text) 57 58 def single_match(self, text): 59 return re.compile("^(?:\\s*)<\\?(?P \\S+)(?P .*)(?P \\?>)(?:\\s*)$").match(text) 60 61 def end_match(self, text): 62 return re.compile("^(?:\\s*)<(?P \\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": -1107 }108 tags.append(tag)109 if Template.single_match(self, text):110 tag["exp"] = Template.single_match(self, text).groupdict()["exp"]111 tag["end"] = i112 tag["content"] = text113 depth -= 1114 else:115 if Template.single_match(self, text):116 depth -= 1117 elif Template.end_match(self, text):118 # match end119 depth -= 1120 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"] = i125 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 pass133 else: #depth < 0134 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")