mcpField
E
export-pdf

export-pdf

github.com/bluzirドキュメント10778 回インストール27 週間前に更新
リポジトリ

export-pdf について

export-pdf は、HTML 成果物を PDF に変換するスキルです。文書やスライドの PDF 化に使え、Node.js スクリプトから Puppeteer を実行します。

主な機能

  1. 01HTML 成果物を PDF に変換
  2. 02Puppeteer Page.pdf() を使用
  3. 03既定の出力拡張子は .pdf
  4. 04A4 とインラインのページサイズ CSS に対応

活用シーン

  1. 01HTML ページを PDF 化
  2. 02スライドデッキを PDF に出力

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bluzir/claude-code-design --skill export-pdf

インストール後、Claude Code で/export-pdfを入力して読み込まれたか確認します。

詳細

PDF をエクスポートする

HTML アーティファクトから PDF を作成します。Puppeteer の Page.pdf() を使用します。ソースが HTML/CSS/SVG の場合、ベクター情報を損なわずに出力できます。

Chrome DevTools MCP ではなく Puppeteer を使う理由: MCP からは Page.printToPDF を直接呼び出せず(take_screenshot、list_console_messages、evaluate_script などのみが公開されています)。Node スクリプト経由で Puppeteer を使うことで、処理が確定的になり、/export-pptx と同じ方法で出力できます。

事前確認

  1. Bash(which node) — 必須です
  2. Bash(test -d node_modules/puppeteer && echo yes || echo no) — no の場合は、ユーザーに /doctor の実行を案内するか、npm i -D puppeteer を実行します

手順

  1. パスを解決します:

    • $0 = 入力 HTML(必須)
    • $1 = 出力先(デフォルト:入力ファイルの拡張子を .pdf に変更したもの)
    • 必要に応じて Bash(mkdir -p $(dirname <output>)) を実行します
  2. エクスポートスクリプトを実行します:

    Bash(node scripts/export-pdf.mjs "<input>" "<output>")
    

    (スクリプトは scripts/export-pdf.mjs にあります。存在しない場合は、以下のテンプレートに従って作成します。)

  3. ファイルサイズとパスを報告します。

スクリプトのテンプレート(scripts/export-pdf.mjs)

#!/usr/bin/env node
// Usage: node export-pdf.mjs <input.html> [output.pdf]
import puppeteer from 'puppeteer';
import { pathToFileURL } from 'node:url';
import path from 'node:path';
import fs from 'node:fs/promises';

const [, , input, output = input.replace(/\.html?$/i, '.pdf')] = process.argv;
if (!input) { console.error('Usage: export-pdf.mjs <input.html> [output.pdf]'); process.exit(1); }

const inAbs = path.resolve(process.cwd(), input);
const outAbs = path.resolve(process.cwd(), output);

const browser = await puppeteer.launch({ args: ['--no-sandbox'] });
const page = await browser.newPage();
await page.goto(pathToFileURL(inAbs).toString(), { waitUntil: 'networkidle0' });

// If it's a deck, set noscale so deck-stage renders at natural dims
const deckDims = await page.evaluate(() => {
  const d = document.querySelector('deck-stage');
  if (!d) return null;
  d.setAttribute('noscale', '');
  return [parseInt(d.getAttribute('width') || '1920', 10), parseInt(d.getAttribute('height') || '1080', 10)];
});

await page.emulateMediaType('print');
const pdfOpts = {
  path: outAbs,
  printBackground: true,
};
if (deckDims) {
  // Deck: one section per page — @media print in deck_stage.js handles page-break
  pdfOpts.width = `${deckDims[0]}px`;
  pdfOpts.height = `${deckDims[1]}px`;
  pdfOpts.pageRanges = '';
} else {
  pdfOpts.format = 'A4';
}

await page.pdf(pdfOpts);
await browser.close();

const stat = await fs.stat(outAbs);
console.log(`wrote ${outAbs} (${(stat.size / 1024).toFixed(1)} KB)`);

メモ

  • スライド資料の場合:deck_stage.js が挿入するグローバルな <style> に、@media print { @page { size: ... } section { page-break-after: always } } が必要です。これはすでに設定されています。
  • 一般的なページの場合:デフォルトは A4 です。サイズを変更するには、ユーザーは @page { size: letter } などの CSS をインラインで指定できます。
  • networkidle0 はすべてのネットワークアクティビティが停止するまで待機します。アーティファクトで遅延読み込み画像を使用する場合は、タイムアウトを 15000ms に延長してください。

コメント