pptx-html-fidelity-audit について
pptx-html-fidelity-audit は、PowerPoint の書き出し結果を HTML ソースと照合し、レイアウトのずれを修正する再現可能なワークフローです。python-pptx などで生成したスライドの監査に使えます。
主な機能
- 01スライドの図形と書式情報を JSON に抽出
- 02レイアウト境界に沿って内容を確認
- 03はみ出し、切れ、スタイルのずれを検出
- 04カーソル式レイアウトと中央配置を採用
- 05再書き出し後に位置関係を検証
活用シーン
- 01HTML のスライドソースと PPTX を照合
- 02フッターへの重なりやキャンバス外の要素を調査
- 03イタリックやスタイルの欠落を確認
- 04修正したスライドの納品前検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nexu-io/ open-design --skill pptx-html-fidelity-auditインストール後、Claude Code で/pptx-html-fidelity-auditを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/audit-table-template.mdfont-discipline.mdlayout-discipline.mdscripts/.gitignoreextract_pptx.pyverify_layout.py詳細
PPTX ↔ HTML の忠実度監査
python-pptx によるエクスポートが HTML ソースから意図せずずれてしまう箇所を見つけ、その後の作業で同じ問題が再発しないよう、レイアウトの規律に沿って修正するための、繰り返し実行可能なワークフローです。
このスキルが適用されるケース
ユーザーが次のものを持っている場合に適用されます。
-
ソースとなる HTML スライドデッキ(通常は
<section class="slide">ブロックを含む単一ファイルのデッキ):<section class="slide light"> <div class="chrome">2026 · Q2 review</div> <span class="kicker">Pillar 03</span> <h2 class="h-xl">Shipping <em>velocity</em> doubled</h2> <p class="lead">…</p> <div class="foot">page 5 / 14</div> </section> -
そのデッキから python-pptx(または同様のツール)で生成した PPTX ファイル。
-
PPTX が HTML と一致していないという疑い(または目に見える証拠)。たとえば、テキストがフッターに入り込む、斜体の単語が通常の書体になる、ヒーロースライドが中央揃えにならない、セクションが切れる、タグのスタイルが失われる、といった状態です。
ユーザーがこれらの成果物のどちらか一方しか持っていない場合、このスキルはまだ適用できません。まず不足している方を生成するか、ユーザーに提供を依頼してください。
難しい理由(そしてスキルが役立つ理由)
PPTX はキャンバスサイズが固定された絶対配置の媒体です。HTML は可変で、フローに基づく媒体です。単純な python-pptx エクスポートでは、各ブロックを手作業で決めた (top, left) 座標に固定します。その方法は、最初にテストしたスライドでは機能しても、コンテンツの本来の高さが異なるほかのスライドでは気づかないうちに失敗します。その結果、次のような、最もよく見られるずれが発生します。
- フッターへのはみ出し — コンテンツの
top + heightがフッター行に入り込みます。 - キャンバス外へのはみ出し — 最後のブロックの下端が
7.5"(16:9 キャンバス)を超えます。 - 斜体の消失 — HTML の
<em>に対してrun.font.italic = Trueが設定されていません。 - ヒーロースライドが中央揃えにならない — 縦積みのスライドで、中央位置を計算せず
MARGIN_TOPを使っています。 - ボックスの境界がはみ出す — テキストは収まっていても、図形の境界ボックス が大きすぎて、視覚的にレールを越えています。
- タグやスタイルの消失 — 色付きのクローム行、キッカーの大文字トラッキング、等幅フォントとセリフフォントの割り当てが、気づかないうちにデフォルトに戻ります。
これらはいずれも、コンテンツの問題ではなく、レイアウトの規律の問題です。この規律を取り入れれば、こうした問題は発生しなくなります。
ワークフロー
監査は 5 つのステップで行います。どれも省略しないでください。監査によって実際の問題リストを作り、それを再エクスポートに反映してこそ、この規律が機能します。監査なしに修正だけを行うと、問題の半分が残りがちです。
ステップ 1 — PPTX から実際の状態を抽出する
python scripts/extract_pptx.py <path-to.pptx> > pptx_dump.json を実行します。このスクリプトは、すべてのスライド上のすべての図形を調べ、テキスト、位置(top / left)、サイズ(width / height)、およびランごとのタイポグラフィ(フォント名、サイズ pt、太字、斜体、色)を出力します。これはエクスポートの実際の状態です。エクスポートスクリプトの意図を信頼するのではなく、ダンプを信頼してください。
14 枚のスライドのデッキでは、ダンプのサイズは約 30~60 KB で、人が読める形式です。
ステップ 2 — HTML の構造を確認する
ソース HTML を読み、<section class="slide"> ブロックを列挙します。それぞれについて、次の項目を記録します。
- スライドのテーマ(
light/dark/hero light/hero dark)。 chrome行のテキスト(上部のメタデータ)。kicker(見出しの上にある小さな大文字のアイブロウ)。- 見出し(h-hero / h-xl など)とサブ見出し。
- 本文と、構造化されたブロック(パイプラインのステップ、カード、柱、観察カードなど)。
foot行(下部のメタデータ)。<em>または斜体スタイルのスパン。斜体は気づかれにくい回帰です。
各 HTML スライドを PPTX のスライドインデックスに対応付けます。「slide 1 = cover、slide N = closing」という慣例に従うデッキでは、順番に対応付けます。
ステップ 3 — 監査テーブルを作成する
各スライドについて、ダンプ内の図形を順に確認し、想定されるレイアウトルールと照合します。次の形式のテーブルをそのまま使用してください。重大度の列が修正の優先順位を決めます。
| Slide | Issue | Severity |
|---|---|---|
| 1 cover | meta-row 底端 6.95" 蓋過 footer (6.7") | 🔴 |
| 5 checklist | row B 步驟描述底端 7.2" 切到 footer | 🔴 |
| 8 3E | 收束段落直接坐在 footer 起點 | 🔴 |
| 9 on-day | step 描述底端剛好碰 footer,無安全距 | 🟠 |
| 多處 | em (Playfair italic) 未保留 | 🟡 |
重大度の基準:
- 🔴 critical — コンテンツが切れている、テキストが見えない、フッターと重なっている、キャンバス外にはみ出している。必ず修正してください。
- 🟠 high — コンテンツは見えるものの、視覚的な階層が崩れている、余白がない、ヒーローが中央に配置されていない。修正してください。
- 🟡 medium — イタリック/強調が欠落している、フォントのフォールバックが誤っている、色がずれている。この作業で修正してください。
- 🟢 low — 軽微な間隔や配置のずれ、サブピクセル単位のオフセット。記録しますが、作業を止める必要はありません。
テーブルの後に、根本原因を簡潔に記載します。通常、問題の 90 % は 2~3 個のシステム上の原因(例:「フッターレールが適用されていない」「ヒーローのスタックが中央ではなく MARGIN_TOP に固定されている」「イタリックが一切引き継がれていない」)から発生します。システム上の原因を特定すれば、再エクスポート用スクリプトを大幅に簡潔かつ正確にできます。
ステップ 4 — フッターレールとカーソルフローのレイアウト規則に沿って再エクスポートする
これは最も重要なテクニックです。すべてのルールについては references/layout-discipline.md を参照してください。概要は次のとおりです。
デッキ全体で使用するレールを、最初に一度だけ定義します。
from pptx.util import Inches
CANVAS_W = Inches(13.333) # 16:9
CANVAS_H = Inches(7.5)
MARGIN_X = Inches(0.6)
MARGIN_TOP = Inches(0.5)
CONTENT_MAX_Y = Inches(6.70) # NOTHING in content area may cross this
FOOTER_TOP = Inches(6.85) # footer row pinned here, edge-to-edge
レールのカスタマイズ。 上記のデフォルト値は、16:9 のキャンバスと細いフッターに適しています。デザインシステムで広いフッターや 4:3 のキャンバスを使用する場合は、エクスポート用スクリプトでこれらの定数を上書きし、同じ値を
--content-max-y/--canvas-h/--canvas-wを使ってverify_layout.pyに渡してください。定数の一覧についてはreferences/layout-discipline.md§1 を参照してください。
各ブロックを絶対 y 座標に固定するのではなく、コンテンツブロックにはカーソルを使用します。
class Cursor:
"""Advances down the slide; refuses to cross the footer rail."""
def __init__(self, y_start, cap=CONTENT_MAX_Y):
self.y = y_start
self.cap = cap
def take(self, h, gap=Inches(0.12)): # ~1 line of whitespace at 14pt; tighten/loosen per design system
top = self.y
self.y = top + h + gap
if self.y > self.cap:
raise OverflowError(
f"cursor at {self.y} exceeds footer rail {self.cap}; "
f"reduce block height or split slide"
)
return top
各スライドで Cursor(MARGIN_TOP) をインスタンス化し、読み進める順に各ブロックで take(height) を呼び出します。ブロックがレールを越える場合、スライドのレンダリングは拒否されます。そのため、オーバーフローは見逃される視覚的な不具合ではなく、明確なビルドエラーになります。
ヒーロー(垂直中央配置)スライドでは、カーソルではなくバジェットを使用します。
def hero_layout(blocks):
"""blocks = list of (height, gap_after) tuples in reading order."""
total = sum(h + g for h, g in blocks)
y_start = (CANVAS_H - total) / 2
return Cursor(y_start)
この変更だけで、「ヒーロースライドのコンテンツが上部に張り付く」という、最もよくあるヒーローの不具合を解消できます。
テキストと最小限のパディングに収まるよう、ボックスの高さを調整します。 図形が重なると、PowerPoint では図形の境界が表示されます(選択時のハロー、Z オーダーの競合)。また、ボックスが大きすぎると、中のテキストが収まっていてもフッターレールを視覚的に越えることがあります。余裕を持たせたラッパーから高さを決めるのではなく、テキストの寸法に約 0.05" のパディングを加えてボックスの高さを計算してください。
イタリック/強調を明示的に保持します。
def add_run(p, text, font, size_pt, italic=False, bold=False, color=None):
r = p.add_run()
r.text = text
r.font.name = font
r.font.size = Pt(size_pt)
r.font.italic = italic
r.font.bold = bold
if color:
r.font.color.rgb = color
return r
HTML をたどる際に、<em> / <i> / インラインスタイル font-style: italic を検出し、italic=True を渡します。イタリック体の表示テキストには、EN セリフ書体(Playfair Display、Source Serif、または代替の Georgia)を使用してください。CJK セリフ書体には通常イタリック体がないため、イタリックにしようとすると表示が崩れて見えます。
レイアウトレールでは検出できないフォント関連の問題(PowerPoint が Calibri / Microsoft JhengHei にひそかに置き換える可変フォントの落とし穴、<a:ea> スロットの欠落による CJK のテキストランのフォールバック、漢字の疑似イタリック)については、references/font-discipline.md を参照してください。そこに記載されている 5 つのレイヤーで、verify_layout.py では確認できない問題をすべて扱っています。
ステップ 5 — エクスポート後に検証する
新しい .pptx を書き出した後、scripts/verify_layout.py <path-to.pptx> を実行します。このスクリプトは次の処理を行います。
- すべてのスライド上の各図形を調べます。
- コンテンツ図形について
top + height ≤ CONTENT_MAX_Yを検証します(フッター/ページ番号の図形はレールより下に配置できます)。 - すべての図形について
top + height ≤ CANVAS_Hを検証します(キャンバス外へのはみ出しがないこと)。 left + width ≤ CANVAS_Wおよびleft ≥ 0を検証します。- 違反があれば、スライドのインデックス、図形名、実際の下端位置、レールをまとめて報告します。
違反がゼロであることが、「この再エクスポートは出荷可能」と判断する条件です。検証スクリプトを実行せずに監査を修正したと主張しないでください。縮小表示では 1~2 mm のはみ出しを人の目で見逃しますが、スクリプトは見逃しません。
ユーザーへの報告
Step 5 に合格したら、次の内容を報告します。
- 監査テーブル — Step 3 のテーブルです。
- 根本原因 — システム上の原因を1段落で説明します。
- 修正内容 — 変更点とその理由を簡潔に列挙します(例:「ヒーロースライドを予算に合わせた中央揃えに変更」「すべてのコンテンツブロックを Cursor 経由で配置」「em ランを明示的にイタリック体に設定」)。
- 検証結果 — 「N 枚のスライドでレール違反は 0 件、ファイルサイズは X KB」。
- パス — 再エクスポートした
.pptxの絶対パス。
ユーザーが確認したいのは、目に見える不具合が修正されたことと、システム上の修正が適切であることの2点です。両方を説明してください。
同梱リソース
scripts/extract_pptx.py— すべてのスライド上のすべての図形を JSON としてダンプします。監査の前に実行してください。重要: 比較のため、元のエクスポートにも実行し、確認のため再エクスポートしたファイルにも実行してください。scripts/verify_layout.py— エクスポート後のレールチェッカーです。違反がある場合はゼロ以外の終了コードを返すため、必要に応じて CI パイプラインに組み込めます。references/layout-discipline.md— フッターレールとカーソルフローのルール一式。一般的な各スライドタイプ(ヒーロー、コンテンツ、パイプライン、2列、観察グリッド)のコード例が記載されています。references/font-discipline.md— 5層のフォント監査:マッピング、フォントの有無、可変フォントと静的フォントの落とし穴、XML の3つの言語スロット(latin/ea/cs)、CJK とラテン文字のイタリック体の相互作用。references/audit-table-template.md— 重要度の凡例付きで、そのままコピーして使えるテーブルテンプレートです。
次の場合は、参考資料を読んでください。
- デッキに SKILL.md が扱っていないスライドタイプ(複数列のダッシュボード、埋め込み画像、グラフ)がある →
layout-discipline.md。 - 監査で 🟡 のタイポグラフィに関する問題が見つかった場合 — イタリック体が適用されていない、CJK 文字が代替フォントにフォールバックする、XML に予期しない
Calibri/Microsoft JhengHeiが含まれるなど →font-discipline.md。 - 監査テーブルをレポートや Markdown の成果物に直接載せたい →
audit-table-template.md。
避けるべきアンチパターン
- システム上の原因を特定せず、個別のスライドだけを修正する。 スライド 5 のブロックを 0.2" 下げて直すだけでは、次にスライド 9、11、14 も直すことになります。4つの問題すべてを引き起こしたルールを見つけてください。
- 元のエクスポートスクリプトの意図を鵜呑みにする。 必ず実際のファイルに対して抽出スクリプトを実行してください。意図と実際の結果のずれが不具合です。
- 「PowerPoint のプレビューでは問題なさそうだった」という理由で検証を省略する。 プレビューのアンチエイリアスでは、1~2 mm のはみ出しが見えません。スクリプトなら検出できます。
- イタリック体の慣習がない文字体系をイタリック体にする。 CJK、アラビア文字、ヘブライ文字、デーヴァナーガリー、タイ文字、クメール文字に
italic=Trueを強制すると、合成された傾きが生じ、機械的にゆがんだ見た目になります。イタリック体にするのは、主な文字体系がイタリック体に対応しているラン(ラテン文字、キリル文字、ギリシャ文字)に限ってください。実装パターンについてはreferences/font-discipline.mdの Layer 5 を参照してください。 - ヒーロースライドに
MARGIN_TOPを使う。 ヒーロースライドでは上端を基準にするのではなく、予算に合わせて中央揃えにする必要があります。これはヒーロースライドで最もよくある不具合であり、最も手軽に修正できます。
ビジュアル差分ではなく、ジオメトリベースで検証する理由
このスキルの初期バージョンでは、ビジュアル差分に頼っていました。.pptx を Keynote → PDF → PNG の順にレンダリングし、Chrome ヘッドレスで HTML のスクリーンショットを撮り、magick で横に並べていました。うまく機能していましたが、次のような大きな欠点が3つありました。
- プラットフォームへの依存。 Keynote の AppleScript は macOS 専用です。
magickやフォント検出コマンドは OS によって異なり、Linux 上の CI パイプラインでは一連の処理を再現できません。 - 精度の低さ。 1~2 mm のはみ出しは、PNG プレビューではアンチエイリアスによって見えなくなります。人間の目では見逃しますが、スクリプトなら数値による明確な違反として検出できます。
- セットアップの手間。 監査を始める前に、すべてのコントリビューターが一連のグラフィックスツールをインストールする必要があります。ジオメトリチェックに必要なのは
python-pptxだけです。
ジオメトリベースの検証では、ビジュアル差分が得意とすることを1つ諦めることになります。つまり、図形の位置は正しくても、レンダリングされたグリフに問題があるケース(フォントのフォールバック、カーニングの不具合、ウェイトの欠落)を検出できません。そのような場合は、手動でスクリーンショットを確認してください。references/font-discipline.md の5層監査で、根本原因のほとんどを確認できます。