Hugo中添加代码高亮支持

对程序员来说,最重要的分享内容,就是代码。

自然语言,只是为了解释代码而已。

Hugo的代码高亮

很多Hugo的主题,都自带代码高亮的支持。其中,Hyde由于极简的设计,默认是没有的。

代码高亮,其实就是把包含在<pre><code></code></pre>之间的内容,做相应的着色。 这个过程中,最麻烦的,莫过于分辨出代码的内容。 谁是函数,谁是类,谁是数字,谁是字符串……

这个问题虽然不是很难,用正则表达式也能做出一个不错的结果,但也是件麻烦事。 幸好,已经有成熟的工具,解决了这个问题。

Hugo在官方文档中,推荐的是Pygments。 (从0.30版本开始,集成了Chroma作为替代。) 而孤则不建议使用这种后端生成的方案。

代码高亮的工作,可以在生成静态网页时做,也可以在浏览器里做。 前者的优势在于,渲染更快,并且在禁用JavaScript的环境下仍然能正常显示,而后者则更加灵活。

Pygments就是在生成时做,需要开发与生产环境下,对其进行安装。 就效果而言,其实也有一些小瑕疵。 最大的问题是,它是维护在Bitbucket上的,而孤的Bitbucket账户又……

虽然Pygments的安装简单,不过孤最终还是选择让代码高亮在浏览器里做。

代码高亮的JavaScript

通过JavaScript,让页面在浏览器里渲染时,顺便给代码上色。 Hugo官方文档推荐了以下的库:

孤考察了上述JavaScript库,最终还是选择了Highlight.js

其实,它们多少都有些问题。 Highlight.js的问题相对少一些,文档好一些。 毕竟,不能指望一群前端工程师对其它语言有多么深入的理解。

使用Highlight.js

<head>的模板中,添加以下内容:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/monokai.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

当前(2017年),highlight.js最新版本是9.12.0。

三行代码,第一行的monokai.min.css是配色方案,孤对Monokai情有独钟。 第二行引入是highlight.js的压缩版,第三行是使用highlight.js着色。 就是这么简单。

考虑到国内的访问速度,本站改用了BootCDN

<link href="https://cdn.bootcss.com/highlight.js/9.12.0/styles/monokai.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

示例

在Markdown中,输入以下内容:


```c
#include 

int main(void)
{
  printf("Hello world!"),
  return 0;
}
```

转换为静态网页后,可以看到:

<pre><code class="language-c">
#include &lt;stdio.h&gt;

int main(void)
{
  printf(&quot;Hello world!&quot;),
  return 0;
}
</code></pre>

这种东西,默认当然是没有代码高亮的。 但是在前面highlight.js的三行代码的帮助下, 就可以按C语言的方式匹配,最终得出以下效果。

#include <stdio.h>

int main(void)
{
  printf("Hello world!"),
  return 0;
}

其中,Markdown里标明的语言,最终会转换成language-*,帮助highlight.js识别。

如果仍然是9.12.0,你应该能明显发现,#include <stdio.h>被错误地识别为注释。 这么简单的东西都会搞错!

highlight.js只是一个最好、但仍不够好的选择。

其它语言支持

在默认的js里,支持很多常见的语言,比如HTML、Java、Python等。 但有些比较偏门的语言或配置文件,默认的js里是没有支持的。 不过,却可以通过引入额外的js来支持,比如Django、Dockerfile、Vim、YAML、Gradle、TeX等。

<link href="https://cdn.bootcss.com/highlight.js/9.12.0/styles/monokai.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/highlight.min.js"></script>

<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/django.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/dockerfile.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/vim.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/yaml.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/gradle.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/tex.min.js"></script>
...

<script>hljs.initHighlightingOnLoad();</script>

注意:这些代码需要放在highlight.min.js之后、hljs.initHighlightingOnLoad();之前。

这些额外的支持,可以在CDN提供页面去查询,按需使用。

心机

  1. 浏览器做代码高亮,可以减少服务器的工作。
  2. 使用CDN,减轻服务器的负担。

参考


相关笔记