Hexo NexT文章中标题自动编号

1. 效果

本文章


NexT主题本身只有左侧边栏有自动编号,如果在文章中加入编号,左边的边栏就会显示两个编号,这个教程将教你怎么给文章自动编号
本教程使用的主题版本是7.7.2


2. 新方法

创建js脚本

2.1. 关闭目录栏的自动计数

打开next的配置文件_congig.yml,搜索tocnumber:后面的true改成false,这样左侧栏就不会自动计数了

2.2. 创建脚本

打开这个路径\themes\hexo-theme-next-7.7.2\scripts\filters新建一个js文件,写入以下脚本

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
'use strict'

let cheerio

hexo.extend.filter.register(
'after_post_render',
(data) => {
if (!cheerio) cheerio = require('cheerio')

const $ = cheerio.load(data.content, {
decodeEntities: false,
})
const $excerpt = cheerio.load(data.excerpt, {
decodeEntities: false,
})

let elHlist = $('h1,h2,h3,h4,h5,h6')
// h1到h6的标题编号
let h1 = '',
h2 = '',
h3 = '',
h4 = '',
h5 = '',
h6 = '',
// 相对于父级的第几个子标题
h1index = 1,
h2index = 1,
h3index = 1,
h4index = 1,
h5index = 1,
h6index = 1

elHlist.each((i, el) => {
// 标题编号
let hindexString = ''
switch ($(el).get(0).tagName) {
case 'h1': {
h2index = 1
h1 = h1index
h1index++
hindexString = h1
break
}
case 'h2': {
h3index = 1
h2 = h1 + '.' + h2index
h2index++
hindexString = h2
break
}
case 'h3': {
h4index = 1
h3 = h2 + '.' + h3index
h3index++
hindexString = h3
break
}
case 'h4': {
h5index = 1
h4 = h3 + '.' + h4index
h4index++
hindexString = h4
break
}
case 'h5': {
h6index = 1
h5 = h4 + '.' + h5index
h5index++
hindexString = h5
break
}
case 'h6': {
h6 = h5 + '.' + h6index
h6index++
hindexString = h6
break
}
}
$(el).prepend(
$('<span />')
.addClass('post-title-index')
.text(hindexString + '. ')
)
})

data.content = $.html()
data.excerpt = $excerpt.html()
},
10
)

2.3. 完成

3. 已过时方法

更改css,比较繁琐

3.1. 启用自定义文件

打开next的配置文件_congig.yml,搜索custom找到以下位置
主题配置文件位置
删除最后一个的注释,如上图

3.2. 编写自定义文件

7.7.2的自定义文件在根目录的\source\_data\styles.styl文件,如果没有就创建一个
填入以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
//文章中编号
body {counter-reset: h1}
h1 {counter-reset: h2}
h2 {counter-reset: h3}
h3 {counter-reset: h4}
h4 {counter-reset: h5}
h5 {counter-reset: h6}
h1:before {counter-increment: h1; content: counter(h1) ". "}
h2:before {counter-increment: h2; content: counter(h1) "." counter(h2) ". "}
h3:before {counter-increment: h3; content: counter(h1) "." counter(h2) "." counter(h3) ". "}
h4:before {counter-increment: h4; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "}
h5:before {counter-increment: h5; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "}
h6:before {counter-increment: h6; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "}

这个是我在一个issue找到的,但那个不支持主标题的自动编号,因为这样总标题也会加数字,你可以看看现在的预览

3.3. 修复上面的问题

这个问题的原因呢是因为主标题用的是<h1>的标签,和文章中的主标题一样,所以也记录了,下面是我的解决方案,有更好的也可以提出来

3.4. 修改主标题的标签

因为主标题的标签是<h1>嘛,那我们改成别的不就好了,打开自动生成的模板文件\themes\next\layout\_macro\post.swig,搜索h1找到默认在19行的这个位置

1
<{%- if theme.seo %}h2{% else %}h1{%- endif %} class="post-title{%- if post.direction and post.direction.toLowerCase() === 'rtl' %} rtl{%- endif %}" itemprop="name headline">

修改h1h0我们自定义一个叫h0的标题样式,可以到预览界面看看,是不是文章中的编号正常了,但是标题变了

3.5. 添加自定义标签样式

打开\source\_data\styles.styl这个自定义文件,添加下面的代码

1
2
3
4
h0{
font-size: $font-size-headings-base - $font-size-headings-step * 1;
display: block;
}

完成

3.6. 已知bug,评论区用标题也会接着文章中的数字编号

4. 一级标题

4.1. 二级标题

4.1.1. 三级标题

4.1.1.1. 四级标题

4.1.1.1.1. 五级标题
4.1.1.1.1.1. 六级标题

欢迎关注我的其它发布渠道