最近作った Jekyll (Liquid) のプラグイン
最近作った、Jekyll (Liquidテンプレート) のプラグインの解説を書きます。Jekyllの良いところは、Rubyプログラマーなら簡単に独自タグ等のプラグインが書けるところです。ただし、情報が少ないので参考になれば嬉しいです。
1. h1タグに付けた番号を引き継げる h2タグ
テキストを書いていると 1. Ruby入門 ... 1.1 リテラル ... 1.2 式 ... 1.3 制御構造 ... のように連番のサブタイトルを書きますが、途中に章が追加さると番号を振り直さないといけません。そこで、サブタイトル(h2)の連番を タイトル(h1) から引き継いだ連番を自動生成すれば良いわけです。
このタグはこのように使います、これで <h2>1.1 リテラル</h2> ... <h2>1.2 式</h2> ... <h2>1.3 制御構造</h2> ... が生成されます
{% h1 1 Ruby入門 %} ... {% h2 リテラル %} ... {% h2 式 %} ... {% h2 制御構造 %} ...
コードは以下のようになります。
module Jekyll class SequencedH1Tag < Liquid::Tag def initialize(tag_name, text, tokens) @h1_text = text super end def render(context) context['h1_seq'] = @h1_text.to_i context['h2_seq'] = 0 "<h1>#{@h1_text}</h1>" end end class SequencedH2Tag < Liquid::Tag def initialize(tag_name, text, tokens) @h2_text = text super end def render(context) context['h2_seq'] = context['h2_seq'] + 1 "<h2>#{context['h1_seq']}.#{context['h2_seq']} #{@h2_text}</h2>" end end end Liquid::Template.register_tag('h1', Jekyll::SequencedH1Tag) Liquid::Template.register_tag('h2', Jekyll::SequencedH2Tag)
2. テーブルの幅(%)指定タグ
これは
{% table_width table1 30,8,8 %} table(table1). |_. Railsのバージョン |_. Ruby1.8.X |_. Ruby1.9.X | | 2.3.X |=. ○ |=. x | | 3.0.X |=. ○ |=. ○ | | 3.1.X |=. ○ |=. ○ | | 3.2.X (現在) |=. ○ |=. ○ | | 4.0.X (次期) |=. x |=. ○ |
のように書くと下のような幅が指定されたテーブルが生成されます。
... | ... | は Textile のテーブルで table(table1). でテーブルに table1というクラス名を付けています。 我ながら便利だと思います ^^)/ |
<style type="text/css"> .table1 {width: 46%;} .table1 td:nth-child(1) {width: 30%;} .table1 td:nth-child(2) {width: 8%;} .table1 td:nth-child(3) {width: 8%;} </style> <table class="table1"> <tr> <th>Railsのバージョン </th> <th>Ruby1.8.X </th> <th>Ruby1.9.X </th> </tr> <tr> <td> 2.3.X </td> <td style="text-align:center;">○ </td> <td style="text-align:center;">x </td> </tr> <tr> <td> 3.0.X </td> <td style="text-align:center;">○ </td> <td style="text-align:center;">○ </td> </tr> ・・・・ </table>
コードは以下で <style ...> 〜 </style>を生成しています。
module Jekyll class TableWith < Liquid::Tag Syntax = /(.*)\s+([\d,]+)\s*/o def initialize(tag_name, markup, tokens) if markup =~ Syntax @table_class = $1 @width_array = $2.split(/,/).map{|e| e.to_i} else raise SyntaxError.new("Syntax Error in 'table_width' - Valid syntax: table_width [class of table] [width, width...]") end end def render(context) s = %|<style type="text/css">\n| s += " .#{@table_class} {width: #{@width_array.inject(0){|x,s| s += x}}%;}\n" @width_array.each_with_index {|w, ix| s += " .#{@table_class} td:nth-child(#{ix + 1}) {width: #{w}%;}\n"} s += "</style>\n" s end end end Liquid::Template.register_tag('table_width', Jekyll::TableWith)
- initializeメソッドの引数の解釈やエラーメッセージの表示は Liquid テンプレート コード https://github.com/Shopify/liquid の定型です
- TextileとLiquid の適応の順番ですがですが、Textile が先に適応されます
3 「この章の目標」タグ
これは
{% goalbox %} * TDDを知る * RSpecについて理解する * 受け入れテストを知る {% endgoalbox %}
が 下のような tableになります
<table class="goalbox"> <tr><th>この章の目標</th></tr> <tr> <td> <ul> <li>TDDを知る</li> <li>RSpecについて理解する</li> <li>受け入れテストを知る</li> </ul> </td> </tr> </table>
コードは
# -*- encoding : utf-8 -*- module Jekyll class GoalBox < Liquid::Block def render(context) output = super %|<table class="goalbox"> <tr><th>この章の目標</th></tr> <tr> <td> #{output} </td> </tr> </table>| end end end Liquid::Template.register_tag('goalbox', Jekyll::GoalBox)
- Liquid::Blockを使うとコンテンツを持つタグが作れます。閉じタグは end〜 になります。
- コンテンツの文字列は親クラスからもらいます