首先看效果

起因

在编码区博主的博客里,最重要的东西,莫过于 代码块的高亮 了(至少我这么认为

在 Hexo 的主题里,代码块的高亮是有很多的,但是,有些主题的代码块高亮,可能并不是你想要的,或者说,你想要的代码块高亮,可能并不在这个主题里。

利用 highlight.js 的话,可以实现代码块的高亮,但是,Highlight.js 的代码块高亮,也是有限的,而且,Highlight.js 的代码块高亮,也不是很好看,因为大家不是设计师,手动调也很难如愿。

(以上的一堆废话由 Copilot 生成)

当然我尝试过手调一版:

2

我发现很多关键词是这个高亮所不支持的,相较于隔壁的 Github ,这么多人在上面看代码,做的高亮是极好的?

我能不能把 Github 的代码块高亮,拿来用呢?

探索&制造

经过一番摸索之后,发现了 Github Gist ,这个是一个类似代码片段的东西,可以用来粘贴代码分享到类似于 twitter 的社交平台,而且令我兴奋的是它支持 Embed,这不正我想要的吗?

3

于是就开始了我的探索之旅。

1. 创建 Github Gist

首先,我们需要创建一个 Github Gist,这个很简单,直接在 Github 上创建一个 Gist 就行了。

但是我们总不能把每篇文章写的代码都手动的创建吧,这太笨了,而且我博客有 900+ 代码块,这太费人了

2. 使用 Github API

Github 有一个 API,可以用来创建 Gist,我们可以利用这个 API 来创建 Gist。

有了API,这就好办了(但是其实Github官方有一个 js 的sdk,可惜是异步的

但是我如果想要把代码提交上去的话,必须在 Hexo 的构建阶段进行,所以只能用 同步,阻塞的 库。(因为这个是工具刚学js的时候写的,所以不大懂很高深的知识点,只能用自己的方法实现)

于是便去搜,发现了一个 "xmlhttprequest": "^1.8.0",这个库可以用来发送同步请求,只需要 open 的时候用第三个参数 false 即可:

用同步的库有什么好处呢,好处就是我们发完请求之后可以直接在下面读取数据,而不用再封装一个函数之类的(看了 hexo-douban 的源码,发现他们也是用的同步阻塞~~)

于是就来创建 Gist 了,这里有一点就是,我们总不能每次构建都把所有的代码块全部构建一遍吧,所以我们要把代码块做一个唯一标识,这里我用的是 md5 也就是算出来当前代码块的 md5 值,然后将这个值作为 Gistdescription,这样就可以保证每次构建的时候,只会创建新的 Gist,而不会重复创建。

正则匹配出文章的 代码块

算出来 md5

创建 Gist

就这样,我们就可以在 Hexo 的构建阶段,将代码块上传到 Gist 上了。

3. 代码块的渲染

既然将代码上传的部分我们都已经实现了,所以只需要读取就可以了,很简单直接上代码呢:

这里是因为 GithubREST API,所以我们判断获取到最后一页的依据这里我使用了判断返回的数据为 0 个时就结束

然后获取到代码的列表之后,我们只需要比一下 descriptionmd5 是否相同,如果相同就获取到 id,然后拼接 iframe 就可以了。

为什么要用 iframe 呢?是因为如果每次都遍历 Gist 列表一次,那么肯定会造成极大的浪费,所以这里采用的 iframe 的方式,就是在构建的时候,将代码块上传到 Gist 上,然后在渲染的时候,直接将 iframe 嵌入到页面中,这样就可以避免每次都遍历 Gist 列表的问题。

还有就是,我第一版写的代码,在 Safari 浏览器上会出现缩进失效的问题,经过一番探索,偶然在这个博客上见到了完美的代码:

4

很爽,之后我就直接拿来用了,这里就不多说了,直接上代码:

其实这里我适配了很多地方,让他来支持我的博客(比如 tags 标签内部 即 display: none 的时候获取不到内容高度 之类的bug,反正修了很久,有兴趣可以自己研究)

完美解决了缩进失效的问题,而且最大高度为 66vh ,非常棒。

效果就是本博客所用的,也是你目前看到的代码块。

这里使用的是 before_post_render

这个函数会在每篇文章渲染之前执行,这里我们可以对文章的内容进行修改,比如添加代码高亮,添加图片懒加载等等。

详情见 Hexo 官方文档

那么如何使用呢?

使用

这里是给大家写的部署教程,可以直接使用我的 iframe 域名哦,使用国内 CDN 加速,速度很快。

  • https://gist.onmicrosoft.cn/ (不支持直接浏览器访问,只支持跨域引用)
  1. 首先,你需要有一个 GitHub 账号,然后在 GitHub 上创建一个 Token, 用于访问 GitHub API,具体操作可以参考这篇文章:

  2. 然后,在环境变量中添加 GITHUB_TOKEN,值为你刚刚创建的 Token,这里我使用的是 vercel,所以是在 vercel 的环境变量中添加,其他平台也是一样的。

4

  1. 然后安装依赖 XMLHttpRequestcrypto
  1. 然后,你需要在 Hexo 根目录,创建一个文件夹 scripts,里面创建一个 gist.js 文件(名字随意,扩展名要js),内容如下:
  • 注意!!!:请将 105 行的 zkeq 替换为你的 GitHub 用户名
  • 示例:https://github.com/zkeq/Coding/blob/main/scripts/tools.js
  • 值得注意的是,Github API 有限制,似乎短时间最多创建 400Gist ,如果代码块太多,只需要隔一段时间再来跑一遍即可,比如我的就是 1200 个,跑了三次左右跑完了,而且这个只是第一次需要跑,后续每次更新文章最多就十几个代码块,所以就第一次慢,以后还是很快的
  • 创建太多不会停止,只是会提示报错,卡住而已,手动暂停部署即可
  1. 然后点击部署就可以啦,会出现文章开头视频的效果,如果后续发布文章,就会是这样:

有问题评论区提出哦

新增功能

  • 2022.12.21 新增自动清理 无用 Gist 的功能(识别到 descriptionmd5 才会清理 不会误删)

7

还是很爽很壮观的(删了1000条左右没用的测试数据[其实是第一次跑的时候忘记加扩展名了,索性再跑了一遍hhh])

  • 2022.12.22 更改获取 Gist 的 时机,避免在执行 yarn hexo cl;yarn hexo new 的时候也会获取,导致报错/资源浪费
  • 2022.12.23 修复了 Safari 浏览器可能遇到的 display:none 的时候遇到的 BUG还有一些小问题是真不想修了,Safari 真难适配啊(我在评论区细说一下这个,真的很难绷) 修好了,用最新代码即可(2022.12.13 20:40)