@TOC
前言
本文只作为笔记记录。
前文我们已经通过TinText
渲染器部分和TinML
获得了test.tin
解释后的标记内容列表。本文,我们将根据这个解释结果将Tin标记转为html文件。
转为html的好处
第一,Tin标记语言作为一个小小小小小项目,光把编写内容呈现在TinText中是不够的,需要导出为其它常见文件。
第二,html足够常见,而且可以通过html格式继续转化为其它格式文件。html转图片、PDF、Markdown等格式的功能,已经有了完善的实现。我们只需要把Tin标记文本转译为html格式文本,就相当于打开了一扇落地窗😇,进而可以借助html格式转变为其它能够转变的任何格式文件。
而如果我们想给Tin标记文本转化为另一个新的格式文件,或者单纯就是为了练手,同样可以根据解释结果列表来进行编写。本篇文章中,就以HTML为例。
tin转译为html
工具类
我们先定义一下转译工具类。
python
class TinTranslator():
"""
tin->html的转译工具类
*后续可能支持tin->markdown
"""
def __init__(self,tinml:TinML):
self.tinml=tinml
self.doc=None
self.tinPmark=('*','/','_','-','!')
self.tinPlink_re=re.compile('.*?!\[(.*?)\]\((..*?)\)')
这里,我们定义了一些基础属性和小工具。
TinTranslator
直接绑定TinML
,做到实时同步。
转译功能
这里先以<title>
为例。
TinText使用dominate作为html生成工具。
python
def tohtml(self,_title='TinText',_style=''):
#tin->html
doc=dominate.document(title=_title)
doc.head.add(meta(charset='utf-8'))
if _style!='':
doc.head.add(style(_style))
_body=div()
doc.body.add(_body)
for tag,kw in self.tinml:
if tag == '<title>':
#标题
text=kw['title']
level=int(kw['level'])
if level==1:
_body.add(h1(text))
elif level==2:
_body.add(h2(text))
elif level==3:
_body.add(h3(text))
elif level==4:
_body.add(h4(text))
elif level==5:
_body.add(h5(text))
elif level==6:
_body.add(h6(text))
有了解释结果,转译就很方便了,不需要处理可能的错误。
<p>
有点复杂,因为Tin的p标记与html的p标记并不同级,而是包含了html中的b, u, i, s, a等标记,还要继续下分情况,因此需要类似TinText中的预渲染步骤。
python
def __tinP_to_html(self,texts):
#tin段落转html段落
res=[]
for text in texts:
if text=='':
res.append(br())
elif text[0]==' ':
res.append(text[1:])
elif text[0] not in self.tinPmark:
res.append(text)
else:
head_mark=text[:5]
head_num=0
now_p=None#初始化,空
if '*' in head_mark: head_num+=1
if '/' in head_mark: head_num+=1
if '_' in head_mark: head_num+=1
if '-' in head_mark: head_num+=1
#开始具体转义html<p>
if '!' in head_mark:
result=self.tinPlink_re.match(text)
if result:
url_text,url=result.groups()
if url_text=='':
url_text=url
now_p=a(url_text,href=url)
else:
head_num+=1
if '*' in head_mark:
if now_p:
now_p=b(now_p)
else:
now_p=b(text[head_num:])
if '/' in head_mark:
if now_p:
now_p=i(now_p)
else:
now_p=i(text[head_num:])
if '_' in head_mark:
if now_p:
now_p=u(now_p)
else:
now_p=u(text[head_num:])
if '-' in head_mark:
if now_p:
now_p=s(now_p)
else:
now_p=s(text[head_num:])
res.append(now_p)
return res
转译部分的代码如下:
python
elif tag == '<p>':
#段落
texts=kw['text']
_p=p('')
htmltexts=self.__tinP_to_html(texts)
for htmltext in htmltexts:
_p.add(htmltext)
_body.add(_p)
尽量保持转译部分的干净,额外的处理交给转译器类的内置函数。
效果展示
下图中,左侧为浏览器,右侧为TinText.TinReader。