当前位置 : 首页 » 文章分类 :  开发  »  Hexo博客(12)使用google-code-prettify代码高亮

Hexo博客(12)使用google-code-prettify代码高亮

Hexo自带的highlight.js代码高亮不好用,我博客里从来没有高亮成功过,指定代码类型也从来不管用,早就想换掉了,今天彻底解决它。偶然搜索到Google提供的code-prettify代码高亮脚本,看起来不错,下面介绍如何在Hexo博客中使用Google的code-prettify代码高亮。


放弃使用highlight.js代码高亮

之前也说过,Hexo自带的highlight.js代码高亮除了不好用,还有个严重的bug,当在博客配置中将highlight的选项auto_detect设为true时,hexo g生成博客时报错:
TypeError: Cannot set property 'lastIndex' of undefined
刚开始上百度查,总是查不到点上,后来用了新出的搜狗英文搜索,一击命中。
解决方法是在配置文件_config.yml中将highlight选项的auto_detect设为false,完美解决。
参考Hexo 3.2.0-beta.2 test result report #1627
后来看Hexo 3.2版的官方文档,也说了使用highlight.js的auto_detect选项会遇到问题,官方都建议将其设为false
自动检测代码类型设为false后,我Markdown写文章时用’’’cpp代码块手动指定代码类型也从来不管用,索性直接放弃使用highlight.js

首先在博客配置文件_config.yml中将highlight相关配置都设为false:

highlight:
  enable: false
  line_number: false
  auto_detect: false
  tab_replace:

然后去掉highlight.css样式文件的加载,注意这个是一定要去掉的,因为其中有代码相关的pre标签和code标签样式,会影响后面我们加载code-prettify代码样式。我是用的free2mind主题在themes\free2mind\layout_partial\head.ejs中加载了这个css,注释掉它:
<link rel="stylesheet" href="<%- config.root %>css/highlight.css" media="screen" type="text/css">


本地安装code-prettify

在code-prettify的GitHub页面https://github.com/google/code-prettify 的releases中下载最新的release版prettify-4-Mar-2013.tar.bz2,解压后将src目录中的样式文件prettify.css拷贝到主题的source\css目录中,将js代码文件prettify.js拷贝到主题的source\js目录中,这样hexo g生成博客时会自动将这些文件拷贝到public文件夹的css和js子文件夹中,页面上就能加载到了。本地安装完毕。

当然code-prettify也能直接通过url加载css和js脚本,由于是Google的东西,怕链接在内地被墙,最好还是把代码下载下来放到本地加载。
通过url加载代码参考 https://github.com/google/code-prettify/blob/master/docs/getting_started.md#auto-loader


code-prettify支持的语言

code-prettify的GitHub页面中列出了支持的语言:
C and friends, Java, Python, Bash, SQL, HTML, XML, CSS, JavaScript, Makefile, and Rust.
以及Ruby, PHP, VB, and Awk and a decent subset of Perl and Ruby
其他语言解析不在prettify.js中,需要手动加载额外的js文件,可在prettify-4-Mar-2013.tar.bz2压缩包的src文件夹内找到这些语言的解析js

指定代码语言

code-prettify会自动检测代码类型,不需要指定,当然自动检测不完全准确,可以通过给pre标签添加特定语言类型来指定,详见code-prettify的GitHub页面说明,我感觉一般使用自动检测就足够了。


加载code-prettify

考虑到加载速度,最好css写到头部head中,js写到文档末尾footer中。

prettify.css代码加载

在主题的themes\free2mind\layout_partial\head.ejs模版中添加prettify.css代码加载:
<link rel="stylesheet" href="<%- config.root %>css/prettify.css" media="screen" type="text/css">

prettify.js脚本加载

在主题的themes\free2mind\layout_partial\footer.ejs模版中添加prettify.js代码加载:
<script src="<%- config.root %>js/prettify.js"></script>
此外,还需要给pre标签加上prettyprint这个css的class,这样code-prettify才能对pre标签中的代码应用样式,脚本为:

<script type="text/javascript">
$(window).load(function(){
 $('pre').addClass('prettyprint linenums');
   prettyPrint();
 })
</script>

以上代码需要有jQuery,几乎所有Hexo主题都已经加载了jQuery,不用担心。

JavaScript代码加载顺序优化

