パブリックAPIが利用可能になりました!MarkdownをAPIで画像に変換、毎月50回まで無料。
ブログに戻る
1970年1月1日木曜日

複数の Markdown ファイルを PDF にバッチ変換する方法

複数の Markdown ファイルを PDF にバッチ変換する方法

短い答え

よくある 3 つのバッチタスク:

  1. 1 つの Markdown → 1 つの PDF を多文書分繰り返す: md-to-pdf *.md(npm CLI)。
  2. 複数の Markdown → 1 つの結合 PDF(本、章付きレポート): pandoc chapter*.md -o book.pdf
  3. 複数の Markdown → コミットごとに PDF: GitHub Actions + npm CLI。

ブラウザ版 /markdown-to-pdf はシングルファイル。バッチには CLI が必要です。本記事はコピペコマンドと落とし穴とともに 3 つのシナリオを走ります。

シナリオ 1 — N → N(Markdown ファイルごとに PDF)

最もシンプルなケース。chapter01.mdchapter02.md、… があり、chapter01.pdfchapter02.pdf、… が欲しい。

npm install -g md-to-pdf
md-to-pdf 'chapters/*.md'

以上 — デフォルトで各 .md の隣に .pdf を書き出します。スタイルシートで見た目を制御:

md-to-pdf 'chapters/*.md' --stylesheet ./style.css

何百ものファイルを並列化:

ls chapters/*.md | xargs -P 4 -I {} md-to-pdf {}

-P 4 で 4 つを並列。 4-8 を越えると Chromium 起動コストがボトルネックに。

シナリオ 2 — N → 1(複数の .md を 1 つの PDF に)

本、技術レポート、多ファイルオンボーディングドキュメントに適しています。

Pandoc(順序付き章に最適)

pandoc chapter01.md chapter02.md chapter03.md -o book.pdf

落とし穴: ファイル名の順序が重要。Pandoc は引数順、アルファベット順ではありません。シェル展開を意識的に:

pandoc chapter*.md -o book.pdf  # アルファベット順、ゼロ埋めなら OK

目次付き:

pandoc chapter*.md --toc -o book.pdf

章間に LaTeX 改ページ:

pandoc chapter*.md --toc --top-level-division=chapter -o book.pdf

Cat-and-Convert(どの Markdown→PDF ツールでも動く)

Pandoc をインストールしたくないなら先に連結します:

echo "" > combined.md
for f in chapter*.md; do
  cat "$f" >> combined.md
  echo -e "\n\n<div style=\"page-break-before: always;\"></div>\n\n" >> combined.md
done
md-to-pdf combined.md

<div> が章間に改ページを入れます。粗いが安定。

シナリオ 3 — CI/CD(コミット毎に PDF)

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: 20
      - 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 に添付できます。

よくある落とし穴

  1. 結合 PDF で画像パスが壊れる。 chapter01.md./images/a.png を参照している場合、連結したファイルでパスが壊れます。絶対パスに、もしくは data URI として埋め込む、または Pandoc で --resource-path=. を使います。
  2. front-matter の衝突。.md に独自の YAML front-matter がある可能性。Pandoc は最初のものを採用、md-to-pdf はファイルごとに独自のものを読みます。衝突するなら連結前に削除。
  3. 章間でページ番号がリセットされる。 Pandoc は --top-level-division=chapter で処理。cat-and-convert はしない(番号は連続、本には通常これが望ましい)。
  4. Unicode / CJK フォント。 中国語/日本語/韓国語: Pandoc は XeLaTeX で --pdf-engine=xelatex -V mainfont:"Source Han Serif CN" が必要。Headless Chromium ツール(md-to-pdf/markdown-to-pdf)はシステムのフォントスタックを引き継ぎ、そのまま動作します。
  5. 大規模バッチのメモリ。 500+ ファイルを md-to-pdf で処理すると Chromium を何百回も起動します。xargs -P で並列化し、CPU コア数で制限を。

ウェブ vs CLI の使い分け

  • たまに 1 ファイル/markdown-to-pdf。npm インストールより早い。
  • 同じテンプレート、数十ファイル、一回限りmd-to-pdf CLI。
  • 同じテンプレート、多ファイル、コミットごと → CI の CLI。
  • 本、レポート、複数章 → Pandoc + --top-level-division=chapter --toc
  • 章ごとに異なるテンプレート → ファイルごとに PDF を生成(シナリオ 1)し、その後 pdfunite または qpdf でマージ。

ツールのトレードオフの詳細は Markdown PDF 方法比較PDF でのコードハイライト を参照。

既存 PDF のマージ

個別の PDF を生成済みで、再レンダリングせずに連結したい場合:

pdfunite chapter01.pdf chapter02.pdf chapter03.pdf book.pdf
qpdf --empty --pages chapter*.pdf -- book.pdf
gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sOutputFile=book.pdf chapter*.pdf

再レンダリングしないのでロスなし、高速(100 ファイルで1 秒以内)。

よくある質問

ウェブ /markdown-to-pdf でバッチできますか?

ウェブはシングルファイル。バッチは CLI、スポット使用はウェブ。

バッチでコードハイライトを保つには?

CLI は --stylesheet で渡したものを全ファイルに適用。同じテーマを一貫して使用。詳しくは コードハイライトを保持した Markdown PDF 変換

結合 PDF の上限は?

実質無限 — 5000 ページでも動いた。実際には:PDF リーダーは ~1000 ページを越えると検索が遅くなり、メール添付は大体 25 MB 上限。巨大ドキュメントは巻で分けましょう。

バッチ変換 API はありますか?

あります — Markdown to Image APIformat=pdf をサポートし、HTTP を叩ける言語ならどこからでもバッチできます。

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 でマージします。

複数の Markdown ファイルを PDF にバッチ変換(CLI、Pandoc、CI) | MarkdownToImage