国庆忙里偷闲,偶尔公号诈尸更新一两篇Python爬虫教程,有个困扰许久的问题 → 文章排版。
需求分析
一直使用 Markdown 语法编写文章,然后用Markdown转换工具转换下,常用的工具有:
- Markdown转换工具:blog.didispace.com/tools/onlin…
- Md2All:md.aclickall.com/
- MPEditor:js8.in/mpeditor/
- Markdown Nice:www.mdnice.com/
硬件准备
在开始折腾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解析前加吧
看下手机上的效果:
换行倒是换行了,就是前面的缩进没了,看了下别的工具的做法:
前面加上缩进对应数量的
所以,还需要统计每行前面的空格,补上对应数量的
看下手机上的效果:
好家伙,可以了,也算是把代码块的坑都踩完了!
然后把引用的样式也补上吧:
传参校验:
最后,把行内代码的样式也补上
传参校验:
常用结点的解析渲染就讲解到这里,然后就是全文渲染的微调了,换行,各种解析冲突处理啊,限于篇幅,就不一一讲解了,可以参考仓库中的最新代码。
传统功夫以点到为止
正文的渲染就这样,另外一般公🀄️号喜欢每一篇都加上一个特定的头部和尾部,这个简单,直接偷两个样式保存成html模板,正文渲染完后,拼接即可,写下简单示例吧
点击预览,手机看下效果:
效果还是很赞的,踩N多坑+写文,总耗时三天,终于把这个工具的雏形做出来了;
尽管它还不完整,不是很人性化,目前只有一个主题,还有各种未知的BUG,鸡动,久违的成就感;
欢迎各位小伙伴们使用,提建议,提issues,慢慢完善这个实用小生产力工具,谢谢~