页面上的Javascript代码是HTML文档的一部分,所以Javascript在页面装载时执行的顺序就是其引入标记<script />的出现顺序。
我的footer.ejs模版中还有CNZZ统计、百度统计、不蒜子访问量统计脚本,这些都需要从外部url加载js,所以要把prettify.js脚本加载代码放在这些的前面,因为prettify.js是从本地加载,避免由于其他外部js服务器无响应加载失败导致代码高亮渲染失败。
2017.7.1修改:
发现打开有代码块的页面后,总是要先等待不蒜子访问量统计代码加载完成后才能将代码块高亮,但是我已经将code-prettify的js代码放在不蒜子js代码之前了,后来终于查到原因了,因为我用了jQuery的$(window).load(function(){})方式加载给pre标签添加class “prettyprint linenums”的js函数,而$(window).load(function(){})是在页面所有元素(包括所有css,js,图片,Flash等)加载完毕后执行的,所以等不蒜子的外部js代码加载完才会高亮。
改进方式是使用jQuery的$(document).ready(function(){})方式加载,$(document).ready(function(){})方式加载函数在当页面的标准DOM元素被解析成DOM树后就执行,完美。
所以js代码改为

<!-- 加载本地Google Prettify 代码高亮js代码-->
<script src="<%- config.root %>js/prettify.js"></script> 

<!-- 用于Google Prettify 代码高亮,给pre标签添加class "prettyprint linenums",有行号 -->
<!-- jQuery的$(window).load(function(){})是在页面所有元素(包括所有css,js,图片,Flash等)加载完毕后执行
<script type="text/javascript">
$(window).load(function(){
 $('pre').addClass('prettyprint linenums');
   prettyPrint();
 })
</script>
-->

<!-- 用于Google Prettify 代码高亮,给pre标签添加class "prettyprint linenums",有行号 -->
<!-- jQuery的$(document).ready(function(){})是当页面的标准DOM元素被解析成DOM树后就执行-->
<script type="text/javascript">
$(document).ready(function(){
 $('pre').addClass('prettyprint linenums');
   prettyPrint();
 })
</script>

还是放在footer.ejs模版开头。


代码样式设置

颜色主题选择

code-prettify项目给出了几个可选的代码框颜色主题 https://rawgit.com/google/code-prettify/master/styles/index.html ,我比较喜欢其中的Sons-Of-Obsidian样式,下载的压缩包prettify-4-Mar-2013.tar.bz2中自带了这几个样式,其css文件在styles文件夹中,将其中的sons-of-obsidian.css拷贝到主题的source\css目录中,在head.ejs模版中改为加载sons-of-obsidian.css即可:
<link rel="stylesheet" href="<%- config.root %>css/sons-of-obsidian.css" media="screen" type="text/css">

添加代码行号

pre标签加上linenums这个css的class即可给代码增加行号,上面的脚本$('pre').addClass('prettyprint linenums'); 就给标签’pre’同时添加了prettyprintlinenums class

自动换行

在主题的style.css样式表中给’pre’标签添加自动换行属性:

pre {
  word-break: break-all;
  word-wrap: break-word;  
}

溢出代码形成滚动条

在主题的style.css样式表中给’pre’标签添加溢出后形成滚动条属性:

pre {
  overflow:scroll; 
}

当然这时要去掉自动换行属性。
或者也可以在js脚本中直接设置内联style样式:
$('pre').addClass('prettyprint linenums').attr('style', 'overflow:scroll;');

溢出代码成滚动条不生效问题

如果博客中有用bootstrap,其中对pre有如下几句
white-space:pre;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;
这会使得pre中的代码自动换行,而不是溢出形成滚动条。解决方法我也不知道,对bootstrap不熟悉,我觉得自动换行比较好,对我不碍事。

其他style.css自定义样式

我使用的free2mind主题也有几个颜色主题,我当前用的是cerulean颜色主题,会加载一个cerulean.css,其中给’pre’标签添加了好些样式,为了不影响code-prettify代码样式,我注释掉了。
此外,我还在主题的style.css样式表中给’pre’标签添加了一些自定义样式,字体改小,行高改小,自动换行,如下:

pre {
  font-size: 13px;
  line-height: 1.42857143;
  word-break: break-all;
  word-wrap: break-word;  
}

参考


上一篇 Hexo博客(13)添加MathJax数学公式渲染

下一篇 Hexo博客(11)添加网易云跟帖评论系统

域名迁移公告
2017年12月20日起,本博客迁移到新域名madaimeng.com,旧域名masikkk.com不再更新内容,但将永久保持可访问!
阅读
2,066
阅读预计8分钟
创建日期 2017-06-11
修改日期 2017-07-01
类别
百度推荐