头像图片

南京笔点信息技术有限公司

漂亮的代码语法高亮插件Prism.js简单使用文档

网页代码高亮插件真的是非常多。例如:SyntaxHighlighterGoogle Code PrettifyHighlight.js等等。

今天介绍一个漂亮而且小巧的JS插件:Prism.js

官网地址:http://prismjs.com/index.html

为什么选用Prism.js?

除了简单,小巧之外,还有以下优点

  1. 极致易用:引用 prism.css 和 prism.js,使用合适的 HTML5 标签(code.language-xxxx),搞定!
  2. 天生伶俐:语言的 CSS 类是可继承的,所以你只需定义一次就能应用到多个代码片段。
  3. 轻如鸿毛:代码压缩后只有 1.6KB。每添加一个语言平均增加 0.3-0.5KB,主题在 1KB 左右。
  4. 快如闪电:如果可能,支持通过 Web Workers 实现并行。
  5. 轻松扩展:定义新语言或扩展现有语法,或者新增功能都非常简单。
  6. 丰富样式:所有的样式通过 CSS 完成,并使用合理的类名如:.comment, .string, .property 等。

谁在使用

我们截取一些官方公布的使用者,这里不乏一些十分大的网站。

image

示例

本文博客就是使用的Prism.js,我们直接来一段代码示例

HTML:

<!DOCTYPE html>
<html>
<head>
    ...
    <link href="themes/prism.css" rel="stylesheet" />
</head>
<body>
    ...
    <script src="prism.js"></script>
</body>
</html>

CSS:

.container .content .copy-link{
    border:1px solid #E5E5E5;
    background:#f9f9f9;
    padding:15px 15px 15px 120px;
    margin-bottom:30px;
    position: relative;
    margin-top:90px;
}

PHP:

public function init()
{
    parent::init(); // TODO: Change the autogenerated stub
    if(Yii::$app->user->id)
    {
        $this->redirect(Url::home());
    }
}

当然,不止这么多。Prism.js还支持其他上百种的编程语言。

其他主题

本博客使用的是Prism.js的默认主题,另外其还支持很多种主题。

Dark:

image

Funky

image

Okdiaia

image

Twilight

image

Coy

image

Solarized light

image

下载

Prism.js支持很多种语言和插件主题。把一些不必要支持的语言包下载下来,会加大库文件大小,拖累我们网站加载速度。所以Prism.js采用自定义下载。

image

从这里可以看出Prism.js支持的配置项还是非常多的。我们勾选上我们需要的选项,点击最下方的下载cssjs下载文件。

提示: 除了选择语言,在最下方的Plugins选项中,有一个Line Numbers还是非常值得下载的,可以在代码前显示行号。

使用

使用非常简单,首先引入刚刚下载好的2个文件。

<!DOCTYPE html>
<html>
<head>
    ...
    <link href="themes/prism.css" rel="stylesheet" />
</head>
<body>
    ...
    <script src="prism.js"></script>
</body>
</html>

页面上只要遇到类似下面的代码,就会被高亮。

<pre><code class="language-css">p { color: red }</code></pre>

但是,并不是所有的后台编辑器都会直接产生类似这样的代码。

下面看两种常用编辑器产生的代码相关HTML

Markdown

首先来看常用markdown编辑器,如果遇到代码编辑,他们会产生如下的HTML代码:

<pre>
    <code class="language-php">
        class GrabImage{

        }
    </code>
</pre>

完全符合要求,所以只需要在markdown编辑代码的时候选择语言就没有问题。

Ueditor

再来看市面上使用非常广泛的百度Ueditor编辑器,后台代码编辑会产生如下的HTML代码

<pre class="brush:html;toolbar:false"><link rel="icon" href=""></pre>

并没有产生预期的效果,而是只生成<pre>和一个class="brush:html;toolbar:false"。这个class可是不一般,其中brush:html中的html就代表的是HTML标签。如果在后台我们选择代码语言为java,那么这里会显示brush:java。所以,我们只要获取语言名称就可以构造符合要求的高亮代码。

这里我们只使用JS构造高亮代码,如果使用后台语言来构造不做研究。

$(document).ready(function(){
    var doc_pre = $("#post_content pre");
    doc_pre.each(function(){
        var class_val = $(this).attr('class');
        var class_arr = new Array();
        class_arr = class_val.split(';');
        class_arr = class_arr['0'].split(':');
        var lan_class = 'language-'+class_arr['1'];
        var pre_content = '<code class="'+lan_class+'">'+$(this).html()+'</code>';
        $(this).html(pre_content);
    });
});

阐述下逻辑:

  1. 首先遍历所有的<pre>标签,获取其class属性值。
  2. 使用;号来分隔值,放入数组。
  3. 再次获取数组第一个值,再次使用:分隔,放入数组。数组内第二个值即为html(代码语种)
  4. 获取<pre>标签内容,放入<code>包裹起来,再次放入<pre>标签。

随便找了个示例看下:

<pre class="brush:html;toolbar:false language-html">
    <code class=" language-html">
        <span class="token tag">
            <span class="token tag">
                <span class="token punctuation"><</span>link
            </span> 
            <span class="token attr-name">rel</span>
            <span class="token attr-value">
                <span class="token punctuation">=</span>
                <span class="token punctuation">"</span>icon
                <span class="token punctuation">"</span>
            </span> 
            <span class="token attr-name">href</span>
            <span class="token attr-value">
                <span class="token punctuation">=</span>
                <span class="token punctuation">"</span>
                <span class="token punctuation">"</span>
            </span>
            <span class="token punctuation">></span>
        </span>
    </code>
</pre>            

添加行号

需要实现行号效果,只需要在<pre>标签中加上line-numbers类即可。在之前的js代码中添加一行。

提示:要记得你下载了Line Numbers插件

$(this).attr("class",'line-numbers '+lan_class);

实现效果:

image

完整代码:

$(document).ready(function(){
    var doc_pre = $("#post_content pre");
    doc_pre.each(function(){
        var class_val = $(this).attr('class');
        var class_arr = new Array();
        class_arr = class_val.split(';');
        class_arr = class_arr['0'].split(':');
        var lan_class = 'language-'+class_arr['1'];
        var pre_content = '<code class="'+lan_class+'">'+$(this).html()+'</code>';
        $(this).html(pre_content);
        $(this).attr("class",'line-numbers '+lan_class);
    });
});