概要

このプログラムは、PowerPointファイル(.pptx)からテキストを抽出し、各テキスト要素が箇条書きかどうかを判定します。コマンドライン引数でファイルを指定すると、スライドごとにテキスト、箇条書き状態、シェイプタイプ、プレースホルダータイプを解析し、コンソールに出力します。テキストボックス、プレースホルダー、表など様々な要素に対応し、エラー処理も行います。PowerPointの内容分析や文書変換の前処理に役立ちます。

仕様書

## 1. 概要
このプログラムは、Microsoft PowerPointのプレゼンテーションファイル(.pptx)からテキスト情報を抽出し、各テキスト要素が箇条書きであるかどうかを判定するツールです。抽出されたテキストとその属性(箇条書きかどうか、シェイプタイプ、プレースホルダータイプ)をコンソールに出力します。

## 2. 主な機能
### 1. PowerPointファイルの読み込み
   * コマンドライン引数として指定されたPowerPointファイル(.pptx)を読み込みます。
   * 読み込み対象は.pptxファイルのみです。

### 2. スライドの処理
   * PowerPointファイル内の各スライドを個別に処理します。
   * 各スライドの開始と終了をコンソールに表示します。

### 3. テキスト要素の抽出
   * スライド内の各シェイプからテキストを抽出します。
   * テキストボックス、プレースホルダー、通常の図形など、様々なタイプのシェイプに対応します。

### 4. 箇条書きの判定
   * 各テキスト要素が箇条書きであるかどうかを判定します。
   * 判定基準には、段落レベル、プレースホルダータイプ、箇条書き記号の有無などを使用します。

### 5. シェイプ情報の取得
   * 各テキスト要素のシェイプタイプを取得します。
   * プレースホルダーの場合は、そのタイプも取得します。

### 6. テーブルの処理
   * スライド内のテーブルを検出し、各セル内のテキストを抽出します。

### 7. 出力
   * 抽出されたテキスト、箇条書きかどうかの判定結果、シェイプタイプ、プレースホルダータイプ(該当する場合)をコンソールに出力します。

## 3. 使用方法
1. コマンドラインからプログラムを実行します。
2. 引数として処理したいPowerPointファイル(.pptx)のパスを指定します。
   例:`python script.py path/to/your/powerpoint.pptx`
3. プログラムが自動的にファイルを処理し、結果をコンソールに表示します。

## 4. 出力形式
* 処理開始時に、PowerPointファイル名と総スライド数を表示します。
* 各スライドの開始と終了を示すメッセージを表示します。
* 各テキスト要素について、以下の情報を表示します:
  - テキスト内容
  - 箇条書きかどうか(「はい」または「いいえ」)
  - シェイプタイプ
  - プレースホルダータイプ(プレースホルダーの場合)
* 処理完了時に、処理したスライド数を表示します。

## 5. エラー処理
* コマンドライン引数が正しく指定されていない場合、使用方法を表示して終了します。
* PowerPointファイルの読み込みに失敗した場合、エラーメッセージを表示します。
* 個々のシェイプの処理中にエラーが発生した場合、警告メッセージを表示し、次のシェイプの処理を続行します。
* 全体の処理中に予期しないエラーが発生した場合、エラーメッセージを表示して終了します。

## 6. 注意事項
* このプログラムは、テキスト情報と箇条書きの判定に特化しています。画像、グラフ、アニメーションなどの非テキスト要素は処理しません。
* 複雑なレイアウトや特殊な書式設定を使用したスライドでは、正確な箇条書き判定が困難な場合があります。
* プログラムの出力は人間が読むことを想定しており、他のプログラムによる自動処理には適していない可能性があります。

このプログラムを使用することで、PowerPointプレゼンテーションのテキスト内容を簡単に抽出し、各テキスト要素の属性(箇条書きかどうか、シェイプタイプなど)を確認することができます。これは、プレゼンテーションの内容分析や、テキストベースの文書への変換の前処理として役立ちます。
プログラム
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
from pptx.enum.dml import MSO_THEME_COLOR_INDEX
import sys

class MSO_PLACEHOLDER:
    TITLE = 0
    BODY = 1
    CENTER_TITLE = 2
    SUBTITLE = 3
    DATE_NUMBER = 4
    FOOTER = 5
    HEADER = 6
    OBJECT = 7

def is_bullet_point(paragraph, shape):
    # 段落レベルが0より大きい場合は箇条書き
    if paragraph.level > 0:
        return True
    
    # プレースホルダーの種類に基づいて箇条書きを判定
    if shape.is_placeholder:
        placeholder_type = shape.placeholder_format.type
        if placeholder_type in [MSO_PLACEHOLDER.BODY, MSO_PLACEHOLDER.OBJECT]:
            return True
    
    # 箇条書きの記号(bullet)が設定されているか確認
    if hasattr(paragraph, '_pPr') and paragraph._pPr is not None:
        if hasattr(paragraph._pPr, 'getBullet') and paragraph._pPr.getBullet() is not None:
            return True
    
    return False

def extract_text_from_shape(shape):
    text_data = []
    if shape.has_text_frame:
        text_frame = shape.text_frame
        for i, paragraph in enumerate(text_frame.paragraphs):
            text = paragraph.text.strip()
            is_bullet = is_bullet_point(paragraph, shape)
            
            if text:
                text_data.append((text, is_bullet))
    elif hasattr(shape, 'text') and shape.text.strip():
        # テキストボックス以外のシェイプのテキストを処理
        text = shape.text.strip()
        text_data.append((text, False))  # 箇条書きでないと仮定
    return text_data

