LoginSignup
6
5

More than 5 years have passed since last update.

メモ: Pandocのテンプレートとデータディレクトリの優先順位

Posted at

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 が指定されたとき(一部推測込みになりますが)、順番は

  1. カレントディレクトリを見る
    • 指定されている文字通りのファイル名を探す
    • 拡張子が無い場合は、出力フォーマットに対応する拡張子を勝手に補う
  2. --data-dir で指定されるユーザデータディレクトリの中にある「templates」ディレクトリを探す
  3. デフォルトユーザデータディレクトリの中にある「templates」を探す
  4. 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\pandocdefault.org という名前でテンプレートファイルを作ります。
  • bodyの下に「AAA」と表示されるようにします。
default.org
$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」と表示されるようにします。

tmp.org
$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」と表示されるようにします。
templates/default.org
$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既定のデータディレクトリについては実験を省略)

以上です。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5