以前、PPTXスキルとSlideKitの比較記事を書いた。あの記事では「3パターンで同じ事業計画書を生成して比較する」という切り口で、SlideKitの概要と使い分けを紹介した。
あれから開発を続け、レイアウトパターンは15種類から43種類に拡張し、画像生成ツールとの連携や事前構築済みテンプレートライブラリも整備した。本記事では、このパイプラインの設計思想と技術的な仕組みを掘り下げる。「なぜHTMLを中間表現にしたのか」「PPTX変換で崩れないHTMLをどう保証しているのか」といった、前回の記事では触れなかった内部構造の話が中心になる。
GitHub リポジトリ: https://github.com/nogataka/SlideKit
パイプラインの全体像
4つのスキルが連携して動作する。
| スキル | 役割 | 入力 → 出力 |
|---|---|---|
slidekit-create |
HTMLスライドをゼロから生成 | テーマ・要件 → HTML |
slidekit-templ |
既存PDFをHTMLテンプレートに変換 | PDF → HTML |
pptx |
HTMLをPowerPointに変換 | HTML → PPTX |
imgen |
スライド用の画像を生成 | テキスト → PNG |
前回の記事では「PPTXスキル単体 vs SlideKit」という比較に焦点を当てた。今回はこのパイプラインの各レイヤーを順に解説していく。
1. PPTX変換から逆算したHTML制約
このパイプラインの設計上の要は、HTML生成とPPTX変換を分離しつつ、両者の整合性を保つことにある。
HTMLの自由度が高すぎるとPowerPointに変換できない。CSSグリッドや複雑なアニメーションを使ったHTMLは、そもそもPPTXのスライドモデルに対応する構造がない。そこで、HTML側に以下の制約を設けている。
| 制約 | 理由 |
|---|---|
テキストは<p>/<h*>で記述し、<div>内テキストを避ける |
PptxGenJSがテキスト要素として認識できる |
::before/::after擬似要素にテキストを入れない |
擬似要素はDOMツリーに存在しないため変換不能 |
| DOM階層を5〜6レベルに抑える | 深いネストは座標計算の精度を落とす |
Font Awesomeアイコンは<i>タグ+fa-クラス |
コンバータがクラス名でアイコンを検出する |
<table>を使わずflex-basedレイアウトにする |
テーブルのセル結合はPPTX変換で崩れやすい |
装飾要素に-z-10/z-0を付与 |
コンテンツレイヤーと装飾レイヤーを分離する |
これらの制約は、SlideKitのSKILL.md内に定義されており、Claude Codeがスライド生成時に自動的に準拠する。開発者が意識する必要はない。
Chart.jsの例外処理
データ可視化が必要なスライドでは、唯一の例外としてChart.jsを許可している。ただし<canvas>要素はDOM解析できないため、PPTX変換時にはスクリーンショットをPNG画像として埋め込む。
変換後の自動修正
PptxGenJSが生成するPPTXには既知の構造的問題が14件ある。fix_pptx.pyでこれらを自動修正する。
python fix_pptx.py output.pptx
修正対象はphantom slideMaster、invalid adj guides、missing effectLst、empty ln elementsなど。PowerPointで開いたときに「修復が必要です」と表示される問題を防ぐ。
2. デザインの一貫性を担保する仕組み
AIにスライドを生成させると、スライドごとに配色が揺らぐ問題が起きる。「1枚目はネイビー基調だったのに、5枚目でいつの間にかグレーになっている」といった現象が起きる。これを防ぐために3つの仕組みを入れている。
カラーパレットの固定
デッキ全体で使う色を3〜4色に限定し、Tailwindユーティリティクラスとして最初に定義する。
.bg-brand-dark { background-color: #1B3A5C; } /* タイトル、濃い背景 */
.bg-brand-accent { background-color: #2D8B7A; } /* ボーダー、ハイライト */
.bg-brand-warm { background-color: #E8A84C; } /* CTA、バッジ */
実績のあるパレットを10組用意している。
| パレット名 | Primary | Accent | Secondary |
|---|---|---|---|
| Midnight Executive |
#1B2A4A Navy |
#C9A84C Gold |
#F5F1E8 Ivory |
| Forest & Moss |
#2D4A3E Forest |
#8FB573 Moss |
#F2EDE4 Cream |
| Coral Energy |
#FF6B6B Coral |
#FFD93D Gold |
#1B2A4A Navy |
| Ocean Gradient |
#0A1628 Deep Blue |
#0EA5E9 Sky |
#64748B Slate |
| Warm Terracotta |
#C2714F Terracotta |
#E8D5B7 Sand |
#7B9E6B Sage |
ユーザーが「青系で」と指示すれば、Ocean GradientかMidnight Executiveが選ばれる。もちろん、任意のhex値を指定することもできる。
フォントペアリング
日本語フォント(本文・見出し)と欧文フォント(数値・ラベル・ページ番号)を組み合わせる。
| 日本語(Primary) | 欧文(Accent) | 印象 |
|---|---|---|
| Noto Sans JP | Lato | ニュートラル、万能 |
| BIZ UDGothic | Inter | ビジネス、堅実 |
| Noto Sans JP | Roboto | テクノロジー、モダン |
Phase 2(デザイン決定)で確定し、全スライドに統一適用される。
バイリンガル見出し
英語ラベルを小さく添えることで、ビジネス資料としての体裁を整える。
<p class="text-xs uppercase tracking-widest text-gray-400 mb-1 font-accent">
Market Analysis
</p>
<h1 class="text-3xl font-bold text-brand-dark">市場分析</h1>
この構造は43のレイアウトパターンすべてに組み込まれている。
3. 43のレイアウトパターン
前回の記事では15パターンだったレイアウトを、43種類まで拡張した。AIに「自由にレイアウトして」と指示すると、タイトル+箇条書きの単調なスライドが量産される。これを解決するため、DOM構造として事前定義し、スライド構成設計の際にパターン番号で指定する仕組みにした。
パターン一覧
A. 基本レイアウト(1〜7)
| # | パターン名 | 用途 |
|---|---|---|
| 1 | Center | 表紙、Thank You |
| 2 | Left-Right Split | 対比、Before/After |
| 3 | Header-Body-Footer (HBF) | 汎用コンテンツ |
| 4 | HBF + 2-Column | 二項目の並列比較 |
| 5 | HBF + 3-Column | 三要素の紹介 |
| 6 | HBF + N-Column | プロセスフロー |
| 7 | Full-bleed | グラデーション背景、画像オーバーレイ |
B. HBF応用(8〜20)
| # | パターン名 | 用途 |
|---|---|---|
| 8 | HBF + Top-Bottom Split | 上下分割 |
| 9 | HBF + Timeline | ロードマップ、沿革 |
| 10 | HBF + KPI Dashboard | 数値指標の一覧 |
| 11 | HBF + Grid Table | データ表 |
| 12 | HBF + Funnel | 営業パイプライン |
| 13 | HBF + Vertical Stack | 積み上げ型リスト |
| 14 | HBF + 2×2 Grid | 4象限マトリクス |
| 15 | HBF + Stacked Cards | カード型情報 |
| 16 | HBF + TAM/SAM/SOM | 市場規模の同心円 |
| 17 | Chapter Divider | セクション区切り |
| 18 | HBF + Contact | 問い合わせ先 |
| 19 | HBF + 5-Column Process | 5段階プロセス |
| 20 | HBF + VS Comparison | A vs B 比較 |
C〜I. 専門レイアウト(21〜43)
| カテゴリ | # | パターン名 | 用途 |
|---|---|---|---|
| セクション | 21 | Section End / Summary | 要点まとめ |
| セクション | 22 | Table of Contents | 目次、アジェンダ |
| グリッド | 23 | HBF + 2×3 Grid | 6要素の整理 |
| グリッド | 24 | HBF + Icon List | アイコン付きリスト |
| パネル | 25 | HBF + Image Header Panel | 画像ヘッダー付きカード |
| パネル | 26 | HBF + Emphasis Panel | 左ボーダー強調 |
| パネル | 27 | Glass Panel (Dark) | ガラス風パネル |
| パネル | 28 | HBF + Gradient Panel | グラデーションパネル |
| パネル | 29 | HBF + Card Layout with Image | アイコン付きカード型 |
| 背景・画像 | 30 | Right-Side Background Image | 左テキスト+右画像 |
| 背景・画像 | 32 | Multiple Images Split | 複数画像の横並び |
| 引用・強調 | 31 | Quote Slide | 引用文の中央配置 |
| 引用・強調 | 33 | Statistics Emphasis | 大きな数値の強調 |
| 引用・強調 | 34 | Center Message | 一言メッセージ |
| 引用・強調 | 35 | Q&A Slide | 質疑応答 |
| 引用・強調 | 36 | Question Slide | 聴衆への問いかけ |
| 引用・強調 | 37 | Movie / Book Quote | 映画・書籍の引用 |
| 混合 | 38 | HBF + Inline Image | 画像+番号付きテキスト |
| 混合 | 39 | HBF + Statistics Ratio | 縦棒グラフ比較 |
| 混合 | 40 | HBF + Text + Stats Panel | テキスト+統計カード |
| まとめ・事例 | 41 | Summary Glass Vertical | ガラス風まとめ |
| まとめ・事例 | 42 | HBF + Simple List + Supplement | 箇条書き+補足 |
| まとめ・事例 | 43 | HBF + Case Study | 企業事例 |
各パターンのDOM構造はTailwindクラス付きで定義されており、同じパターンが3回以上連続しないよう自動制御される。
DOM構造の例:KPI Dashboard(#10)
具体例として、KPI Dashboardパターンの構造を示す。
<div class="slide bg-white flex flex-col">
<!-- Header -->
<div class="px-12 pt-8 pb-4">
<p class="text-xs uppercase tracking-widest text-gray-400 font-accent">Key Metrics</p>
<h1 class="text-2xl font-bold text-brand-dark">重要指標サマリー</h1>
</div>
<!-- Body: KPI Cards -->
<div class="flex-1 px-12 grid grid-cols-4 gap-6 items-center">
<div class="bg-gray-50 rounded-xl p-6 text-center">
<p class="text-sm text-gray-500">売上高</p>
<p class="text-4xl font-bold text-brand-dark font-accent">¥12.5M</p>
<p class="text-xs text-green-500 mt-1">▲ 15% YoY</p>
</div>
<!-- 他のKPIカード -->
</div>
<!-- Footer -->
<div class="px-12 py-3 flex justify-between text-xs text-gray-400">
<span>Company Name</span>
<span class="font-accent">4</span>
</div>
</div>
Header-Body-Footerの3層構造、flexベースのレイアウト、テキストは<p>/<h1>タグ、DOM階層は5レベル。前述のHTML制約をすべて満たしている。
4. slidekit-createの7フェーズ
前回の記事では8フェーズと紹介したが、ワークフローを整理し7フェーズに再構成した。
Phase 0:テンプレート検出
references/templates/をスキャンし、カスタムテンプレートがあればテンプレートモードに切り替わる。テンプレートモードではデザイン関連の質問(スタイル・テーマ・配色)がスキップされる。
Phase 1:ヒアリング
1問1答形式で要件を確認する。通常モードでの質問項目は以下の9つ。
- 出力ディレクトリ
- コンテンツソース(テキストファイル or 口頭説明)
- プレゼンタイトル
- スライド枚数
- 会社名・ロゴ
- スタイル選択(Creative / Elegant / Modern / Professional / Minimalist)
- テーマ選択(Marketing / Portfolio / Business / Technology / Education)
- カラー希望
- 背景画像の有無
Phase 2:デザイン決定
ヒアリング結果からカラーパレット(3〜4色)、フォントペア(日本語+欧文)、ブランドアイコン(Font Awesome)を確定する。
Phase 3:スライド構成設計
コンテンツを分析し、各スライドに43パターンから最適なレイアウトを割り当てる。ここで「同じパターンが3回以上連続しない」制約が適用される。
Phase 4:HTML生成
各スライドを001.html, 002.html, ...として出力する。1ファイル = 1スライド = 1280×720px。
Phase 5:print.html生成
全スライドをiframeで並べた一覧ページを生成する。俯瞰確認と、ブラウザの印刷機能でのPDF書き出しに使う。
Phase 6:品質チェック
CDNリンク、カラーパレットの一貫性、DOM構造(.slideラッパー)、ファイル数、フォント、フッター・ページ番号を自動検証する。
5. PDFからのデザイン抽出(slidekit-templ)
前回の記事でも軽く触れたが、この機能の内部動作をもう少し詳しく説明する。
既存のプレゼンテーションPDFからデザインを抽出し、HTMLテンプレートとして再利用する。PDFを画像に変換し、各スライド画像をClaude Visionで読み取ってHTMLを書き起こす。
# PDFをスライド画像に分割
python scripts/pdf_to_images.py input.pdf output_dir
# 出力: slide-01.jpg, slide-02.jpg, ...
AIが各画像から抽出する情報は以下の通り。
- カラーパレット(hex値)
- フォントスタイル(セリフ/サンセリフ、ウェイト)
- ヘッダー/フッターのパターン
- 全体のスタイル分類
生成したHTMLはslidekit-createのテンプレートとして登録できる。1セットあたり最大5ファイル。
mkdir -p ~/.claude/skills/slidekit-create/references/templates/my-design
cp output/templ/00[1-5].html ~/.claude/skills/slidekit-create/references/templates/my-design/
6. imgenによる画像生成
スライドの配色に合った画像素材を、Azure OpenAIのgpt-image-1.5で生成する。カラーパレットのhex値をプロンプトに含めることで、デッキ全体と調和した画像が得られる。
# 背景画像の生成
npm run dev --prefix /path/to/imgen -- image gen \
"ミニマルなテクノロジーの抽象的背景、濃紺(#1B3A5C)とティール(#2D8B7A)のグラデーション" \
-q high -s 1536x1024 -o slides/bg-tech.png
# アイコンの生成
npm run dev --prefix /path/to/imgen -- image gen \
"フラットデザインのチームワークイラスト、白背景" \
-q high -s 1024x1024 -o slides/team-icon.png
# 既存画像の配色調整
npm run dev --prefix /path/to/imgen -- image edit \
slides/photo.jpg "カラートーンを濃紺とゴールドに統一" \
-s 1536x1024 -o slides/photo-adjusted.png
| コマンド | 用途 |
|---|---|
image gen |
テキストから画像生成(背景、アイコン、イラスト) |
image edit |
既存画像のAI編集(配色調整、背景変更) |
image explain |
画像の内容説明(ALTテキスト生成) |
| プリセット | サイズ | スライドでの用途 |
|---|---|---|
builtin:landscape |
1536×1024 | 全面背景、ワイド画像 |
builtin:square |
1024×1024 | アイコン、図解 |
builtin:portrait |
1024×1536 | 縦型画像、人物写真 |
builtin:draft |
1024×1024 (low) | ラフ案、プロトタイプ |
7. テンプレートライブラリ
11セットのHTMLテンプレートが事前に用意されている。ゼロからデザインを考える手間を省きたいときに使う。
| テンプレート | 枚数 | テーマ | 用途 |
|---|---|---|---|
| abc-navy | 20 | Navy + Gold | 汎用ビジネス |
| venture-split | 18 | Orange + Green | スタートアップ提案 |
| biz-plan-blue | 20 | Blue + Amber | 事業計画書 |
| greenfield | 20 | Forest Green | 新規事業提案 |
| novatech | 20 | Navy + Orange | テック系提案 |
| skyline | 20 | Cyan + Red | 次世代戦略 |
| ai-proposal | 20 | — | AI事業提案 |
| customer-experience | 13 | M+1 font | CX変革 |
| ai-tech | 11 | — | AI技術紹介 |
| marketing-research | 10 | — | 市場調査レポート |
| digital-report | 11 | Navy + Gold | デジタル戦略 |
# テンプレートの導入
mkdir -p ~/.claude/skills/slidekit-create/references/templates/abc-navy
cp slide-templates/abc-navy/00[1-5].html \
~/.claude/skills/slidekit-create/references/templates/abc-navy/
8. なぜこの設計にしたのか
最後に、このパイプラインの設計判断の背景を整理する。
中間表現としてのHTML
PowerPointを直接生成するアプローチには2つの選択肢がある。PptxGenJS等のライブラリでプログラマティックに組む方法と、テンプレートPPTXのXMLを直接編集する方法がある。前者はレイアウトの表現力に限界があり、後者はXML構造の複雑さに悩まされる。
HTMLを中間表現にすることで、Tailwind CSSでレイアウトの表現力を確保しつつ、ブラウザでの即時プレビューとテキストベースのdiff管理を実現した。
パターンによる品質の底上げ
43のレイアウトパターンは、単なるテンプレート集ではない。PPTX変換の検証が済んだDOM構造の集合体になっている。新しいパターンを追加する際は、変換テストを通過したものだけを採用する。
パイプラインの分離
生成(slidekit-create)、変換(pptx)、素材調達(imgen)、デザイン抽出(slidekit-templ)を独立したスキルとして分離した。各工程を単独で改善・差し替えできる。たとえば、PPTX変換の精度が上がれば、HTML側の制約を緩和できる。画像生成モデルが進化すれば、imgenだけを差し替えればよい。
PDFからの逆変換
slidekit-templにより、既存資料のデザインをHTMLテンプレートとして取り込むサイクルが成立する。社内で蓄積されたデザイン資産をAI生成のベースとして再利用できる。
まとめ
SlideKitは「HTMLを中間表現にしてPPTXに変換する」というシンプルなアイデアから始まった。しかし、実用に耐えるものにするには、PPTX変換から逆算したHTML制約、デザインの一貫性を保つ仕組み、多彩なレイアウトパターン、既存デザインの取り込みパイプラインなど、地味だが不可欠な設計が必要だった。
前回の記事で「どのパターンが合うか」を検討してもらったように、今回は「中身がどうなっているか」を知った上で、自分のワークフローに合わせたカスタマイズを考えてもらえればと思う。
GitHub リポジトリ: https://github.com/nogataka/SlideKit
参考
- PPTXスキルとSlideKitの比較記事 — 本記事の前編にあたる比較検証
- Claude Opus4.6はどのようにPPTXを生成しているか — PPTXスキルの内部動作の解説
- Anthropic公式 PPTXスキル