powerpoint について
PowerPoint Skill は python-pptx を使い、YAML 定義からスライドデッキを生成・管理します。スクリプトでの作成、抽出、更新、検証を行いたいユーザー向けです。
主な機能
- 01YAML による内容とスタイルの定義
- 02スライドデッキの生成と更新
- 03既存 PPTX 内容の抽出
- 04配置と視覚面の検証
- 05画像または SVG への書き出し
活用シーン
- 01構造化データからデッキを生成
- 02デッキ内の特定スライドを更新
- 03レイアウトや視覚上の問題を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ microsoft/ hve-core --skill powerpointインストール後、Claude Code で/powerpointを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
content-extra-py-template.mdcontent-yaml-template.mdpyproject.tomlreferences/script-reference.mdscripts/build_deck.pyembed_audio.pyembed-audio.shexport_slides.pyexport_svg.pyexport-svg.shextract_content.pygenerate_themes.pygenerate-themes.shInvoke-EmbedAudio.ps1Invoke-ExportSvg.ps1Invoke-GenerateThemes.ps1invoke-pptx-pipeline.shInvoke-PptxPipeline.ps1pdf_safety.pypptx_charts.pypptx_colors.pypptx_fills.pypptx_fonts.pypptx_shapes.pypptx_tables.pypptx_text.pypptx_utils.pyrender_pdf_images.pyvalidate_deck.pyvalidate_geometry.py詳細
PowerPoint スキル
python-pptx を使用し、YAML によるコンテンツとスタイルの定義に基づいて、PowerPoint のスライドデッキを生成、更新、管理します。
概要
このスキルには、YAML 設定ファイルを読み込んで PowerPoint のスライドデッキを作成する Python スクリプトが含まれています。各スライドは、レイアウト、テキスト、図形を記述した content.yaml ファイルで定義します。style.yaml ファイルでは、寸法、テンプレート設定、レイアウトのマッピング、メタデータ、既定値を定義します。
SKILL.md では、前提条件、コマンド、スクリプトのアーキテクチャ、API の制約、トラブルシューティングに関する技術情報を説明しています。要素の配置、ビジュアル品質、色とコントラスト、コンテキストに応じたスタイル設定などの規約とデザインルールについては、pptx.instructions.md に従ってください。
前提条件
PowerShell
Invoke-PptxPipeline.ps1 スクリプトは、uv sync による仮想環境の作成と依存関係のインストールを自動で処理します。uv、Python 3.11 以降、PowerShell 7 以降が必要です。
uv のインストール
uv がインストールされていない場合は、公開済みのハッシュ値とダウンロードを照合するパッケージマネージャーを使用してください。
# Windows
winget install --id astral-sh.uv -e
# macOS / Linux (Homebrew)
brew install uv
リリースアーカイブからインストールする場合は、uv リリースページからダウンロードし、展開する前に .sha256 ファイルと照合してください。
システム依存関係(エクスポートと検証)
エクスポートと検証のアクションでは、PPTX から PDF への変換に LibreOffice が必要です。また、PDF から JPG をレンダリングするために、オプションで poppler の pdftoppm を使用できます。pdftoppm が利用できない場合は、PyMuPDF が画像のレンダリングを処理します。
検証アクションのビジョンベースのチェックでは、モデルにアクセスするために GitHub Copilot CLI が必要です。
# macOS
brew install --cask libreoffice
brew install poppler # optional, provides pdftoppm
# Linux
sudo apt-get install libreoffice poppler-utils
# Windows (winget preferred, choco fallback)
winget install TheDocumentFoundation.LibreOffice
# choco install libreoffice-still # alternative
# poppler: no winget package; use choco install poppler (optional, provides pdftoppm)
Copilot CLI(ビジョン検証)
validate_slides.py スクリプトは GitHub Copilot SDK を使用して、スライド画像をビジョン対応モデルに送信します。GitHub Copilot CLI をインストールし、認証を済ませてください。
# Install Copilot CLI
npm install -g @github/copilot-cli
# Authenticate (uses the same GitHub account as VS Code Copilot)
copilot auth login
# Verify
copilot --version
必須ファイル
style.yaml— 寸法、既定値、テンプレート設定、メタデータcontent.yaml— スライドごとのコンテンツ定義(テキスト、図形、画像、レイアウト)- (オプション)
content-extra.py— 複雑なスライド描画用のカスタム Python コード
コンテンツディレクトリの構造
すべてのスライドコンテンツは、作業ディレクトリ内の content/ フォルダーに配置します。
content/
├── global/
│ ├── style.yaml # Dimensions, defaults, template config, and theme metadata
│ └── voice-guide.md # Voice and tone guidelines
├── slide-001/
│ ├── content.yaml # Slide 1 content and layout
│ └── images/ # Slide-specific images
│ ├── background.png
│ └── background.yaml # Image metadata sidecar
├── slide-002/
│ ├── content.yaml # Slide 2 content and layout
│ ├── content-extra.py # Custom Python for complex drawings
│ └── images/
│ └── screenshot.png
├── slide-003/
│ ├── content.yaml
│ └── images/
│ ├── diagram.png
│ └── diagram.yaml
└── ...
グローバルスタイル定義(style.yaml)
グローバルな style.yaml では、寸法、テンプレート設定、レイアウトのマッピング、メタデータ、既定値を定義します。色とフォントはスタイルファイルに一元化するのではなく、各スライドの content.yaml で要素ごとに指定します。
完全なテンプレート、フィールドのリファレンス、使用方法については、style.yaml テンプレートを参照してください。
スライドごとのコンテンツ定義(content.yaml)
各スライドの content.yaml では、レイアウト、テキスト、図形、配置を定義します。位置とサイズの値はすべてインチ単位です。色の値には、#RRGGBB 形式の 16 進数、または @theme_name 参照を使用します。
テキストの仕様:textbox.text と shape.text 内の Markdown 形式のリスト行は、レンダリング時に PowerPoint のリストとして解釈されます。順序なしリストのマーカー(-、+、*)は箇条書きの段落になり、順序付きリストのマーカー(1.、1))は自動番号付きの段落になります。また、行頭のインデントは段落レベルに反映されます。
完全なテンプレート、サポートされている要素の種類と図形の種類、使用方法については、content.yaml テンプレートを参照してください。
アクセシビリティ:各スライドの title は、スクリーンリーダーが読み上げやナビゲーションに使用するスライドタイトルになります。画像の alt または decorative は代替テキストを設定し、style.yaml の metadata.language はドキュメントとテキストの言語を設定します。
複雑な描画(content-extra.py)
content.yaml の要素定義では表現できない複雑な描画が必要なスライドでは、スライドのフォルダーに content-extra.py ファイルを作成してください。render() 関数のシグネチャは固定です。ビルドスクリプトは、標準の content.yaml 要素を配置した後にこの関数を呼び出します。
完全なテンプレート、関数のパラメーター、使用上のガイドラインについては、content-extra.py テンプレートを参照してください。
セキュリティ検証
content-extra.py の実行はデフォルトで無効です。スライドフォルダーにこのファイルが含まれていて、--allow-scripts が指定されていない場合、ファイル名を示すエラーでビルドが失敗します。スクリプトを確認したうえで実行を許可するには、--allow-scripts を指定してください。
実行が許可されると、ビルドスクリプトはファイルを実行する前に AST ベースの静的解析を行い、以下のパターンを拒否します。この解析は、明らかな問題を早期に検出するためのリンターです。セキュリティ境界ではありません。別名を介してブロック対象のモジュールに到達するケースは検出されず、pathlib と open は許可されています。実行を許可するかどうかが制御手段です。
許可されるインポート:
pptxとすべてのpptx.*サブモジュール- 安全な標準ライブラリモジュール(例:
math、copy、json、re、pathlib、collections、itertools、functools、typing、enum、dataclasses、decimal、fractions、string、textwrap)
ブロックされるインポート:
subprocess、os、shutil、socket、ctypes、signal、multiprocessing、threading、http、urllib、ftplib、smtplib、imaplib、poplib、xmlrpc、webbrowser、code、codeop、compileall、py_compile、zipimport、pkgutil、runpy、ensurepip、venv、sqlite3、tempfile、shelve、dbm、pickle、marshal、importlib、sys、telnetlib- 許可リストにないサードパーティパッケージ
ブロックされる組み込み関数:
- 危険な関数:
eval、exec、__import__、compile、breakpoint - 間接的な回避につながる関数:
getattr、setattr、delattr、globals、locals、vars builtins、os、sys、subprocess、importlibに対する属性形式の呼び出し(例:builtins.eval(...))
--allow-scripts フラグ:
content-extra.py ファイルの実行を許可するには、--allow-scripts を指定してください。指定しない場合、スクリプトが存在するとスキップされるのではなくビルドが失敗するため、デッキからカスタム描画が黙って失われることはありません。このフラグは実行を許可するものであり、リンターをスキップするものではありません。
これは動作の変更です。以前は content-extra.py があってもビルドできていたデッキで、今後は --allow-scripts が必要になります。また、ブロック対象のインポートに依存するスクリプトを回避して実行することはできなくなります。
python scripts/build_deck.py \
--content-dir content/ \
--style content/global/style.yaml \
--output slide-deck/presentation.pptx \
--allow-scripts
検証に失敗すると、ビルドは違反内容とファイルパスを示すメッセージとともに ContentExtraError を発生させます。
スクリプトリファレンス
コマンドの全容は references/script-reference.md に記載されています。デッキのビルド、テンプレートからのビルド、特定のスライドの更新、既存の PPTX からのコンテンツ抽出、検証、スライドの画像または SVG へのエクスポート、ドライラン検証、テーマバリエーションの生成、音声の埋め込みを行えます。
スクリプトのアーキテクチャ
ビルドスクリプトと抽出スクリプトでは、scripts/ ディレクトリ内の共有モジュールを使用します。
| モジュール | 用途 |
|---|---|
pptx_utils.py | 共有ユーティリティ:終了コード、ログ設定、スライドフィルターの解析、単位変換(emu_to_inches())、YAML の読み込み |
pptx_colors.py | 色の解決(#hex、@theme、明るさを指定した dict)、テーマカラーのマップ(16 エントリー) |
pptx_fonts.py | フォントの解決、ファミリーの正規化、ウェイト接尾辞の処理、配置のマッピング |
pptx_shapes.py | 図形定数のマップ(29 エントリーと circle エイリアス)、オートシェイプ名のマッピング、回転ユーティリティ |
pptx_fills.py | 単色、グラデーション、パターン塗りつぶしの適用と抽出、破線スタイルによる線/枠線のスタイル設定 |
pptx_text.py | テキストフレームのプロパティ(余白、自動サイズ調整、垂直アンカー)、段落のプロパティ(間隔、レベル)、ランのプロパティ(下線、ハイパーリンク)、箇条書き/自動番号付き段落への Markdown 風リスト解析 |
pptx_tables.py | セルの結合、帯状のスタイル設定、セルごとのスタイル設定に対応したテーブル要素の作成と抽出 |
pptx_charts.py | 12 種類のグラフ(縦棒、横棒、折れ線、円、散布図、バブルなど)のグラフ要素の作成と抽出 |
validate_deck.py | 発表者ノートとスライド数の PPTX 専用検証 |
validate_geometry.py | 要素の端の余白、隣接する要素間の隙間、境界からのはみ出し、タイトルとの間隔に関する構造検証 |
validate_slides.py | 組み込みチェックとスライドごとのプレーンテキスト出力を備えた、Copilot SDK による画像認識ベースのスライド問題の検出と品質検証 |
render_pdf_images.py | PyMuPDF による PDF から JPG へのレンダリング。オプションでスライド番号に基づくファイル名を指定可能 |
generate_themes.py | カラーマッピング YAML ファイルを使用して、ベースコンテンツディレクトリからテーマバリエーションを生成 |
embed_audio.py | スライドごとのファイル照合と画面外へのオーディオアイコン配置による、WAV 音声の PPTX スライドへの埋め込み |
export_svg.py | LibreOffice による PDF 変換と PyMuPDF による SVG レンダリングを利用した、PPTX から SVG へのエクスポート |
python-pptx の制約
- python-pptx は SVG 画像をサポートしていません。必ず
cairosvgまたはPillowを使用して PNG に変換してください。 - python-pptx では、スライドマスターやレイアウトをプログラムから新規作成できません。空白のレイアウトを使用するか、
--template引数でテンプレート PPTX を指定してください。 - 既存ファイルを開いて保存すると、画面切り替えとアニメーションは保持されますが、API から作成または変更することはできません。
- コンテンツを抽出する際は、スライドマスターとレイアウトの継承により、多くのテキスト要素にインラインのスタイル設定がありません。再構築する前に、コンテンツ YAML でフォントプロパティを明示的に追加してください。
- Export と Validate の操作では、PPTX から PDF への変換に LibreOffice が必要です。PowerShell オーケストレーターは開始前に LibreOffice の利用可否を確認し、インストールされていない場合はプラットフォーム別のインストール手順を表示します。
- 継承された背景を持つスライドで
background.fillにアクセスすると、背景がNoFillに置き換わります。塗りつぶしプロパティにアクセスする前に、slide.follow_master_backgroundを確認してください。 - グラデーション塗りつぶしには、
GradientStopオブジェクトを使用する python-pptx のGradientFillAPI を使います。各ストップでは、位置(0~100)と色を指定します。 - テーマカラーは
MSO_THEME_COLOR列挙型を介して解決されます。明るさの調整は、色形式のbrightnessプロパティで行います。 - テンプレートベースのビルドでは、名前またはインデックスでレイアウトを読み込みます。一致するレイアウトが見つからない場合、レイアウト名の解決はインデックス 6(空白)にフォールバックします。
セキュリティ上の考慮事項
このスキルは、MuPDF C ライブラリをラップする PyMuPDF を介して PDF ファイルを処理します。MuPDF は信頼できないバイナリ構造(相互参照テーブル、ストリームオブジェクト、フォント定義)を解析します。過去の CVE では、C パーサーのメモリ安全性に関するバグによって、クラッシュ、メモリ漏えい、まれにコード実行が発生する可能性があることが示されています。
実施済みの緩和策
scripts/pdf_safety.pyはfitz.open()の呼び出し前に、すべての PDF を検証します(ファイルの存在、通常ファイルであること、サイズが 100 MB 以下、%PDF-マジックバイト、ページ数が 1000 以下)。- すべての
fitz操作はsafe_open_pdf()でラップされ、MuPDF の例外は型付きのPdfSafetyErrorサブクラス(PdfTooLargeError、PdfInvalidFormatError、PdfTooManyPagesError、PdfParseError、PdfRenderError)に変換されます。 pymupdfはpyproject.tomlでバージョンを固定し(>=1.27.1,<2.0)、メジャーバージョンの API 変更を予告なく取り込まずにセキュリティ修正を追跡します。
多層防御に関する注意:5 バイトの
%PDF-マジックチェックは必要ですが、構造的な妥当性を保証するには不十分です。%PDF-で始まる細工された小さなファイルでも MuPDF パーサーに渡され、そこにメモリ安全性に関するバグが存在する可能性があります。呼び出し元は、PyMuPDF を最新の勧告に対して必ずパッチ適用した状態に保ち(microsoft/hve-core#1020 /pip-auditで追跡)、そのような入力を引き続き信頼できないものとして扱う必要があります。PdfSafetyErrorの階層(PdfTooLargeError、PdfInvalidFormatError、PdfTooManyPagesError、PdfParseError、PdfRenderError)は、バージョン固定と CVE 監視に加わる防御層の 1 つです。単独で十分な防御層はありません。
許容するリスク
これらの緩和策によって C 拡張機能の攻撃対象領域は縮小しますが、完全には排除されません。このスキルの PPTX から PDF へのパイプライン以外から取得した PDF 入力は信頼できないものとして扱い、悪意ある入力を渡す前に、追加のサンドボックス化(サブプロセス、コンテナー)を適用してください。
更新ポリシー
MuPDF と PyMuPDF に関する勧告を、NVD と OSV で四半期ごとに、また pip-audit の警告が出るたびに再確認してください。
相互参照
- microsoft/hve-core#1018 — 元のセキュリティ強化リクエスト
- microsoft/hve-core#1020 — 継続的な CVE 監視のための pip-audit CI(別の取り組み)
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| SVG の実行時エラー | python-pptx は SVG を埋め込めません | 追加する前に cairosvg で PNG に変換します |
| 要素間でテキストが重なる | 垂直方向の間隔が不十分 | pptx.instructions.md に記載されている要素の配置規則に従います |
| スライド外への幅のはみ出し | 要素がスライドの境界を超えています | pptx.instructions.md に記載されている要素の配置規則に従います |
| 明るいアクセントカラーの塗りつぶしが読みにくい | 明るい背景に白いテキストが配置されています | ボックスの塗りつぶしには、アクセントカラーの彩度を約 60% まで下げます |
| 背景の塗りつぶしが NoFill に置き換わる | 継承された背景で background.fill にアクセスしました | アクセスする前に slide.follow_master_background を確認します |
| 発表者ノートがない | content.yaml でノートが指定されていません | 各コンテンツスライドに speaker_notes フィールドを追加します |
| Validate の実行時に LibreOffice が見つからない | Validate はまずスライドを画像にエクスポートします | LibreOffice をインストールします:brew install --cask libreoffice(macOS) |
uv が見つからない | uv パッケージマネージャーがインストールされていません | uv をインストールします:winget install --id astral-sh.uv -e(Windows)または brew install uv(macOS/Linux)。上記の「uv のインストール」を参照してください |
| uv で Python が見つからない | PATH に Python 3.11 以降がありません | uv python install 3.11 または pyenv install 3.11 でインストールします |
uv sync が失敗する | .venv がないか、破損しています | スキルのルートにある .venv/ を削除して、uv sync を再実行します |
| スクリプトでインポートエラーが発生する | 依存関係がインストールされていないか、仮想環境が古くなっています | スキルのルートで uv sync を実行し、環境を再作成します |
環境の復旧
モジュール不足、インポートエラー、または仮想環境の破損が原因でスクリプトが失敗した場合は、次の手順で復旧します:
cd "<powerpoint-skill-root>"
rm -rf .venv
uv sync
コマンドを実行する前に、読み込まれたスキルの場所から <powerpoint-skill-root> を特定します。
これにより、唯一の信頼できる情報源として pyproject.toml を使用し、仮想環境が最初から再作成されます。Invoke-PptxPipeline.ps1 オーケストレーターは、-SkipVenvSetup が渡されない限り、実行のたびに uv sync を自動的に実行します。
uv 自体が利用できない場合は、まずインストールしてから(上記の「uv のインストール」を参照)、再試行します。Python 3.11 以降が利用できない場合は、uv python install 3.11 を実行して、uv にインタープリターを取得・管理させます。