pptx2md_with_image.py 技術ドキュメント

プログラムの動作

pptx2md_with_image.py は、PowerPoint (PPTX) またはPDFスライドの内容(テキスト、数式、画像)を抽出し、それらを基にAIモデル(OpenAIのGPTシリーズまたはGoogle Gemini)を使って詳細な解説を生成し、Markdown形式のドキュメントとして出力するPythonプログラムです。

主な機能:

  • コンテンツ抽出: PPTXファイルからテキストコンテンツとOMML (Office Math Markup Language) 形式の数式を抽出します。

  • 数式変換: 抽出したOMML形式の数式を、Markdownでレンダリング可能なLaTeX形式に自動変換します。

  • 画像化: PPTXファイルをPDFに変換し、さらに各スライドを高解像度のPNG画像として保存します。PDFファイルを直接入力として使用することも可能です。

  • AIによる解説生成: 抽出されたテキスト、変換されたLaTeX数式、および生成されたスライド画像をAIモデルに送信し、スライドの内容に基づいた詳細な解説文を生成させます。

  • プロンプトカスタマイズ: INIファイルを介してAIへのプロンプトテンプレートを自由にカスタマイズできます。

  • 既存テキストの利用: オプションで、既に抽出済みのテキストファイルを入力として使用し、AIによる解説生成に役立てることができます。

  • 多言語対応: AIに生成させる解説の言語を指定できます。

解決する課題:

PowerPointスライドの内容を手動で詳細な説明ドキュメントに書き起こす作業は時間がかかり、特に数式の正確な記述や図表の解説は手間がかかります。このプログラムは、スライドの内容を自動的に抽出し、AIが画像とテキスト情報を統合して文脈に沿った解説を生成することで、この課題を解決し、効率的なドキュメント作成を支援します。

原理

このプログラムは、以下の主要なステップで構成されており、それぞれのステップで特定の技術やアルゴリズムが利用されています。

  1. PPTXコンテンツの解析と抽出:

    • python-pptx ライブラリを使用してPPTXファイルを読み込みます。

    • スライドのタイトルは、プレースホルダーの種類やテキストフレームの最初の行から抽出されます。

    • スライドの生XMLデータ(slide.part.blob)を lxmletree を用いて解析します。

    • XPathクエリを使用し、以下の要素を抽出します。

      • テキスト: //a:t (DrawingMLのテキスト実行要素)

      • 数式: //m:oMathPara | //m:oMath[not(ancestor::m:oMathPara)] (OMMLの数式段落または単独の数式要素)

    • OMMLからLaTeXへの変換: プログラムの中心的な機能の一つです。omml_to_latex 関数は再帰的にOMMLのXML要素を走査し、対応するLaTeXコマンドに変換します。

      • 要素マッピング:

        • <m:f> (Fraction) は \frac{numerator}{denominator} に。

        • <m:rad> (Root) は \sqrt[degree]{expression} または \sqrt{expression} に。

        • <m:sSup> (Superscript) は base^{superscript} に。

        • <m:sSub> (Subscript) は base_{subscript} に。

        • <m:sSubSup> (Subscript and Superscript) は base_{subscript}^{superscript} に。

        • <m:d> (Delimiter) は (content)[content] などに。

        • <m:nary> (N-ary Operator: , , など) は \sum_{lower}^{upper} content\int_{lower}^{upper} content といった形式に変換されます。演算子の文字は NARY_TO_LATEX マップで対応するLaTeXコマンドに変換されます。

      • Unicode変換: MATH_UNICODE_MAP 辞書を用いて、数学用のUnicode文字(例: 𝑷, , α)を対応するASCII文字やLaTeXコマンドに置換します。

      • 複数行の数式: 抽出されたLaTeXコード内に \\ が含まれる場合、これを区切り文字として数式を分割し、個々のブロック数式 $$ ... $$ として出力します。これはPandocなどのMarkdownレンダリングツールとの互換性を高めるための処理です。

  2. PDF/画像変換:

    • PPTXからPDFへ: pywin32 ライブラリを使用して win32com.client.Dispatch("PowerPoint.Application") を介し、PowerPointアプリケーションをプログラム的に制御して、入力PPTXファイルをPDF形式で保存します。これにより、元のレイアウトやフォントを保持したままスライドの画像を生成するための準備を行います。

    • PDFからPNG画像へ: PyMuPDF (fitz) ライブラリを使用して、PDFファイルの各ページを独立した高解像度PNG画像に変換します。fitz.Matrix(2.0, 2.0) を使用することで、標準よりも高精細な画像を生成します。

  3. AIによる解説生成:

    • プロンプト構築: 抽出されたスライドテキスト、スライド番号、出力言語、およびINIファイルで定義されたカスタムテンプレートを組み合わせて、AIに与えるプロンプトを生成します。

    • API呼び出し:

      • OpenAI APIの場合: OpenAI クライアントを使用し、生成されたPNG画像をBase64エンコードしてプロンプトと共にVisionモデル(例: gpt-4o)に送信します。

      • Google Gemini APIの場合: google.generativeai クライアントを使用し、PNG画像のバイナリデータをプロンプトと共にGeminiモデルに送信します。

    • 数式出力の指示: プロンプトには、AIがMarkdown形式で数式を出力する際に、必ずブロック数式 $$ LaTeX $$ の形式で出力するよう明示的に指示が含まれています。

