- Pandocは、MarkdownやHTMLやLaTeXやWordのdocxなどを相互変換するCLI(Command Line Interface:コマンドラインインターフェース)ツールです1。
- 見出しや段落といった構造は変換先でも保たれますが、余白や行間といった細かい書式は自動的には引き継がれません。
- PDFへの変換だけは、既定でLaTeXという組版システムを経由するため、他の形式への変換とは仕組みが異なります。
- 余白やフォント、文字サイズはPandocの変数として渡すことで、YAMLファイルやコマンドラインから自分で指定できます。
1. Pandocが変換しているのは文書の構造であって見た目ではない
Pandocは、入力ファイルと出力ファイルを指定するだけで動く道具です。
pandoc input.md -o output.html
Code language: CSS (css)
こう打つだけでHTMLになりますし、拡張子をdocxに変えればWordファイルになります。 形式ごとに専用の変換スクリプトが動いているように見えますが、実際の中身は少し違う。
Pandocは、入力ファイルを一度、内部の文書モデルに読み込みます。 見出しはこのレベルの見出し、箇条書きはこの項目のリスト、というふうに、形式に依存しない構造として保持する。 そのうえで、指定された出力形式に合わせて書き出し直しています。
だから、見出しや段落、箇条書きといった構造は、MarkdownからWordに移してもHTMLに移してもほぼそのまま残ります。 一方で、余白のサイズや行間、フォントの太さといった見た目の細部は、内部の文書モデルには含まれていない情報です。 公式ドキュメントでも、見出しや段落などの構造要素は保とうとする一方で、細かな書式は完全には保持されず、複雑な表などはそもそも単純な文書モデルに収まらない場合があると説明されています2。
この理解があると、あとで出てくる「PDFだけ別のエンジンが必要」という話も、「余白はYAMLで指定する」という話も、根っこは同じだと分かります。 Pandocが扱っているのは見た目ではなく構造で、見た目は出力段階で毎回組み立て直されている。
2. PDF出力だけLaTeXという別のエンジンが挟まる
Markdown、HTML、Wordのdocxへの変換は、Pandoc自身が構造を読み書きすれば完結します。 ところがPDFだけは事情が違って、既定ではLaTeXという組版システムを経由します3。
pandoc input.md -o output.pdf
Code language: CSS (css)
このコマンドを実行するには、Pandoc本体だけでなく、LaTeXの実行環境がマシンに入っている必要があります。 入っていなければ、コマンドは失敗します。 最初にPDF変換でつまずく人の多くは、ここで詰まっているのではないでしょうか。
エンジンは--pdf-engineオプションで切り替えられて、xelatexやlualatex、typst、weasyprintなどが選べます。
pandoc input.md -o output.pdf --pdf-engine=xelatex
どのエンジンを選ぶかは、日本語フォントを扱うかどうかで変わってきます。
2.1. macOSでのLaTeX環境の選び方
macOSでLaTeXを入れる方法は、実質2つに絞られます。
ひとつはMacTeXです。 TeX Live一式をmacOS向けにまとめたパッケージで、日本語を含む多言語組版に対応しています4。 Homebrewを使えば、GUIなし版を次のコマンドで入れられます。
brew install pandoc
brew install --cask mactex-no-gui
インストール後はターミナルを開き直して確認します。
pandoc --version
lualatex --version
もしlualatexが見つからない場合は、TeXのパスが通っていないだけなので、次を実行すれば直ります。
echo 'export PATH="/Library/TeX/texbin:$PATH"' >> ~/.zshrc
source ~/.zshrc
Code language: PHP (php)
もうひとつはBasicTeXです。 必要最小限のパッケージだけを含む軽量版で、MacTeXよりインストールサイズが小さい。 ただし小さい分、あとから日本語組版用のパッケージなどをtlmgrで個別に追加する必要が出やすくなります。
brew install pandoc
brew install --cask basictex
echo 'export PATH="/Library/TeX/texbin:$PATH"' >> ~/.zshrc
source ~/.zshrc
sudo tlmgr update --self --all
sudo tlmgr install collection-langjapanese collection-latexrecommended collection-fontsrecommended
Code language: PHP (php)
最初から確実に動かしたいならMacTeX、容量を抑えたいならBasicTeXという選び方になります。 PDF生成時にパッケージ不足のエラーが出た場合は、エラーメッセージに出てくる.styファイル名を手がかりに、tlmgr searchで該当パッケージを探して追加すれば直ります。
tlmgr search --global --file '/geometry.sty'
sudo tlmgr install geometry
Code language: PHP (php)
3. 日本語PDFを組むにはLuaTeX-jaという仕組みが要る
LaTeX環境が入っただけでは、日本語PDFはまだ組めません。 LaTeXはもともと欧文の組版を前提にした仕組みなので、日本語を縦横に正しく流し込むには、別の拡張が必要です。
その拡張がLuaTeX-jaです。 LuaLaTeXというエンジンの上で動く日本語組版の仕組みで、CJKmainfontのようなフォント指定は、--pdf-engine=lualatexを使ったときにこの仕組み経由で反映されます5。 なので、日本語PDFを作るときのエンジン選びは、基本的にlualatex一択と考えてよさそうです。
文書の種類を指定するdocumentclassも、日本語を組むなら通常のarticleではなく、LuaTeX-ja用に用意されたltjsarticleを使います。
documentclass: ltjsarticle
lang: ja-JP
Code language: HTTP (http)
このあたりの設定は、Markdown本文とは別に、YAML metadata(YAML Ain’t Markup Language:文書の先頭に書く設定情報の記法)としてファイルの先頭に書くか、あるいは別ファイルに切り出して--metadata-fileで読み込ませます。 本文はMarkdownのまま書けて、見た目の設定だけを切り離せるのは、地味に扱いやすい。
4. 余白・フォント・文字サイズは変数として渡す
ここまでの理解を踏まえると、余白やフォントサイズの調整は、Pandocに用意された変数を指定するだけの作業になります。 公式には、本文サイズを決めるfontsize、日本語などのフォントを指定するCJKmainfont、リンクの色を決めるlinkcolorなど、多くの変数が定義されています。
余白はgeometryで指定します。
geometry:
- top=25mm
- bottom=25mm
- left=25mm
- right=25mm
文字サイズはclassoptionにポイント数を並べて指定します。 標準的なLaTeXの文書クラスでは、10pt、11pt、12ptが基本の選択肢です6。
classoption:
- a4paper
- 11pt
日本語フォントはCJKmainfontで本文用、CJKsansfontで見出しなどのゴシック体用を分けて指定できます。 macOSに標準で入っているフォントなら、Hiragino Mincho ProNやHiragino Sansがそのまま使えます。
CJKmainfont: "Hiragino Mincho ProN"
CJKsansfont: "Hiragino Sans"
Code language: JavaScript (javascript)
4.1. YAMLにまとめるか、コマンドラインで都度渡すか
これらの変数は、-Vオプションを使ってコマンドラインから直接渡すこともできます。
pandoc input.md \
--pdf-engine=lualatex \
-V documentclass=ltjsarticle \
-V geometry:top=25mm \
-V CJKmainfont="Hiragino Mincho ProN" \
-o output.pdf
Code language: JavaScript (javascript)
動作は確認できますが、指定が増えるほどコマンドは長くなる一方です。 毎回同じ設定を打つのは、正直だんだん面倒になってきます。
実用上は、style.yamlのような設定専用ファイルに変数をまとめておいて、--metadata-fileで読み込ませる形が扱いやすい。
documentclass: ltjsarticle
classoption:
- a4paper
- 11pt
geometry:
- top=25mm
- bottom=25mm
- left=25mm
- right=25mm
linestretch: 1.2
CJKmainfont: "Hiragino Mincho ProN"
CJKsansfont: "Hiragino Sans"
colorlinks: true
linkcolor: blue
Code language: JavaScript (javascript)
pandoc input.md --metadata-file=style.yaml --pdf-engine=lualatex -o output.pdf
こうしておけば、本文のMarkdownファイルは内容だけに集中できて、見た目の設定はstyle.yaml側の役割として分けられます。 文書ごとに見た目を変えたいときは、style.yamlを複製して数値を書き換えるだけで済みます。
余白1つ、フォント1つが、内部では変数の値として扱われている。 そう考えると、Pandocの見た目の調整は、身構えるほど複雑な作業ではなくなってきます。
- Pandoc公式は、Markdown、HTML、LaTeX、Word docxなど多数の形式間で変換できるコマンドラインツールと説明しています。 – Pandoc – Pandoc User’s Guide
- Pandoc公式は、見出しなどの構造要素は保とうとする一方、余白のような書式の細部は保持されず、複雑な表などは単純な文書モデルに収まらない場合があるとしています。 – Pandoc – Pandoc User’s Guide
- Pandoc公式は、既定ではPDF作成にLaTeXを使用し、LaTeXエンジンのインストールが必要だとしています。 – Pandoc – Pandoc User’s Guide
- TeX Users Groupは、MacTeXはTeX Liveの完全版をmacOS向けにインストールするパッケージだと説明しています。 – MacTeX – TeX Users Group
- Pandoc公式は、CJKmainfontを設定した場合、xelatex使用時はxeCJKパッケージ、lualatex使用時はluatexjaパッケージが必要になるとしています。 – Pandoc – Pandoc User’s Guide
- Pandoc公式は、標準的な文書クラスで指定できる本文サイズは10pt、11pt、12ptだとしています。 – Pandoc – Pandoc User’s Guide