《Hexo:从零开始编写自己的主题》
1. Hexo概述以及Hexo工作原理
2. 入门Hexo主题编写
3. 优化样式,设计自己的主题
4. fancybox优化图片展示效果、代码高亮以及数学公式
5. 添加本地搜索功能以及发布博客让官网接收
6. 添加自己的脚本处理数学公式

6. 添加自己的脚本,以处理数学公式为例

6.1 问题描述

这个应该算法是 hexo 的一个BUG或者说是hexo的不足。正常情况下,我们将 markdown 文件渲染为 html 时,需要保护一些特别部分不被渲染,比如说代码块与公式。

代码块中写

1
<h1> Hello World </h1>

很明显这块代码不应该被渲染,公式也是如此,但是对于复杂的公式,可能存在大公式里包含小公式的情况,hexo 有可能只渲染子模块,比如:

公式为

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
$$
f(x)=\left\{
\begin{aligned}
x & = & \cos(t) \\
y & = & \sin(t) \\
z & = & \frac xy
\end{aligned}
\right.
$$

$$
F^{HLLC}=\left\{
\begin{array}{rcl}
F_L & & {0 < S_L}\\
F^*_L & & {S_L \leq 0 < S_M}\\
F^*_R & & {S_M \leq 0 < S_R}\\
F_R & & {S_R \leq 0}
\end{array} \right.
$$

$$
f(x)=
\begin{cases}
0,& \text{x=0}\\
1,& \text{x!=0}
\end{cases}
$$

6.2 解决方法

为了保护我们的公式不被瞎渲染,我们需要在公式前后加 p 标签,即

1
2
3
4
5
6
7
8
9
10
11
<p>
$$
f(x)=\left\{
\begin{aligned}
x & = & \cos(t) \\
y & = & \sin(t) \\
z & = & \frac xy
\end{aligned}
\right.
$$
</p>

所以接下来就是算法设计部分,我们拿到的是markdown 的文字,在渲染前进行 过滤处理。

以下内容的概念就是在 “before_post_render” 时触发的代码,即对所有的博客进行渲染前的工作。

1
2
3
4
hexo.extend.filter.register('before_post_render', data => {
// 在这对 data 进行处理
return data;
}, 5);

总体思路为:

1. 将原文划分为 “代码块” 与 “非代码块” 两部分。如果是代码块的公式,不做处理。比如 ```bash 中的内容。

2. 非代码块的内容根据 两个美元符号 $$ 进行 split,再对每一个分割块进行处理。

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
// 根据 $$ 将原内容分块
// 如果是奇数块则前后添加 $$ 符号
function dollarsHandle(data) {
var math_blocks = data.split('$$')
var newContent = ""
if (math_blocks.length > 2) {
math_blocks.forEach((one, i)=>{
if (i % 2 == 1 ) {
newContent += '<p>$$'
newContent += one
newContent += '$$</p>'
} else {
newContent += one
}
})
return newContent
}
return data
}


hexo.extend.filter.register('before_post_render', data => {
// 首先根据 ```划分为代码块与非代码块
var blocks = data.content.split('```')
blocks.forEach((block, i) => {
// 如果是偶数块
if (i % 2 == 0) {
blocks[i] = dollarsHandle(block)
}
})

if (blocks.length > 2) {
var newDataContent = ""
blocks.forEach((block, i)=>{
newDataContent += block
newDataContent += "```"
})
data.content = newDataContent
} else {
data.content = dollarsHandle(data.content)
}
return data;
}, 5);

6.3 效果查看

前往smileyan个人网站 https://smileyan.cn/heyan/ 查看效果。

源码的地址为:https://github.com/smile-yan/hexo-theme-heyan

6.4 总结

如果觉得别人的主题不够符合自己的喜好,那就自己写个主题。

如果觉得 hexo 渲染可能存在问题,那就自己写脚本纠正官方的问题。

如果觉得本文有用,请点个赞支持一下吧~ 感谢!

原文链接:https://blog.csdn.net/smileyan9/article/details/124400719