目的
Markdownは、シンプルで書きやすくていいですが、マニュアルを書くには少し物足りない部分があるのでerbでどうにかならないか試してみました。
Markdownに追加できれば便利な機能
- ファイル分割
- テンプレートファイル利用(変数)
- if/else
erb
erbは、テキストにRubyスクリプトを埋め込むことができるRubyの標準ライブラリです。
Rubyスクリプトを埋め込めるので、テキストファイルを一部パラメータ化したり、if/elseで条件分岐したりできます。Markdownに足りないと思っている機能を補えそうです。
試した結果
Markdownの書き方に少しerbの書き方を加えるだけの、いい感じなものを短いスクリプトで実現できました。ただ、erbの方で頑張りすぎると、Markdownの良さである読みやすさがなくなるので、erbを少し活用する程度が良さそうです。
全体像
全体の作りとしては、erbの書き方に沿ってRubyスクリプトを埋め込んだMarkdownファイルを、Rubyスクリプトで素のMarkdownに変換します。
- 基本Markdownで書いて
- テンプレート的に穴埋めする部分はerbの決まりで書いておく
- if/elseする部分はerbの決まりで書いておく
- 別ファイルのMarkdownを読み込む部分は、読み込むメソッドを書いておく
- Rubyスクリプトを実行して変換
ruby main.rb > main.md
erbを埋め込んだMarkdownファイルを変換するスクリプト
erbを埋め込んだMarkdownファイルを変換するスクリプト(main.rb)の実装例です。paramには変数として渡したいものを記載します。Pageクラス内で、Object#instance_variable_setで展開しているので読み込んでいるerbファイル内でパラメータとして利用できます。
# -*- coding: UTF-8 -*-
require "erb"
class Page
def initialize(locals={})
locals.each { |key, val|
self.instance_variable_set("@#{key}", val)
}
end
def render(path)
content = File.read(File.expand_path(path))
t = ERB.new(content, nil, '-')
t.result(binding)
end
end
# Markdownファイルに埋め込むパラメータを事前に定義する
param = {
title: "何かのマニュアル",
plan: "梅",
}
page = Page.new(param)
markdown = page.render("main.erb.md")
puts markdown
読み込むMarkdownファイル例
スクリプトから読み込むトップのMarkdownファイル(main.erb.md)です。erbの書き方は省略しますが、ここではplanが松、竹の場合は別のMarkdownファイルに書いたスペシャル機能の説明を埋め込む例です。
<%= @title %>
# このマニュアルについて
このマニュアルは<%= @plan %>プラン向けのマニュアルです。
# スペシャル機能について
<% if ["松", "竹"].include?(@plan) %>
<%= render "special.erb.md" %>
<% else %>
スペシャル機能は、<%= @plan %>プランでは利用できません。
<% end %>
トップのMarkdownファイル(main.erb.md)から、読み込まれるファイル(special.erb.md)です。読み込む時、erbとして読むのでこっちでもerbの書き方が利用できます。
スペシャル機能は、<%= @plan %>プランで利用できます。スペシャル機能は、特別な機能です。
スペシャル機能のとても長い説明。
実行結果例
planを松とした場合。
何かのマニュアル
# このマニュアルについて
このマニュアルは松プラン向けのマニュアルです。
# スペシャル機能について
スペシャル機能は、松プランで利用できます。スペシャル機能は、特別な機能です。
スペシャル機能のとても長い説明。
planを梅とした場合。
何かのマニュアル
# このマニュアルについて
このマニュアルは梅プラン向けのマニュアルです。
# スペシャル機能について
スペシャル機能は、梅プランでは利用できません。
外部ファイルの読み込みと、if/elseができました。
補足
パラメータの部分も別ファイル(yamlなど)にして、実行時に指定できるようにした方が良さそうです。今回は、ファイル分割とif/elseが実現できればよかったので、最小限の実装です。
あと、ファイル拡張子(erb.md)は、変換前もそこそこMarkdownプレビューできるようにmdとしています。ファイル的にはmd.erbの方が正しい気もしますが、プレビューできないので。
参考URL
erbファイルに別のerbファイルを読み込む方法は、下記URLを参考にしました。