首先看效果
起因
在编码区博主的博客里,最重要的东西,莫过于 代码块的高亮
了(至少我这么认为
在 Hexo 的主题里,代码块的高亮是有很多的,但是,有些主题的代码块高亮,可能并不是你想要的,或者说,你想要的代码块高亮,可能并不在这个主题里。
利用 highlight.js 的话,可以实现代码块的高亮,但是,Highlight.js 的代码块高亮,也是有限的,而且,Highlight.js 的代码块高亮,也不是很好看,因为大家不是设计师,手动调也很难如愿。
(以上的一堆废话由 Copilot 生成)
当然我尝试过手调一版:
我发现很多关键词是这个高亮所不支持的,相较于隔壁的 Github
,这么多人在上面看代码,做的高亮是极好的?
我能不能把 Github
的代码块高亮,拿来用呢?
探索&制造
经过一番摸索之后,发现了 Github Gist
,这个是一个类似代码片段的东西,可以用来粘贴代码分享到类似于 twitter
的社交平台,而且令我兴奋的是它支持 Embed
,这不正我想要的吗?
于是就开始了我的探索之旅。
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
值,然后将这个值作为 Gist
的 description
,这样就可以保证每次构建的时候,只会创建新的 Gist
,而不会重复创建。
正则匹配出文章的 代码块
:
算出来 md5
:
创建 Gist
:
就这样,我们就可以在 Hexo
的构建阶段,将代码块上传到 Gist
上了。
3. 代码块的渲染
既然将代码上传的部分我们都已经实现了,所以只需要读取就可以了,很简单直接上代码呢:
这里是因为 Github
是 REST
API,所以我们判断获取到最后一页的依据这里我使用了判断返回的数据为 0 个时就结束
然后获取到代码的列表之后,我们只需要比一下 description
和 md5
是否相同,如果相同就获取到 id
,然后拼接 iframe
就可以了。
为什么要用 iframe 呢?是因为如果每次都遍历 Gist 列表一次,那么肯定会造成极大的浪费,所以这里采用的 iframe 的方式,就是在构建的时候,将代码块上传到 Gist 上,然后在渲染的时候,直接将 iframe 嵌入到页面中,这样就可以避免每次都遍历 Gist 列表的问题。
还有就是,我第一版写的代码,在 Safari
浏览器上会出现缩进失效的问题,经过一番探索,偶然在这个博客上见到了完美的代码:
很爽,之后我就直接拿来用了,这里就不多说了,直接上代码:
其实这里我适配了很多地方,让他来支持我的博客(比如 tags 标签内部 即
display: none
的时候获取不到内容高度 之类的bug,反正修了很久,有兴趣可以自己研究)
完美解决了缩进失效的问题,而且最大高度为 66vh
,非常棒。
效果就是本博客所用的,也是你目前看到的代码块。
这里使用的是 before_post_render
这个函数会在每篇文章渲染之前执行,这里我们可以对文章的内容进行修改,比如添加代码高亮,添加图片懒加载等等。
详情见 Hexo
官方文档
那么如何使用呢?
使用
这里是给大家写的部署教程,可以直接使用我的 iframe
域名哦,使用国内 CDN
加速,速度很快。
https://gist.onmicrosoft.cn/
(不支持直接浏览器访问,只支持跨域引用)
首先,你需要有一个
GitHub
账号,然后在GitHub
上创建一个Token
, 用于访问GitHub API
,具体操作可以参考这篇文章:然后,在环境变量中添加
GITHUB_TOKEN
,值为你刚刚创建的Token
,这里我使用的是vercel
,所以是在vercel
的环境变量中添加,其他平台也是一样的。
- 然后安装依赖
XMLHttpRequest
和crypto
- 然后,你需要在
Hexo
根目录,创建一个文件夹scripts
,里面创建一个gist.js
文件(名字随意,扩展名要js),内容如下:
注意!!!:请将 105 行的 zkeq 替换为你的 GitHub 用户名
- 示例:https://github.com/zkeq/Coding/blob/main/scripts/tools.js
- 值得注意的是,
Github API
有限制,似乎短时间最多创建400
个Gist
,如果代码块太多,只需要隔一段时间再来跑一遍即可,比如我的就是1200
个,跑了三次左右跑完了,而且这个只是第一次需要跑,后续每次更新文章最多就十几个代码块,所以就第一次慢,以后还是很快的 - 创建太多不会停止,只是会提示报错,卡住而已,手动暂停部署即可
- 然后点击部署就可以啦,会出现文章开头视频的效果,如果后续发布文章,就会是这样:
有问题评论区提出哦
新增功能
- 2022.12.21 新增自动清理
无用 Gist
的功能(识别到description
为md5
才会清理 不会误删)
还是很爽很壮观的(删了1000条左右没用的测试数据[其实是第一次跑的时候忘记加扩展名了,索性再跑了一遍hhh])
- 2022.12.22 更改获取
Gist
的 时机,避免在执行yarn hexo cl;yarn hexo new
的时候也会获取,导致报错/资源浪费 - 2022.12.23 修复了
Safari
浏览器可能遇到的display:none
的时候遇到的BUG
,还有一些小问题是真不想修了,修好了,用最新代码即可(2022.12.13 20:40)Safari
真难适配啊(我在评论区细说一下这个,真的很难绷)