注意:本站已迁移至 Hugo。请访问本站「历史节点」获取有关 Hexo 的内容。
使用 Hexo 过滤器(Filter)实现 Fluid 主题的代码折叠。
过滤器简介
过滤器(Filter)细节参见「官方文档」。
过滤器(Filter)用于修改特定文件,Hexo 将这些文件依序传给过滤器,而过滤器可以针对文件进行修改。注册过滤器的方式如下:
JavaScript
hexo.extend.filter.register(
type,
function () {
// do something...
},
priority
);
priority
是过滤器的优先级,priority
值越小,过滤器会越早执行,默认的 priority
是 10。
思路
我们可以自定义一个过滤器,在文章完成渲染后增加折叠功能的代码。
折叠功能借助 Bootstrap - Collapse 实现。此外,Fluid 主题已引入 Bootstrap,我们无需再次引入。
实现
在 scripts/
目录下新建文件 <fileName>.js
,文件名自定,内容如下:
JavaScript
"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
):
增加相应的样式,进行美化:
Stylus
.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;
}
}
}
效果如下: