hexo-theme-fluid
hexo-theme-fluid copied to clipboard
给代码块增加折叠功能
如是功能需求,请确定符合以下情况
- [ ] 难以通过自定义实现
- [ ] 难以通过第三方插件实现
请描述该需求尝试解决的问题
代码块没有折叠功能,虽然可以通过自定义实现,但是需要每次打开页面都动态替换页面内容,非常不方便也不高效,而且折叠功能也较为重要。
请描述您认为可行的解决方案
添加折叠功能。
我的替代方案
效果见我的博客,比如文章 https://kiyanyang.github.io/posts/f92be1eb 。 我的效果和 https://github.com/fluid-dev/hexo-theme-fluid/issues/530 进行了结合。
注意:该方法对按照如下主题配置有效,对其他类型的主题配置可能无效
code: highlight: enable: true line_number: true lib: "highlightjs" highlightjs: style: "Github Gist" bg_color: false
总思路:借助 bootstrap 的 collapse 功能来折叠代码块
对于我的主题配置来说就是:获取所有 figure.highlight
元素,这个元素内有一个 table
(带行号的代码块),因此使用 bootstrap 的 collapse 功能来折叠 table
即可。代码如下(JavaScript):
// KiyanYang
// 获取唯一 ID
function getUuiD() {
return Math.random().toString(36).substring(2, 8) + Date.now().toString(36);
}
function addLanguage() {
// 获取所有 figure.highlight 元素
var hs = $("figure.highlight");
for (var i = 0; i < hs.length; i++) {
// 获取代码语言
var lang = hs[i].firstChild.firstChild.firstChild.lastChild.firstChild.firstChild.classList[1];
// 折叠块的 id
var id = `kiyan-collapse-${getUuiD()}`;
// 前面折叠按钮,这里我使用的是 FAS 图标,可以在 custom_css 添加 https://use.fontawesome.com/releases/v5.15.4/css/all.css 来引入
var btn = `<i class="fas fa-angle-down" type="button" data-toggle="collapse" data-target="#${id}"></i>`;
// 代码语言
var span = `<span>${lang}</span>`;
// 折叠块包裹原来的内容
var div = `<div class="collapse show" id="${id}">${hs[i].innerHTML}</div>`;
hs[i].innerHTML = btn + span + div;
}
}
$(document).ready(addLanguage);
关于我代码块部分的样式也一并展示如下(Stylus):
// ==================================================
// 代码块折叠
// ==================================================
figure.highlight {
background: rgb(230, 235, 241);
border-radius: 0.5rem;
table {
border-radius: 0 0 0.5rem 0.5rem;
}
// 折叠图标动画
.fas.fa-angle-down {
transform: none;
transition: transform 0.2s ease-in-out;
&.collapsed {
transform: rotate(-90deg);
}
}
// 折叠图标
> i {
color: #777777;
margin-left: 10px;
line-height: 2rem;
}
// 代码语言
> span {
color: #777777;
margin-left: 10px;
font-weight: bold;
}
// 固定代码块的第一列也即固定代码行数
td:first-child {
position: sticky;
left: 0;
z-index: 1;
}
}
// ==================================================
// 代码块的复制按钮
// ==================================================
.copy-btn {
// 注意:top 是和折叠功能共生的
top: 5px;
font-size: 1rem;
> i {
font-size: 0.875rem;
font-weight: bold;
}
}
.copy-btn-dark {
color: darkslategrey;
}
引入外部的 js、css 请参看官方文档
使用过滤器在文章完成渲染后增加折叠功能的代码。
在 scripts/
目录下新建文件 <fileName>.js
,文件名自定,内容如下:
"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 // 应该在完成其他渲染后执行,因此将优先级设大一点
);
更多细节请查看我的博客文章「使用 Hexo 过滤器实现 Fluid 主题的代码折叠」。
大佬你好,引入下拉图标(fas fa-angle-down)能仔细讲下吗,我博客现在只能使用fluid自带的图标,前端小白,导入cumtom_css也试过了,无果,
图标来自 https://fontawesome.com/ ,可以参考以下代码
custom_css:
- https://lib.baomitu.com/font-awesome/6.1.2/css/all.min.css # Font Awesome
- /css/code-folding # 你的图标的旋转动画, 注意这里使用无后缀或者使用 css 后缀
感谢大佬,问题解决了!
除了按照你说的修改custom_css:
外,还需要修改code-folding.styl
中的选择器, 可能hexo版本不一致,导致生成的静态文件.html结构不一样, 我的是hexo5.4.2 。
<blog>/public/<post path>/<post name>.html
:
<div class="markdown-body">
<!-- ... -->
<p>OuterClass.java:外部类嵌套内部类</p>
<figure class="highlight java"><i class="fas fa-angle-down" type="button" data-toggle="collapse"
data-target="#collapse-er2vp8l9qvgz18"></i><span>java</span>
<div class="collapse" id="collapse-er2vp8l9qvgz18">
<table>
<tr>
<td class="gutter">
<pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
</td>
<td class="code">
<pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">OuterClass</span> { <br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">InnerClass</span>{} <br> <span class="hljs-keyword">class</span> <span class="hljs-title class_">InnerClass2</span>{} <br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">InnerClass3</span>{}<br>}<br></code></pre>
</td>
</tr>
</table>
</div>
</figure>
<!-- ... -->
</div>
<blog>/source/css/code-folding.styl
:
// table里放的是代码
.markdown-body > figure > div > table{
border-radius: 0 0 0.5rem 0.5rem;
}
.markdown-body > figure{
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 > figure{
background-color: #696969;
transition: background-color 0.2s ease-in-out;
> i {
color: #c4c6c9;
}
> span {
color: #c4c6c9;
transition: color 0.2s ease-in-out;
}
}
}
效果图:
请问您方便贴一下这两个文件:code-folding.styl
和 过滤器的js文件 的目录供我参考一下吗?
blog
|----scripts
| |----filter-code-collapse.js
|
|----source
|----css
|----code-collapse.styl