使用 Hexo 过滤器实现 Fluid 主题的代码折叠

本文最后更新于:2 天前

使用 Hexo 过滤器(Filter)实现 Fluid 主题的代码折叠。

过滤器简介

过滤器(Filter)细节参见「官方文档」。

过滤器(Filter)用于修改特定文件,Hexo 将这些文件依序传给过滤器,而过滤器可以针对文件进行修改。注册过滤器的方式如下:

JavaScript
1
2
3
4
5
6
7
hexo.extend.filter.register(
type,
function () {
// do something...
},
priority
);

priority 是过滤器的优先级,priority 值越小,过滤器会越早执行,默认的 priority 是 10。

思路

我们可以自定义一个过滤器,在文章完成渲染后增加折叠功能的代码。

折叠功能借助 Bootstrap - Collapse 实现。此外,Fluid 主题已引入 Bootstrap,我们无需再次引入。

实现

scripts/ 目录下新建文件 <fileName>.js,文件名自定,内容如下:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
"use strict";

// 获取唯一 ID
function getUuid() {
return Math.random().toString(36).substring(2, 8) + Date.now().toString(36);
}

hexo.extend.filter.register(
"after_post_render",
(data) => {
const { line_number, lib } = hexo.theme.config.code.highlight;

let reg;
if (lib === "highlightjs") {
if (line_number) {
reg = /(<figure class="highlight.+?>)(.+?hljs (.*?)".+?)(<\/figure>)/gims;
} else {
reg = /(<div class="code-wrapper.+?>)(.+?hljs (.*?)".+?)(<\/div>)/gims;
}
} else if (lib === "prismjs") {
reg = /(<div class="code-wrapper.+?>)(.+?data-language="(.*?)".+?)(<\/div>)/gims;
}

data.content = data.content.replace(reg, (match, begin, inner, lang, end, offset, string) => {
const collapseId = `collapse-${getUuid()}`;
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 设置折叠按钮图标,此处使用 GitHub 图标
const collapseBtn = `<i class="iconfont icon-github-fill" type="button" data-toggle="collapse" data-target="#${collapseId}"></i>`;
const collapseDiv = `<div class="collapse show" id="${collapseId}">${inner}</div>`;
const langSpan = `<span>${lang}</span>`;
return begin + collapseBtn + langSpan + collapseDiv + end;
});
return data;
},
10000 // 应该在完成其他渲染后执行,因此将优先级设大一点
);

此时的效果如图(使用 highlightjs):

demo-1

增加相应的样式,进行美化:

Stylus
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
.markdown-body .highlight table,
.markdown-body .code-wrapper pre {
border-radius: 0 0 0.5rem 0.5rem;
}

.markdown-body .highlight,
.markdown-body .code-wrapper {
background-color: #e6ebf1;
border-radius: 0.625rem;

// 折叠图标
> i {
color: #777777;
margin-left: 10px;
line-height: 2rem;
transform: none;
transition: color 0.2s ease-in-out, transform 0.2s ease-in-out;

&.collapsed {
transform: rotate(-90deg);
}
}

// 代码语言
> span {
color: #777777;
margin-left: 10px;
font-weight: bold;
}
}

[data-user-color-scheme='dark'] {
.markdown-body .highlight,
.markdown-body .code-wrapper {
background-color: #696969;
transition: background-color 0.2s ease-in-out;

> i {
color: #c4c6c9;
}

> span {
color: #c4c6c9;
transition: color 0.2s ease-in-out;
}
}
}

效果如下:

demo-2

参考


使用 Hexo 过滤器实现 Fluid 主题的代码折叠
https://kiyanyang.github.io/posts/c4dd4019/
作者
杨可
发布于
2022年5月22日
许可协议