@TOC
前言
本文仅作为笔记记录。
在前文中,我们通过标记意义解释生成了带有明确渲染要求的参数组,以<title>
为例,我们获取了title, level
两个明确的渲染标记,这一部分由Tin标记解释器完成,不需要编写者花费过多心思。
上一篇文章的代码片段中,出现了self.__render_title(...), self.__render_paragraph(...)
两个方法,这就是TinText的渲染器部分。这篇文章将以这两个标签为例,解释新一版TinText的渲染器实现。
标题
def __render_title(self,title,level):
#标题
self.insert('end',title,('title',f'title{level}'))
self.insert('end','\n')
这就是逐个解释再即时渲染的好处,渲染器部分非常简介,因为所有渲染参数已经由解释器部分处理完毕。
在文本框的tag设定中,使用了f'title{level}'
的样式命名,这是因为(见前文)我们已经将六种层级的标题样式在TinText初始化时就确定好了。
段落
语法
新一版Tin的标记段落一上来就是可多样化的。
旧版Tin标记语言的段落标记经过两个大版本更新才支持段落内部样式化,而且标记比较混乱,一个文本块最多使用一种样式。
先看语法定义:
<p>段落演示;
|*粗体
|/斜体
|-删除线
|_下划线
|![链接](https://.../)
|*-/这是粗体和删除线、斜体的组合文本块
| 第一个空格没有意义,这就是普通文本块
| 这才会显示一个空格
|*_![粗体下划线链接](https://.../)|
当然,这些都可以挤在同一行,而且我觉得那样更好,不必担心混乱,因为在新版TinText实现应用中,TinWriter是可以明显分隔“|”的。
若文本块中含有删除线,就需要在同一行(段落)中书写,这是强制设计的。否则会被当作注释(|-)
样式拼接渲染
在<p>
标记的渲染中,新一版TinText采用样式拼接的方法,使得不同样式可以作用于同一个文本块,这是旧版Tin标记语言做不到的。
def __render_paragraph(self,text,newline=False):
#普通文本,默认不自动换行
if text=='':
pass
elif text[0]==' ':
self.insert('end',text[1:],'paragraph')
elif text[0] not in self.paragraph_mark:
self.insert('end',text,'paragraph')
else:
head_mark=text[:5]
head_num=0
p_tags=[]
if '*' in head_mark:
head_num+=1
p_tags.append('bold')
if '/' in head_mark:
head_num+=1
p_tags.append('italic')
if '_' in head_mark:
head_num+=1
p_tags.append('underline')
if '-' in head_mark:
head_num+=1
p_tags.append('overstrike')
if '!' in head_mark:
# head_num+=1
result=self.paragraph_link_re.match(text)
if result==None:
#如果使用了!开头标记但没有遵循![text](url)格式
#按普通文本渲染
head_num+=1
else:
text,url=result.groups()
if text=='':
text=url
index=self.index('end')
tag_name=f'"link-{index}"'
if 'underline' not in p_tags:
p_tags.append('underline')
self.tag_config(tag_name,font=(self.font_family,self.font_size,*p_tags))
self.tag_bind(tag_name,'<Button-1>',lambda e:webbrowser.open(url))
self.tag_bind(tag_name,'<Enter>',lambda e:self.balloon.show(e,url))
self.tag_bind(tag_name,'<Leave>',lambda e:self.balloon.hide(e))
self.insert('end',text,('link',tag_name))
if newline:
self.insert('end','\n')
return
index=self.index('end-1c')
tag_name=f'"paragraph-{index}"'
self.tag_config(tag_name,font=(self.font_family,self.font_size,*p_tags))
self.insert('end',text[head_num:],('paragraph',tag_name))
if newline:
self.insert('end','\n')
在粗体、斜体、下划线、删除线部分,存在开头标记就在样式列表p_tags
中加入关键词,超链接这在最后进行判断。最后的渲染中,通过在font
参数里使用*p_tags
释放样式关键词,就完成了文本段的渲染。