From https://subce.gitee.io/htmls/essays/typora_base64_html.html
问题描述
typora 导出 html 的时候不带文档中的图片,不方便个人网站的上传。所以想办法将markdown中的图片转化为base64格式,嵌入到html中,这样就省略的图床的需要,对于图像需要较少的网页,使用很好。
解决办法
将markdown中的图片,按照路径读取并且转为 base64 放到 markdown 的后面,同时修改前面的图片引用。这样typora 在导出html的时候,便自带base64的图片了
如下
![][01]
sxxxxxx
fdfsdgrfg ![][02] cscfdas
[01]:base64_data
[02]:base64_data
主要步骤如下:
- 设置typora,将图片保存在本地,如下图,这样是方便读取。
-
使用python正则表达式匹配图片标签
这里使用了如下的正则表达式
pattern1 = re.compile(r'.*!\[.*\](\(.*\.[a-z]*\))') pattern2 = re.compile(r".*<img src=\"(.*\.[a-z]*)\" ([a-z]*=.*;\" />)")
-
python 读入图片,转为 base64
try: with open(img_path, 'rb') as fg: image = fg.read() image_base64 = str(base64.b64encode(image), encoding='utf-8') except: image_base64 = "path error"
使用方法
python tb.py -f 文件路径
例如:
python tb.py -f HTML/test.md
代码会在相同的地方创建一个文件夹 [md2html] 文件夹内带有同名的带有“_html"的 markdown 文件,然后使用typora导出html就好了
注意,这里定义了默认的起始路径,如果需要,请自行修改,另外,在执行python前,请把cmd的工作路径切换到 tb,py 所在的路径,使用 cd xx 命令.
代码
import sys
import getopt
import re
import base64
import os
if __name__ == "__main__":
# 表示参数选项有:-h, -f, -p, --help, --functionname, --partdate,它们相互对应;
# 该方法的返回值有两个元素: 第一个是(opt, value)元组的列表,
# 第二个是一般参数列表,包含那些没有 '-' 或 '--' 的参数
typora_path = "E:/Users/SubChange/OneDrive - zju.edu.cn/CollaborationWork/typora/" # typora 工作路径
try:
opts, args = getopt.getopt(sys.argv[1:], "hf:", ["help", "functionname="])
except getopt.GetoptError:
print('Error: ***.py -f <functionname> -p <partdate>')
print(' or: ***.py --functionname=<functionname> --partdate=<partdate>')
sys.exit(2)
for opt in opts:
if opt[0] == "-f":
file_type_name = opt[1].split("/")[-1]
file_name = file_type_name[:-3] # md文件文件名 不带后缀
file_folder = typora_path + opt[1][:-(len(file_type_name)+1)] + "/" # md文件所在文件夹
#file_folder = "E:/Users/SubChange/OneDrive - zju.edu.cn/CollaborationWork/typora/" + "HTML/"
#file_name = "test"
file_path = file_folder + file_name + ".md"
print(file_path)
if not os.path.exists(file_folder + "md2html"):
os.mkdir(file_folder + "md2html")
new_file_path = file_folder + "md2html/" + file_name + "_html.md"
base64_data_list = []
base64_type_list = []
fig_num = 0
# 同时打开两个,一个读取 一个写入
with open(file_path, 'r+', encoding='utf-8') as f1:
with open(new_file_path,'w+', encoding='utf-8') as f2:
while True:
line = f1.readline() # 逐行读取
# 正则表达式
pattern1 = re.compile(r'.*!\[.*\](\(.*\.[a-z]*\))')
pattern2 = re.compile(r".*<img src=\"(.*\.[a-z]*)\" ([a-z]*=.*;\" />)")
matchObj1 = re.match(pattern1, line, flags=0)
matchObj2 = re.match(pattern2, line, flags=0)
if matchObj1 is None and matchObj2 is None:
f2.write(line)
elif matchObj2 is None:
# matchObj1
line_pre = line[:matchObj1.regs[1][0]].split("![")[0]
line_bd = line[matchObj1.regs[0][1]:]
img_name = matchObj1.group(1)[1:-1]
img_path = file_folder + img_name
fig_num = fig_num + 1
try:
with open(img_path, 'rb') as fg:
image = fg.read()
image_base64 = str(base64.b64encode(image), encoding='utf-8')
except:
image_base64 = "path error"
base64_data_list.append(image_base64)
base64_type_list.append(img_name[-3:])
line_mid = "[" + str(fig_num) + "]"
new_line = line_pre + "![]" + line_mid + line_bd
f2.write(new_line)
else:
img_name = matchObj2.group(1)
img_path = file_folder + img_name
fig_num = fig_num + 1
try:
with open(img_path, 'rb') as fg:
image = fg.read()
image_base64 = str(base64.b64encode(image), encoding='utf-8')
except:
image_base64 = "path error"
base64_data_list.append(image_base64)
base64_type_list.append(img_name[-3:])
line_pre = line[0:matchObj2.regs[1][0]][:-10]
line_mid = "[" + str(fig_num) + "]"
line_bd = line[matchObj2.regs[2][1]:]
new_line = line_pre + "![]" + line_mid + line_bd
f2.write(new_line)
if line == "":
break
f2.write("\n")
f2.write("\n")
for i in range(len(base64_data_list)):
if base64_type_list[i] == "svg":
# svg
f2.write("[" + str(i+1) + "]:data:image/svg+xml;base64,")
else:
f2.write("[" + str(i+1) + "]:data:image/png;base64,")
f2.write(base64_data_list[i])
f2.write("\n")
print("")
```