Claude Media
Claude CodeでPandocを使う — Markdownからdocx・日本語PDFへ変換

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. 1

    中間のtexを出力する

    pandoc -d docs/pandoc/pdf.yaml -s -o build/debug.tex docs/*.md を実行し、texが生成されるかを見る。ここで失敗すれば、Markdown側かPandocの設定の問題。

  2. 2

    texを単独でコンパイルする

    xelatex build/debug.tex を実行する。ここで出るエラーが、足りないパッケージやフォントの手がかりになる。

  3. 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には、変換の前後に確認の段を置かせると堅くなります。

  1. 変換前: Markdownの規約違反を直す。見出しの階層や表の書き方は、markdownlint-cli2をフックで回す設定で自動チェックにできる
  2. 変換: defaultsファイル経由でPDFとdocxを出す
  3. 変換後: 出力ファイルの有無とサイズを確かめ、失敗時は中間texを出して調べ直す
  4. 人の確認: 日本語の字形抜け(豆腐)や改ページの位置は、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を開いて人が見る工程として残すのが現実的です。

この記事を共有:XはてブLinkedIn