Edited at

Markdownのファイル分割とif/elseをerbで実現したよ

More than 1 year has passed since last update.


目的

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ファイル内でパラメータとして利用できます。


main.rb

# -*- 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ファイルに書いたスペシャル機能の説明を埋め込む例です。


main.erb.md

<%= @title %>

# このマニュアルについて

このマニュアルは<%= @plan %>プラン向けのマニュアルです。

# スペシャル機能について

<% if ["松", "竹"].include?(@plan) %>

<%= render "special.erb.md" %>

<% else %>

スペシャル機能は、<%= @plan %>プランでは利用できません。

<% end %>


トップのMarkdownファイル(main.erb.md)から、読み込まれるファイル(special.erb.md)です。読み込む時、erbとして読むのでこっちでもerbの書き方が利用できます。


special.erb.md

スペシャル機能は、<%= @plan %>プランで利用できます。スペシャル機能は、特別な機能です。

スペシャル機能のとても長い説明。



実行結果例

planを松とした場合。

何かのマニュアル

# このマニュアルについて

このマニュアルは松プラン向けのマニュアルです。

# スペシャル機能について

スペシャル機能は、松プランで利用できます。スペシャル機能は、特別な機能です。

スペシャル機能のとても長い説明。

planを梅とした場合。

何かのマニュアル

# このマニュアルについて

このマニュアルは梅プラン向けのマニュアルです。

# スペシャル機能について

スペシャル機能は、梅プランでは利用できません。

外部ファイルの読み込みと、if/elseができました。


補足

パラメータの部分も別ファイル(yamlなど)にして、実行時に指定できるようにした方が良さそうです。今回は、ファイル分割とif/elseが実現できればよかったので、最小限の実装です。

あと、ファイル拡張子(erb.md)は、変換前もそこそこMarkdownプレビューできるようにmdとしています。ファイル的にはmd.erbの方が正しい気もしますが、プレビューできないので。


参考URL

erbファイルに別のerbファイルを読み込む方法は、下記URLを参考にしました。