国庆卷王用python撸一个专属Markdown转换工具(附源码)

国庆忙里偷闲,偶尔公号诈尸更新一两篇Python爬虫教程,有个困扰许久的问题 → 文章排版。

需求分析

一直使用 Markdown 语法编写文章,然后用Markdown转换工具转换下,常用的工具有:

硬件准备

在开始折腾Android APP逆向前,你需要:

在这里插入图片描述

1、一台【具有完整Root权限】的Android手机,注意是【完整Root】权限!!!

比如安卓手机在设置—>安全—>Root权限中可以开启Root权限,但是却是阉割的Root权限,安装SuperSu重启后就一直卡气球。

还行,简洁够用。但,人总是很难满足于现状,三个诱因让我有了改变的念头:

  • 工具毕竟不是开源的,你用别人也用,样式烂大街,都是改改颜色,替换图片、审美疲劳;
  • 老弟给我安利的公号编辑插件,如新媒体管家(已凉),壹伴助手,秀米,135、小蚂蚁等;

作为漆黑中的萤火虫,怎甘平平无奇,于是花了点时间,来定制自己的文章排版~

在这里插入图片描述
在参考多个公号后,整理了自己的公号排版规范,有需要的可以参考一波~

# 字号:正文(14、15),注释-标注来源-超链接-代码(12)
# 字间距:(1、1.5)
# 行间距:(1.5、1.75、2)
# 页边距:即双端缩进、两端对齐,页面左右留白,建议缩进尺寸为1.0

# 字体颜色:标题 #000000;正文 #4C4C4C;标注 #888888;其他 #B2B2B2
# 正文也可以尝试:#545454;#3f3f3f;#7f7f7f;#2f2f2f
# 备注性文字:#a5a5a5

# Tips:除去字体颜色,公号排版颜色不宜超过三种,颜色一旦多起来,风格就很难定,2-3种尤佳;
# 比如我的三种颜色:蕾姆蓝#5A78EA;拉姆粉#FF4081;艾米莉亚:#C65BDA

# 符号系统:建立自己的符号系统,用作内容分割,比如用//作为正文大段落的分隔,- 作为段落小结的分隔,有时还可以使用一些表情符号来增加趣味性:http://cn.piliapp.com/symbol/

# 不管怎么排,要有自己固定的设置,如:段落和图片间空2行、图片大小控制在一屏版面的1/3面积内、一个段落不超过3行字、每当一屏版面文字太满时,拆解段落做分段或做一些highlight制造空间感等。

# 总而言之,尽量利用 简单的基础设置 去优化阅读体验,让整体排版看起来简洁但有序、不密集、不沉重、不压抑。

# 采用固定格式的公号封面图!!! 
# 固定版式形成强烈的个人特色,制作新的封面图只需置换文字和图片,好看又方便。

大概的样式,其实就下面这几种:

请添加图片描述

而每次写完文章,想发布到公号,我需要这样:

复制文章内容()
无格式粘贴到公号文章编辑处()
for(其中一行:所有内容) {
    when(其中一行) {
        is 一级标题 → 应用一级标题样式
        is 二级标题 → 应用一级标题样式
        is 正文 → 应用正文样式
        ...
    }
}

机器重复,费事费力费神,特别是表格复制粘贴,令人绝望,文章内容多的时候,得花上半把小时,热情也被消磨殆尽… 迫切需一种工具,帮我跳出这样的困境,不能全自动,也要尽可能减少我花在排版上的时间。

工具设计

转换工具的核心:→ 解析Markdown文件 → 对特定类型元素进行渲染 → 生成HTML文件

这里的渲染,其实没那么高深,以 Md2All工具为例,输入:# 一级标题

请添加图片描述

点击复制,然后随便贴到一个IDE,保存为.html后缀,格式化一下:

请添加图片描述

因为公中号文章不支持CSS和JS(不过支持SVG),所以只能在HTML标签里写内联样式。 所以,这里的渲染其实只是:当解析到特定类型元素时,替换成对应的带内联样式的HTML代码。

所以,想写这样的工具,要点就是:

① 解析Markdown,能对不同类型的元素做区分;
② 各种带有样式的HTML代码;

先是解析Markdown的问题,秉着有轮子就不自己造的精神,直接搜关键字Python MarkDown解析,在众多的库中选择了mistune

