« 2018年12月 | トップページ

2019年12月

2019年12月12日 (木)

pandocでなんとかする話

Fujitsu Advent Calendar 2019の12日目です。 このエントリは個人の立場で書いております。 所属企業の見解を示すものではありません。

今年は最近個人的にちまちま書いているツールについて書こうと思います。 たいしたことやってるわけでは無いんだけど、 まあせっかく作ってるんだし。

そのモノはpandocでなんとかするためのツールです。

pandocは例えばmarkdownをHTMLとかに変換したりするのにとても便利なツールなのですが、 一群のmarkdownをまとめて変換しようとすると色々面倒があります。

  • 「一群」に含まれる他のmarkdownファイルへのリンクの拡張子を自動的に変更してくれない
  • 文書タイトルの扱いがなんか思てたんと違う
  • サブディレクトリがある場合、cssの相対パスとかの調整が面倒

等々。 こういった面倒事をよきにはからってなんとかするためのツールです。 名前は"Panasu"(ぱなす)と言います。 「んどっくでんとかる」の略です。 ソースはGitHub上に置いています。

縁起

メモをmarkdownで書きたいなあ、と思ったのがことの起こりです。

メモなんかOneNoteなりEvernoteなりのサービスを使えばいいじゃないか、 と言われればその通りで、 実際OneNoteを日常的なノートに使ってたりしてます。 そうなのですが、バージョン管理しながらプレーンテキストでメモしたいこととかもあるのです。 技術関連のメモとか。 コードブロックとか書きたいし。

じゃあ、GitHubなりGitLabに置けばいいじゃないか。 バージョン管理してくれる上にmarkdownは自動的にHTML化して表示してくれるし。 まあそうなんだけど(どうせgitに入れるんだし)、 サーバー側にコミットしないとHTMLで読めないのがなあ。 ネットワークがつながらない所でも手元ですぐ見れてほしいし、 HTML化されたmarkdown見てて「あっ、ちょっと書き方間違えてる」と気が付いて ちまちましたコミットがやたらと増えるの嫌なんですよ。 間違える自分が悪いんだけど。

ということで、 煮え切らないままに、 しばらくmarkdownを書いてそれをそのまま読む日々を送っていました。 が、ある日「やっとれるかー」と感極まってですね、 なんとかすることにしました。

最初はmarkdownを表示するブラウザのプラグインをいくつか試して、 ブラウザ経由で見る方法を試してみたんですけど、 フレームとか対応していないので左側に目次を置く構成とか面倒そうだし、 cssの指定とか柔軟じゃなさそうだし。 また、ローカルにWebサーバー立ち上げる式のツールも試してみたけど、 複数デバイスで共有することを考えると、 各環境にツール入れるんじゃなくて、 変換後のHTMLをOneDriveとかで共有できるようにした方がいいんじゃないかと感じました。 ということで、スクリプト一発でpandoc使ってhtmlを生成できるようにする方針で行くことにしました。

で、Makefileとかまじめに書いてたんですけど、 一群のファイルをひとかたまりとしてpandocで変換しようとすると、 色々と面倒が出てきまして。 しばらくスクリプトがりがり書いて頑張っていたんですけど、 ある日「やっとれるかー」と感極まってですね、 ツールを作ることにしました。

ざっと検索してみたんですけど、 似たようなツールはありませんでした。 皆さんどうしてるんですかね。 頑張って各自スクリプト書いているのかな。

効能

このツールは、 入力ディレクトリ下のソースファイル群をpandocを使って変換し、 それを出力ディレクトリにディレクトリ構造を保ったまま出力します。 その際に、 独自のpandocフィルタをかますことで、 以下の面倒事をなんとかします。

  • 変換に伴い相対リンクが切れてしまうのをなんとかします。 例えば、markdownファイル(拡張子.md)をHTML(拡張子.html)に変換する場合、 入力ファイルに"a.md"へのリンクがあれば、 それを"a.html"へ変換します。
  • pandocでタイトルの扱いが微妙に面倒なのをなんとかします。 詳細はGitHub上のチュートリアルを見ていただきたいんですけど、 markdown文書の先頭に唯一のlevel-1ヘッダとしてタイトルを書いておいてもらえれば、 だいたい期待した通りに出力される、はず。
  • メタデータの指定が面倒なのをなんとかします。 pandocでは変換に対するパラメーター的なものを「メタデータ」として指定できます。 メタデータはmarkdown中に埋め込むこともできますが、それをするとソースのmarkdownとしての互換性が低くなります。 コマンドラインで指定することもできますが、いちいちソースごとに指定するのも面倒です。 ということで、このツールでは"a.md"というソースファイルに対して"a.md.metadata.yaml"というファイルがあれば、 そこにこのソースに対するメタデータがYAML形式で記述されているとして扱います。
  • 変換セッション全体で共通なメタデータの指定が面倒なのをなんとかします。 例えば、入力ソースがすべて日本語文書の場合、 langメタデータの値を"ja"に設定する指定を各ソースに対して行うのは面倒です。 このツールでは、変換セッション全体に適用するメタデータをYAML形式で指定できます。
  • ローカルなCSSとかの指定が面倒なのをなんとかします。 pandocでソースをHTMLへ変換する場合、 変換後のHTMLファイルにスタイルシートを適用したい場合はcssメタデータを指定します。 そのcssが相対URLになる場合、ソースの場所に応じてcssのパスを調整する必要があります。 例えば、"a.html"に対しては"styles/style.css"、"sub/b.html"に対しては"../styles/style.css"のように指定しなければなりません。 これを何とかするため、メタデータに対して簡単なマクロ機能を提供します。 このケースの場合、共通メタデータ中にcssメタデータの値としてrebaseマクロとともにcssへのパスを書いておけば、 このツールがなんとかします。
  • 変換対象外ファイルへの相対リンクの扱いがなにかと面倒なのをなんとかします。 典型的には画像へのリンクですけど、 文書形式変換の対象ではないファイルへの相対リンクの扱いに二つのモードを用意しています。
    • その場で見るためのモード。 対象となる相対リンクはオリジナルのファイルを指すように書き換えられます。 例えば、"image.png"へのリンクは、"../md/image.png"のようにオリジナルの場所を指すように書き換えられます。
    • 出力をまとめてどこかへ持っていくためのモード。 対象となる相対リンクは変更されません。 その代わり、その相対リンクが有効であるようにするために、 オリジナルのファイルを出力ディレクトリ下へコピーします。

