基于jQuery的方案,为Ruhoh生成目录。
最近扔了不少笔记在 wiki 上。笔记一多就出现了查找定位的问题。比如,当我学了 awk 后想回过头来再看一下 mysql ,我可能就已经忘记了 mysql 的笔记的结构,于是为了定位到某个关键词,我可能得花半天时间在查找上。我想这种情况会随着我日后笔记的增多而越发严峻,所以最好就现在就动手解决它。
最简单有效的办法是实现站内搜索功能。ruhoh这类静态博客的一个缺点是没有自带搜索的能力。一个解决方案是动用 Google 来生成站内搜索。实际上 Google 的自定义搜索还可以进行一些定制,不过最简单的样式已经满足我的需求,我把它加到了 wiki 首页的底部。
但站内搜索并不完美。首先这个搜索依赖于 Google 的抓取,所以一些刚写不久的笔记如果还没被 Google 抓取到的话是搜不到的。另外一个问题是这本质上并不能避免我忘记笔记结构的问题,反而是更容易恶化这个情况:有了搜索引擎的支持,我可能就会在笔记内容的组织上更加随意。因为不管我怎么写,Google 都能帮我找出来。这好比一个仓库:原先我自己亲手打理,每样物品的摆放我都要求井井有条。后来我请了个下手帮我去仓库找东西,这个下手也很任劳任怨,每次我需要某个物品的时候他都可以找出来。于是,我放物品的时候也开始变得随意起来了。反正不是我来找,管他呢?时间久了,我肯定会忘记仓库里的一切。当有一天下手不干活了 11这种情况还经常发生呀!,或者我决定要考验下自己尚能饭否,非得要亲自要到仓库里取一样东西,我很可能会在仓库里迷路。
于是,最好的做法是再雇一个人,在我每次放东西的时候,他负责记录我把东西放在哪个区域。这样即使我亲自去找某个物品,根据他给的记录,我也可以大致判断该走哪个方向。这就是目录(Table of Contents, ToC)的作用:通过为我的每篇笔记生成一个目录,我可以对每篇笔记的结构和脉络有个更加清晰的印象,这有助于对知识结构的整理和回顾。同时,我也会更加认真地组织一下内容,以期让目录也尽可能的保持清晰。 < 要生成目录,目前大致有三种方案:
--toc
选项,就可以在生成的页面开头带上目录。但这种方式最不灵活,它生成的位置只能在文章顶部,这对于我想把ToC生成在页面左侧的栅格内是不可行的。经过仔细对比,我选择了第三个方案。一个最重要的原因就是它可以完整保留原来的页面结构,并不会在页面源码中插入目录。如果我以后想从HTML页面转换回Markdown或者其他格式的话会方便一些。
下载 jQuery,把下载下来的 jquery.1.x.min.js22由于 jQuery 2.x 不支持 ie 6、7或8,因此建议下载 1.x。 放到主题目录下的 javascript 目录下。然后在 default.html 中添加引用。
下载 Table of Contents jQuery Plugin,同样放置在 javascript 目录下。
当然直接参照该插件的示例代码就可以生成 ToC 了,但为了更加灵活,可以为文档提供一个 toc
选项,如果为 true 就生成目录,否则就不生成目录;另外还可以添加一个 startLv
选项,用以指定从第几级标题开始生成目录。因此可以写一个 js 脚本 33代码参考了这篇文章。,保存为 javascript/tocgenerator.js
:
1 | function generateTOC(insertBefore, heading, startLv) { |
默认会从第一级标题开始一直生成到到第六级。如果只想解析第二级标题和第三级标题,只需要指定深度为2。可以把上面的代码改为:
1 | function generateTOC(insertBefore, heading, startLv) { |
当然再给文章加一个 depth
选项也是可行的,但是 Mustache 这货的逻辑处理能力巨弱,连逻辑与或非操作也没有44难怪叫做 Logic-Less Template --bb
。因此,多加一个可选的选项就会在下面要介绍的 Mustache 模板中多加一层嵌套,代码就会写的很冗长。是否扩展它由读者自行斟酌。
之后需要在 default.html 中引用 ToC 插件。跟 Octopress 的做法不同,实现这个需要用到 Mustache 模板语言。在 footer 处加入:
这样,对于需要生成目录的文章,只需要在开头部分添加 toc: true
,以及设置一下生成目录的初始标题级别 tocstartlv
(可选),就可以在页面顶端生成目录了。对上面的 tocgenerator.js
稍加修改可以让其放在文档中的任意位置。我的笔记的目录都统一放在了左侧的栅格中,例如这篇笔记。
最后还可以给草稿添加scaffold,在posts目录(或者你自己定义的collection)新建或修改 _scaffold
,内容如下:
1 | --- |
这样每次当你调用 draft
命令时,ruhoh就会按照上面的设置新建一篇草稿。记得把上面的 tocstartlv
设为你自己需要的初始标题级数。