让Octopress为文章自动生成目录

平时写Markdown的时候,已经养成了用不同个数的#来分级标题的习惯。对于一篇较长的文章,如果能有一个包含这些分级标题的目录,不仅可以较方便的概览文章内容,还可以快速定位到想要看的内容。之前的文章我曾经手动加过目录,实在是很麻烦,今天周末闲着没事就写了一个自动生成目录的插件。

Octopress的插件是用ruby写的,之前没有接触过ruby,好在不难,照葫芦画瓢也就写出来了,根据h标签生成目录然后在对应地方添加锚点就可以了。

安装

安装插件十分简单,只要在plugins文件夹中新建一个markdwon_dir.rb文件,并将以下代码拷进去,最后重新rake generate一下就可以了。

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
# MardowndirFilter.rb
# Add content for each post
# swm8023 c4fun.cn
# 11.24.2013
#
require './plugins/post_filters'

module MarkdowndirFilter
@@ind = 0
def generatedir(post)
content = post.content;
dir_str = "<div id='markdir'><p><strong>Contents</strong></p>";
pcontent = ""
while md = /<h(\d)>(.*?)<\/h\d>/.match(content) do
# puts md[0];
content = md.post_match
pcontent += md.pre_match + "<span id =\"markdir#{@@ind}\"></span>"+md[0]
hx = Integer(md[1])
dir_name = md[2]
dir_name = md[1] if md = /<strong>(.*?)<\/strong>/.match(dir_name)
dir_str += "&nbsp;&nbsp;&nbsp;&nbsp;" while (hx = hx - 1) > 0
dir_str += "<a href=\"#markdir#{@@ind}\">" + dir_name +"</a><br/>"
@@ind = @@ind + 1
end
pcontent += content
dir_str += "</div>"
#puts dir_str
dir_str + pcontent
end
end

module Jekyll
class Markdowndir < PostFilter
include MarkdowndirFilter
def post_render(post)
post.content = generatedir(post) if post.is_post?
end
end
end

Liquid::Template.register_filter MarkdowndirFilter

然后为目录增加CSS效果,将下面的CSS代码添加/sass/custom/_style.scss中就可以了。我对前端的这些东西一直不擅长,随便写了一下,前端大牛们有兴趣的话可以帮着美化一下。

1
2
#markdir{background:#ebebeb;padding:10px;margin-bottom:10px;}
#markdir p{font-size:18px;margin-bottom:3px;}

使用

我们在markdown中编写如下代码,在博客的最前面能看到生成的目录效果

1
2
3
4
5
6
7
8
## 一、测试一级菜单
### 1.1测试二级菜单
### 1.2测试二级菜单
#### 1.2.1测试三级菜单
### 1.3测试二级菜单
## 二、测试一级菜单
### 2.1测试二级菜单
### 2.2测试二级菜单

一、测试一级菜单

1.1测试二级菜单

1.2测试二级菜单

1.2.1测试三级菜单

1.3测试二级菜单

二、测试一级菜单

2.1测试二级菜单

2.2测试二级菜单

文章目录
  1. 1. 安装
  2. 2. 使用
  3. 3. 一、测试一级菜单
    1. 3.1. 1.1测试二级菜单
    2. 3.2. 1.2测试二级菜单
      1. 3.2.1. 1.2.1测试三级菜单
    3. 3.3. 1.3测试二级菜单
  4. 4. 二、测试一级菜单
    1. 4.1. 2.1测试二级菜单
    2. 4.2. 2.2测试二级菜单