技術同人誌 Advent Calendar 2019の6日目です。
自作サービスのコンテンツ拡充をするためにpdfを作る機会があったので
vivliostyleによるCSS組版環境をざっくり組みました。
ブツをgithubに上げたのでそれについてメモを書いておきます。
https://github.com/liarnose/book_tnm/tree/new_master
ビルド
gulpは最近下火なので何か他の方法を使ってみたかった。結局SSGをビルダ代わりに使うことに。
metalsmith
プラグインをパイプでつなげてそこに対象ファイルを流し込むという
gulpの兄弟のような作りの静的サイトジェネレーター。
gulpを知ってると使いやすいけどプラグインがメンテされなくなる等の
gulpの欠点を解決してる訳でもないので別にこれを使う必然性はあんまりなかった。
vivliostyle-savepdf
ローカルサーバーとかヘッドレスブラウザとか知らなくてもvivliostyleを使えてたいへん便利。
テーマ
作ったCSSやテンプレートを何度も使いまわしたかったので
その分をテーマとして別フォルダにくくりだすようにした。
CSS
将来的に使い続けるのが難しいのが分かってる関係上
脱ePub Adaptive Layoutしたかったのでページ周りは全部CSS Paged Mediaで書く。
と言っても、もともとAdaptive Layoutの機能を利用していたのはランニングヘッダとノンブルだけだったので
- ランニングヘッダ→文章中でヘッダ内容を書き換えるような機能をあきらめてページ背景に統合する。
- ノンブル→ページマージンボックスに移植。
とした。実は傍注はただのCSSのトリックでCSS組版の機能は使っていない。
ネストが使えるのでCSS設計自体はぞんざいだった。タイプセレクタもガンガン使っている。
PostCSS
全部プラグインとして機能拡張するコンセプトのCSSトランスパイラ。軽いらしい。
PostCSS Nested
セレクタをSCSSライクな記法でネストできる。&も使える。
PostCSS Custom Properties
CSSの中で定数を宣言できる。calc()と組み合わせてページサイズなんかを担当。
カラーテーマなんかにも使えるかも。
テンプレート
vivliostyleに食わせる時点ではすでにレンダリング済みのhtmlを用意したいが、
SSRの仕組みを流用してどうのというのは流石に牛刀割鶏感あるので
ビルド手順の中にふつうのテンプレートエンジンを組み込む方向で。
使ったことのあるやつの中からhandlebarsを採用。
handlebars
デフォルトだとかなりシンプルな機能だけがサポートされているテンプレートエンジン。
「この項目は5文字以上だったら長体がかかる」みたいな条件分岐ですらおいそれと書けない。
本文
markdownだけだと表現力が足りないけどmarkdownライクに楽に書きたいので
markdownをプラグインでオレオレ拡張する方針にした。
markdown内にテンプレートを挿入する部分に至っては自前拡張。
markdown
markdown-it
プラグインもりもり系markdownパーサ。
vivlioisyle界隈だと同じコンセプトでもremarkの方が注目されてるのでそっちがいいかも知れない。
option: { html: true }
markdown-it本体に設定できるオプションで、htmlタグをエスケープせずにそのまま出力する。
間に空行が入ると一つのブロックとして認識されなくなってしまうので、
純粋なhtmlと書き心地は違うけどないと困るやつ。
markdown-it-attrs
ありとあらゆるmarkdown役物にクラス等を設定できるようにするプラグイン。
ただの本文のpタグにすら設定できる。
今回の本文のフォントスタイルは3種類もあったのでこれがないと使い分けができなかった。
markdown-it-containerとどっちがいいかは趣味。
markdown-it-deflist
定義リストの記法を追加。
傍注の中で使ってるけどただのヘッダーとパラグラフで十分な気がする。
markdown-it-statblock
自前実装したmarkdown本文にhandlbersテンプレートを挿入する記法を追加するプラグイン。
本文中に<<statblock [テンプレートのパス],[jsonデータのパス]>>
と書くと
テンプレートにjsonを食わせた結果が挿入される。
json
テンプレートの食わせるデータは.jsonファイルの形で外付けにした。
特に専用のエディタなどは用意せずbrackets上でテキストとして編集してたが、
書式のエラーを探すのに相当時間を取られてるのでjsonLintを導入するとか何らかの対策が必要。
あと長い文章を担当する型が無いので一文ごとに分割して
配列に入れるとかしなきゃなのはいかんともしがたいものがある。
感想
今CSS組版で同人誌を書くとしたら 2017からほぼ変わらなかったので
「2年間俺は一体何を…?」と軽くショックを受けた。