必要な非標準ライブラリとインストール方法

このプログラムの実行には、以下のPython非標準ライブラリが必要です。pip コマンドでインストールできます。

  • pywin32: PowerPointファイルをPDFに変換するために必要です。(Windows環境のみ)

    pip install pywin32
    
  • PyMuPDF (fitz): PDFファイルをPNG画像に変換するために必要です。

    pip install pymupdf
    
  • python-pptx: PowerPointファイルからテキストやOMML数式を抽出するために必要です。

    pip install python-pptx
    
  • lxml: XML構造から数式要素を効率的に解析・抽出するために必要です。

    pip install lxml
    
  • openai: OpenAI API (GPTモデル) を利用する場合に必要です。

    pip install openai
    
  • google-generativeai: Google Gemini API を利用する場合に必要です。

    pip install google-generativeai
    

必要な入力ファイル

  • 入力プレゼンテーション/ドキュメント (.pptx または .pdf)

    • プログラムが解析し、AIによる解説を生成する対象となるファイルです。

    • 例: my_presentation.pptx, report.pdf

  • 既存のテキストファイル (.txt) (オプション)

    • --txt オプションで指定します。

    • このファイルが存在する場合、PPTXからのテキスト抽出の代わりに、このファイルの内容がスライドごとのテキスト情報として使用されます。

    • ファイルはMarkdown形式で、各スライドのテキストが以下の形式で区切られていることを期待します。

      # Slide 1
      これはスライド1のテキストです。
      数式はここにインラインで記述できます $E=mc^2$。
      
      # Slide 2
      スライド2の主要な議論。
      
  • 設定ファイル (.ini) (オプション)

    • --ini または -i オプションで指定します。指定しない場合、スクリプトと同じディレクトリにある pptx2md_with_image.ini (またはカレントディレクトリ) が探索されます。

    • AIへのプロンプトテンプレートをカスタマイズするために使用します。

    • 例: custom_prompt.ini

    • ファイルの内容は key=value 形式で記述します。特に prompt_template キーでAIへの指示内容を定義します。値は単一行でも、値が「3重引用符」で囲まれていれば複数行でも記述できます。

      # custom_prompt.ini
      prompt_template = """
      あなたは熟練した科学ジャーナリストです。
      以下のスライド番号: {slide_no} の内容を科学的に深く掘り下げて解説してください。
      抽出テキスト:
      {slide_text}
      言語: {lang}
      
      # フォーマット:
      ## 概要
      ## 科学的考察
      ## 今後の研究
      """
      
    • テンプレート内の ${VAR_NAME} 形式の変数は、他のINIエントリの値で置換されます(例: OPENAI_MODEL=${GPT_MODEL})。

