前言在《一篇带你用 VuePress + Github Pages 搭建博客》中,我们使用VuePress搭建了一个博客,最终效果可以查看:TypeScript中文文档。在搭建博客的过程中,出于实际需要,我们在《VuePress 博客优化之拓展 Markdown 语法》中讲解了如何编写一个markdown-it插件。在本文中,我们将深入markdown-it的源码,讲解markdown-it的执行原理。让大家对markdown-it有更深入的了解。介绍参考了markdown-itGithub仓库的介绍:Markdownparserdoneright。快速且易于扩展。可见markdown-it是一个markdown解析器,易于扩展。其demo地址为:https://markdown-it.github.io/markdown-它具有以下优点:遵循CommonMark规范,增加了语法扩展和语法糖(如URL自动识别和打印特殊处理)可配置语法,你可以添加新规则或替换现有规则快速默认安全社区有很多插件或其他包使用//installnpminstallmarkdown-it--save//node.js,“经典”方式:varMarkdownIt=require('markdown-it'),md=newMarkdownIt();varresult=md.render('#markdown-itrulezz!');//没有AMD的浏览器,在脚本加载时添加到“窗口”//注意,“markdownit”中没有破折号。varmd=window.markdownit();varresult=md.render('#markdown-itrulezz!');源码分析再看一下markdown-it的入口代码,可以发现代码逻辑清晰://...varRenderer=require('./renderer');varParserCore=require('./parser_core');varParserBlock=require('./parser_block');varParserInline=require('./parser_inline');functionMarkdownIt(presetName,options){//...this.inline=newParserInline();this.block=newParserBlock();this.core=newParserCore();this.renderer=newRenderer();//...}MarkdownIt.prototype.parse=函数(src,env){//...varstate=newthis.core.State(src,this,env);这个.core.process(状态);返回state.tokens;};MarkdownIt.prototype.render=function(src,env){env=env||{};返回this.renderer.render(this.parse(src,env),this.options,env);};从render方法也可以看出,它的渲染分为两个过程:Parse:将Markdown文件解析成TokensRender:遍历Tokens生成HTML和Babel很像,只不过Babel把它转成了抽象语法树(AST),而markdown-it没有选择使用AST,主要是遵循KISS(KeepItSimple,Stupid)原则Tokens是什么样子的?我们在demo页面试一下:可以看出#header生成的Token的格式为(注:为了方便展示,这里做了简化):[{"type":"heading_open","tag":"h1"},{"type":"inline","tag":"","children":[{"type":"text","tag":"","content":"header"}]},{"type":"heading_close","tag":"h1"}]具体Token中各字段含义参见TokenClass。通过这个简单的Tokens例子也可以看出Tokens和AST的区别:Tokens只是一个简单的数组。开始标签和结束标签是分开的。Parse查看parse方法相关的代码://...varParserCore=require('./parser_core');functionMarkdownIt(presetName,options){//...this.core=newParserCore();//...}MarkdownIt.prototype.parse=function(src,env){//...varstate=newthis.core.State(src,this,env);这个.core.process(状态);返回state.tokens;};可以看到具体的执行代码,应该是写在.在/parse_core中查看parse_core.js的代码:var_rules=[['normalize',require('./rules_core/normalize')],['block',require('./rules_core/block')],['inline',require('./rules_core/inline')],['linkify',require('./rules_core/linkify')],['replacements',require('./rules_core/replacements')],['smartquotes',require('./rules_core/smartquotes')]];functionCore(){//...}Core.prototype.process=function(state){//...for(i=0,l=rules.length;i foo\uFFFDbar'+escapeHtml(tokens[idx].content)+'
';};CustomRules至此,我们对markdown-it的渲染原理有了一个简单的了解,无论是Parse还是Render过程中的Rules,markdown-it都可以提供自定义这些Rules的方式,这也是写法的关键markdown-it插件。我们会在后续的系列文章中谈到。博客搭建系列是我目前为止唯一写的实用系列教程,讲解如何使用VuePress搭建博客。并部署到GitHub、Gitee、个人服务器等平台。一会带你用VuePress+GitHubPages搭建博客一会教你如何在GitHub和Gitee之间同步代码还是不知道如何使用GitHubActions?看看这个Gitee是如何自动部署Pages的?仍然使用GitHubActions!一个前端足够用的Linux命令一个足够简单的NginxLocation配置说明从购买服务器到部署博客代码的详细教程从域名购买到备案到解析的详细教程VuePress博客优化最后更新最后更新时间如何设置VuePress博客优化添加统计功能VuePress博客优化启用HTTPSVuePress博客优化启用Gzip压缩从头开始实现一个VuePress插件微信:“mqyqingfeng”,加我到SaeYu的唯一读者群。如有错误或不准确的地方,请务必指正,万分感谢。如果你喜欢或者有启发,欢迎star,这也是对作者的鼓励。
