1 问题由来
前几天将个人简书的markdown文章直接copy到然后发布到个人博客上发现以下两大格式问题。
1.1 图片布局
简书的markdown文章中的图片不用做其他设置都是默认居中,而在个人博客中却默认左对齐,具体效果如下图。对于有轻微强迫症的笔者决定将所有图片修改为居中对齐,搜索了一下,只需在markdown文件中的图片引用前后加上*** HTML
个人博客默认不居中效果
简书默认居中效果
图片居中效果实现:
-----空行----
![网页关系可视化结果](http://upload-images.jianshu.io/upload_images/3471485-81b21488533234e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
-----空行----
1.2 标题导航
在简书中需手动设定目录,如1、1.1、1.1.1等,在个人博客中,由于使用hexo主题,其默认目录如下图:
个人博客默认目录
所以并不需要手动添加1、1.1、1.1.1等标志,只需要用md语法写完之后其会自动识别,假如还手动添加则如“1. 从Google网页排序到PageRank算法”会变成“1. 1 从Google网页排序到PageRank算法”。
1.3 文章题目
在简书markdown文件头部插入如下三行以设置文章题目。
---
title:fileName
---
那么问题就来了,每篇文章中引用的图片肯定不止一张,标题肯定不止一个,手动修改肯定很耗时的,考虑到后续的文章大部分都会在简书和个人博客中同步更新,所以决定偷懒利用Python字符串处理的相关知识写个小小的Python程序实现此格式转换功能。
2 方案步骤
导入:设置文件所在路径,导入md文件并将其转换为字符串列表;
处理:插入文章题目;循环获取图片引用所在列表位置索引,利用索引插入相应居中标签;正则格式化标题,将如“## 1.1.1”转换为“## ”;
导出:设置文件导出路径将其导出为md文件。
3 Python脚本
3.1 知识应用
3.1.1 Python文件处理(如导入导出)
3.1.2 Python正则表达式
字符
点("*** . *** "):匹配任意除换行符"\n"外的字符,如a.b可以匹配出abc、adc等。
数量词
星号(" *** * *** "):匹配前一个字符0次或无限次;
加号(" ** + ** "):匹配前一个字符1次或无限次;
问号(" ** ? ** "):匹配前一个字符0次或1次。
逻辑
中括号(" ** [] ** "):字符集,如[0-9],只要满足0-9数字都会被匹配出来;
括号(" ** () ** "):被括起来的表达式作为分组,如(abc){2}则会匹配两个分组的字符abc,即"abcabc";
或(" ** | ** "):左右表达式任意匹配一个,优先匹配左边表达式,一旦左边被匹配成功则直接跳过右边。
3.2 Python实现
#######################################
####实现简书md和个人博客md的格式问题####
#######################################
#######################################
################使用说明################
##参数设置:文件导入路径、文件导出路径##
#######################################
import re
def getContent(input_path):
'''
功能:导入markdown文件
@input_path:md文件所在路径
'''
content = []
for line in open(input_path,'rb'):#二进制读入
content.append(line.decode())
return content
def formatCon(content,input_path):
'''
功能:统一markdown文件格式
@content:文章内容列表
@input_path:md文件所在路径
'''
#定义全局变量
global reple
#(1)插入标题
content.insert(0,"---")
content.insert(1,"title:"+(input_path.split('/'))[-1][0:-3]) #从文件路径提取文件名
content.insert(2,"---")
#(2)设置目录格式
img_pat = '!['
img_index = [] #获取图片所在位置索引
for i in range(len(content)):
con = content[i]
tmp1 = re.findall('^\#+',con.rstrip()) #匹配模式“一个或者无数个#号开头”
if len(tmp1)!=0:
reple = tmp1[0] +' '
content[i] = re.sub('\#+\s[0-9]\.?[0-9]?\.?[0-9]?\s+',tmp2,con.rstrip()) #匹配模式“一个或者无数个#号+空格+标题数字+空格”
if img_pat in con:
img_index.append(i)
#(3)设置图片居中
count = 0
for idx in img_index:
if (content[idx+count-1].strip())!="":#假如有空行则不插入空行
content.insert(idx+count,"")
count += 1
content.insert(idx+count,"
count += 1
content.insert(idx+count+1,"
count += 1
if (content[idx+count+1].strip())!="":#假如有空行则不插入空行
content.insert(idx+count+1,"")
count += 1
return content
def writeCon(format_con,output_path):
'''
功能:导出markdown文件
@format_con:已格式化的文章内容列表
@output_path:md文件导出路径
'''
fh = open(output_path,'wb')
try:
for i in range(len(format_con)):
data = format_con[i]
if "\r\n" in data:
data = data
else:
data = data+"\r\n"
data = data.encode()
#print(data)
fh.write(data)
except Exception as er:
print('写入文件时出现错误')
print(er)
finally:
fh.close()
def main(input_path,output_path):
'''
功能:主函数,函数调用接口
'''
content = getContent(input_path)#获取文本
format_con = formatCon(content,input_path)#格式化文本
writeCon(format_con,output_path)#输出格式化文本
if __name__ == '__main__':
#1、输入文件路径
input_path = "C:/Users/whenif/Desktop/ggtest.md"
#2、输出文件路径
output_path = "C:/Users/whenif/Desktop/ggtestnew.md"
main(input_path,output_path)
本文所有代码只用于技术交流,拒绝任何商用活动
后续的学习细节将会记录在个人博客DebugNLP中,欢迎各路同学互相交流