前言:Using highlight.js with marked

这是我的自建博客系统使用Marked.jsparsemarkdown文件再结合highlight.js来让代码高亮的时候碰到的问题,拿出来分享一下~~

博客地址:The blog of billyhu

Marked的问题

在这里我们可以看到Marked.js官方文档关于用其配合highlight.js做代码高亮的使用介绍

贴出核心代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Create reference instance
var myMarked = require('marked');

// Set options
// `highlight` example uses `highlight.js`
myMarked.setOptions({
  renderer: new myMarked.Renderer(),
  highlight: function(code) {
    return require('highlight.js').highlightAuto(code).value;
  },
  pedantic: false,
  gfm: true,
  tables: true,
  breaks: false,
  sanitize: false,
  smartLists: true,
  smartypants: false,
  xhtml: false
});

// Compile
console.log(myMarked('I am using __markdown__.'));
  • renderer选项new了一个markdown解析器

  • highlight选项这里引入了highlight.js的高亮处理模块

我基于上面配置用markdown写一段代码块注明为js代码,Marked将markdown解析为html的时候,处理结果是这样:

1
2
3
4
5
6
<pre>
<code class="language-js">
<!--这里面是各种标上了hljs-string、hljs-attr、hljs-literal等类名的span标签-->
<!--highligh.js依据这些类名为其渲染不同的颜色和样式-->
</code>
</pre>

上面这种示例方式有两个问题: - highlight.js会用到<code>标签中的类名'hljs'来为代码添加一部分样式,但是上面没有'hljs'

  • highlight.js的高亮解析模块需要传入'lang'参数确定当前语言,才能依据不同语言针对不同的关键字生成不同的类名(hljs-string、hljs-attr、hljs-literal等),以便做到精确的高亮

所以由于这两个问题,经常发现写的HTML、JS、CSS等代码出现各种莫名其妙的高亮,比如注释被高亮了,关键字却不高亮。。。

解决方法

首先这两个模块的官方文档都写得及其含糊。。。很多关键的细节在文档中根本没提到,查看一番源码方才得知方法:

  • 解决问题一:

上面的setOptions有一个langPrefix选项,允许你在<code>标签标明代码的类名之前自定义一个前缀(默认的前缀为'language-'):

1
langPrefix:'hljs ',

加了前缀之后,上面的代码变成了:

1
2
3
4
5
6
<pre>
<code class="hljs js">
<!--这里面是各种标上了hljs-string、hljs-attr、hljs-literal等类名的span标签-->
<!--highligh.js依据这些类名为其渲染不同的颜色和样式-->
</code>
</pre>

这样就搞定了第一个问题,这里官方介绍说是给类名加前缀,我这里是把前缀带上空格,就直接变成了两个类名(也许是官方有让你这样搞的意思,但是好歹说明一下啊,不然谁想得出来-_-)

  • 解决问题二:

看了两个模块的源码就知道Markedhighlight选项的函数是允许传入多个参数的code, lang, callback

同时highlight.js存在hljs.highlight(lang, code)函数,允许传入lang参数指定语言

于是最开始的highlight选项变成下面这样

1
2
3
highlight: function (code, lang, callback) {
  return hljs.highlight(lang, code).value;
}

下面是最终的正确配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
myMarked.setOptions({
  renderer: new myMarked.Renderer(),
  highlight: function(code, lang, callback) {
    return require('highlight.js').highlight(lang, code).value;
  },
  langPrefix:'hljs ',
  pedantic: false,
  gfm: true,
  tables: true,
  breaks: false,
  sanitize: false,
  smartLists: true,
  smartypants: false,
  xhtml: false
});

参考文档: