用Python创造一门标记语言并渲染(2)——解析
- 初步解析语法
- 解析标签集
- 替换关键符号
- 另一种符号标签
- 类html方法
- 结语
初步解析语法
在前一篇文章中,已经初步给定了Tin的语法。文本主要采用标签格式,先通过解析分别获得标签的名称以及参数,然后再交给渲染文本框进行着色呈现。
这个步骤很简单,简单示例如下:
for i in units:#units为Tin标记文本列表
obj_arg=re.findall('^(<.*?>)(.*)$',i)
if len(obj_arg)==0:
print('wrong tin')
continue
obj,arg=obj_arg[0]
#...
在获得标签名称后,就可以通过名称分别进行渲染了。
解析标签集
在之前的文章提到过,Tin需要提供容器标签。在容器标签的使用中,不可能每一个普通标签前都要加上标识符,因此密码容器必须是一个有开头有结尾的标签集。在Tin中,目前,标签集的定义有以下三种。
;密码标签
;定义密码
<key>key
<-pass->
<main>……
;……
</-pass>
;询问标签
<-askyesno->WHY
<main>……
;……
</-askyesno>
;直接调用渲染框
<tkiner>
tag_configure(...)
;...
</tkinter>
当然,在Tin中,密码容器和询问容器可以独作一行使用,每个标签行用“|”分割。
为了处理标签集,在渲染文本框中,对每个标签集的名称都匹配了一个渲染锁。这个渲染锁是布朗值,当渲染锁中的任意一个为True时,就代表需要解析标签集。具体逻辑操作如下。
self.pass_l=False
self.pass_u=[]#标签行列表
self.askyn_l=False
self.askyn_u=[]
self.tk_l=False
self.tk_u=[]
for i in units:#同上面的代码片段
#【正则匹配部分】
#...
#判断是否结束标签集
if obj in ['</-pass>','</-askyesno>','</tkinter>']:
if obj=='</-pass>':
self.pass_l=False
self.point_file(self.pass_u)#渲染容器内标签
self.pass_u=[]
continue
#其它标签集同理
#判断是否正在标签集,其它标签集同理
if self.pass_l==True:
self.pass_u.append(i)
continue
#【渲染部分】
#...
#判断是否开始标签集
if obj in ['<-pass->','<-askyesno->','<tkinter>']:
if obj=='<-pass->':
self.pass_l=True
continue
#其它标签集同理
在TinEngine中,每一个标签集的标签行列表都要在最后加一个空值,确保标签行列表全部都能够被正常解析。
具体原因在后面的文章会提到。
替换关键符号
在Tin中,-、;、| 等符号有些时候有特殊含义,那怎么显示这些字符呢?本来想打算像很多语言一样用“\”转义,但是发现在编辑过程中很容易看走眼。那么吸取html的方法,通过其它字符组显示这些字符,除此之外,我还用来另一种简单无脑的方法。
另一种符号标签
在Tin中,以“-”开头的,直接显示后面内容,但不可避免得会破坏前面的解析规则,所以这种方法实际上调用了==<main>==标签,只不过将“;”和“|”全都在内部转义了。
类html方法
使用多字符组代替这些特殊字符:
@SEM@ => ;
@VEB@ => |
...
用Python实现很简单,直接用 replace 更换字符就行了,这里不给出代码。
结语
对Tin标记语言的前期介绍已经完成,之后的文章将讲述Tin的渲染和使用。
Tin不依赖于或转换成html、Markdown和其它任何渲染类标签语言,因此Tin拥有其它标记语言不具备的容器标签,可以动态渲染。