当前位置 : 首页 » 文章分类 :  开发  »  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

google/code-prettify
https://github.com/google/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>
此外,还需要给 precode 标签加上 prettyprint 这个 css 的 class,这样 code-prettify 才能对 pre 标签中的代码应用样式,脚本为:

<script type="text/javascript">
$(document).ready(function(){
 $('pre').addClass('prettyprint linenums');
 $('code').addClass('prettyprint');
 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树后就执行,完美。

所以最终 footer.ejs 中的 js 代码改为:

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

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

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

2018.1.15,颜色主题更新
最近看现在用的代码框主题不爽,找到一个不错的code-prettify主题网站
Color themes for Google Code Prettify
https://jmblog.github.io/color-themes-for-google-code-prettify/
下载了一包主题css,换来换去,选中了自己中意的一款主题。

添加代码行号

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

给每行添加行号

code-prettify将每行代码放在一个HTML的<li>列表中,然后通过给<li>列表加数字行号来实现代码行号功能,如下图:


默认每5行添加一个行号,可以修改,编辑prettify.css,找到下面的代码段,修改list-style-type属性值为decimal

<style>
li.L0, li.L1, li.L2, li.L3,
li.L5, li.L6, li.L7, li.L8 {
  list-style-type: decimal !important;
}
</style>

自动换行

在主题的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;');

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

可能是有 white-space:pre-wrap; 属性加到了 pre 标签上,自己找到在哪加的,去掉即可

其他style.css自定义样式

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

/* 2017.6.11,添加pre代码块自定义样式,作为code-prettify代码样式的补充 */
pre {
  font-size: 85%;
  line-height: 1.42857143;
  word-break: break-all;
  word-wrap: break-word;
  /*
  display: block;
  padding: 9.5px;
  margin: 0 0 10px;
  color: #333333;
  background-color: #f5f5f5;
  border: 1px solid #cccccc;
  border-radius: 4px;
  */
}

/* 2020.1.15 从 cerulean.css 迁移过来的 code 样式 */
code {
  padding: 2px 4px;
  font-size: 85%;
  border-radius: 4px;
  /* color: #c7254e;
  background-color: #f9f2f4; */
}

参考


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

下一篇 Java编码基础培训笔记

阅读
评论
2.5k
阅读预计10分钟
创建日期 2017-06-11
修改日期 2020-01-15
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论