当前位置: 首页 > Web前端 > HTML

如何编写markdown-it插件(三)

时间:2023-03-28 11:03:57 HTML

前言在《一篇带你用 VuePress + Github Pages 搭建博客》中,我们使用VuePress搭建了一个博客。查看最终效果:TypeScriptChineseDocumentation。在搭建博客的过程中,我们针对实际需要在《VuePress 博客优化之拓展 Markdown 语法》中讲解了如何编写markdown-it插件,在《markdown-it 原理解析》中讲解了markdown-it的执行原理。在这篇文章中,我们将详细讲解实战代码,帮助大家更好的编写插件。markdown-it-inlinemarkdown-it的作者提供了markdown-it-inine以方便修改内联标记。举个例子,如果我们给所有的链接添加target="_blank",通常你需要这样写://记住旧的渲染器,如果被覆盖,或者代理到默认渲染器vardefaultRender=md.renderer.rules.link_open||function(tokens,idx,options,env,self){returnself.renderToken(tokens,idx,options);};md.renderer.rules.link_open=function(tokens,idx,options,env,self){//如果您确定其他插件无法添加`target`-请检查下面的varaIndex=tokens[idx].attrIndex('target');如果(aIndex<0){tokens[idx].attrPush(['target','_blank']);//添加新属性}else{tokens[idx].attrs[aIndex][1]='_blank';//替换现有attr的值}//将令牌传递给默认渲染器。returndefaultRender(tokens,idx,options,env,self);};使用markdown-it-for-inline后:variterator=require('markdown-it-for-inline');varmd=require('markdown-it')().use(iterator,'url_new_win','link_open',function(tokens,idx){varaIndex=tokens[idx].attrIndex('目标');如果(aIndex<0){tokens[idx].attrPush(['target','_blank']);}else{tokens[idx].attrs[aIndex][1]='_blank';}});如果我们想替换某个文本,我们也可以使用markdown-it-for-inline:variterator=require('markdown-it-for-inline');//pluginparamsare:////-规则名称(应该是唯一的)//-要应用的标记类型//-函数//varmd=require('markdown-it')().use(iterator,'foo_replace','text',function(tokens,idx){tokens[idx].content=tokens[idx].content.replace(/foo/g,'bar');});markdown-it-containerPluginforcreatingblock-levelcustomcontainersformarkdown-itmarkdown的作者parser.markdown-it还提供了markdown-it-container用于快速创建块级自定义容器有了这个插件,你可以像这样使用markdown语法::::spoilerclickme*content*:::注意::::是插件定义的语法,它会把::::后面的字符去掉,在这个example是warning,提供自定义渲染结果的方法:varmd=require('markdown-it')();md.use(require('markdown-it-container'),'spoiler',{validate:function(params){returnparams.trim().match(/^spoiler\s+(.*)$/);},render:function(tokens,idx){//通过tokens[idx].info.trim()'clickme'stringvarm=tokens[idx].info.trim().match(/^spoiler\s+(.*)$/);//开始标签的嵌套为1,结束标签是-1if(tokens[idx].nesting===1){//开始标签return'

'+md.utils.escapeHtml(m[1])+'\n';}else{//结束标记return'
\n';}}});最终的渲染结果是:
clickme

content

和VuePress一样,它提供了一个自定义的容器:它实际实现了使用markdown-it-container,其源代码为:constcontainer=require('markdown-it-container')module.exports=md=>{md.use(...createContainer('tip','TIP')).use(...createContainer('warning','WARNING')).use(...createContainer('danger','WARNING')'))//...}functioncreateContainer(klass,defaultTitle){return[container,klass,{render(tokens,idx){consttoken=tokens[idx]constinfo=token.info.trim().slice(klass.length).trim()if(token.nesting===1){return`${信息||defaultTitle}

\n`}else{return`
\n`}}}]}系列文章博客搭建系列是我目前为止唯一写的实用系列教程,预计20篇左右对了,讲解如何使用VuePress搭建和优化博客,并部署到GitHub、Gitee、私服等平台,将我添加到SaeYu的唯一读者群。如有错误或不准确的地方,请务必指正,万分感谢。如果你喜欢或者有启发,欢迎star,这也是对作者的鼓励。