使用Python从Markdown文档中自动生成标题导航
概述###
Markdown 很适合于技术写作,因为技术写作并不需要花哨的排版和内容, 只要内容生动而严谨,文笔朴实而优美。
为了编写对读者更友好的文章,有必要生成文章的标题导航,让读者有个预期的阅读概览。当文章标题比较多时,手工去编写导航锚点比较费时,因此决定使用Python解析Markdown文档自动生成标题导航。
知识与思路###
写过Markdown的人知道,Markdown的标题是使用一到六个# 左右包围住标题文字,而锚点是 [标题](#标题)。 比如 ## 知识与思路 ## ,锚点连接是 [知识与思路](#知识与思路)。标题文字允许包含空格,不过最好不要用空格或特殊不可打印字符,因为在网页上点击带锚点的链接时可能失效,并且网站对Markdown锚点的支持可能有特殊规则,比如博客园会将标题中的大写字母自动转成小写字母,并且对于有空格的标题可能无法链接到锚点。
这样,就需要解析标题行,从中提取出标题并生成锚点链接。通常使用正则表达式来匹配和提取文本内容。此外,为了排版,也要根据标题的级别生成相应的缩进。考虑到段落中很可能含有#字符,因此标题最好从第二级开始,不超过四级。
标题行的正则表达式是:
\s*(#{2,6})\s*(.*?)\s*(?:\1)\s+
知识点:
- 2-6 个#号使用 #{2,6} 匹配;
- 由于行起始和标题前后都可能含有空格,因此需要使用\s*来兼容;行末尾至少有个换行符,因此要使用 \s+;
- 使用(subregex)捕获 subregex 匹配的文本, 使用 \1 表示后面与前面对应的被匹配的分组文本, 使用 (?:subregex) 表示匹配 subregex 的文本,但在捕获分组时忽略,不作为提取内容;
- 使用 (.*?) 匹配标题内容, ? 表示非贪婪模式,避免将 # 也包含到标题中;
- 标题的缩进比较简单,第二级的不缩进,第N级缩进 (N-2)个指定字符,这里字符选定为中文空格
  - 程序会接受一系列 Markdown 文档的文件路径参数,并输出对应于每个文件的导航文本;由于参数比较简单,就不使用 argparse 这样的参数解析模块了;
- 使用: python mdnav.py filename1 filename2 ... filenameN
代码实现###
#!/usr/bin/python
#_*_encoding:utf-8_*_
##########################################################################
# mdnav.py: Generate nav anchors for given markdown files
# usage: python mdnav.py md_filename1 md_filename2 ... md_filenameN
##########################################################################
import re
import sys
mdTitleRegex = r'\s*(#{2,6})\s*(.*?)\s*(?:\1)\s+'
mdTitlePatt = re.compile(mdTitleRegex)
def parseLineByRegex(line, regex_patt):
m = regex_patt.match(line)
return m.groups() if m else ()
def outputAnchor(titleTuple):
if len(titleTuple) == 2:
intents = ' ' * (len(titleTuple[0])-2)
title = titleTuple[1]
anchor = '[%s](#%s)' % (title, title)
print intents,anchor
def procLine(line):
outputAnchor(parseLineByRegex(line, mdTitlePatt))
def help():
print '%s usage: need at least one param as markdown filename' % sys.argv[0]
print 'python %s filename1 filename2 ... filenameN' % sys.argv[0]
if __name__ == '__main__':
if len(sys.argv) < 2:
help()
exit(1)
for ind in range(1, len(sys.argv)):
filename = sys.argv[ind]
print 'file: ', filename
with open(filename) as mdtext:
map(procLine, mdtext.readlines())
使用Python从Markdown文档中自动生成标题导航的更多相关文章
- 【技术博客】利用Python将markdown文档转为html文档
利用Python将markdown文档转为html文档 v1.0 作者:FZK 元素简单的md文件 Python中自带有一个markdown库,你可以直接这样使用 md_file = open(&qu ...
- 如何在Markdown文档中插入空格?
简单说 在 Markdown 文档中,可以直接采用 HTML 标记插入空格(blank space),而且无需任何其他前缀或分隔符.具体如下所示: 插入一个空格 (non-breaking space ...
- 01将图片嵌入到Markdown文档中
将图片内嵌入Markdown文档中 将图片嵌入Markdown文档中一直是一个比较麻烦的事情.通常的做法是将图片存入本地某个路径或者网络存储空间,使用URL链接的形式插入图片: ![image][ur ...
- python实现解析markdown文档中的图片,并且保存到本地~
背景 前阵子简书好像说是凉了,搞得我有点小慌,毕竟我的大部分博客都是放在简书上面的,虽然简书提供了打包导出功能,但是只能导出文字,图片的话还是存在简书服务器上面,再加上我一直想要重新做一个个人博客,于 ...
- 2018-10-04 [日常]用Python读取word文档中的表格并比较
最近想对某些word文档(docx)的表格内容作比较, 于是找了一下相关工具. 参考Automate the Boring Stuff with Python中的word部分, 试用了python-d ...
- 用python把技术文档中,每个模块系列截图生成一个动态GIF
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 最近在写技术文档的时候,发现一个问题.对于每个技术步骤,都需要一个截图,这 ...
- 第一节:python提取PDF文档中的图片
由于项目需要将PDF文档当中的图片转换成图片,所以参考了这篇文章https://blog.csdn.net/qq_15969343/article/details/81673302后项目得以解决. 1 ...
- 如何制作dll库的API文档,自动生成微软风格的chm文件 Sandcastle Help File Builder 使用方法
当你开发了一个库的时候,就需要给库开发一个api文档,微软提供了一个C#库的自动生成工具.我在使用的过程中记录了相关的信息,以供大家学习和查阅,如有不正之处,欢迎指出. 首先先下载一个软件,下载地址在 ...
- 吴裕雄--天生自然python学习笔记:python文档操作自动生成菜单 Word 文件
许多学校营养午餐的菜单是由教师来轮流制作 ,这是一个 比较烦锁的工作,如 果能自动用教师最熟悉的 Word 文件来生成一个菜单文件,使教师对生成的菜单稍作 修改即可使用,那将是一个不错的主意. 案例要 ...
随机推荐
- DevOps is dirty work - CI drives you crazy
一直很想谈谈Continuous Integration(CI),持续集成. 就在不久前一次朋友聚会上,一个刚刚跳槽到一家创业公司的朋友跟我抱怨说他们没有CI,没有code review,要做点事太累 ...
- C#编译执行过程
前言 大家好,我是卫斯理(Wesley).喜欢武侠的朋友可能知道小说中也有个卫斯理,他是位冒险家,财力充沛,极富冒险精神,并且有着超强的好奇心,对奇异的事情总有"打破沙锅问到底"的 ...
- python爬虫beta版之抓取知乎单页面回答(low 逼版)
闲着无聊,逛知乎.发现想找点有意思的回答也不容易,就想说要不写个爬虫帮我把点赞数最多的给我搞下来方便阅读,也许还能做做数据分析(意淫中--) 鉴于之前用python写爬虫,帮运营人员抓取过京东的商品品 ...
- partnerv2.1
2.1.实时获取产品价格(action=queryprice) 请求 { "useDate": "2016-04-05T19:56", //开始用车时间(当地时 ...
- rabbitmq method之queue.declare
queue.declare即申请队列,首先对队列名作处理,若未指定队列名则随机生成一个,然后查询数据库队列是否已经创建,若创建完成则会申请队列返回 handle_method(#'queue.decl ...
- 给Source Insight做个外挂系列之五--Insight “TabSiPlus”
“TabSiPlus 外挂插件”主要有两部分组成,分别是“外挂插件加载器”和“插件动态库”.“插件动态库”完成Source Insight窗口的Hook,显示Tab标签栏,截获Source Insig ...
- iOS进阶篇索引,标记和自定义的table
一.带索引目录的表视图 ①效果图 图1 带索引的列表 ② 数据源 本想获取通讯录中得名字,但为了用模拟器调试方便,就写死了数据,所以也只写了部分字母,总之有那么点意思就成 @interface Vie ...
- IDEA +maven+ ContextLoaderListener not find
tomcat 启动失败:SEVERE: Context [] startup failed due to previous errors 查看pox.xml 有spring-web依赖 查看tomca ...
- Canvas 知识体系简单总结
Canvas 知识体系简单总结 标签(空格分隔): HTML5 Canvas 本文原创,如需转载,请注明出处 前言 知识点零零散散,一个上午整理了一下,内容不多,方便记忆. 本文不是教程,如需教程移步 ...
- js的forEach,for in , for of
forEach遍历数组 [].forEach(function(value, index, array) { // ... }); 例子 var myArry =[1,2,3,4]; myArry.d ...