🅿️

Pandocテンプレート:デフォルトのやつを使うべきか否か

2020/12/25に公開

Pandocのテンプレートについて、次のような話題が出ました。

結論からいえば次のように筆者は考えます。

  • 本を制作するなら自前テンプレート
  • 体裁にこだわらない文書、短いレポートやプレゼン資料ならデフォルトテンプレート

※ 今回はLaTeX出力を例として取り上げますが、HTMLベースの出力などについても同様のことがいえます。

本題へ入る前に、テンプレートの基本を説明します。

デフォルトテンプレートの基本

通常、Pandocはヘッダ・フッタ付きの文書(スタンドアロン文書;-sまたは--standaloneオプション)を出力するために、テンプレートを利用します。

Pandocがデフォルトで使用するテンプレート(以下、デフォルトテンプレート)をコマンドライン上で出力したい際は pandoc -D 出力フォーマット名 またはpandoc --print-default-template=出力フォーマット名で可能です。

たとえばLaTeX(latex)のテンプレートを出力するには次のコマンドで可能です。

pandoc -D latex

当然ながらパイプ・リダイレクトも可能です。テンプレートは長いので個人的には less で読むことが多いです。

pandoc -D latex | less
pandoc -D latex > my-template.tex

出力フォーマット名は pandoc --list-output-formats で確認できます。参考までに出力フォーマット名をリストアップします。

asciidoc asciidoctor beamer commonmark commonmark_x context csljson 
docbook docbook4 docbook5 docx dokuwiki dzslides epub epub2 epub3 
fb2 gfm haddock html html4 html5 icml ipynb jats jats_archiving 
jats_articleauthoring jats_publishing jira json latex man markdown 
markdown_github markdown_mmd markdown_phpextra markdown_strict 
mediawiki ms muse native odt opendocument opml org pdf plain pptx 
revealjs rst rtf s5 slideous slidy tei texinfo textile xwiki zimwiki

ブラウザで閲覧する際は、GitHubのjgm/pandoc-templatesが便利です。tagがPandoc本体のリリースと連動します。

jgm/pandoc-templates: Templates for pandoc, tagged to release

たとえばLaTeXのテンプレートは下記から閲覧可能です。

pandoc-templates/default.latex

テンプレートの使い方

テンプレートには変数を含むことが可能です。変数をテンプレートに流し込むことによって、Pandocは文書に値を埋め込んだり、条件分岐・複数要素の繰り返しなどを行ったりできます。詳細はUser's GuideのTemplatesを参照。

たとえば自前のテンプレートを次のように用意します。

hello-template.txt
$foo$

$body$

のように定義すれば、変数fooに任意の値を流し込むことが可能です。

本文は$body$に流し込まれます。今回は標準入力(echoのパイプ)から本文を流し込みます。

変数は-V/--variable=オプションで直接渡すことができます。具体的には-V foo=値-V foo:値のように指定します。

$ echo 'Merry Christmas' | pandoc -f markdown -t latex --template=hello-template.txt -V foo='Ho ho ho!'
Ho ho ho!

Merry Christmas

もう少し具体的な話は Pandocのテンプレート機能でYAMLから本の奥付を自動生成する - Qiita も参考にしてください。

また文書のメタデータも変数に流し込めます。 変数と違い、メタデータは次の特徴があります。

  • メタデータは入力データから自動的に読み込まれることがある(titleauthordateなど)
  • メタデータはフィルタからアクセスできる(変数はアクセスできない)

1つ注意があります。メタデータと変数が両方指定されている場合は、変数が優先されてメタデータは破棄されます。

参考:Pandocでメタデータはテンプレート変数になるかならないか - マクロツイーター

自前でテンプレートをつくる方針

自前でテンプレートをつくる際に、方針は2つあります。

  • (a) デフォルトテンプレートをベースにして変更する
  • (b) ゼロからテンプレートをつくる(必要に応じて変数を足す)

またLaTeXの場合は、\input\includeによって別のLaTeX文書を取り込むことが可能です。よって次の選択肢も出てきます。

  • (c) Pandoc側でテンプレートを作らず、完全にLaTeX側でテンプレートに相当する文書を作る

(c)の場合は -s/--standalone オプションを指定しません(非スタンドアロンモード)。Pandocには本文のみを出力させます。

ラムダノートの鹿野さんは、(c)に相当するワークフローを紹介しています。

マクロな構造は完全にLaTeXで用意しておき、PandocはあくまでもコンテンツをMarkdownからLaTeXの章や節に変換するのに使っています。 この方法の利点は、書籍のマクロ構造に関して完全に枯れた技術であるLaTeXのパワーを余すところなく利用できることです。 欠点は、Pandocで完結しないのでMakefileのような仕組みが必要になることです。 もっとも、この欠点は高い柔軟性という利点でもあります。

Markdownで書籍を作るとは - golden-luckyの日記

(c)のワークフロー(引用)

Markdownで書籍を作るとは - golden-luckyの日記から引用)

なお出力がWord・PowerPoint・LibreOffice Writer(ODT)の場合は、テンプレートではなくスタイル参照ファイル(reference-doc)を利用します。この場合は事実上(a)の選択肢しかなく、(b)は困難です。

自前テンプレートがよい場面

出力フォーマットをがっちり固定できる前提では、自前でテンプレートをつくってしまうのがよいでしょう。たとえば「MarkdownからLaTeXに変換したい」ことが確定している場合は、自前テンプレートの方が(ほぼ)LaTeXの知識のみで柔軟にカスタマイズできます。

