簡素化されたPandocを使ったウェブサイト構築システム。
PureBuilder Simplyはウェブサイト構築スクリプトである。
ACCSはウェブサイト上で連載を構築するためのスクリプトである。
PureBuilder Simply ACCS はPureBuilder Simplyによって index.html
ファイルを生成する。
gem install pbsimply
gem build pbsimply.gemspec
gem install pbsimply-$version.gem
git clone https://github.com/reasonset/purebuilder-simply
bin/
ディレクトリのファイルをPATHの通ったディレクトリにコピーするlib/
ディレクトリのファイルをRubyライブラリのディレクトリにコピーする
- ドキュメントルートディレクトリを作成する
- ドキュメントルートディレクトリに
.pbsimply.yaml
ファイルを設置する - ディレクトリ及びドキュメント(MarkdownまたはReST)を書く
pandoc -D html5 > template.html
としてテンプレートファイルを作成し、編集する
- Ruby >= 3.0
- Pandoc >= 2.8
ドキュメントルートに移動してから次のように実行する。
pbsimply directory
PureBuilder Simplyはdirectoryにあるドキュメントを構築する。
構築されるドキュメントから除外したい場合、ファイル名をdraft-
または.
ではじまるものにするか、
frontmatterのdraft
の値を真にする。
オプション | 内容 |
---|---|
-f , --force-refresh |
すべてのドキュメントを強制的に更新する。テンプレートを更新した場合に便利 |
-I , --skip-index |
.indexes.rbm に登録しない |
-A , --skip-accs |
ACCSの処理をしない |
-o FILE , --output |
出力ファイルをFILEに指定する |
-m FILE , --additional-metafile |
さらに追加のメタデータYAMLファイル |
pbsimply
は自動的にACCSドキュメントディレクトリを発見し、処理する。
あなたは.accs.yaml
ファイルをディレクトリに配置することで、そのディレクトリがACCSドキュメントディレクトリであることを示すことができる。
ACCSプロセッサはindex.html
を生成し、配置する。
テンプレートまたは生成されたドキュメントでeRubyを使うことができる。
eRubyでは次のオブジェクトが利用できる。
Loaded config YAML file (.pbsimply.yaml
).
コンパイルされたインデックスデータベース。
このオブジェクトはpbsimply
の途中で実行される場合、不完全である可能性が高い。
"default | indexed | frontmatter | current"にあるドキュメントメタデータ。
ドキュメントメタデータは各ドキュメントディレクトリ上のデータベースに保存される。
デフォルトでは.indexes.rbm
という名前のRuby Marshalファイルとして保存される。
設定ファイルのdbstyle
の値としてjson
あるいはoj
を設定すると、
Ruby Marshalの代わりにJSONが使用され、ファイル名も.indexes.json
になる。
Key | Type | Description |
---|---|---|
outdir | String | 出力先ベースディレクトリ。必須 |
template | String | Pandoc HTMLテンプレートファイル。 temaplte.html がデフォルト |
css | String / Array | CSSファイル |
toc | Boolian | 真ならばTOCを生成する |
pandoc_additional_options | Array | 追加で渡されるPandocのコマンドラインオプション |
post_eruby | Boolean | 真にするとPandocの出力をerbによってプロセッシングする |
alt_frontmatter | Hash | ACCSインデックスファイルのデフォルトのfrontmatter |
default_meta | Hash | デフォルトのfrontmatter |
testserver_port | Fixnum | pbsimply-testserver が使用するポート(default 8000) |
self_url_prefix | String | 生成されたドキュメントのURLの絶対パスのプレフィックス部。デフォルトは/ |
self_url_external_prefix | String | self_url_prefix のpage_url_encoded_external 用 |
dbstyle | String | json に設定すると.indexes.rbm に代えて.indexes.json が使用される。さらにoj に設定した場合、JSON ライブラリではなくOj ライブラリを使用する |
bless_style | String | cmd の場合、Ruby Procを使用する通常のblessではなくコマンドを使用する |
bless_cmd | String / Array | blessに使用するコマンド |
bless_accscmd | String / Array | ACCSのblessに使用するコマンド |
blessmethod_accs_rel | String | 「次」「前」の記事を探索する自動blessメソッド |
auto_delete | Boolean | ソースドキュメントが消えた場合、出力ドキュメントからも削除する |
detect_modification | String | 更新の検出方法。changes はchanges ヘッダーの変更から検出する。mtimesize はmtimeとファイルサイズから検出する。 これ以外の場合、mtimeで検出する |
pandoc_command | String | Pandocのコマンド。デフォルトはpandoc |
jsonout | Boolean | 真である場合、JSON形式で出力する |
jsonout_include | String[] | jsonout で出力されるJSONに含むfrontmatterのキーの配列。この設定はjsonout_exclude より優先される |
jsonout_exclude | String[] | jsonout で出力されるJSONから除外されるfrontmatterのキーの配列 |
Key | Set by | Used by | Description |
---|---|---|---|
title | frontmatter | frontmatter | 文書タイトル。必須 |
author | frontmatter | frontmatter | 著者 |
date | frontmatter/system | frontmatter or system. | 執筆日 |
lang | frontmatter | additional option / Pandoc template | lang /xml:lang |
keywords | frontmatter | additional option / Pandoc template | An array, HTML metaタグのキーワードとして使うもの |
description | frontmatter | additional option / Sample template | HTML metaタグのdescriptionとして使うもの |
draft | frontmatter | additional option / system | 草稿。真である場合プロセッシングから除外される |
_last_proced | system | system | Integer. 最後にPureBuilderで処理された時刻。. はじめてのプロセッシングの場合(あるいはデータベースを削除した場合)0 になる |
last_updated | system | system | String. 最後にPandocで生成した時刻 |
_size | system | system | ファイルサイズ (byte) |
_mtime | system | system | Integer. mtime of this file. |
_filename | system | system | ファイル名 |
_docformat | system | system | Document Format. Markdown or ReST . |
categories | frontmatter | ACCS | ドキュメントのカテゴリ。ACCSによって使われる |
pagetype | frontmatter/config | ACCS | ページタイプ。デフォルトはpost 。ACCSによって生成されるインデックスページはaccsindex |
source_directory | system | system | ソースディレクトリ |
source_file | system | system | ソースファイル名 |
source_path | system | system | ソースファイルパス |
dest_path | system | system | 出力ファイルパス |
normalized_docdir | system | / で始まる正規化されたソースディレクトリ |
|
normalized_docpath | system | / で始まる正規化されたドキュメントパス |
|
page_url | system | 当該ドキュメントの生成後のURL | |
page_url_encoded | system | 当該ドキュメントの生成後のURLのURIエンコードされたもの | |
page_url_encoded_external | system | page_url_encoded でself_url_external_prefix を使うもの |
|
page_html_escaped | system | 当該ドキュメントの生成後のURLのHTMLエンコードされたもの | |
page_html_escaped_external | system | page_html_encoded でself_url_external_prefix を使うもの |
|
title_encoded | system | タイトルをURIエンコードしたもの | |
title_html_escaped | system | タイトルをHTMLエスケープしたもの | |
timestamp | frontmatter | frontmatter / system | date よりも詳細なドキュメントの日時を記載する項目 |
timestamp_xmlschema | system | system | XMLスキーマでフォーマットされたドキュメント日時。timestamp が定義されていない場合、date を使う |
timestamp_jplocal | system | system | 日本のローカル形式でフォーマットされたドキュメント日時。timestamp が定義されていない場合、date を使う |
timestamp_rubytimestr | system | system | RubyのTime#to_s のようなフォーマットされたドキュメント日時。timestamp が定義されていない場合、date を使う |
timestamp_str | system | %Y-%m-%d[ %H:%M:%S %Z] 形式の日時。 timestamp が定義されていない場合、date を使う |
Pre Plugins, Post plugins, Blessing command, Hooksにおいて利用できる環境変数
変数 | Pre | Post | Bless | 説明 |
---|---|---|---|---|
pbsimply_outdir |
Yes | Yes | Yes | Yes |
pbsimply_subdir |
Yes | Yes | Yes | Yes |
pbsimply_indexes |
Yes | Yes | Yes | Yes |
pbsimply_frontmatter |
Yes | Yes | Yes | Yes |
pbsimply_working_dir |
Yes | Yes | Yes | Yes |
pbsimply_currentdoc |
Yes | Yes | No | No |
pbsimply_filename |
Yes | Yes | No | No |
ドキュメント中のリンクはローカルな場所に すべきではなく 、 web上のURLでなくてはいけない 。 そのため生成したファイルを静的にテストすることはできない。
ドキュメントルートでpbsimply-testserver
を実行すると、テストサーバーを稼働させる。
使い方はとても簡単。
- ドキュメントルートに移動する
- 起動する
http://localhost:port
にアクセスする
ポートは設定ファイルのtestserver_port
で設定でき、デフォルトは8000。
もしhttp://example.com/site/index.html
のように本番環境がサブディレクトリにある場合、
ドキュメントをサブディレクトリ化に配置することを推奨する。
.pbsimply-bless.rb
というRubyスクリプトファイルを使うことでFrontmatterに手を加えることができる。
これを使用したい場合、同ファイルでPureBuilder::BLESS
Procオブジェクトを定義する。
このオブジェクトはPureBuilder::BLESS.call(frontmatter, self)
のように呼び出される。
呼び出されるタイミングはシステムによってセットされる値が全てセットされた後である。
この関数は値を返す必要はなく、引数として渡されたFrontmatter Hashオブジェクトを直接変更できる。
もしも処理中のディレクトリがACCSドキュメントディレクトリである場合、PureBuilder::BLESS
のあとでさらにPureBuilder::ACCS::BLESS
も(定義されていれば)呼び出される。
さらにあなたはPureBuilder::ACCS::DEFINTIONS
Hashに対してProc
値を追加することができる。
これらは特別な値のために使用される。
Key | 動作 |
---|---|
:next |
戻り値をfrontmatter["next_article"] にセットする |
:prev |
戻り値をfrontmatter["prev_article"] にセットする |
一例として、次に示すのはChienomiのblessing scriptである。
#!/usr/bin/ruby
load "./.lib/categories.rb"
TOPICPATH = {
"" => ["TOP", "/"],
"/articles" => ["Articles", "/#Category"],
"/override" => ["Override", "/"],
"/archives" => ["Old Archives", "/articlelist-wp.html"]
}
ARTICLE_CATS.each do |k,v|
TOPICPATH[["/articles", k].join("/")] = [v, ["", "articles", k, ""].join("/")]
end
PureBuilder::BLESS = ->(frontmatter, pb) {
content = nil
filetype = nil
content = File.read(frontmatter["source_path"])
filetype = File.extname(frontmatter["_filename"])
url = frontmatter["page_url"].sub(/^\.?\/?/, "/")
frontmatter["topicpath"] = []
url = url.split("/")
(1 .. url.length).each do |i|
path = url[0, i].join("/")
if v = TOPICPATH[path]
frontmatter["topicpath"].push({"title" => v[0], "url" => v[1]})
else
frontmatter["topicpath"].push({"title" => frontmatter["title"]})
break
end
end
if frontmatter["category"] && url.include?("articles")
frontmatter["category_spec"] = [ARTICLE_CATS[url[-2]], frontmatter["category"]].join("::")
end
if content
if((filetype == ".md" && content =~ %r:\!\[.*\]\(/img/thumb/:) || (filetype == ".rst" || filetype == ".rest") && content =~ %r!\.\. image:: .*?/img/thumb!)
frontmatter["lightbox"] = true
end
end
}
article_order = nil
rev_article_order_index = {}
PureBuilder::ACCS::BLESS = -> (frontmatter, pb) {
frontmatter["ACCS"] = true
unless article_order
article_order = pb.indexes.to_a.sort_by {|i| i[1]["date"]}
article_order.each_with_index {|x,i| rev_article_order_index[x[0]] = i }
end
}
PureBuilder::ACCS::DEFINITIONS[:next] = ->(frontmatter, pb) {
index = rev_article_order_index[frontmatter["_filename"]] or next nil
if article_order[index + 1]
{"url" => article_order[index + 1][1]["page_url"],
"title" => article_order[index + 1][1]["title"]}
end
}
PureBuilder::ACCS::DEFINITIONS[:prev] = ->(frontmatter, pb) {
index = rev_article_order_index[frontmatter["_filename"]] or next nil
if index > 0
{"url" => article_order[index - 1][1]["page_url"],
"title" => article_order[index - 1][1]["title"]}
end
}
設定ファイルのbless_style
の値としてcmd
をセットすると、Ruby Procの代わりに外部コマンドによって祝福を行う。
bless_cmd
は通常の祝福用、
bless_accscmd
はACCSの祝福用である。
いずれの場合も環境変数$PBSIMPLY_WORKING_DIR
のディレクトリにあるpbsimply-frontmatter.json
ファイルからドキュメントメタデータを読み取ることができ、同ファイルを書き換えることで変更を反映することができる。
いくつかの設定は自動的に予め用意されたメソッドで祝福する。
blessmethod_accs_rel
はnext_article
とprev_article
を設定する。
これらはurl
とtitle
からなる連想配列である。
numbering
(ファイル名先頭の数値), lexical
(ファイル名辞書順), date
, timestamp
が用意されている。
Filename | Description |
---|---|
pbsimply-testserver | テスト用ウェブサーバー起動スクリプト |
accsindex.erb | .accsindex.erb のサンプル。通常編集せずそのまま利用できる |
ファイル名 | 場所 | Description |
---|---|---|
.pbsimply.yaml | root | 設定ファイル。ドキュメントルートに置く |
.indexes.rbm | each | PureBuilder Simplyが生成するRuby marshalファイルのインデックスデータベース |
.indexes.json | each | PureBuilder Simplyが生成するJSONファイルのインデックスデータベース |
.index.md | each | ACCSが生成するインデックスページ |
.accsindex.erb | root or each ACCS | ACCSインデックスページ用Markdown eRubyテンプレート |
.accs.yaml | each | ACCSインデックスページ用の@index |
.pbsimply-bless.rb | root | Bless用のRubyスクリプト |
このテンプレートは標準的なブログをイメージしたテーマとなっている。
- ふたつのヘッダーを持つ。通常は
display: none
になっているバナーのための#TopHeader
と、タイトルのための#TitleHeader
- メインセクションは
#MainContainer
sectionで囲まれる - 記事は
#MainArticle
articleに囲まれる - サイドバーは
#SideBar
sectionとして容易されている。include beforeを使ってサイドバーの中身を書くことができる - 著者部分は削除された
- 埋め込みCSSは削除された
- シンタックスハイライトのテーマも削除された。必要ならpandoc-goodiesなどで入手できる。
基本的でシンプルなCSSが用意されている。
ファイル | 内容 |
---|---|
layout.css | レイアウト |
base.css | 最小限のデザイン |
skylightning.css | PandocデフォルトのソースコードCSS |
lightbox.css | Lightboxプラグインのテーマ |
ACCSのベースになるディレクトリ。
post-pluginsのサンプルスクリプト
.accsindex.rb
と .pbsimply.yaml
のサンプルファイルが用意されている。
JavaScriptプラグインファイル。
それぞれのファイルにあるREADMEを読むこと。
コピーしたサンプルドキュメントディレクトリにテーマディレクトリをマージすることでテーマを利用することができる。
PureBuilder SimplyはPandocを使うことで非常に強力なツールとなるが、Pandocを好まない場合、他のドキュメントプロセッサを使うこともできる。
ただし、機能的には制約を受ける。
使用するプロセッサは.pbsimply.yaml
のpbsimply_processor
の値を用いて指定する。
Processor | pbsimply_processor |
---|---|
RDoc | rdoc |
RDoc/Markdown | rdoc_markdown |
Kramdown | kramdown |
Redcarpet | redcarpet |
CommonMarker (cmark-gfm) | cmark |
Docutils (実験的) | docutils |
また、テンプレートをeRubyテンプレートとして評価するものについては、テンプレート上で次の値を利用することができる
(ほとんどの場合、frontmatter
とarticle_body
を使う)。
変数名 | 内容 |
---|---|
dir |
ドキュメントルートからの相対ディレクトリ |
filename |
ソースファイル名 |
frontmatter |
blessの行われたメタデータ |
orig_filepath |
処理対象のもとのファイルパス |
procdoc |
ソースとして実際に処理されているファイルパス |
article_body |
生成されたHTMLドキュメント |
Rubyの標準ドキュメントシステムのRDocを用いる。
ソースファイルはRDocであるとして処理し、対象は*.rdoc
ファイルに限られる。
テンプレートはeRubyテンプレートとして扱う。
- rdoc library
css
toc
pandoc_additional_options
post_eruby
Rubyの標準ドキュメントシステムのRDocのMarkdownプロセッサを用いる。
ソースファイルはMarkdownであるとして処理し、対象は*.md
ファイルに限られる。
テンプレートはeRubyテンプレートとして扱う。
- rdoc library
css
toc
pandoc_additional_options
post_eruby
RubyのMarkdownライブラリ、Kramdownを用いて生成する。
ソースファイルはMarkdownであるとして処理し、対象は*.md
ファイルに限られる。
テンプレートはeRubyテンプレートとして扱う。
- kramdown library
css
toc
pandoc_additional_options
post_eruby
Key | Type | Description |
---|---|---|
kramdown_features |
Hash | Kramdown::Document.new の第2引数として渡される連想配列。詳細はAPIドキュメントを参照すること。 |
RubyのMarkdownライブラリ、Redcarpetを用いて生成する。
ソースファイルはMarkdownであるとして処理し、対象は*.md
ファイルに限られる。
テンプレートはeRubyテンプレートとして扱う。
- redcarpet library
css
toc
pandoc_additional_options
post_eruby
Key | Type | Description |
---|---|---|
redcarpet_extensions |
Hash | Redcarpetの拡張を示す連想配列。詳細はRedcarpetのページを参照 |
libcmark-gfm
のRubyラッパーであるCommonMarkerを用いて生成する。
ソースファイルはMarkdownであるとして処理し、対象は*.md
ファイルに限られる。
table
及びstrikethrough
拡張が有効になる。
テンプレートはeRubyテンプレートとして扱う。
- libcmark-gfm
- commonmarker library
css
toc
pandoc_additional_options
post_eruby
Pythonで書かれたReSTructured Textプロセッサ、Docutilsを用いて生成する。
ソースファイルはReSTructured Textであるとして処理し、対象は*.rst
ファイルに限られる。
- Docutils (
rst2html5
)
toc
pandoc_additional_options
Key | Type | Description |
---|---|---|
docutils_options |
Array | rst2html5 コマンドに渡されるコマンドラインオプション引数 |
Hooksを使うことで、PureBuilder Simplyの処理に追加の挙動を加えることができる。
Hooksを定義するには、ドキュメントルートディレクトリに.pbsimply-hooks.rb
を置く。
このスクリプトでは、PBSimply::Hooks.load_hooks
を定義する必要がある。
このメソッドにはPBSimply::Hooks
オブジェクトが引数として渡される。
PBSimply::Hooks
オブジェクトはタイミングをメソッドとして持っており、それぞれのタイミングオブジェクトの<<
メソッドにProc
オブジェクトを渡すことで、hookに処理を追加することができる。
#!/bin/ruby
def (PBSimply::Hooks).load_hooks h
h.process << ->(v) {
db[v["normalized_docpath"]] = v
}
h.post << ->(v) {
db.delete_if do |dbk, dbv|
not File.exist? dbv["dest_path"]
end
}
end
hookには必ず1つの引数(通常はHash)が渡されるが、その中身はタイミングによって異なる。
PBSimply::Hooks#load_hooks
の引数オブジェクトのメソッド。
ブロックをタイミングオブジェクトに追加する。
Procオブジェクトをタイミングオブジェクトに追加する。
system(*cmdarg)
形式でコマンドを実行する。
pre
では$pbsimply_currentdoc
の内容を更新して反映させることができる。
IO.popen(cmdarg, "w+")
形式でコマンドを実行する。
コマンドは標準入力からドキュメントの内容が与えられ、ドキュメントの内容はコマンドの出力で置き換えられる。
このコマンドはpre
においてのみ利用可能。
PBSimply::Hooks#pre
はドキュメント処理の直前に呼ばれる。
引数はfrontmatter
とprocdoc
.
frontmatter
はこのタイミングでのfrontmatterが入っている。
pre
が呼ばれるのはBLESSよりも後である。
procdoc
には処理中のドキュメントの一時ファイルのパスが入っている。
この時点では、このファイルの中身はソースドキュメントからfrontmatterを除いたものに過ぎない。
PBSimply::Hooks#process
はドキュメントの一連の処理を行い、最後の生成を行った直後に呼ばれる。
引数はfrontmatter
, procdoc
, outpath
である。
frontmatter
およびprocdoc
は#pre
と同様だが、生成前の処理はすべて終わった状態になっている。
outpath
は出力予定されたドキュメントのパス。
PBSimply::Hooks#delete
は、ドキュメントが「なくなった」場合に呼ばれる。
これは、ドキュメントがdraftに変更された場合を含む。
引数はtarget_file_path
とsource_file_path
である。
target_file_path
はこのドキュメントが生成される場合の出力ファイルパスである。
このファイルは存在する場合もあれば、存在しないこともある。
source_file_path
はソースドキュメントのパスである。
存在することもあれば、存在しないこともある。
PBsimply::Hooks#post
はすべてのドキュメントの生成が終わったタイミングで呼ばれる。
引数はthis_time_processed
である。
これは、Hash
の配列で、実際にPureBuilder Simplyが今回の処理したドキュメントが入っている。
中身はsource
(オリジナルのソースファイルのパス), dest
(出力ファイルのパス), frontmatter
である。
PBSimply::Hooks#accs
はACCSインデックスを生成するときに呼ばれる。
引数としてindex
とindexes
が渡される。
これは、.accsindex.erb
で認識される@index
および@indexes
と同じものである。