如何在Angular 项目中使用Prism.js?

1. 从Prism.js 说起

Prims.js 是一个代码高亮插件。它的使用方式非常简单,只需要三步:

第一步,在官网上选择自己喜欢的皮肤和要高亮的代码语言;


第二步,下载相应的js 和css 文件;


第三步,在你展示代码的页面中引入刚刚下载的js 和css 文件,并为包含代码的code 标签添加相应的类。


经过以上三步就可以完成简单的代码高亮操作,通过观察形成的html 结构我们可以发现,Prism.js 所做的事情实际上是使用js 将你用code 标签包含的代码部分拆分,使用不同类名的span 标签包裹。然后利用提前设定好的皮肤,即你下载的css 文件实现高亮效果,不同的文件就对应了不同的皮肤。


2. 在Angular 项目中使用Prism.js 存在什么问题?

在传统的多页面应用中使用Prism.js 基本上没什么问题,但是在像Angular 这样的单页面应用中使用Prism.js 则会产生一些问题。问题主要表现在两个方面。

其一,Prism.js 中将代码转换为由span 标签包裹的html 是在一个立即函数中执行的。而在Angular 中,这个函数运行的时候很多页面可能还没有进行初始化,因此之后通过路由跳转到这些页面的时候无法看到代码高亮效果。

其二,Angular 中会存在包含html 和css 的ts 代码,这些代码往往由ES6 的反引号(`)包裹。Prism.js 原生皮肤对包含在ts 文件中的html 和css 代码不支持高亮显示。

3. 如何解决?

参考阿里ant design 的解决方案,两个问题分别以以下方式进行解决。

针对问题二,通过扩展原生Prism.js 方法的方式让其支持ts 文件中的html 和css 代码高亮显示,扩展代码写法如下:

const Prism = require('node-prismjs');
Prism.languages.angular = Prism.languages.extend('typescript', {});

Prism.languages.insertBefore('angular', 'string', {
  'template-string': {
    pattern: /template[\s]*:[\s]*`(?:\\[\s\S]|[^\\`])*`/,
    greedy : true,
    inside : {
      'html': {
        pattern: /`(?:\\[\s\S]|[^\\`])*`/,
        inside : Prism.languages.html
      }
    }
  },
  'styles-string'   : {
    pattern: /styles[\s]*:[\s]*\[[\s]*`(?:\\[\s\S]|[^\\`])*`[\s]*\]/,
    greedy : true,
    inside : {
      'css': {
        pattern: /`(?:\\[\s\S]|[^\\`])*`/,
        inside : Prism.languages.css
      }
    }
  }
});

module.exports = Prism;

针对问题一,先将选定的皮肤样式(css 文件内容)复制到根组件样式app.component.less 文件中。然后调用Prism.js 扩展的highlight 方法对要展示的代码进行转换得到由span 标签包含的html 代码。接着对这段代码使用encodeURIComponent 进行编码得到编码结果。再将这一段类似乱码的代码放到网站中需要展示的部分即可实现代码的高亮展示。

var angularPrism = require('./angular-marked.js');
var res = encodeURIComponent(angularPrism.highlight(code, Prism.languages['angular']));
return res;

其中使用encodeURIComponent 的原因在于使用highlight 方法转换过的代码很可能包含双引号("),单引号(')和反引号(`)三种符号,对于这种代码我们是无法将它赋给一个字符变量的,因为没有任何符号可以容纳它。 


Ref: Prism 官网

Ref: Github of ng-zorro-antd

猜你喜欢

转载自blog.csdn.net/qq_33594380/article/details/81048240