Differences between revisions 1 and 19 (spanning 18 versions)
Revision 1 as of 2004-08-24 22:28:53
Size: 4356
Editor: limodou
Comment:
Revision 19 as of 2005-07-27 05:12:52
Size: 7113
Editor: limodou
Comment:
Deletions are marked like this. Additions are marked like this.
Line 31: Line 31:

一个模板元素相互引用的例子如:

attachment:template_ref.gif

这个图是用Graphviz的dot生成的:

attachment:ref.gif

.dot文件内容:

{{{
digraph G {
A -> B;
A -> C;
B -> D;
B -> E;
}
}}}

命令行参数为:dot -Tgif ref.dot -o ref.gif

很简单吧!
Line 64: Line 87:
 * 模板类可以装入多个模板同时进行处理。
Line 72: Line 96:
vars = dict(hello=[{'var':'var1'},      #提供在模板中未定义的引用变量的值,如果没有可以省略
    {'var':'var2'},{'var':'var3'}])
template = Template()                   #生成模板类
template.load('tmp2')                   #装入模板
print template.value('program', vars)   #生成模板元素'program'的值
vars = {
 'program':{
  '
hello':[
   
{'var' :'var1'},
   {'var' :'var2'},
   
{'var' :'var3'},
  
],
 },
}

template = Template()
template.load('tmp2')
print template.value('program', vars)
Line 89: Line 120:
== 模板脚本功能 ==

模板脚本是将一系列的动作组合起来,批量进行执行的功能。它现在支持:

 * 创建目录
 * 拷贝文件
 * 模板替换

测试用例可以参考Template源代码。下面将它用到的例子抄过来:

{{{
mkdir src/doc
mkdir build
copy dict.xml src/doc
run tmp2 py "program" build/s.py
}}}

前两行创建两个目录。命令格式为:
{{{
mkdir 目录名
}}}
这里目录名可以为多层

第三行将dict.xml拷贝到src/doc目录下。如果目的为文件名,则将会改名拷贝。命令格式为:
{{{
copy 源文件 目标文件|目标目录
}}}

第四行将执行模板替换,所用到的变量会在运行时作为参数提供,在脚本中看不到。命令格式为:
{{{
run 模板文件名 模板类型 要处理的模板变量 保存路径
}}}
如果是python模板类型,则模板文件名不带.py
 
模板类型如果为python模板则为: py

注意:

 * 每个模板命令点一行
 * 模板命令与参数之间均以一个空格隔开
 * 如果参数含有空格请用双引号括起来

== Otter模板测试 ==

这是我对Otter模板进行的测试,其间又发现一些不足,已经进行了改正。不过此测试的数据完全是按照meteor的要求填写的,没有XML的解析过程。同时对原来生成的程序结构也有一些调整。

["Otter模板测试记录"]

== Tomz 所提的noweb模板测试 ==

这是在讨论区中Tomz所提的一个模板系统,当然他提的还是相对简单的一个原型。我针对这个原型扩展了Meteor进行了处理和测试。

["Tomz 所提的noweb模板处理"]
Line 100: Line 185:


== 讨论 ==

 * 可惜python比较不支持这种模板模式,因为python是和缩进有关的.这个模板系统和noweb这种文学编程类似,只是noweb更好看.

* 这个模板系统如果发展成文学编程就好了。文学编程只是模板系统的更好看的形式。比如:

{{{
<<*>>=
<<def>>
<<print>>
<<defend>>
<<run>>

<<def>>=
def myprint():

<<print>>
print "test"

<<run>>=
myprint()
}}}

最后的输出是:

{{{
def mypirnt():
print "test"
myprint()
}}}

可以看出文学编程不支持python的缩进。
这个是不是比meteor的调用方式更好呢?
另外,文学编程能集成面向方面编程就更好了。

by tomz

原来上次是你写的呀,没有留名字。下面是我针对你提出的noweb做的测试:["Tomz 所提的noweb模板处理"] -- limodou

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

-- limodou [DateTime(2004-08-24T22:28:53Z)] TableOfContents

meteor(流星) 模板系统说明

meteor(流星)是我给这个模板系统起的名字,因为它可能象流星一样发出耀眼的光芒,但生命却很短暂。我希望在 NewEdit 中用到它。

模板定义

meteor模板是一个真正的Python程序。它是由许多模板元素的定义组成的。一个简单的模板原型为:

{{{!#python from Template import T

hello = T("Hello, <#var#> \n") message = T("Please input yourname:") program = T("""name = input_raw("<#message#>") print <#hello#>

  • """)

}}}

一个模板文件由许多的模板元素构成。模板元素是Template中T类的一个实例。每个模板元素在创建时要传入它所代表的文本。我定义一个模板元素的文本为未经过替换的原始信息,一个模板元素的值为进行了替换后的文本。文本中可以包含进行替换的模式(pattern),一个模式是形如:

<#name#>

的东西。<#和#>为前导和后导串,可以在Template中进行改变。name为此替换模式的名字,我定义它为一个引用变量。因此<#name#>定义了名为name的引用变量。引用变量最终会用实际的值进行替换:当它的名字正好是本模板中定义的其它模板元素时,此引用变量将用对应的模板元素值进行替换。如果引用变量没有对应的模板元素,则在进行此模板替换的时候应提供一个包含该名字的字典。

一个模板元素相互引用的例子如:

attachment:template_ref.gif

这个图是用Graphviz的dot生成的:

attachment:ref.gif

.dot文件内容:

digraph G {
A -> B;
A -> C;
B -> D;
B -> E;
}

命令行参数为:dot -Tgif ref.dot -o ref.gif

很简单吧!

meteor模板文件有以下特点:

  • 它是一个真正的Python程序。
  • 由许多的模板元素组成。
  • 模板元素之间可以相互引用,但不能出现循环的情况。如果按模板元素之间的引用关系生成一个图的话。应该是一个有向不连通图。
  • 模板元素是一个T类的实例。它可以包含替换模式(引用变量)。
  • 引用变量是在模板元素中定义的,并且它的前导和后导串可以在Template类中进行修改。
  • 一个模板元素在替换时,如果它所用到的引用变量全部是其它的模板元素时,则不必提供额外的数据字典。如果它用到的引用变量在模板中不存在,即为外部变量时,需要提供一个额外的数据字典。
  • 在一个复杂的模板元素相互引用的情况下,模板系统会自动根据模板元素之间的引用进行替换,替换的规则是根据有向图,从最后被引用的元素开始向后直到要处理的模板元素进行替换。这些模板元素如果都有外部引用变量,则均应提供额外的数据字典。数据字典形如:

{
    'template_element1':{'t1_var1':'t1_var1_value', 't1_var2':'t1_var2_value'},
    'template_element2':{'t2_var1':'t2_var1_value', 't2_var2':'t2_var2_value'},
}
  • 从上面可以看出是,这个数据字典是以模板元素为键字(如果需要的话),其值又是一个字典。这个字典中就是此模板元素中用到的外部引用变量。如果一个模板是可以循环的,那么这个模板元素的值应该是一个字典的列表,如:

{
    'template_element1':{'t1_var1':'t1_var1_value', 't1_var2':'t1_var2_value'},
    'template_element2':[
        {'t2_var1':'t2_var1_value1', 't2_var2':'t2_var2_value1'},
        {'t2_var1':'t2_var1_value2', 't2_var2':'t2_var2_value2'},
        ]
}
  • 上例中template_element2就是一个可以循环的字典定义。
  • 模板元素是否循环完全是根据提供的数据来决定的。
  • 模板类可以装入多个模板同时进行处理。

模板替换

一个调用模板进行转换的示例程序如下:

   1 from Template import Template
   2 
   3 vars = {
   4         'program':{
   5                 'hello':[
   6                         {'var'  :'var1'},
   7                         {'var'  :'var2'},
   8                         {'var'  :'var3'},
   9                 ],
  10         },
  11 }
  12 template = Template()
  13 template.load('tmp2')
  14 print template.value('program', vars)

运行结果如:

name = input_raw("Please input yourname:")
print '''Hello, var1
Hello, var2
Hello, var3
'''

模板脚本功能

模板脚本是将一系列的动作组合起来,批量进行执行的功能。它现在支持:

  • 创建目录
  • 拷贝文件
  • 模板替换

测试用例可以参考Template源代码。下面将它用到的例子抄过来:

mkdir src/doc
mkdir build
copy dict.xml src/doc
run tmp2 py "program" build/s.py

前两行创建两个目录。命令格式为:

mkdir 目录名

这里目录名可以为多层

第三行将dict.xml拷贝到src/doc目录下。如果目的为文件名,则将会改名拷贝。命令格式为:

copy 源文件 目标文件|目标目录

第四行将执行模板替换,所用到的变量会在运行时作为参数提供,在脚本中看不到。命令格式为:

run 模板文件名 模板类型 要处理的模板变量 保存路径

如果是python模板类型,则模板文件名不带.py

模板类型如果为python模板则为: py

注意:

  • 每个模板命令点一行
  • 模板命令与参数之间均以一个空格隔开
  • 如果参数含有空格请用双引号括起来

Otter模板测试

这是我对Otter模板进行的测试,其间又发现一些不足,已经进行了改正。不过此测试的数据完全是按照meteor的要求填写的,没有XML的解析过程。同时对原来生成的程序结构也有一些调整。

["Otter模板测试记录"]

Tomz 所提的noweb模板测试

这是在讨论区中Tomz所提的一个模板系统,当然他提的还是相对简单的一个原型。我针对这个原型扩展了Meteor进行了处理和测试。

["Tomz 所提的noweb模板处理"]

名词列表

模板文件

模板元素

模板文本

模板值

替换模式(引用变量)

讨论

  • 可惜python比较不支持这种模板模式,因为python是和缩进有关的.这个模板系统和noweb这种文学编程类似,只是noweb更好看.

* 这个模板系统如果发展成文学编程就好了。文学编程只是模板系统的更好看的形式。比如:

<<*>>=
<<def>>
<<print>>
<<defend>>
<<run>>

<<def>>=
def myprint():

<<print>>
print "test"

<<run>>=
myprint()

最后的输出是:

def mypirnt():
print "test"
myprint()

可以看出文学编程不支持python的缩进。 这个是不是比meteor的调用方式更好呢? 另外,文学编程能集成面向方面编程就更好了。

by tomz

原来上次是你写的呀,没有留名字。下面是我针对你提出的noweb做的测试:["Tomz 所提的noweb模板处理"] -- limodou

meteor(流星)模板系统说明 (last edited 2009-12-25 07:16:33 by localhost)