(c)の場合、Pandocの責務はだいぶ小さくなり、「Markdown原稿をLaTeXの本文に変換するだけ」です。また参考文献はLaTeX側のBibTeXなどで処理することになります。

Pandocには「本をつくる」ために必要な機能がいくつか足りません。索引やページ制御などです。これらは(LaTeX出力なら)LaTeX側でしか実現できないので、LaTeXの知識がある方なら「自動組版に関する機能はLaTeX側で制御する」という割り切りでよいと思います。

デフォルトテンプレートをベースにしても、結局ヘッダを追加する(header-includes変数や-H/--include-in-header=オプション)ことになります。ヘッダが膨大になるぐらいなら、全部自前でテンプレートをつくってしまう方が楽でしょう。

なおjgm/pandoc-templatesには、次のように「リポジトリをForkすることを推奨する(将来のPandocリリースに追従するため)」と書いています。

If you use custom templates, we recommend forking this repository, so that you can integrate changes to the default templates in future pandoc releases.

これには良し悪しがあります。

  • メリット:Pandocの最新機能・バグフィックスの恩恵にあずかりやすい
  • デメリット:出力が不安定になる(Pandocのバージョンに依存する)

本の制作(特に商業)の場合、どちらかといえば上記のデメリットの方が大きいでしょう。

デフォルトテンプレートがよい場面

デフォルトテンプレートが有利な場面は、基本的に「手っ取り早くラフに書きたい」場合になってきます。体裁をあまり気にしなくてもいい短いレポートには便利でしょう。

またPandocの機能をフル活用したい場合にも、デフォルトのテンプレートがよい場合もあります。ただし文書の構造や仕様が複雑でない場合に限ります。

  • 複数フォーマット・複数設定で出力したい
  • LaTeX Beamerなどのプレゼンを手軽に使いたい
  • 参考文献をCSLベースにしたい
  • Pandoc's Markdownで使える記法をフルに使いたい
    • strikeout(取消線)拡張など
  • Pandocのオプションやメタデータ・変数で文書の出力を切り替えたい
    • links-as-notes(リンクを脚注扱いする)など

複数フォーマット・複数設定に出力したい場合には、たとえばデフォルトファイルをフォーマット・設定ごとに書き換える方法があります。

LaTeX Beamerは「新幹線の中で急いで書きたい」といった場面があるため(筆者の体験談)、適当なテーマとオプションを選択してデフォルトテンプレートで済ますメリットが大きいように感じます。とはいえLaTeXの知識が豊富であったりBeamerの細かいカスタマイズをしたいなら、自前テンプレートを用意する方がベターでしょう。

なお「自前でテンプレートをつくる方針」で述べたうちの「(a) デフォルトテンプレートをベースにして変更する」は、デフォルトテンプレートのメリットをかなり享受できます。

pandocコマンドだけでPDF生成するか否か

そもそも「pandocコマンドだけでPDF生成までするか否か」という論点もあります。

日本語Markdown文書を入力とするなら、次のコマンドのいずれかでLaTeXエンジンベースのPDF生成が可能です。

# 方法1: BXjsclsを使う
$ pandoc sample.md -o sample.pdf --pdf-engine=xelatex -V documentclass=bxjsarticle -V classoption=pandoc
$ pandoc sample.md -o sample.pdf --pdf-engine=lualatex -V documentclass=bxjsarticle -V classoption=pandoc

# 方法2-1: luatexjapresetoptions変数を使う方法
$ pandoc sample.md -o sample.pdf --pdf-engine=lualatex -V documentclass=ltjsarticle -V luatexjapresetoptions=hiragino-pron

# 方法2-2: LuaTeX-jaで CJKmainfont変数を使う方法
$ pandoc sample.md -o sample.pdf --pdf-engine=lualatex -V documentclass=ltjsarticle -V CJKmainfont=HiraMaruProN-W4

# 方法2-3: BXjsclsで CJKmainfont変数を使う方法
$ pandoc sample.md -o sample.pdf --pdf-engine=lualatex -V documentclass=bxjsarticle -V classoption=pandoc -V CJKmainfont=HiraMaruProN-W4

参考:メモ: Pandoc+LaTeXで気軽に日本語PDFを出力する - Qiita

この方法は「とにかく手軽に生成したい」というユースケースには向いています。

しかし 「本を制作したい」というユースケースにはお勧めしません。 なぜならLaTeX側でエラーが起こったときに、デバッグが困難だからです。本を制作する場合のワークフローは、少なくとも次の2つのフェーズに分けておきましょう(これらをMakefileなどで書いておくとベター)。

  1. Pandoc:Markdown→LaTeX文書
  2. LaTeX:LaTeX文書→PDF

まとめ

今回はPandocにおいて自前テンプレートを選ぶか、デフォルトテンプレートを選ぶかという問題について取り上げました。

結論としては「本を制作するなら自前テンプレート」「体裁にこだわらない文書、短いレポートやプレゼン資料ならデフォルトテンプレート」という落としどころになりそうです。

筆者は「本をデフォルトテンプレートベースで制作する」という無謀なことをした経験があります。一応できなくはないですが、結局pandocコマンド単体では無理だったのでLaTeX側のコマンドを別途叩いていましたし、LaTeX向けヘッダも膨大になりました。

LaTeXエンジンを使う限り、結局LaTeXの知識は必要になります。ならば最初からPandocの責務を薄くして、極力LaTeX側の知識で制作できる体制をつくった方が楽でしょう。

次に本を書くなら、素直に自前テンプレートを書こうと思っています😂

Discussion