含有章节索引的中文 文章模板
-- limodou [DateTime(2004-08-28T04:10:50Z)] TableOfContents
Meteor源程序
程序不长,因此列在这里
Template程序代码
1 #coding=utf-8
2
3 import re
4 import sets
5 import copy
6 import types
7
8 class TemplateException(Exception): pass
9 class ObjectType(TemplateException): pass
10 class NoPreprocess(TemplateException): pass
11
12 class T:
13 def __init__(self, string):
14 self.text = string
15
16 def getText(self):
17 return self.text
18
19 #预处理器基类
20 class PreprocessBase:
21 #ptype 为处理器的名字,如'py'
22 def __init__(self, ptype, beginchars='<#', endchars='#>'):
23 self.ptype = ptype
24 self.beginchars = beginchars #define template var's left delimeter chars
25 self.endchars = endchars #define template var's right delimeter chars
26
27 #进行模板分析,应返回T对象的一个字典和相应的相关集
28 def process(self, obj):
29 return {}, {}
30
31 def getPattern(self):
32 return r'%s(\w+)%s' % (self.beginchars, self.endchars)
33
34 class PyPreprocess(PreprocessBase):
35 def process(self, modulename):
36 mod = __import__(modulename)
37 components = modulename.split('.')
38 for comp in components[1:]:
39 mod = getattr(mod, comp)
40
41 vars = {}
42 nodes = {}
43 for vn in dir(mod):
44 v = getattr(mod, vn)
45 if hasattr(v, '__class__') and v.__class__.__name__ == 'T':
46 vars[vn] = v
47 nodes[vn] = self._get_rely_on_node(v.getText())
48
49 return vars, nodes
50
51 #取模板元素的相关集
52 def _get_rely_on_node(self, s): #search for %(name)s format, make a dict
53 re_node = re.compile(self.getPattern())
54
55 return list(sets.Set(re_node.findall(s)))
56
57 #定义模板处理类
58 class Template:
59
60 preprocess ={}
61
62 def __init__(self):
63 self.vars = {}
64 self.nodes = {}
65
66 #装入模板
67 def load(self, tplfile, tpltype='py'):
68 self.pre = self.preprocess.get(tpltype, None)
69 if not self.pre:
70 raise NoPreprocess, 'No proper preprocess'
71
72 vars, nodes = self.pre.process(tplfile)
73 self.vars.update(vars)
74 self.nodes.update(nodes)
75
76 #生成模板值
77 #values应为字典的字典。即每一个模板元素如果引用有外部的变量,那么在values中应有此模板元素的一个键。
78 #同时它的值应为所有外部变量的一个字典
79 def value(self, target, values={}):
80 self.global_values = values.get(target, {})
81 self.target = target
82 return self._value(target, self.global_values)
83
84 def _value(self, target, values=None):
85
86 text = self.OnReplace(target, values)
87 if text is not None:
88 return text
89
90 nodes = self.nodes[target]
91
92 if not isinstance(values, types.ListType):
93 values = [values]
94
95 s = []
96 for v in values:
97 vals = {}
98 for node in nodes:
99 if not v.has_key(node):
100 if node in self.vars.keys():
101 vals[node] = self._value(node, self.global_values.get(node, {}))
102 else:
103 if node in self.vars.keys(): #如果node是一个模板变量,则继续替换
104 vals[node] = self._value(node, v[node])
105 else: #说明为一个外部变量
106 vals[node] = v[node]
107 s.append(self._replace(target, self.vars[target].getText(), vals))
108
109 return ''.join(s)
110
111 #可以自已写处理函数
112 #name为模板元素的名字
113 #text为要替换的引用变量的名字
114 def OnReplace(self, name, values):
115 return None
116
117 #把一段文件本的可替换信息使用values中的变量进行替换
118 #text是段字符串
119 #values是一个对应替换信息的字典
120 def _replace(self, name, text, values):
121 def dosup(matchobj, name=name, text=text, values=values):
122 if values:
123 result = values.get(matchobj.groups()[0], matchobj.group())
124 else:
125 result = matchobj.group()
126 return result
127
128 if not text:
129 return text
130 return re.sub(self.pre.getPattern(), dosup, text)
131
132
133 #注册预处理器函数,是一个处理器实例
134 def register(preprocess):
135 Template.preprocess[preprocess.ptype] = preprocess
136
137 register(PyPreprocess('py'))
138
139 if __name__ == '__main__':
140 vars = {
141 'program':{
142 'hello':[
143 {'var' :'var1'},
144 {'var' :'var2'},
145 {'var' :'var3'},
146 ],
147 },
148 }
149 template = Template()
150 template.load('tmp2')
151 print template.value('program', vars)