而样式HTML的获取,就简单多了,善用Chrome开发者工具的Elements即可,比如:

请添加图片描述

看上的样式,直接偷,劝那种用烂大街转换工具的年轻人 耗子喂汁~

请添加图片描述

当然,获取到的样式可能还需要微调下,接着到工具开发环节~

我啪的就站起来了,很快嗷

上面也说了,使用浑元功法(mistune),来解析Markdown,简要介绍下此库:

  • 一个目前最快的纯Python markdown快速解析器,灵感来源于marked。
  • 官方仓库:github.com/lepture/mis…
  • 官方文档:mistune.readthedocs.io/en/latest/

直接用pip命令安装一波:

pip install mistune==2.0.0a4

用法也很简单,写个简单的Demo体验体验:

请添加图片描述

默认渲染样式显然不能满足我们的需求,需要自定义渲染器,定义一个渲染器 mistune.HTMLRenderer 的子类,重写相应的函数即可。同样写个简单例子,以#、##的解析为例:

请添加图片描述

运行输出结果如下:

请添加图片描述
接着塞到文章编辑器里验证下,微信不支持粘贴源码,借助开发者工具,定位到正文元素,右键选中:

请添加图片描述
粘贴一波:

请添加图片描述

回到编辑器看下效果:

请添加图片描述

可以,跟预期一致,大概玩法就这样,接着就是具体逻辑的细化及优化了。更多渲染器中可供重写的函数可以参见下述链接: https://mistune.readthedocs.io/en/latest/advanced.html

松果弹抖闪电鞭

接着是记录开发此工具的细节,有兴趣想自定义的可以借鉴一波,不感兴趣的直接跳过用成品亦可。

① → 样式采集示例

因为用的壹伴助手插件,复制元素的时候带了点没用的东西:

请添加图片描述

有些洁癖,写个正则清洗一下:

请添加图片描述

清洗完:

请添加图片描述

强迫症作祟,格式化下代码,这里用的lxml,你也可以用BeautifulSoup或者其他:

write_file(etree.tostring(html.fromstring(result),encoding='unicode',pretty_print=True))

看下效果:

请添加图片描述
可以,舒适感up↑,后续采集到的样式,先放这个池子里清洗一下,再用,也可添加新的过滤规则。

样式搞到手了,接着就该想想怎么存了,总不能像Demo那里一样,复制一堆字符串吧。繁冗不说,复用性也差,这里引入模板的概念,将每个样式保存成单个html,用到传参渲染,此处使用jinja2模板库

pip命令安装一波:

pip install Jinja2

接着把文本部分,替换成一个变量text:

在这里插入图片描述

再接着使用jinja2获取模板并渲染:

请添加图片描述
输出结果如下:

在这里插入图片描述

可以,很强,关于Jinja2的具体用法可参见:

  • 官网:jinja.palletsprojects.com/en/2.11.x/

创建模板,使用模板渲染的流程就这样,接下来演示下每种样式的具体获取过程。

② → 标题、粗体、段落

h3和h2类似,都是直接将样式文本替换为{{text}}

请添加图片描述
h4稍微麻烦一点,因为前面还传多一个顺序参数:

请添加图片描述

接着重写heading函数,根据不同的level进行渲染:

请添加图片描述
接着传入下述mardown字符串:

请添加图片描述

运行,把渲染后的HTML贴到微信编辑器校验下:

请添加图片描述

可以,效果是针不戳,尔后是粗体及段落样式:

请添加图片描述

运行后,把生成的样式贴到公号编辑器看看效果:

请添加图片描述

擦,换行全没了,原因是:微信会自动滤除文本结点中的\n换行符。 一个简单的解决方法就是:在渲染段落文本时,将\n替换为

修改下渲染处逻辑:

请添加图片描述

校验下效果:

请添加图片描述

③ → 表格、列表

表格的话直接用的微信编辑器自带的表格,样式如下:

请添加图片描述

对应代码如下:

请添加图片描述

mistune需启用plugin_table工具,才能解析表格,提供了下述可供覆盖的函数:

请添加图片描述

写个简单的demo试试看:

请添加图片描述

<th style="text-align:center">表达式</th>
<th style="text-align:left">描述</th>

可以看到table_head中获取到了表头的文本结构,其他几个函数同样可获得不同部位的表结构。

