js压缩代码后怎么生成source map_??markdown生成导航? #x27;[toc]#x27;足矣
背景
什么是toc? table of contents 是markdown中的导航信息,能够通过heading和锚点快速定位。
最近在开发个人博客的时候,希望有一个生成目录导航的功能,目的是做一个像语雀右上角一样的导航栏:
使用的markdown渲染引擎是showdown,找了半天,只找到一个jquery写的toc插件,也不支持nodejs。(很好,又是一个造轮子,开源,刷福报的好机会!)
于是就自己做了一个插件,支持两大功能:
效果:
使用前:
使用后:
开发过程
汲取和熟悉
首先阅读showdown的wiki,了解extension机制和写法。了解到以下几点:
思路
老的思路:自己写一个lang插件,在一开始引擎读md的时候,就去收集信息,结果证明:❌
原因: 实践过程中,showdown有缓存机制,只会读取一遍md内容,之后读的都是html的内容,就无法收集toc的元信息了。
新思路:在output阶段中解析html的h1到h6标签,收集heading信息,并替代[toc]的占位符,输出到html中,结果证明:✅
步骤以及代码:
整个代码的核心是这个正则:/(<h([1-6]).*?id="([^"]*?)".*?>(.+?)</h[1-6]>)|(<p>[toc]</p>)/g;
这个正则,获取了h1-h6的标题信息以及toc的占位符的位置和次数
第一步:
在这里,showdown-toc会去寻找并按出现次序收集tocItem和[toc]
// find and collect all headers and [toc] node;const collection: MetaInfo[] = [];source.replace(regex, (wholeMatch, _, level, anchor, text) => {if (wholeMatch === '<p>[toc]</p>') {collection.push({ type: 'toc' });} else {text = text.replace(/<[^>]+>/g, '');const tocItem = {anchor,level: Number(level),text,};// 如果传了闭包的数组参数toc,就会把标题信息推入if (toc) {toc.push(tocItem);}collection.push({type: 'header',...tocItem,});}return '';});tocItem长这样:
type TocItem = {anchor: string; // 锚点level: number; // 标题级别text: string; // 标题内容 };第二步
这里,出现[toc]之后,会收集这个[toc]到下个[toc]之间的标题信息
// calculate toc infoconst tocCollection: TocItem[][] = [];collection.forEach(({ type }, index) => {if (type === 'toc') {if (collection[index + 1] && collection[index + 1].type === 'header') {const headers = [];const { level: levelToToc } = collection[index + 1] as TocItem;for (let i = index + 1; i < collection.length; i++) {if (collection[i].type === 'toc') break;const { level } = collection[i] as TocItem;if (level === levelToToc) {headers.push(collection[i] as TocItem);}}tocCollection.push(headers);} else {tocCollection.push([]);}}});第三步:
这个阶段,会把source中的showdown给我们生成的<p>[toc]</p>标签替换成我们生成toc标签,也就是ol和li标签啦。然后把处理后的source返回给showdown就好了。整个插件也就完成了。
// replace [toc] node in sourcesource = source.replace(/<p>[toc]</p>[n]*/g, () => {const headers = tocCollection.shift();if (headers && headers.length) {const str = `<ol>${headers.map(({ text, anchor }) => `<li><a href="#${anchor}">${text}</a></li>`).join('')}</ol>n`;return str;}return '';});总结
整个插件很简单,但是中间也遇到了不少坑,出现过思路的碰撞。实现的主要步骤逻辑如下:
欢迎pr
项目地址:https://github.com/ahungrynoob/showdown-toc
总结
以上是生活随笔为你收集整理的js压缩代码后怎么生成source map_??markdown生成导航? #x27;[toc]#x27;足矣的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: python人工智能要学什么_为什么学人
- 下一篇: centos 下载 哪个版本_生信分析平