def process_shape(shape):
    if shape.shape_type == MSO_SHAPE_TYPE.GROUP:
        for subshape in shape.shapes:
            process_shape(subshape)
    else:
        text_data = extract_text_from_shape(shape)
        for text, is_bullet in text_data:
            print(f"テキスト: {text}")
            print(f"箇条書き: {'はい' if is_bullet else 'いいえ'}")
            print(f"シェイプタイプ: {shape.shape_type}")
            if shape.is_placeholder:
                print(f"プレースホルダータイプ: {shape.placeholder_format.type}")
            print("-" * 30)

def process_table(table):
    for row in table.rows:
        for cell in row.cells:
            text_data = extract_text_from_shape(cell)
            for text, is_bullet in text_data:
                print(f"テキスト (表のセル): {text}")
                print(f"箇条書き: {'はい' if is_bullet else 'いいえ'}")
                print("-" * 30)

def process_slide(slide, slide_number):
    print(f"=== スライド {slide_number} ===")
    for shape in slide.shapes:
        try:
            if shape.shape_type == MSO_SHAPE_TYPE.TABLE:
                process_table(shape.table)
            else:
                process_shape(shape)
        except Exception as e:
            print(f"警告: スライド {slide_number} のシェイプ処理中にエラーが発生しました: {str(e)}")
    print(f"=== スライド {slide_number} 終了 ===\n")

def main(pptx_file):
    try:
        prs = Presentation(pptx_file)
        total_slides = len(prs.slides)
        print(f"PowerPointファイル '{pptx_file}' を処理します。全 {total_slides} スライド。\n")

        for i, slide in enumerate(prs.slides, start=1):
            process_slide(slide, i)

        print(f"処理完了。{total_slides} スライドを処理しました。")
    except Exception as e:
        print(f"エラー: PowerPointファイルの処理中に問題が発生しました: {str(e)}")
        sys.exit(1)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("使用方法: python script.py ")
        sys.exit(1)

    pptx_file = sys.argv[1]
    main(pptx_file)


では、仕様書の修正を行います。修正点としては、プログラムのソースコードに対応しつつ、一貫性と正確性を保つために重要な箇所を整理しました。

---

## 1. 概要
このプログラムは、Microsoft PowerPointのプレゼンテーションファイル(.pptx)をマークダウン形式のテキストファイル(.md)に変換するツールです。ユーザーが選択したPowerPointファイルを解析し、その内容をマークダウン形式で出力します。

## 2. 主な機能
### 1. PowerPointファイルの選択
   * Tkinterを使用したグラフィカルユーザーインターフェース(GUI)を通じて、ユーザーがファイルを選択できます。
   * 変換対象は.pptxファイルのみです。

### 2. スライドの変換
   * 各スライドを個別のセクションとして処理します。
   * マークダウンでは、各スライドの番号はレベル1の見出しとして表示されます(例:`# Slide 1`、`# Slide 2`、`# Slide 3`)。

### 3. スライドタイトルの処理
   * マークダウンでは、スライドタイトルはレベル2の見出しとして表示されます(例:`## スライドタイトル`)。

### 4. テキストボックスの処理
   * テキストボックス内のテキストが箇条書き、番号付きリスト、レベル3の見出し、またはその他の形式であるかを判断します。
   * 箇条書きは、マークダウンでハイフン(`-`)と字下げを使用して表します。
     - 例:
       ```
       - りんご
       - バナナ
       ```
   * ネストされた箇条書きは、さらに字下げを追加します。
     - 例:
       ```
       - 果物
         - りんご
         - バナナ
       ```
   * 番号付きリストは、マークダウンで数字と字下げを使用して表します。
     - 例:
       ```
       1. 果物
          1. りんご
          2. バナナ
       ```
   * 単純なテキストや見出しとして識別されないテキストボックスの内容は、通常の段落として出力します。

### 5. 強調とリンクの処理
   * テキストボックス内の太字やアンダーラインは、マークダウンの強調表現として二重アスタリスク(`**`)を使用します。
   * URLを検出し、マークダウンのリンク形式に変換します(例:`[リンクテキスト](URL)`)。

### 6. 出力
   * 変換されたマークダウン内容は新しいファイルとして保存されます。
   * 元のファイル名を基に、拡張子を.mdに変更して保存します。

## 3. 使用方法
1. プログラムを実行します。
2. ファイル選択ダイアログが表示され、変換したいPowerPointファイル(.pptx)を選択します。
3. 選択が完了すると、変換処理が自動的に開始されます。
4. 変換が完了すると、元のファイルと同じディレクトリに、同じ名前で拡張子が.mdのファイルが作成されます。
5. 処理の結果(成功または失敗)がコンソールに表示されます。

## 4. 出力形式
* 各スライドは`# Slide X`(Xはスライド番号)で始まります。
* スライドのタイトルは`## タイトル内容`として記録されます。
* テキストボックスの内容は、通常のテキスト、箇条書き、番号付きリスト、または見出しとして変換されます。

## 5. エラー処理
* ファイルが選択されなかった場合、プログラムは終了します。
* 指定されたファイルが存在しない場合、エラーメッセージを表示します。
* 変換処理中にエラーが発生した場合、エラーの内容をコンソールに表示します。

## 6. 注意事項
* 複雑なレイアウト、アニメーション、その他の高度な機能は保持されません。

このプログラムを使用することで、PowerPointプレゼンテーションの内容を簡単にマークダウン形式に変換し、テキストベースの文書として再利用することができます。