@TOC
前言
本文只作为笔记记录。
在上一版的Tin标记语言实现体系中,把Tin标记文本通过tkinter文本框渲染出来就结束了。如果在这一版的Tin标记语言实现中也仅仅完成这个任务,还谈什么升级? 是无法体现新一版Tin标记语言更强的呈现导出能力,只能让编写成果龟缩在小小的TinText中。
Tin标记语言从来不想取代什么或开拓什么,这一系列文章就是python.tkinter在这个方面的一个小例子,当作是小实践作业就行。
那么呈现转译的基础,跟渲染在本质上是一样的,像是语法树,都是要告诉输出器要怎么输出内容。因此,我们需要一个中间模块,实现Tin标记的解释工作,将标记内容赋予意义。
在前文当中我们在渲染器里实现了边解释边渲染,实际上已经完成了解释工作,所以我们还需要重新来一遍吗?没必要,接着渲染器往下写就是了。
解释记录器
让我们再回过头来看看TinText的初始化:
class TinText(ScrolledText):
"""
TinEngine.TinText
tin标记语言渲染核心
"""
RENDERING=False#渲染状态
def __init__(self, master, *args, **kw):
"""
部分参数是直接确定的
开发者只能通过实例化后进行更改
"""
super().__init__(master, *args, **kw)
self.config(borderwidth=0, relief="flat", insertbackground='#000000', insertborderwidth=1,
wrap='char', spacing1=10)
self.tinml=TinML()#tin标记记录
self.tinparser=TinParser()#解析器
self.balloon=Balloon()#提示框
self.img_thread_pool=ThreadPoolExecutor(max_workers=10)#图片下载线程池
self.__initialize()
其中的self.tinml=TinML()
就是创建了一个解释记录器。这个类也很简单,本质上就是一个列表,内部单元为字典。看看TinML类的定义:
class TinML(list):
"""
tin->html的中间工具
addtin(tag, **kw) - 加载tin解析内容
clear() - 清空
"""
def __init__(self):
super().__init__()
def addtin(self,tag,**kw):
super().append((tag,kw))
def clear(self):
super().clear()
承接渲染器的解释结果
以<title>
为例。
在渲染器中,我们已经获得了标记内容的title, level
值,我们只需要让解释记录器记录这个已经有意义的渲染内容和条件即可。
在解释渲染<title>
的最后一行中加入:
self.tinml.addtin('<title>',title=unit[2],level=level)
这样在渲染器中进行中间模块的记录有几个好处:
-
解释记录可以根据渲染进度同步变化
-
解释记录器的操作过程中,任何操作都是对当前TinText内容的等价信息的操作
-
方便后期管理,同时提高效率,没必要单独写、单独分析
示例
根据编写本文章时,在TinText(应用项目名,不是那个控件)的测试文件目录里的test.tin
内容如下:
<tin>TinText测试文件
<title>一级标题|
<title>二级标题|2
<title>三级标题|3
<title>四级标题|4
<title>五级标题|5
<title>六级标题|6
<p>
<p>/*-_普通文本;
|直接使用<p>来表示,
|-comment
|结尾会自带换行。|
<p>下方暂停一秒。
|-下方为暂停
<stop>1
这又是一个普通文本。
<p>
<lnk>TinText应用的UI界面库-TinUI|tinui.smart-space.com.cn|TinUI是完全基于tkinter的现代化元素组件库
<link>GitHub|https://github.com/
|-<lnk>标签是自带换行的,而<p>可以拼接含超链接的文本
<p><lnk>会自带换行,若不想要换行,可使用<p>的!开头标记: |*/![](www.baidu.com)|。
<p>
<p>使用<img>标签载入网络图片,若本地存在同名图片,优先使用本地。;
|*注意,如果文件名为空,则直接使用链接。
|/<img>本身不换行。|
|-<img>TinLogo.png
|-目前,暂不支持只含图片名称的<img>标记转译为html
<img>TinLogo.png|https://smart-space.com.cn/img/TinLogo.png|100%x200
<p>
<p>使用<sp>标签生成分割线↓
<sp>
<t>结尾(<title>可用<t>替代,其它同义标记详见tin标记语言说明)
解释记录结果如下:
[('<title>', {
'title': '一级标题',
'level': '1'
}), ('<title>', {
'title': '二级标题',
'level': '2'
}), ('<title>', {
'title': '三级标题',
'level': '3'
}), ('<title>', {
'title': '四级标题',
'level': '4'
}), ('<title>', {
'title': '五级标题',
'level': '5'
}), ('<title>', {
'title': '六级标题',
'level': '6'
}), ('<p>', {
'text': ('', )
}), ('<p>', {
'text': ('/*-_普通文本', '直接使用<p>来表示,', '结尾会自带换行。')
}), ('<p>', {
'text': ('下方暂停一秒。', )
}), ('<p>', {
'text': ('这又是一个普通文本。', )
}), ('<p>', {
'text': ('', )
}), ('<lnk>', {
'text': 'TinText应用的UI界面库-TinUI',
'url': 'tinui.smart-space.com.cn',
'description': 'TinUI是完全基于tkinter的现代化元素组件库'
}), ('<lnk>', {
'text': 'GitHub',
'url': 'https://github.com/',
'description': 'https://github.com/'
}), ('<p>', {
'text': ('<lnk>会自带换行,若不想要换行,可使用<p>的!开头标记: ', '*/![](www.baidu.com)', '。')
}), ('<p>', {
'text': ('', )
}), ('<p>', {
'text': ('使用<img>标签载入网络图片,若本地存在同名图片,优先使用本地。', '*注意,如果文件名为空,则直接使用链接。', '/<img>本身不换行。')
}), ('<img>', {
'filename': 'TinLogo.png',
'url': 'https://smart-space.com.cn/img/TinLogo.png',
'size': ['100%', '200']
}), ('<p>', {
'text': ('', )
}), ('<p>', {
'text': ('使用<sp>标签生成分割线↓', )
}), ('<sp>', {
'color': '#545965'
}), ('<title>', {
'title': '结尾(<title>可用<t>替代,其它同义标记详见tin标记语言说明)',
'level': '1'
})]
这样,无论需要把Tin标记文件转为其它什么文件,只需要拿着这个已经解释好的列表就行了,这就是解释中间件。