Nanocのフィルターを作成/改造する
カスタムフィルター
nanoc create_siteで作ったディレクトリにあるlib以下のファイルがコンテンツのコンパイル前に読み込まれるので、ここでNanocのフィルターを新しく作成したり、既存のものを上書きしたりできる。
こうしたカスタムのフィルターを作るにはNanoc3::Filterを継承(Nanoc3を使っている場合)し、runメソッドを定義/上書きすればOK。
runは引数としてコンテンツ本文とオプションパラメータを受け取る。
以下では試しにredcarpetフィルターをRedcarpet2に対応したものに改造してみた。
lib/filter_redcarpet.rb
# -*- coding: utf-8 -*- module Nanoc3::Filters class Redcarpet < Nanoc3::Filter # for Redcarpet2 def run(content, params={}) markdown_options = params[:markdown_options] || {} render_options = params[:render_options] || {} render = ::Redcarpet::Render::HTML.new(render_options) md = ::Redcarpet::Markdown.new(render, markdown_options) md.render(content) end end end
とにかくファイルを置けば読み込まれる。他で何か設定したりする必要は無い。
このフィルターを使うにはRulesに以下のように書く。
filter :redcarpet, :markdown_options => {:autolink => true}, :render_options => {:hard_wrap => true}
このように簡単にフィルターが作れるのはいいかんじ。
フィルターは複数適用できるので、ちょっとした単機能のフィルターをさくっと作ってNanocを便利にするといったことも難しくない。
カスタムタグっぽいものも簡単に作れる。
フィルターの複数適用について
フィルターを複数指定した場合は上から順に適用される。Unixのパイプのイメージ。
例えばMarkdownの中に変数を埋めたいときは、erbのフィルターをかませてやればよい。
filter :erb filter :redcarpet, :markdown_options => {:autolink => true}, :render_options => {:hard_wrap => true}
ちなみに順番を逆にするとredcarpetによってerbのタグの「<」と「>」が実体参照にエスケープされてしまうのでうまいこと動かない。
順番は重要。
追記
新しいフィルターを登録する場合は以下のように登録する必要があった。
Nanoc3::Filter.register '::Nanoc3::Filters::CustomFilter', :custom_filter