Python脚本转换Typora中的Html标签(1)
在之前的几篇文章当中,都介绍了通过在Typora当中添加html标签来设置字体的方法
文章链接如下:
但是由于之前一直使用的是
<span>
标签,之前写过的文章在CSDN上发布需要更改为<font>
标签才能够显示,那么问题来了,难不成一个个标签来改吗?那当然不可能🙅♂️
作为一名合格的程序猿,对于这种需要大量手工劳动的活,都应该想办法进行自动化处理🐶,那么自然就想到编写一段脚本来完成这一功能
分析需求
首先可以明确的是需要完成两个html标签之间的转换,首先来看一个 <span>
标签和<font>
标签的示例
<span style='color:red;font-size:文字大小;'>This is some text!</span>
<font color="red">This is some text!</font>
- 两者之间的结构差别并不大,不难看出
<font>
标签中需要的color
属性包含在<span>
标签的style属性当中 - 其次,两者的文本内容需要保持一致,而文本内容处于两个
<><>
之间,需要提取出<span>
标签的文本信息
编写脚本
在分析出了两个标签之间的结构以及需要提取的信息之后,就可以开始处理文件了,首先建立了如下的目录结构
transmd
├── transform.py
├── transformed
└── wait_transform
其中
-
wait_transform
文件夹需要提前创建用于存放待转换的markdown文件 -
transformed
文件夹为脚本自动创建,用于存放转换后的markdown文件 -
transform.py
则是用于转换markdown文件的python脚本
转换思路:
- 实际上完成转换就是需要对原文件的内容进行字符串查找以及替换,那么很容易想到直接读取文件,并按行处理即可,可以先编写转换一行的函数
- ⚠️由于这里需要处理的是html标签,因此引入了
BeautifulSoup
库避免了一些复杂的字符串处理
- ⚠️由于这里需要处理的是html标签,因此引入了
def trans_span(self, line):
"""
完成以下两类标签的转换
<span style='color:red;font-size:文字大小;'>This is some text!</span>
to
<font color="red">This is some text!</font>
"""
soup = BeautifulSoup(line, "html.parser")
newLine = ''
for content in soup.contents: # 处理一行中的所有内容,包括文本以及span标签
if isinstance(content, bs4.element.Tag):
color = content['style'] # 提取style属性的内容
tmp = color.split(";")[0].split(":")
attr = tmp[0] + "=" + '"' + tmp[1] + '"'
newTag = "<font " + attr + ">" + content.text + "</font>" #生成font标签
newLine += newTag
else:
newLine += str(content)
return newLine
- 接下来只要完成读入markdown文件并按行处理的函数即可
def transform(self, filename):
try:
name = filename.split("/")[1]
savepath = "transformed/" + name[:-3] + "-transformed" + name[-3:]
with open (filename, "r") as r, open(savepath, "w") as w:
for line in r.readlines():
found_span = line.find("<span")
if found_span != -1: # 若本行中包含有span标签
w.write(self.trans_span(line)) # 则将转换后的行写入新文件当中
else:
w.write(line)
except Exception as e:
print(filename)
traceback.print_exc()
- 最后处理一下遍历
wait_transform
文件夹并依次处理所有待转换的markdown文件:
def transformDir(self, dirname):
"""
对dirname中对所有md文件进行转换
:param dirname: 文件夹路径
"""
for path, dir_list, file_list in os.walk(dirname):
for file_name in file_list:
if file_name[-3:] == ".md":
self.transform(os.path.join(path, file_name))
- 综合一下前几步的内容,就可以得到完整的转换脚本
import os
import traceback
import bs4
from bs4 import BeautifulSoup
class TransformMD(object):
def __init__(self):
if not os.path.exists("transformed"):
os.mkdir("transformed")
def trans_span(self, line):
"""
完成以下两类标签的转换
<span style='color:red;font-size:文字大小;'>This is some text!</span>
to
<font color="red">This is some text!</font>
"""
soup = BeautifulSoup(line, "html.parser")
newLine = ''
for content in soup.contents: # 处理一行中的所有内容,包括文本以及span标签
if isinstance(content, bs4.element.Tag):
color = content['style'] # 提取style属性的内容
tmp = color.split(";")[0].split(":")
attr = tmp[0] + "=" + '"' + tmp[1] + '"'
newTag = "<font " + attr + ">" + content.text + "</font>" #生成font标签
newLine += newTag
else:
newLine += str(content)
return newLine
def transform(self, filename):
try:
name = filename.split("/")[1]
savepath = "transformed/" + name[:-3] + "-transformed" + name[-3:] #生成保存路径
with open (filename, "r") as r, open(savepath, "w") as w:
for line in r.readlines():
found_span = line.find("<span")
if found_span != -1:
w.write(self.trans_span(line))
else:
w.write(line)
except Exception as e:
print(filename)
traceback.print_exc()
def transformDir(self, dirname):
"""
对dirname中对所有md文件进行转换
:param dirname: 文件夹路径
"""
for path, dir_list, file_list in os.walk(dirname):
for file_name in file_list:
if file_name[-3:] == ".md":
self.transform(os.path.join(path, file_name))
if __name__ == '__main__':
TMD = TransformMD()
TMD.transformDir("wait_transform")
总结
虽然测试过一些文件,但是不能保证这样的处理完全没有问题,比如碰到了一个公式无法正确渲染的情况(个别情况),但是总体来说基本解决了释放重复劳动的目的了。
此外,这一方法同样适用于转换其他Typora中的html标签,只需要根据需求添加相应的转换函数即可