PureBuilder Simply 3.3 / JSONoutとテーマインストール
開発::util
序
PureBuilder Simplyは7ヶ月ぶりのリリースとなる3.3.0が登場した。
今回のPureBuilder Simplyは予定されていた2つの機能、JSONoutとテーマインストールを追加した。 JSONoutはPureBuilder Simplyの利用幅を広げる機能、テーマ機能は一般ユーザーの敷居を下げる機能だ。
JSONout
JSONoutは、従来は出力形式がHTMLに限られていたが、これに加えてJSONでの出力ができるようになったものだ。
JSON出力はfrontmatterオブジェクトとレンダリングされたbodyからなる。 SPAなどウェブアプリケーションからより扱いやすくするのが目的だ。
ボディをレンダリングしないのは、さすがにPureBuilder Simplyである必要性が怪しいため、サポートしない。 もしそういうニーズがあるのなら考えるかもしれないが……
jsonout
が真である場合、JSON形式で出力する。
jsonout_include
を指定することでfrontmatterに含めるものを、jsonout_exclude
を指定することでfrontmatterに含めないものを指定できる。
両方指定した場合はホワイトリスト方式のjsonout_include
が優先。
今のところincludeをexcludeできるようにはなっていない。パターン指定したりはできないためだ。
「シンプル故に懐が広い」はPureBuilder Simplyの特徴のひとつなので、ウェブアプリケーションフレンドリーな構造を追加した。
これを実現するために、これまで単純にメソッドの一部分だった出力処理を複数のメソッドに分割しており、JSON以外の形式への対応も容易になった。
テーマインストール
概要
従来は「リポジトリからコピーしてね」という形式だったテーマの導入を、pbsimply-init
に統合した。
加えて、サードパーティテーマにも対応。
テーマファイル (非Rubyファイル) の場所を知る
これを実現するために重要だったのはファイルの場所を知ることだ。 RubyGemsのファイル構成はバンドルしたそのときと変わらない。 そのため、そのファイルの位置から相対的にテーマとして扱うためのファイル群のパスを知ることができる。
そのために利用できそうなのは$0
と__FILE__
だ。
$0
はコマンドのパスとなる。
これは通常の意味での$0
ではなく、Rubyに渡された実行ファイルの引数を意味する。
例えば、
#!/bin/ruby
p __FILE__
として、これをtest.rb
とする。
ruby test.rb
ならtest.rb
になるし、ruby ./test.rb
なら./test.rb
になる。
また、ruby foo/../test.rb
ならfoo/../test.rb
になる。
これが実行ファイルであった場合はどうかというと、カーネルによりshebangが解釈され、このshebang解釈では$PATH
以下にある実行されるファイルの絶対パスに展開される。
このため、test.rb
と実行すると/usr/local/bin/test.rb
のようになる。
では__FILE__
はどうか。
例えば、a/test.rb
がa/testlib.rb
をrequire_relative
で./testlib.rb
として読むとする。
この場合testlib.rb
の中ではtestlib.rb
の絶対パスになる。
実行ファイルもライブラリも、シンボリックリンクである場合シンボリックリンクのパスになる。
ただし、require_relative
するとき、自身のシンボリックリンクは解決された状態を起点にする。
このため、単に__FILE__
を基準にファイルを探そうとすると、シンボリックリンク化されている場合にうまく動作しない。
RubyGemsはライブラリも含めた構成になっているのが普通なので、bin/
配下をコピーした場合は動かないのも仕方のない話だが、通常はシンボリックリンクするのは動くものなので、シンボリックリンクすることが動かなくなるのはあまり良くない。
なので、File.readlink(__FILE__)
すれば良いのだが、__FILE__
がシンボリックリンクでない場合にエラーになる。
また、ライブラリであれば__FILE__
は常に絶対パスになっているが、実行ファイルだとどのように実行されたかによって絶対パスでない場合がある。
以上を踏まえ
= __FILE__
pwd = File.readlink __FILE__ if File.symlink? __FILE__
pwd = File.expand_path(pwd)
pwd $GemRoot = pwd
で自分のディレクトリが分かる。
$GemRoot/themes
は実行ファイルから見れば../themes
になるため、ここまで含めて
= __FILE__
pwd = File.readlink __FILE__ if File.symlink? __FILE__
pwd = File.join(File.dirname(pwd), "..")
pwd = File.expand_path(pwd)
pwd @gemroot = pwd
@themes_root = File.join(pwd, "themes")
とすることで目的のファイルを発見できる。
ここまですれば配置規則と動作を規定すれば難しいことではない。
利用方法
使い方はとても簡単で、pbsimply-init
に-t
オプションが追加された。
テーマはプロセッサ/テーマ名
という構成になっており、pandoc/paper
のように指定する。
また、この機能の利便性を考え、上書きインストールが可能になった。
これはインストールプロセスを今存在するファイルを無視して実行するものである。
.pbsimply.yaml
も上書きされることには注意が必要だ。
上書きインストールを行う場合は-f
オプションを使用する。
さらに、-s
オプションを指定するとソースのみインストールするようになった。
つまり、
pbsimply-init foo
とした場合、foo/Source
とfoo/Build
が生成されるわけだが、
pbsimply-init -s foo
とした場合、foo
にソースがインストールされた状態になる。
テーマの移植と制作
実はテーマ機能までであれば6月くらいにできていたのだが、リリースまでは随分時間がかかった。 主な理由は、従来存在したテーマを移植するのが面倒だったからだ。
従来、docroot-sample
というディレクトリ以下にコピーして使用するためのテーマが置かれていたが、これをテーマ機能に統合するため、新しいテーマ機能の形式に合わせてtheme
以下に配置する必要があった。
これをシンプルに実現するため、base_theme
という機能が必要になった。
テーマの設定は.theme.yaml
ファイルによって定義されているが、initial_control.base_theme
を指定することで、テーマインストール時に先にベーステーマをインストールするようになっている。
従来、docroot-sample
はベーステーマをコピーしてから使いたいテーマをコピーするというレイヤー構造になっていたため、この機能が必要だったのだ。
この機能を実現する手順が少し面倒で、これに1ヶ月くらいかかった。
で、そこまでやるにはやったのだが、docroot-sample
を今の形式に変換する作業が面倒で放置していたのだ。
なお、実際に作業をやった感じでは、全体で15分くらいでできるようなものだった。
旧来のテーマであるpandoc/bloggy
,
pandoc/practical
,
pandoc/warm
は従来のままだが、新たにpandoc/cooldark
とpandoc/paper
を追加した。
これらのテーマは急造であるため、クオリティはまだ高くない。
ただ、制作には1日がかりであったため、リリース時の最後の壁となった。
contribution theme募集中
theme機能を追加したことで、ユーザーがテーマを制作することが容易になった。
そこで、user contributionテーマを受け付けている。
テーマ制作については、ポータルサイトのテーマのページを見てもらえば良いと思うのだが、基本的には.pbsimply.yaml
と.theme.yaml
以外はPureBuilder
Simplyの雛形プロジェクトを作れば良いだけだ。
プロセッサ別にテーマを書けるようになったため、好みの(あるいはハードルの低い)プロセッサのテーマを作ることもできる。
とりあえずは任意の既存のテーマ(purebuilder-simplyリポジトリのthemes
ディレクトリ以下にあるもの)をコピーして使うところから始めると良いだろう。
投稿待っています!