Pandocのテンプレート・ユーザデータディレクトリに関して質問があったのでメモしておきます。
何の話か
Pandocの出力をカスタマイズする仕組みとして、テンプレートまたはユーザデータがあります。
詳細は User's GuideのTemplates を参照。
テンプレート
例えばHTMLやLaTeXで出力する際に、「ヘッダ・フッタをカスタマイズしたい」「スタイルファイルへのリンクを挿入したい」「変数で条件分岐させたい」というケースに、ユーザはテンプレートを編集できます。
ユーザデータ
テンプレートが使えない例外がたまにあり、例えばWord docx(docx)やLibre office Writer(odt)の書式カスタマイズはこちらでやります。
詳細は ドキュメント変換ツールPandoc:ユーザーズガイドを熟読して分かったマニアックな使い方 - Qiita をご覧ください。
ユーザデータディレクトリ
テンプレートとユーザデータを格納するディレクトリをデータディレクトリと呼び、そのうちユーザがカスタマイズするためのものをユーザデータディレクトリと呼びます。
データディレクトリのうち、特に「templates」以下のファイルを テンプレート と呼び、それ以外を データファイル と呼びます。
ただしテンプレートは
-
--template
オプションで指定する場合 - ユーザデータディレクトリを指定して格納する場合
があります。後者では、ユーザデータディレクトリの中の「templates」ディレクトリにテンプレートを入れます。 (これを忘れると読まれません)
ユーザデータディレクトリには --data-dir
オプションで直接指定できるものと、Pandocが(既定のデータディレクトリよりも優先して)勝手に読みにいくデフォルトユーザデータディレクトリがあります。
デフォルトユーザデータディレクトリの場所は通常、 pandoc -v
で示されます。 (Default user data directory: hoge
という形で)
実際には
- Windows 7以降:
%HOME%\AppData\Roaming\pandoc
- Unix系 (macOS/Linux):
~/.pandoc
であることが多いです。
ただし、勝手に作られるとは限らないので、そのディレクトリがない場合は自分でディレクトリを作ります。
以下、Pandocのテンプレートとユーザデータディレクトリについて、どのように適用されるのか(適用の優先順位)について説明します。
既定のデータディレクトリ
Pandocが既定で使うデータディレクトリが実際のマシン上でどこに置かれるかについては、ドキュメント上の明示はありません。ただし、GitHubディレクトリの
において、確認することができます。
ただし、公式で推奨する方法は、
- テンプレート:
pandoc -D FORMAT
またはpandoc --print-default-template FORMAT
(FORMATは-f/-t
で指定するフォーマット名) - ユーザデータ:
pandoc --print-default-data-file FILE
(FILEはデータファイルの名前)
によって出力することです。(標準出力に出るので、リダイレクトで保存します)
テンプレート・ユーザデータディレクトリの優先順位
どの優先順位でテンプレートやユーザデータディレクトリが使われるかは、(よく読めば)Pandocのユーザーズガイドに書かれています。
結論から言えば
テンプレートを引数で指定 (--template
) > ユーザデータディレクトリを引数で指定 (--data-dir
) > デフォルトユーザデータディレクトリ > Pandoc既定のデータディレクトリ
のようです。
順に見ていきます。
--template=FILE
Use FILE as a custom template for the generated document. Implies --standalone. See Templates, below, for a description of template syntax. If no extension is specified, an extension corresponding to the writer will be added, so that --template=special looks for special.html for HTML output. If the template is not found, pandoc will search for it in the templates subdirectory of the user data directory (see --data-dir). If this option is not used, a default template appropriate for the output format will be used (see -D/--print-default-template)
つまり --template
が指定されたとき(一部推測込みになりますが)、順番は
- カレントディレクトリを見る
- 指定されている文字通りのファイル名を探す
- 拡張子が無い場合は、出力フォーマットに対応する拡張子を勝手に補う
-
--data-dir
で指定されるユーザデータディレクトリの中にある「templates」ディレクトリを探す - デフォルトユーザデータディレクトリの中にある「templates」を探す
- Pandoc既定のデータディレクトリの中にある「templates」を探す
となるようです。
実験
筆者環境 (Windows 10 build 15063, pandoc 1.19.2.1) で実験してみました。
- 特に意味はありませんが、Emacs org-mode (org)をフォーマットとして使います。
- 注意:Chocolatey v0.10.5 で入れたのですが、Chocolatey上では「pandoc 1.19.2.1」というバージョンなのに、
pandoc -v
では「pandoc 2.0」と表示されます。実際には前者の「pandoc 1.19.2.1」が入っていると思われます。
1. デフォルトユーザデータディレクトリにテンプレートを格納
- Windowsなので
%HOME%\AppData\Roaming\pandoc
にdefault.org
という名前でテンプレートファイルを作ります。 - bodyの下に「AAA」と表示されるようにします。
$if(title)$
#+TITLE: $title$
$endif$
$if(author)$
#+AUTHOR: $for(author)$$author$$sep$; $endfor$
$endif$
$if(date)$
#+DATE: $date$
$endif$
$for(header-includes)$
$header-includes$
$endfor$
$for(include-before)$
$include-before$
$endfor$
$body$
AAA
$for(include-after)$
$include-after$
$endfor$
2. 適当なディレクトリにテンプレートを作成
bodyの下に「BBB」と表示されるようにします。
$if(title)$
#+TITLE: $title$
$endif$
$if(author)$
#+AUTHOR: $for(author)$$author$$sep$; $endfor$
$endif$
$if(date)$
#+DATE: $date$
$endif$
$for(header-includes)$
$header-includes$
$endfor$
$for(include-before)$
$include-before$
$endfor$
$body$
BBB
$for(include-after)$
$include-after$
$endfor$
3. カレントディレクトリにtemplatesディレクトリを作成、その下にテンプレート作成
- 2.のtmp.orgと同じディレクトリにtemplatesディレクトリを作成
- その更に下にdefault.orgというテンプレートファイルを作成
- bodyの下に「CCC」と表示されるようにします。
$if(title)$
#+TITLE: $title$
$endif$
$if(author)$
#+AUTHOR: $for(author)$$author$$sep$; $endfor$
$endif$
$if(date)$
#+DATE: $date$
$endif$
$for(header-includes)$
$header-includes$
$endfor$
$for(include-before)$
$include-before$
$endfor$
$body$
CCC
$for(include-after)$
$include-after$
$endfor$
まとめると、こういう構造です。(実際に入れているファイルの一部は省略)
%HOME%/AppData/Roaming/pandoc/templates
└── default.org
カレントディレクトリ
├── templates
│ └── default.org
└── tmp.org
4. pandocコマンドを実行
$ echo '**hoge**' | pandoc -s -f markdown -t org # (A)
*hoge*
AAA
$ echo '**hoge**' | pandoc -s -f markdown -t org --template tmp.org # (B)
*hoge*
BBB
$ echo '**hoge**' | pandoc -s -f markdown -t org --data-dir . # (C)
*hoge*
CCC
$ echo '**hoge**' | pandoc -s -f markdown -t org --data-dir . --template tmp.org # (D)
*hoge*
BBB
$ echo '**hoge**' | pandoc -s -f markdown -t org --template tmp.org --data-dir . # (E)
*hoge*
BBB
- (A) デフォルトユーザデータディレクトリが指定された
- (B) カレントディレクトリのテンプレート(tmp.org)が指定された
- (C) カレントディレクトリの中のtemplatesディレクトリにあるdefault.orgが指定された
- (D) カレントディレクトリのテンプレート(tmp.org)が指定された
-
--template
オプションが優先され、--data-dir
オプションは無視された
-
- (E) Dと同様(引数の順番を入れ替えたが、結果は同じだった)
5. 結論
先ほどのように
テンプレートを引数で指定 (--template
) > ユーザデータディレクトリを引数で指定 (--data-dir
) > デフォルトユーザデータディレクトリ
という優先順位を確認しました。(Pandoc既定のデータディレクトリについては実験を省略)
以上です。