目录
前言
本以为我的博客程序是没有 [TOC]
这样东西来自动生成目录树的,都已经把代码写好了,一看文档就懵逼了。原来文档最后一条写明了,[TOC]
以及其用法,是我自己没好好看文档,心痛。
不过既然写完了,那就把原理分享出来吧,反正也就 30 行代码。千万别钻牛角尖跟我说超过了 30 行,你硬是觉得括号占一行也算行的话我也没办法。
第一步、提取标题
既然要为 Markdown 生成目录树,那么第一个步骤就是提取 Markdown 中的所有标题。因为 Markdown 本身语法非常简单,由若各个 #
符号开头,所以可以用一个正则表达式 /^(#+)[ \t](.*)$/
进行匹配提取。(#+)
用来提取是第几级的标题,(.*)
用来提取出具体标题内容。因为很多 Markdown 实现里面都要求标题的 #
符号后面要跟空格或者 tab 来进行分隔,所以我们也按照这样的标准,用 [ \t]+
来强制要求至少有一个空格或者 tab 进行分隔。
下面这个 getHeaders 就是用来提取一个 Markdown 里面标题的,具体过程如下:
- 将 Markdown 文件用
split('\n')
分成一个行数组。
- 将行数组里面的每一行用
/^(#+)[ \t](.*)$/
进行匹配和提取标题。
- 过滤掉不匹配的行。
- 最后将提取出来的字符整理成一个级数和标题的对象。
const getHeaders = text =>
text
.split('\n')
.map(line => line.match(/^(#+)[ \t]+(.*)$/))
.filter(header => header !== null)
.map(([, prefix, title]) => ({ level: prefix.length, title }))
getHeaders 函数会提取出一个 Markdown 文件里面所有的标题信息,这个标题信息里面包含了标题的级数和标题内容。