生成される出力ファイル

  • Markdown解説ファイル (.md)

    • デフォルトは入力ファイル名と同じステムで .md 拡張子が付いたファイルです(例: my_presentation.md)。-o または --output オプションでファイル名を指定できます。

    • このファイルには、AIによって生成されたスライドごとの詳細な解説がMarkdown形式で格納されます。

    • 各スライドの解説は # Slide N の見出しで区切られ、AIが指示されたフォーマットに従って出力します。

    • 数式は全てブロック数式 $$ ... $$ の形式で出力されます。 例:

      # Analysis Report: my_presentation.pptx
      
      ---
      
      # Slide 1
      
      ## 1. 解説
      このスライドは、理想気体の状態方程式である$PV=nRT$について解説しています。これは、気体の圧力($P$)、体積($V$)、物質量($n$)、気体定数($R$)、温度($T$)の関係を示します。
      
      ## 2. 図・グラフの分析
      [スライド1の図1](my_presentation_work/slides_png/slide_001.png)
      添付画像は、PV=nRTの式と、各変数の説明を示しています。Pは圧力、Vは体積、nはモル数、Rは気体定数、Tは絶対温度を表します。
      
      ## 3. このスライドから読み取れる詳細な情報、データの議論・予測
      理想気体の状態方程式は、多くの熱力学的プロセスの基礎となります。…
      
      $$ P_1V_1 = nRT_1 $$
      
      $$ P_2V_2 = nRT_2 $$
      
      ---
      
      # Slide 2
      ...
      
  • 作業ディレクトリ (<入力ファイル名>_work/)

    • 入力ファイルと同じディレクトリに、入力ファイル名に _work を付加したディレクトリが作成されます(例: my_presentation_work/)。

    • このディレクトリには以下のファイルが格納されます。

      • PDFファイル (<入力ファイル名>.pdf): 元のPPTXファイルから変換されたPDFファイルです。

      • 画像ディレクトリ (slides_png/): 各スライドから変換された高解像度のPNG画像ファイルが格納されます(例: slide_001.png, slide_002.png など)。Markdown出力では、これらの画像への相対パスが埋め込まれます。

コマンドラインでの使用例 (Usage)

プログラムは以下の形式で実行します。

python pptx2md_with_image.py <infile> [-o <output_md_file>] [--txt <existing_text_file>] [--ini <ini_file>] [--api <gemini|openai|openai5>] [--model <model_name>] [--visible] [--language <lang>] [--pause <0|1>]

引数説明:

  • <infile> (必須): 入力するPowerPointプレゼンテーションファイル (.pptx) またはPDFファイル (.pdf) へのパス。

  • -o <output_md_file>, --output <output_md_file> (オプション): 生成されるMarkdownファイルのファイル名。省略した場合、入力ファイル名に基づいて自動的に命名されます(例: my_presentation.md)。

  • --txt <existing_text_file> (オプション): 既に抽出されたスライドテキストを含むMarkdown形式のテキストファイルへのパス。これを使用すると、PPTXからのテキスト抽出ステップをスキップできます。

  • --ini <ini_file>, -i <ini_file> (オプション): プロンプトテンプレートを読み込むINIファイルへのパス。指定がない場合、スクリプト名と同じINIファイル(例: pptx2md_with_image.ini)がカレントディレクトリまたはスクリプトディレクトリから探索されます。

  • --api <gemini|openai|openai5> (オプション): 使用するAIモデルのAPIを指定します。

    • gemini (デフォルト): Google Gemini APIを使用。

    • openai: OpenAI APIの最新モデル(例: gpt-4o)を使用。

    • openai5: OpenAI APIのより高度なモデル(OPENAI_MODEL5 環境変数で指定、デフォルトはgpt-5.2)を使用。

  • --model <model_name> (オプション): --api で指定したAPIで使用する具体的なモデル名を指定します(例: gpt-4o, gemini-1.5-pro)。この引数は、--google_model, --openai_model, --openai_model5 を上書きします。

  • --google_model <model_name> (オプション): Gemini APIで使用するモデル名を指定します (デフォルトは環境変数 GEMINI_MODEL または GOOGLE_MODEL、または gemini-2.5-flash)。

  • --openai_model <model_name> (オプション): OpenAI APIで使用するモデル名を指定します (デフォルトは環境変数 OPENAI_MODEL または gpt-4o)。

  • --openai_model5 <model_name> (オプション): OpenAI APIのより高度なモデル(--api openai5 で使用)を指定します (デフォルトは環境変数 OPENAI_MODEL5 または gpt-5.2)。

  • --visible (オプション): PPTXをPDFに変換する際に、PowerPointアプリケーションのウィンドウを表示します。通常はバックグラウンドで処理されます。

  • --language <lang> (オプション): AIに解説を生成させる言語を指定します (デフォルト: Japanese)。

  • --pause <0|1> (オプション): エラー発生時にプログラムを一時停止するかどうかを制御します (0: しない, 1: する、デフォルト: 0)。

