Hexo提供了诸多插件来增强博客体验,地址http://hexo.io/plugins/
在博客搬迁的时发现一个生成文章目录的插件,hexo-toc

hexo-toc

为防插件误认标记,文章以下出现的 ttoc 实际为 toc。

使用方法跟显示文章摘要类似,在Markdown中需要显示文章目录的地方添加 <!-- ttoc -->

安装

npm install hexo-toc --save

配置

在博客根目录下的 _config.yml 中如下配置:

toc:
maxDepth: 3

maxDepth 表示目录深度为3,即最多生成三级目录。

好了,现在重启Hexo预览下效果吧。

Toc文章目录
Toc文章目录

然后你会发现点击目录链接,没反应!
F12查看生成的HTML代码:

Toc生成代码
Toc生成代码

标题id生成没问题,锚链接中的中文都被转义为 - 了。

看了该插件的issues中已经提到了这个问题,不过好像是没解决。
也没用搜索到其他人有关该插件的使用经验。
没办法,自己动手丰衣足食!

解决锚链接中文被转义

也没什么好的办法,只凭着入门级的Node水平,顺藤摸瓜!
从插件下的index.js开始,一路跟踪代码调试,在感觉可能出现问题的地方console输出内容,最终让我给找到了。

文件位置:Hexo根目录\node_modules\hexo-toc\node_modules\markdown-toc\index.js
找到如下方法,把原来返回值注释掉,直接 return str;

function slugify(str, opts) {
if (opts && opts.slugify === false) return str;
if (opts && typeof opts.slugify === 'function') {
return opts.slugify(str, opts);
}
str = str.split('.').join('');
//return str.toLowerCase().replace(/[^a-z0-9]/g, '-');
return str;
}

现在重启Hexo后链接都正常可用了。

更好的方法是不改变插件源代码的情况下进行配置。
在以上方法中可以发现,插件有个slugify的配置项,当此项配置为false时即直接return str;

所以,我们可以到_config.yml添加toc配置:

toc:
  maxDepth: 3
  slugify: false

给Toc添加样式

如本文中文章目录样式,置于文章右侧,又加了个背景等。

hexo-toc插件是生成的文章目录最终还是Markdown格式的,最后被Hexo的marked模块解析为HTML。

要添加样式先加选择器。
想通过修改插件代码增加选择器是行不通的,也不能直接在 <!-- ttoc -->标记外包裹 <div>

因为添加了HTML标签的地方就不会在被marked模块解析。

那就只能在HTML生成之后增加,用js。

hexo-toc插件生成文章目录时还在其前后增加了 <!-- ttoc --><!-- ttocstop --> 注释。
解决办法就是把这两个注释替换为可控的 <div>

找到主题下的文章模版,我的是themes\yilia\layout\_partial\article.ejs
在其末尾增加代码:

<% if (!index && theme.toc){ %>
<script>
var tocEx = function(el){
var toc = document.querySelector(el), content = toc.innerHTML;
content = content.replace('<!-- ttoc -->', '<div class="toc">').replace('<!-- ttocstop -->', '</div>');
toc.innerHTML = content;
}('.article-entry');
</script>
<% } %>

这样我们就为文章目录外包裹了一对<div>标签和一个toc类。

再写这个类的样式,放到主题下的相关css文件中。

.toc {
float: right;
margin-left: 40px;
padding: 10px 20px;
background: #f1f1f1;
border-radius: 10px;
box-shadow: 0 0 3px #bbb;
}

这些都做完再次重启Hexo,成功!

2016年更新

Hexo 已经有生成文章目录的辅助函数了,使用更方便。我现在博客中的文章目录就是使用辅助函数生成的。

Hexo辅助函数#toc

不需要安装额外插件!
不需要在文章中插入标记!
不需要在配置文件添加配置!

仅仅是在你的文章页模版中,插入调用辅助函数的代码即可。

<%- toc(page.content, {
class: 'post-toc',
list_number: true
}) %>