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

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