但是,我最后还是选择了重写table()函数,因为表格的渲染是连贯的,如果每个函数单独渲染,最后塞到一个

里非常麻烦。

另外,公号大多时候是在手机上阅读,屏幕宽就那么点,一般建议两列的表格,这里我另外定义一个类Cell:

请添加图片描述

先来编写模板吧,预期是传入 表头列表表内容列表,然后遍历渲染:

请添加图片描述

模板弄完,接着就是数据处理了,提取表头及表内容,塞到列表中,打印下text:

请添加图片描述

哦豁,直接用lxml提取一波:

请添加图片描述

丢个测试markdown进来:

请添加图片描述

复制生成样式至编辑器,检验下效果:

请添加图片描述

可以,舒服,然后是无序列表,也是使用编辑器自带样式:

请添加图片描述

抠出模板:

<p><br></p>
<ul style="list-style-type:disc;">{{text}}</ul>
<p><br></p>
<li><span style="font-size:15px;letter-spacing:1px;">{{text}}</span></li>

重写函数渲染模板:

请添加图片描述

传参校验:

请添加图片描述

Tips:把渲染后的HTML贴到编辑器处,空白处按下回车,无序列表才能正确缩进!

④ → 代码高亮、引用、行内代码

代码块的渲染亦称代码高亮,看了网上大部分转换工具,使用的都是使用 highlight.js,样式多多: highlightjs.org/

这里是Python,直接调js渲染有些麻烦,这里使用 pygments代码高亮库 来替换,样式及预览可到下述链接挑选: pygments.org/demo/

pip命令安装一波库:

pip install Pygaments

使用方式也很简单:

请添加图片描述

参数简述:

  • noclasses=True:设置不生成css文件,即使用HTML内联样式;
  • style=‘perldoc’:设置主题;
  • wrapcode=True:使用code包裹渲染后的代码;

复制到编辑器看下效果:

请添加图片描述

这里坑可多着呢,罗列下:

  • ① 代码超过屏幕,没有显示横向滚动条,需添加 overflow-x: auto;
  • ② 字体大了,设置12px为佳,要为每个span标签的style属性添加 font-size: 12px;
  • ③ 如下图,代码中的部分字符串没有用span包裹,大小不一,需外层套一个span包裹;

请添加图片描述

此处使用lxml操作节点元素增删及属性修改,具体代码如下:

请添加图片描述

传参校验:

请添加图片描述

字体大小和滚动条都出来了,看似没啥问题了,但如果你点击手机上预览:

卧槽,全乱了,有些代码挤在一行上了,归根到底还是换行符\n被微信吃了呗,看了下其他工具的做法:

添加 → white-space:nowrap,指定文本不换行,直到遇到
为止。

所以我们需要在合适的地方插入<br>标签,就在lxml解析前加吧

请添加图片描述

看下手机上的效果:

请添加图片描述

换行倒是换行了,就是前面的缩进没了,看了下别的工具的做法:

前面加上缩进对应数量的&nbsp;

所以,还需要统计每行前面的空格,补上对应数量的&nbsp;

请添加图片描述

看下手机上的效果:

请添加图片描述

好家伙,可以了,也算是把代码块的坑都踩完了!

然后把引用的样式也补上吧:

请添加图片描述

传参校验:

请添加图片描述

最后,把行内代码的样式也补上

请添加图片描述

传参校验:

请添加图片描述

常用结点的解析渲染就讲解到这里,然后就是全文渲染的微调了,换行,各种解析冲突处理啊,限于篇幅,就不一一讲解了,可以参考仓库中的最新代码。

传统功夫以点到为止

正文的渲染就这样,另外一般公🀄️号喜欢每一篇都加上一个特定的头部和尾部,这个简单,直接偷两个样式保存成html模板,正文渲染完后,拼接即可,写下简单示例吧

请添加图片描述

点击预览,手机看下效果:

请添加图片描述

效果还是很赞的,踩N多坑+写文,总耗时三天,终于把这个工具的雏形做出来了;
尽管它还不完整,不是很人性化,目前只有一个主题,还有各种未知的BUG,鸡动,久违的成就感;
欢迎各位小伙伴们使用,提建议,提issues,慢慢完善这个实用小生产力工具,谢谢~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值