代码高亮工具highlightjs和prismjs

2018-07-16
JavaScript
12585

在编写文档或者博客的时候,常常需要将代码高亮显示。一般做法是加载第三方js库,处理代码高亮。这里,推荐两个js库,highlightjs 和 prismjs。

highlightjs

highlight.js 简介

highlight.js 大家可能并不陌生,一个轻量级的代码高亮库。可以在浏览器或者服务端运行。不依赖其他框架的js库。

highlight.js 使用

入门

<link rel="stylesheet" href="/path/to/styles/default.css">
<script src="/path/to/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
  1. 引入highlight的css资源,可以根据需要引用
  2. 引入highlight js文件
  3. 执行initHighlightingOnLoad方法。这个方法会将页面中<pre><code>标签中的代码高亮表示,它会尝试自动检测语言。如果自动检测不适用于您,则可以在class属性中指定语言:
<pre><code class="html">...</code></pre>

类也可以用前缀language-或 lang-

要禁用高亮显示,请使用nohighlight该类:

<pre><code class="nohighlight">...</code></pre>

进阶

上面的方法适合小白用户,如果想对高亮代码做一些定制化,就需要进一步了解highlight.js 的api了。highlight.js 有一下主要api(官方地址)

configure(options)

全局配置方法,

  • tabReplace: 用于替换缩进中的TAB字符的字符串
  • useBR : <br> 在输出中生成标签而不是换行符的标志,在使用非<pre>容器标记代码时非常有用。
  • classPrefix: 在生成的标记中的类名之前添加的字符串前缀,用于向后兼容样式表
  • languages:一组语言名称和别名,仅限于自动检测这些语言。
hljs.configure({
  tabReplace:''// 默认什么都不加,4个空格
  classPrefix:''//不要附加类前缀,默认前缀是'hljs-'
                      // 没有设置则不更改
}

highlight(lang, value, ignore_illegals, continuation)

highlight.js 核心方法,以某种语言高亮代码。

参数:

  • name 语言名称
  • value 代码字符串
  • ignore_illegals 可选参数,为true时,即使在检测到语言的非法语法而不是抛出异常的情况下也强制高亮
  • continuation 可选参数,是一个代表未完成解析的可选模式堆栈。当存在时,函数将重新从这个状态解析,而不是初始化一个新的状态

返回对象:

  • language 语言名称,与传入函数的语言名称相同,返回与highlightAuto方法一致
  • relevance 整数值
  • value 带突出显示标记的HTML字符串
  • top 当前栈的顶部

demo:

const hljs = require('highlightjs');
const html = hljs.highlight('js', 'var a = 123');
console.log(html);
// 输出
{ relevance: 1,
  value: '<span class="hljs-keyword">var</span> a = <span class="hljs-number">123</span>',
  language: 'js',
  top: ...
}

highlightAuto(value, languageSubset)

自动检测语言,高亮显示。

参数:

  • value 代码段
  • languageSubset 可选参数,数组类型,可选的语言名称,将检仅限于这些语言

返回对象字段:

  • language 检测到的语言
  • relevance 整数值
  • value 带突出显示标记的HTML字符串
  • second_best 一个更加友好,合理的高亮方案,可能不存在

demo:

const hljs = require('highlightjs');
const html = hljs.highlightAuto('var a = 123');
console.log(html);

// 输出
{ relevance: 4,
  value: '<span class="hljs-selector-tag">var</span> <span class="hljs-selector-tag">a</span> = <span class="hljs-number">123</span>',
  language: 'stylus',
  top: {},
  second_best: {
    relevance: 1,
     value: '<span class="hljs-keyword">var</span> a = <span class="hljs-number">123</span>',
     language: 'actionscript',
     top: {}    
  }
}

highlightBlock(block)

参数:

block 文档节点

将高亮block中的元素。下面展示一段使用highlightBlock达到initHighlightingOnLoad的功能

$(document).ready(function() {
  $('pre code').each(function(i, block) {
    hljs.highlightBlock(block);
  });
});

prismjs

prismjs 简介

prismjs 是一种轻量级的、可扩展的语法高亮器,它是用现代Web标准构建的。它在成千上万的网站中使用,包括你每天访问的一些网站。相比于highlightjs,prismjs高亮的代码更准确、更加的细粒度。所以,更推荐使用prismjs做代码高亮。

prismjs 使用

和highlightjs类似,在浏览器使用prismjs,直接引入css,js就行,唯一不同的是,prismjs不用调用init函数,而是自动解析在language-xxxx包裹下的<code></code>包裹下的代码。

<link rel="stylesheet" href="./node_modules/prismjs/themes/prism-coy.css">
<pre class="language-js">
    <code>
        var a = 'bbb';
    </code>
</pre>

<script src="./node_modules/prismjs/prism.js"></script>

prismjs API

Prism.highlight(text, grammar)

将代码text,以grammer指定的语言,高亮处理。

参数:

text string 类型,要高亮显示的代码 grammar prismjs 内置对象,通常指定某种语言,Prism.languages.js

返回:

高亮html代码

二者对比

相比highlightjs,prismjs代码高亮更准确,更加细粒度。看一个例子:

<pre class="language-js">
    <code>
        var a = {
            name: 'liming',
            age: 20
        };
    </code>
</pre>

prismjs 高亮结果

<code class=" language-js">
    <span class="token keyword">var</span>
    a 
    <span class="token operator">=</span>
    <span class="token punctuation">{</span>
    name
    <span class="token punctuation">:</span>
    <span class="token string">'liming'</span>
    <span class="token punctuation">,</span>
    age
    <span class="token punctuation">:</span> 
    <span class="token number">20</span>
    <span class="token punctuation">}</span>
    <span class="token punctuation">;</span>
</code>

highlightjs 高亮结果

<code class="hljs javascript">
    <span class="hljs-keyword">var</span> a = {
    <span class="hljs-attr">name</span>: <span class="hljs-string">'liming'</span>,
    <span class="hljs-attr">age</span>: <span class="hljs-number">20</span>
    };
</code>

很明显,prismjs会更加细致的划分代码段,所以,如果想高亮更好看,推荐使用prismjs

最后,再推荐一段prismjs高亮css

pre {
    display: block;
    background-color: #282c34;
    color: #fff;
    padding: 20px 24px;
    text-align: left;
    font-family: Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;
    border: 1px solid transparent;
    line-height: 1.4;
    transition: all 0.3s;
    font-size: 14px;
    border-radius: 5px;
    overflow-x: auto;
    margin: 13px 0;
    white-space: pre;
    word-spacing: normal;
    word-break: normal;
    word-wrap: normal;
}

pre code {
    font-family: inherit;
    color: #fff;
    padding: 0;
}
.token.block-comment, .token.cdata, .token.comment, .token.doctype, .token.prolog {
    color: #999
}

.token.punctuation {
    color: #ccc
}

.token.attr-name, .token.deleted, .token.namespace, .token.tag {
    color: #e2777a
}

.token.function-name {
    color: #6196cc
}

.token.boolean, .token.function, .token.number {
    color: #f08d49
}

.token.class-name, .token.constant, .token.property, .token.symbol {
    color: #f8c555
}

.token.atrule, .token.builtin, .token.important, .token.keyword, .token.selector {
    color: #cc99cd
}

.token.attr-value, .token.char, .token.regex, .token.string, .token.variable {
    color: #7ec699
}

.token.entity, .token.operator, .token.url {
    color: #67cdcc
}

.token.bold, .token.important {
    font-weight: 700
}

.token.italic {
    font-style: italic
}

.token.entity {
    cursor: help
}

.token.inserted {
    color: green
}