想定しているのはmarkdownからHTMLへの変換ですが、 pandocがサポートしている任意の入力・出力形式に対して適用することができます。

使い方

このツールは、現在のところPowerShell Coreのスクリプトと.NET Coreで書いたpandocフィルタでできています。 私は主にWindows上で使っていますが、 手っ取り早く試せるようにLinuxコンテナを作るDockerfileをご用意しております。

Linux上のdockerなり、Windows上のDocker Desktop for Windowsなりに対して 以下のコマンドを打てばpanasu:latestという名前のイメージができます。

docker build -t panasu https://github.com/ipponshimeji/Panasu.git#:Docker/Ubuntu_18.04

まあ、正直使ってくれる人はそんなにいないだろうと思っているので、 出来上がりイメージはレジストリに置いていません。

直接セットアップする場合や、コンテナ使う場合の詳細については、 インストールを見てください。

デフォルト状態での使い方としましては、 以下のようなディレクトリ構造を作ります。

- Documents(ここの名前は何でもよい)
  - _scripts
  - md
  - html

mdにmarkdownのファイルを格納します。 _scriptsにこのツールや変換に関する諸々を入れておき、 _scriptsディレクトリ上で_scripts/format.ps1を実行すると、 htmlに変換されたHTMLが出力されます。

コンテナイメージの場合は、 ~/PanasuSampleにこの構造のサンプルが格納されています。 ツール本体は~/.local/Panasuにあります。

詳細な使い方は、 チュートリアルにありますので、 ご興味ありましたらご覧くださいまし。 上の「効能」で述べた各機能の使い方も説明しています。

今後など

今作っているのがひと段落したら、 入力ディレクトリのファイルをまとめて一個にまとめるスクリプトも作ろうと思っています。 最終的に一枚のhtmlとかwordとかpdfにするやつ。 というか、 今頃はその機能ができているつもりだったんだけど、 この秋は何かと暇がなくて、あまり進みませんでした。 ぼちぼち進めていきたいと思っております。

パルナスとわたくし

さて、ここからは完全に余談なのですが、 ツールの名前をどうするか考えているときに、 「ぱんどっく、ぱ…ぱ…ぱなす、パルナス」とパルナスのことを思い出してですね。 思い出したついでに何か書き残しておこうと思うのです。

パルナスとは私の地元(神戸の西の方)の周辺にいくつか店があった洋菓子店です。 山陽電鉄や神戸電鉄の駅によく店がありました。 月見山駅と明石駅と三木駅に店があったのは覚えている。 板宿駅にあったっけなあ。 山陽そばがあったのは覚えている。大昔に洋菓子売っている一角があったような気がするけど、 もう震災前の板宿の記憶が定かではない。

まあともかく、 「モスクワの味」をキャッチフレーズに、 とんがり帽子の丸い口の子供が諸手をあげてうわーと走っているマスコットを掲げた店があったのです。 TV CMも流していました。 私的にはドレミファ噴水パレスと並ぶローカルCMの双璧です。

二年前くらいでしょうか、 ひょんなことからWikipediaの「パルナス製菓」の項を見つけまして、 2000年に最後の店舗が閉鎖、2002年にパルナスが解散していたことを知り、遠い目になりました。 パルナスの店がない世をもう20年近く過ごしていたのか。

そんなことも思い出して、 一時、ツールの名前を「パルナス」にしようかと迷いました。 ツールの語呂合わせどうしよう、ぱるなす、ぱんどっくでなんとかする、る、「る」って意外と言葉がない。 る、る、るしゃなぶつ、「ぱんどっくで廬舎那仏となんとかする」、 アイコンは金色に輝く大仏さんで。 この時、脳裏には廬舎那仏の前に展開する僧侶団がそれぞれ手にした経典をpandocで五色の瑞雲に変換するイメージが浮かんでいたのですが、 そこそこ知られた店の名前を流用するのも何か障りがありそうで、なんとか思いとどまりました。 なので、せめてここに記しておくものであります。

でもまあ、思い返してみたらパルナスのものを実際に食った記憶は無いんだなあ。

« 2018年12月 | トップページ