Claude CodeでPandocを使う — Markdownからdocx・日本語PDFへ変換
Claude CodeにPandocでMarkdownをdocxやPDFへ変換させる設定です。変換条件をdefaultsファイルとCLAUDE.mdに固定し、日本語PDFで必要なエンジンとフォント指定を押さえます。
Claude CodeにPandocでMarkdownを変換させるなら、毎回コマンドを説明させるより、変換条件を設定ファイルに固定して呼び出し方だけをCLAUDE.mdに書くほうが安定します。日本語PDFは既定のPDFエンジンのままでは組めないため、エンジンとフォントの指定が最初の壁になります。この記事は、docx・PDF・HTMLの変換コマンド、defaultsファイルへの固定、CLAUDE.mdと権限の書き方、日本語PDFの切り分けの順で進めます。
先に押さえる3点
- 変換条件は
-dで読むdefaultsファイル(YAML)に置く。コマンドの引数が短くなり、毎回同じ結果になる - 日本語PDFは
--pdf-engine=xelatexなどを選び、CJKmainfontに日本語フォントを渡す - docxの見た目は
--reference-docの雛形、HTML経由のPDFはCSSで決まる
Pandocの基本コマンドと、Claude Codeに任せる範囲
Pandocは、入力形式と出力形式を指定して文書を変換するコマンドラインツールです。出力先は -o で指定し、拡張子から形式が決まります。-s(--standalone)を付けると、HTMLなら head と body を含む単体のファイルが出ます。pdf・epub・docx・odtでは -s が自動で有効になります。
pandoc -s -o output.html input.md
pandoc -o report.docx input.md
pandoc -o report.pdf input.md最後のPDF出力は、既定ではLaTeXを使います。LaTeXエンジンが入っていない環境では失敗するので、PDFが必要なら先にTeX環境か別のPDFエンジンを用意します。入力が複数あれば、Pandocは間に空行を挟んで連結してから解析します。
Claude Codeに任せやすいのは、次の作業です。
- 章ごとに分かれたMarkdownを連結してdocxに変換する
- 変換に失敗したときにエラーを読み、オプションを直して再実行する
- 中間のLaTeXソースを出して、どこで崩れているかを調べる
一方、Wordで開いたときの最終的な見た目の判断は人間の目が要ります。出力ファイルが生成されたかどうかは確かめられますが、Wordでの最終的な体裁は人が開いて判断する工程として残します。
変換条件をdefaultsファイルに固定する
コマンドラインのオプションが長くなると、Claude Codeが呼ぶたびに少しずつ違う引数になり、出力が揺れます。Pandocには、オプションをまとめたYAMLまたはJSONを -d(--defaults)で読ませる仕組みがあります。ファイルは作業ディレクトリ、次にユーザーデータディレクトリの defaults サブディレクトリの順に探されます。
コマンドラインの --toc は toc: true、--number-sections は number-sections: true、--pdf-engine xelatex は pdf-engine: xelatex と対応します。--variable は variables: のマップに書きます。次は、公式の対応表に沿って組んだ日本語PDF向けの例です。
# docs/pandoc/pdf.yaml
from: markdown
pdf-engine: xelatex
toc: true
number-sections: true
variables:
lang: ja
CJKmainfont: "Noto Serif CJK JP"フォント名は、手元のマシンに入っているものに置き換えます。呼び出しは次のようにそろいます。
pandoc -d docs/pandoc/pdf.yaml -o build/report.pdf docs/*.mdコマンドラインで指定した値は、defaultsファイルの設定を上書きまたは拡張します。--css や --variable のように繰り返せるオプションは、置き換えではなく合算される点に注意してください。defaultsに variables を書いたうえで、コマンドラインから -V を足すと、両方が有効になります。
defaultsファイルの中では、ファイルパスのフィールドに限り ${.} が使えます。これは、defaultsファイル自身があるディレクトリを指すので、画像や雛形を相対位置で参照できます。
日本語PDFでつまずく原因は、エンジンとフォント
PDFエンジンの既定は出力形式ごとに決まります。LaTeX経由なら pdflatex、HTML経由なら weasyprint です。選べるエンジンとして、xelatex、lualatex、tectonic、typst などが挙がっています。
日本語を含む文書では、次の関係が効きます。
日本語PDFで効く3つの条件
CJKmainfontを使うならxelatexかlualatex
CJKmainfontは、xelatexならxeCJK、lualatexならluatexjaのパッケージ経由で効きます。マニュアルがCJKmainfontの前提として挙げるエンジンはxelatexとlualatexの2つです。フォールバックはlualatexだけ
mainfontfallbackは、本文フォントにない字形を別フォントで補う設定です。マニュアルには、この設定はlualatexでのみ動作すると書かれています。HTML経由はCSSで決まる
HTMLを中間形式にしたPDFの見た目は
--cssで整えます。日本語フォントはCSSのfont-familyで指定し、PDFエンジンはweasyprintなどを選びます。
TeXを使う場合、xeCJK や fontspec などのパッケージが必要です。マニュアルには、CJKmainfont を設定したときの前提パッケージが、xelatexなら xeCJK、lualatexなら luatexja と明記されています。パッケージが足りないと、変換の途中でLaTeXが止まります。
中間のLaTeXソースを出して切り分ける
PDFの生成が失敗したとき、公式の案内は、-o test.pdf の代わりに -s -o test.tex で中間のLaTeXを出す方法です。出したソースは、pdflatex test.tex などで単独にコンパイルして試せます。日本語の場合は、手元のエンジンに合わせて xelatex test.tex とします。
Claude Codeには、次の順に調べさせると原因が分かれます。
PDFが生成されないときの切り分け
- 1
中間のtexを出力する
pandoc -d docs/pandoc/pdf.yaml -s -o build/debug.tex docs/*.mdを実行し、texが生成されるかを見る。ここで失敗すれば、Markdown側かPandocの設定の問題。 - 2
texを単独でコンパイルする
xelatex build/debug.texを実行する。ここで出るエラーが、足りないパッケージやフォントの手がかりになる。 - 3
エンジンとフォントを見直す
エラーに
xeCJKやフォント名が出ていれば、CJKmainfontの指定と、そのフォントが手元に入っているかを確かめる。
エラーメッセージはTeXの環境ごとに異なるため、ここで特定の文面は示しません。Claude Codeにはログの末尾ではなく、最初に出た ! で始まる行(TeXの典型的なエラー行)から読ませると、連鎖するエラーに惑わされにくくなります。
縦書きなど、日本語の組版を詰めたい場合は、別の手順が要ります。Claude Codeで縦書き日本語PDFを作る手順で、日本語文書クラスを使うLaTeX直書きの方法を扱っています。
docxは雛形ファイルで見た目を決める
docxとodtの体裁は、--reference-doc に渡す雛形で決まります。雛形の中身の文章は無視され、スタイル、余白、ページサイズ、ヘッダーとフッターが新しい文書に引き継がれます。
雛形の作り方は、Pandocが出力する既定の雛形から始めます。
pandoc -o custom-reference.docx --print-default-data-file reference.docx出てきた custom-reference.docx をWordやLibreOfficeで開いて、スタイルだけを直して保存します。マニュアルは、スタイル以外の変更を避けるよう勧めています。docx用のdefaultsファイルは、次のようになります。
# docs/pandoc/docx.yaml
from: markdown
reference-doc: docs/pandoc/custom-reference.docx
toc: true--reference-doc を指定しない場合、Pandocはユーザーデータディレクトリの reference.docx を探し、なければ既定の見た目を使います。つまり、手元のマシンにだけ雛形があると、別の環境で同じ文書が違う見た目になります。雛形をリポジトリに入れて、defaultsファイルから明示的に指すのは、これを避けるためです。
CLAUDE.mdに書く断片と、権限の絞り方
CLAUDE.mdは、Claude Codeがセッション開始時に読む指示ファイルです。公式は、1ファイル200行以下を目安に、具体的で検証できる書き方にするよう案内しています。変換については、コマンドの実体を書くより、defaultsファイルへの入口と守るルールだけを書くと短く済みます。
## 文書の変換(Pandoc)
- PDFは `pandoc -d docs/pandoc/pdf.yaml -o build/<名前>.pdf docs/*.md`
- docxは `pandoc -d docs/pandoc/docx.yaml -o build/<名前>.docx docs/*.md`
- オプションはdefaultsファイルで管理する。コマンドに足さず、必要ならYAMLを直す
- PDFが失敗したら、まず `-s -o build/debug.tex` で中間texを出して調べる
- 入力はUTF-8。Shift-JISの原稿は変換前にUTF-8へ直す
- 変換後は、出力ファイルの存在とサイズを確認して報告する入力の文字コードの行には理由があります。PandocはUTF-8で入力を読み、UTF-8で出力するのが前提です。ローカルの文字コードがUTF-8でない場合は、iconv を通すよう案内されています。Shift-JISの原稿を扱う場合は、Claude CodeでShift-JISを編集できない原因とUTF-8変換の手順も参考になります。
許可ルールはdefaultsファイル指定までに絞る
毎回の許可確認を減らすには、.claude/settings.json に許可ルールを置きます。Bash(pandoc *) のようにサブコマンドを問わず許す書き方は、Pandocの任意のオプションを通します。変換に使うdefaultsファイルを固定するなら、-d までをルールに含めるほうが範囲が狭くなります。
{
"permissions": {
"allow": [
"Bash(pandoc -d docs/pandoc/pdf.yaml *)",
"Bash(pandoc -d docs/pandoc/docx.yaml *)"
]
}
}ルールは、* より前の部分を書かれたとおりに照合します。pandoc -d docs/pandoc/pdf.yaml * は、そのdefaultsファイルを指定した呼び出しだけに一致します。コマンドを && や ; でつないだ場合、各部分が個別にルールと照合されるため、許可ルールを足しただけで連結コマンドまで通ることはありません。
落とし穴
defaultsファイルを書き換えさせると、許可ルールの意味が薄れる
許可ルールがdefaultsファイルのパスで絞っていても、そのYAMLの中身は変更できます。YAMLの編集まで自動承認にしている環境では、変換条件の変更がレビューを通らずに入ります。defaultsファイルとCLAUDE.mdの変更は、通常のコード変更と同じくdiffで確認する運用が前提です。
変換の前後で品質を保つ反復
Pandocは、Markdownの書き方が崩れていても何かしらの出力を返します。そのため、変換が通ったことと、文書が意図どおりであることは別の話です。Claude Codeには、変換の前後に確認の段を置かせると堅くなります。
- 変換前: Markdownの規約違反を直す。見出しの階層や表の書き方は、markdownlint-cli2をフックで回す設定で自動チェックにできる
- 変換: defaultsファイル経由でPDFとdocxを出す
- 変換後: 出力ファイルの有無とサイズを確かめ、失敗時は中間texを出して調べ直す
- 人の確認: 日本語の字形抜け(豆腐)や改ページの位置は、PDFを開いて目で見る
字形抜けは、フォントに含まれない文字が出たときに起きやすい不具合です。mainfontfallback(lualatexのみ)で補えます。Claude CodeにPDFを読ませて字形抜けを探させることはできますが、見落としがないとは言い切れません。本文を機械的に抽出して文字列を照合する方法もあるものの、フォントの描画が正しいかどうかまでは分からないため、最後の目視は省けません。
文書変換のツールをMCP経由で呼ぶ方法もあります。PDFやOfficeファイルを構造化して読み取る用途なら、Docling MCPでローカル文書変換を任せる設定が向いています。Markdownから書き出す方向はPandoc、既存ファイルを読み取る方向はDoclingと、役割が分かれます。
症状別の見る場所
| 症状 | 最初に見る場所 |
|---|---|
| PDFが生成されない | 最初に見る場所LaTeXエンジンの有無。-s -o debug.tex で中間texが出るか |
| 日本語だけが出ない・欠ける | 最初に見る場所pdf-engine が xelatex か lualatex か。CJKmainfont に実在するフォント名を入れたか |
| 豆腐(□)が混じる | 最初に見る場所本文フォントにない字形。lualatexなら mainfontfallback を検討 |
| docxの見た目が環境で違う | 最初に見る場所reference-doc を明示しているか。ユーザーデータディレクトリの reference.docx に依存していないか |
| 日本語の改行・ハイフネーションが変 | 最初に見る場所lang: ja の指定。LaTeXでは lang がハイフネーションを制御する |
| 設定を変えても反映されない | 最初に見る場所defaultsファイルが読まれているか。コマンドラインの指定で上書きされていないか |
lang は、IETFの言語タグでドキュメントの主言語を表す変数です。LaTeXでの出力ではハイフネーションの制御に使われます。日本語文書では、defaultsに lang: ja を書いておくと、言語設定の抜けを防げます。
まとめ
Claude CodeにPandocを任せるときの勘所は、オプションをdefaultsファイルに寄せ、CLAUDE.mdには入口だけを書くことです。日本語PDFは、pdf-engine をxelatexかlualatexにし、CJKmainfont を入れるのが最初の分かれ目になります。docxは雛形をリポジトリに置いて明示的に指すと、環境差が出ません。
許可ルールは、defaultsファイルのパスまで含めて絞れます。ただし、YAML自体を書き換えさせない運用とセットでなければ、絞った意味が薄れます。体裁の最終確認は、PDFやWordを開いて人が見る工程として残すのが現実的です。