Help us understand the problem. What is going on with this article?

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を参考にしました。

kijibato
2018年も6投稿を目標に。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away