美柑の部屋

涙は見せないと誓った。

Loading…

Octopress插件:表格

很多Markdown语法都支持在文章中嵌入表格,但是Octopress竟然不支持。为了使得在文章中插入表格更加方便,我开发了一个插件table。在这篇文章中我简要介绍一下该插件的开发流程。

一、概述

简单的html表格由table标签以及一个或多个trthtd标签组成,其中tr标签定义表格行,th标签定义表头,td标签定义表格单元。
我将本插件的语法定义为{% table title %} content {% endtable %},其中content代表表格内容,由多行构成,content的一行对应着表格中的一行,这一行中的不同单元用字符|分割。content的第一行对应着表头。比如表格:

歌曲列表
歌曲名称歌手名称
Hacking to the Gateいとうかなこ
コネクトClariS
MagiaKalafina
secret armsRay

对应的Markdown文件的代码为:

1
2
3
4
5
6
7
{% table 歌曲列表 %}
歌曲名称 | 歌手名称
Hacking to the Gate | いとうかなこ
コネクト | ClariS
Magia | Kalafina
secret arms | Ray
{% endtable %}

二、插件开发

根据插件的语法,我们知道该插件仍然需要继承自Liquid::Block。在插件中,我们将用户的Markdown代码转换为html语言。表格的标题可以从initialize函数中的markup变量获得;而表格的内容则需要在render函数中调用super来获得。获得了表格的内容后,我们需要对其进行分割:首先按照字符\n分割,将表格的每行分离出来;然后对于每行内容,按照字符|分割,将表格的每个单元分离出来。
需要额外考虑的有两点。第一,表格内容的第一行需要当做表头处理,所以要使用th标签而不是td标签;第二,为了使表格更加美观,我为表格的奇数行和偶数行设置了不同的背景色,所以在处理的时候,要为奇数行和偶数行对应的tr设置不同的class属性,以便在css中设置不同的样式。
插件对应的ruby代码如下:

table.rb
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
module Jekyll

  class Table < Liquid::Block
    def initialize(tag_name, markup, tokens)
        str = "#{markup}".strip
        @title = str
        super
    end

    def render(context)
        @res = ""
        content = super.strip!
        rows = content.split("\n")
        count = 0
        while count < rows.size do
            row = rows[count]
            columns = row.split("|")
            colCount = 0
            colhtml = ""
            while colCount < columns.size do
                element = columns[colCount]
                element.strip!

                if count == 0
                    colhtml = colhtml + "<th>#{element}</th>"
                else
                    colhtml = colhtml + "<td>#{element}</td>"
                end
                colCount = colCount + 1
            end

            #判断是奇数还是偶数
            if count == 0 or count % 2 == 1
                @res = @res + "<tr>#{colhtml}</tr>"
            else
                @res = @res + "<tr class=\"alt\">#{colhtml}</tr>"
            end
            count = count + 1
        end
      "<div align=\"center\"><table class=\"blogTable\"><caption>#{@title}</caption>" + @res + "</table></div>"
    end
  end
end

Liquid::Template.register_tag('table', Jekyll::Table)

三、定制样式表

还是老样子,我们在_styles.scss中定制样式表,要定制的部分包括单元格的样式、表头的样式、奇数行和偶数行的背景色以及表格标题的样式等。我定义的样式表如下:

_styles.scss
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
//blogTable
.blogTable {
    margin-bottom: 27.6px;
}

.blogTable td, .blogTable th{
    font-size: 1em;
    border: 1px solid #888888;
    padding: 3px 7px 2px 7px;
}

.blogTable th { //表头的样式需要额外定制
    padding-top: 5px;
    padding-bottom: 4px;
    background-color: #aaaaaa;
    font-family: SimHei;
    font-weight: 600;
}

.blogTable tr.alt td { //偶数行的背景色需要额外定制
    background-color: #eeeeee;
}

.blogTable caption { //标题栏的样式
    text-align: center;
    font-family: KaiTi;
    font-size: 1.1em;
    font-weight: bold;
    margin-bottom: 5px;
}

有些人可能想在表格单元中显示一小段行内代码段,为了使其正常显示,我们需要为blogTable内的code元素定制样式表:

_styles.scss
1
2
3
4
5
6
7
8
9
10
11
.blogTable code{
    display: inline-block;
    background: #fff;
    font-size: .8em;
    line-height: 1.5em;
    color: #555;
    border: 1px solid #ddd;
    border-radius: .4em;
    padding: 0 .3em;
    margin: 0;
}

评论