環境変数:

  • OPENAI_API_KEY: OpenAI APIを使用する場合に必要です。

  • GEMINI_API_KEY または GOOGLE_API_KEY: Google Gemini APIを使用する場合に必要です。

コマンドラインでの具体的な使用例

例1: 基本的なPPTXからAI解説生成 (Gemini API利用)

my_presentation.pptx というPPTXファイルの内容を解析し、AI(デフォルトのGemini API)による解説を my_report.md というファイルに保存します。

python pptx2md_with_image.py my_presentation.pptx -o my_report.md

実行結果の説明:

  1. my_presentation.pptx からテキスト、数式、画像を抽出します。

  2. my_presentation_work/ ディレクトリが作成され、その中に my_presentation.pdfslides_png/ ディレクトリ(各スライドのPNG画像を含む)が生成されます。

  3. 各スライドのテキスト、数式、PNG画像がGoogle Gemini APIに送られ、AIがそれぞれのスライドに対する解説を生成します。

  4. 生成された解説はMarkdown形式で my_report.md に追記されていきます。

例2: OpenAI GPT-4oモデルを使用し、INIファイルでプロンプトをカスタマイズ

sales_data.pptx を入力として、OpenAIの gpt-4o モデルを使用し、custom_prompt.ini で定義されたプロンプトテンプレートを用いて英語の解説を生成し、sales_analysis.md に保存します。

python pptx2md_with_image.py sales_data.pptx --api openai --model gpt-4o --ini custom_prompt.ini -o sales_analysis.md --language English

実行結果の説明:

  1. custom_prompt.ini ファイルからカスタムプロンプトテンプレートが読み込まれ、AIへの指示内容が上書きされます。

  2. sales_data.pptx からコンテンツが抽出され、sales_data_work/ ディレクトリに中間ファイルが生成されます。

  3. 抽出されたデータとスライド画像がOpenAI APIに送信され、gpt-4o モデルが英語で解説を生成します。

  4. 生成された解説は、custom_prompt.ini で指定されたフォーマットに従って sales_analysis.md に出力されます。

例3: 既存のテキストファイルとPDFを入力として使用

technical_manual.pdf を入力として、画像はPDFから抽出し、スライドテキストは extracted_text.txt の内容を使用します。AIがこれらを基に解説を生成し、manual_summary.md に出力します。

python pptx2md_with_image.py technical_manual.pdf --txt extracted_text.txt -o manual_summary.md

実行結果の説明:

  1. technical_manual.pdf はPDFファイルとして扱われ、technical_manual_work/slides_png/ に画像が抽出されます。PDFからPPTXへの変換は行われません。

  2. extracted_text.txt ファイルが読み込まれ、プログラムがPPTXからのテキスト抽出を行いません。このファイル内の # Slide N ヘッダーに従って各スライドのテキストがAIに渡されます。

  3. 抽出された画像と extracted_text.txt の内容がAIに送信され、解説が生成されます。

  4. 最終的な解説は manual_summary.md に保存されます。