含有章节索引的中文 文章模板

-- 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)