複数の Markdown ファイルを PDF にバッチ変換する方法
よくある 3 つのバッチタスク:
- 1 つの Markdown → 1 つの PDF を多文書分繰り返す:
md-to-pdf *.md(npm CLI)。 - 複数の Markdown → 1 つの結合 PDF(本、章付きレポート):
pandoc chapter*.md -o book.pdf。 - 複数の Markdown → コミットごとに PDF: GitHub Actions + npm CLI。
ブラウザ版 /markdown-to-pdf はシングルファイル。バッチには CLI が必要です。本記事はコピペコマンドと落とし穴とともに 3 つのシナリオを走ります。
最もシンプルなケース。chapter01.md、chapter02.md、… があり、chapter01.pdf、chapter02.pdf、… が欲しい。
npm install -g md-to-pdf
md-to-pdf 'chapters/*.md'
以上 — デフォルトで各 .md の隣に .pdf を書き出します。スタイルシートで見た目を制御:
md-to-pdf 'chapters/*.md' --stylesheet ./style.css
何百ものファイルを並列化:
find chapters -name '*.md' -print0 | xargs -0 -P 4 -I {} md-to-pdf '{}'
低い並列数から始め、CPU とメモリを見ながら増やします。各ワーカーがブラウザプロセスを起動する場合があります。
本、技術レポート、多ファイルオンボーディングドキュメントに適しています。
pandoc chapter01.md chapter02.md chapter03.md -o book.pdf
落とし穴: ファイル名の順序が重要。Pandoc は引数順、アルファベット順ではありません。シェル展開を意識的に:
pandoc chapter*.md -o book.pdf # alphabetical order, fine if you've zero-padded
目次付き:
pandoc chapter*.md --toc -o book.pdf
章間に LaTeX 改ページ:
pandoc chapter*.md --toc --top-level-division=chapter -o book.pdf
Pandoc をインストールしたくないなら先に連結します:
: > combined.md
for f in chapter*.md; do
cat "$f" >> combined.md
printf '\n\n<div style="page-break-before: always;"></div>\n\n' >> combined.md
done
md-to-pdf combined.md
<div> が章間に改ページを入れます。粗いが安定。
main へのプッシュごとに PDF を生成する GitHub Actions:
# .github/workflows/build-pdfs.yml
name: Build PDFs
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
- run: npm install -g md-to-pdf
- run: md-to-pdf 'docs/**/*.md'
- uses: actions/upload-artifact@v4
with:
name: pdfs
path: 'docs/**/*.pdf'
docs/ 以下のすべての Markdown に md-to-pdf を走らせ、PDF をビルドアーティファクトとしてアップロード。タグプッシュに切り替えると Release に添付できます。
- 結合 PDF で画像パスが壊れる。
chapter01.mdが./images/a.pngを参照している場合、連結したファイルでパスが壊れます。絶対パスに、もしくは data URI として埋め込む、または Pandoc で--resource-path=.を使います。 - front-matter の衝突。 各
.mdに独自の YAML front-matter がある可能性。Pandoc は最初のものを採用、md-to-pdfはファイルごとに独自のものを読みます。衝突するなら連結前に削除。 - 章間でページ番号がリセットされる。 Pandoc は
--top-level-division=chapterで処理。cat-and-convert はしない(番号は連続、本には通常これが望ましい)。 - Unicode / CJK フォント。 Pandoc + XeLaTeX はインストール済みフォントを明示します。例:
--pdf-engine=xelatex -V mainfont:"Source Han Serif CN"。ローカル Chromium は実行環境のフォントを使い、ホスト型は実文字で対応範囲を試します。 - 大規模バッチのメモリ。 ブラウザ系変換は資源を使います。並列数を制限し、メモリを監視し、巨大な処理は再開可能な単位に分けます。
- たまに 1 ファイル →
/markdown-to-pdf。npm インストールより早い。 - 同じテンプレート、数十ファイル、一回限り →
md-to-pdfCLI。 - 同じテンプレート、多ファイル、コミットごと → CI の CLI。
- 本、レポート、複数章 → Pandoc +
--top-level-division=chapter --toc。 - 章ごとに異なるテンプレート → ファイルごとに PDF を生成(シナリオ 1)し、その後
pdfuniteまたはqpdfでマージ。
ツールのトレードオフの詳細は Markdown PDF 方法比較 と PDF でのコードハイライト を参照。
個別の PDF を生成済みで、再レンダリングせずに連結したい場合:
# pdfunite (poppler-utils)
pdfunite chapter01.pdf chapter02.pdf chapter03.pdf book.pdf
# or qpdf
qpdf --empty --pages chapter*.pdf -- book.pdf
# or ghostscript
gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sOutputFile=book.pdf chapter*.pdf
結合は再描画を避けるため内容品質を保てます。所要時間はファイル数、容量、ストレージ、ツールで変わります。
ウェブ /markdown-to-pdf でバッチできますか?
ウェブはシングルファイル。バッチは CLI、スポット使用はウェブ。
バッチでコードハイライトを保つには?
CLI は --stylesheet で渡したものを全ファイルに適用。同じテーマを一貫して使用。詳しくは コードハイライトを保持した Markdown PDF 変換。
結合 PDF の上限は?
共通のページ上限はありません。メモリ、画像、フォント、レンダラー、PDF 閲覧ソフトが影響します。代表的な大文書を試し、CI にタイムアウトを設け、巨大な手引きは分冊してください。
Pandoc はバッチで Mermaid を保ちますか?
ネイティブでは保ちません。pandoc-mermaid-filter が必要、もしくは事前に Mermaid を SVG に変換して参照させます。
何を生成したいかによる:
- 1 対 1 PDF →
md-to-pdf '*.md' - N 対 1 本 →
pandoc chapter*.md --toc -o book.pdf - 連続ビルド → GitHub Actions + npm CLI
- 既存 PDF を連結 →
pdfuniteまたはqpdf
何もインストールしていない一回限りのバッチなら、摩擦の低い道はウェブ /markdown-to-pdf でファイルごとに PDF を作り、pdfunite でマージします。
上記の制限とコマンドは、次の最新一次資料で確認しました:
MarkdownToImage を開いて Markdown を描画し、用途に合う形式を選びます。バッチ自動化の前に代表的な文書 1 件で検証してください。