add_notes_pptx.py 技術ドキュメント
プログラムの動作
add_notes_pptx.py は、Microsoft PowerPoint(.pptx)ファイルを操作するためのPythonスクリプトです。主な目的は、PowerPointスライドのノート情報を活用して、プレゼンテーションの表示内容を強化または自動化することです。
本プログラムは以下の2つの主要な機能モードを提供します。
addモード:各スライドに添付されているノートのテキスト内容を読み込みます。
読み込んだノート内容を、スライドの下部に半透明の字幕テキストボックスとして追加します。
字幕ボックスのフォント、サイズ、色、背景色、透明度、位置(余白、高さ)はコマンドライン引数で細かく設定可能です。
これにより、発表者はスライドノートを別途参照することなく、プレゼンテーション中に重要な情報を視覚的に提示できるようになります。
replaceモード:スライド内のテキストに含まれる
{{key}}形式のプレースホルダーを、事前に定義された値で置換します。置換する値は、コマンドラインで指定するTOML風の
key=value形式のファイルから読み込まれます。さらに、各スライドに添付されているノート内容も
{{supertitle}}という特別なキーの値として利用され、ファイル側の指定よりも優先されます。このモードの重要な特徴は、既存のテキスト書式(フォント、色、サイズなど)やアニメーションを保持したまま、指定された部分のみを置換することです。
これにより、テンプレートスライドの特定の情報を動的に変更したり、プレゼンテーションのパーソナライズを効率的に行ったりすることが可能になります。
本プログラムは、PowerPointのノート機能をより柔軟に活用したいユーザーや、定型的なプレゼンテーションのテキスト更新作業を自動化したいユーザーの課題を解決します。
原理
add_notes_pptx.py は、Windows環境でMicrosoft PowerPointアプリケーションをCOM(Component Object Model)経由で操作するために、win32com.client ライブラリを利用しています。
共通処理: ノート本文の取得と整形
PowerPointアプリケーションとの連携:
ppt = win32com.client.Dispatch("PowerPoint.Application")このコードにより、PowerPointアプリケーションのインスタンスが取得され、スクリプトからPowerPointを制御できるようになります。プレゼンテーションのオープン:
presentation = ppt.Presentations.Open(args.infile, WithWindow=False)指定された入力PowerPointファイルを非表示モードで開きます。ノート本文の取得:
get_notes_text(slide)関数は、各スライドのノートページからテキストを抽出します。具体的には、ノートページのシェイプコレクション内のPlaceholders(2)(通常はノート本文のプレースホルダー)からTextFrame.TextRange.Textを読み込みます。テキストの整形:
clean_text(text)関数は、取得したテキストから空行や空白文字のみの行を除去し、整形されたテキストを返します。これにより、ノートに記述された余分な改行などが取り除かれます。
add モード: 字幕テキストボックスの追加
スライド寸法の取得:
presentation.PageSetup.SlideWidthおよびpresentation.PageSetup.SlideHeightを利用して、スライド全体の幅と高さを取得します。字幕ボックスの位置とサイズの計算: コマンドライン引数で指定された左右余白 (
box_margin) と高さ (box_height)、およびスライド全体の寸法に基づいて、字幕テキストボックスのLeft、Top、Width、Heightを計算します。Topの計算では、スライド下部から一定の余白を取って配置されます。テキストボックスの追加:
slide.Shapes.AddTextbox(Orientation=1, Left=..., Top=..., Width=..., Height=...)スライドに新しいテキストボックスを追加します。Orientation=1は水平方向のテキストを意味します。テキストとスタイルの設定:
shape.TextFrame.TextRange.Text = note_textで、整形済みのノートテキストをボックスに設定します。TextRange.Font.Name、TextRange.Font.Size、TextRange.Font.Color.RGBでフォント、サイズ、色を設定します。色のRGB値は、引数で受け取った16進数文字列(例: "884444")をint(args.font_color, 16)で10進数に変換して使用します。shape.Fill.ForeColor.RGB、shape.Fill.Transparency、shape.Fill.Visible = True、shape.Fill.Solid()で背景色と透明度を設定し、塗りつぶしを有効にします。
replace モード: プレースホルダーの置換
TOML風ファイルのパース:
parse_toml_style(filepath)関数は、key=value形式のテキストファイルを読み込み、辞書として解析します。正規表現
r'^\s*([a-zA-Z0-9_]+)\s*=\s*(.*?)\s*(?:#.*)?$'を使用して、行頭・行末の空白、コメント行(#で始まる)、キーと値の間の=を柔軟に処理します。値がシングルクォート
'またはダブルクォート"で囲まれている場合は、それらを除去します。
置換マップの構築:
replace_placeholders_on_slide関数内で、読み込んだ基本マップ(base_map)に、現在のスライドのノート内容をsupertitleキーとして追加します。このsupertitleはbase_map内の同じキーよりも優先されます。スライド内のシェイプの再帰的走査:
_replace_in_shapesおよび_replace_in_shape_deep関数は、スライド内のすべてのシェイプを走査します。グループ化されたシェイプ:
shp.Type == 6(msoGroup) の場合、shp.GroupItemsを再帰的に走査します。表 (Table):
shp.HasTableの場合、表の各セルtbl.Cell(r, c).Shapeを取得し、そのシェイプに対して置換処理を行います。通常のテキストフレーム: 上記以外のテキストフレームを持つシェイプに対しては、
_replace_in_textframeを呼び出します。
プレースホルダーの部分置換:
_replace_in_textframe(shp, kv)関数が置換処理の中核を担います。shp.TextFrame.TextRangeオブジェクトを取得し、そのFindメソッドを利用して、{{key}}形式のプレースホルダーを検索します。Find(FindWhat=placeholder, After=after_pos, ...)をループで繰り返し呼び出すことで、テキスト全体からすべてのプレースホルダーを見つけ出します。プレースホルダーが見つかると、
tr_hit.Text = valueのように、win32comが提供するTextRangeオブジェクトのTextプロパティを直接書き換えます。この操作により、テキストの書式設定(フォント、色、サイズ、太字、斜体など)や、そのテキストに適用されているアニメーション、ハイパーリンクなどの属性を維持したまま、テキスト内容だけを更新することが可能です。これは、PowerPoint COM API の強力な機能の一つです。
全体の終了処理
処理完了後、presentation.SaveAs(args.outfile) で変更を新しいファイルに保存し、presentation.Close() でプレゼンテーションを閉じ、ppt.Quit() でPowerPointアプリケーションを終了します。最後に terminate() 関数がユーザーにEnterキーの入力を促し、プログラムを終了します。
必要な非標準ライブラリとインストール方法
このプログラムは、Microsoft PowerPointのCOMオブジェクトを操作するために pywin32 ライブラリに依存しています。
ライブラリ名:
pywin32インストール方法: 以下の
pipコマンドでインストールできます。pip install pywin32
必要な入力ファイル
入力PowerPointファイル (.pptx)
形式: Microsoft PowerPoint 2007以降の
.pptx形式のファイル。目的:
addモードの場合: ノートを字幕として追加する元のプレゼンテーションファイル。replaceモードの場合:{{key}}プレースホルダーを含むプレゼンテーションファイル。
データ構造: 各スライドのノートページにテキストデータが含まれていることが想定されます。
replaceモードでは、スライド内のテキストボックスや表のセルに{{key}}形式のプレースホルダーが含まれていることが期待されます。
置換用のTOML風
key=valueファイル (任意)形式: 任意の拡張子(例:
.txt,.toml,.conf)を持つプレーンテキストファイル。目的:
replaceモードで使用され、{{key}}プレースホルダーを置換するためのキーと値のペアを提供します。データ構造:
各行に
key = valueの形式で記述します。行頭/行末の空白は無視されます。
#で始まる行はコメントとして無視されます。値はクォート (
"または') で囲むこともでき、その場合はクォートが剥がされます。例:
title = "プロジェクト概要" date = '2023-10-27' version = 1.0 # これはコメント行です author = John Doe
注意: このファイルが指定されない場合、
replaceモードでは各スライドのノート内容({{supertitle}})のみが置換対象となります。
生成される出力ファイル
本プログラムは、常に新しいPowerPointファイルを出力します。入力ファイルは変更されません。
ファイル形式:
.pptxファイル名:
コマンドラインで
-oまたは--outfileオプションを使って出力ファイル名を明示的に指定した場合、そのファイル名が使用されます。出力ファイル名が指定されなかった場合、入力ファイル名に基づいて以下の規則で自動生成されます。
addモード: 入力ファイル名の末尾に-note-added.pptxが付加されます。例:
MyPresentation.pptx→MyPresentation-note-added.pptx
replaceモード: 入力ファイル名の末尾に-replaced.pptxが付加されます。例:
MyPresentation.pptx→MyPresentation-replaced.pptx
内容:
addモード: 入力PowerPointファイルに、各スライドのノート内容が半透明の字幕テキストボックスとして追加されたプレゼンテーション。replaceモード: 入力PowerPointファイルのスライド内の{{key}}プレースホルダーが、指定された置換マップ(TOML風ファイルおよびスライドノート)に従って置換されたプレゼンテーション。既存の書式やアニメーションは保持されます。
コマンドラインでの使用例 (Usage)
add_notes_pptx.py スクリプトの基本的な使用方法は以下の通りです。
python add_notes_pptx.py [-h] [-o OUTFILE] [--mode {add,replace}] [--replace REPLACE]
[--box_margin BOX_MARGIN] [--box_height BOX_HEIGHT]
[--font_name FONT_NAME] [--font_size FONT_SIZE]
[--font_color FONT_COLOR] [--bgcolor BGCOLOR]
[--bgalpha BGALPHA]
infile
infile: 必須。処理する入力PowerPointファイル(.pptx)のパス。-o OUTFILE,--outfile OUTFILE: オプション。生成される出力PowerPointファイルのパス。省略した場合、入力ファイル名に基づき自動生成されます。--mode {add,replace}: オプション。スクリプトの動作モードを指定します。add: ノートを字幕テキストボックスとして追加します。(デフォルト)replace:{{key}}プレースホルダーを置換します。
-R REPLACE,--replace REPLACE:replaceモードの場合に必須。置換用のkey=value形式のファイルパス。
add モード固有のオプション:
--box_margin BOX_MARGIN: 字幕ボックスの左右余白(pt)。デフォルトは50。--box_height BOX_HEIGHT: 字幕ボックスの高さ(pt)。デフォルトは60。--font_name FONT_NAME: フォント名。デフォルトはメイリオ。--font_size FONT_SIZE: フォントサイズ(pt)。デフォルトは12。--font_color FONT_COLOR: 文字色(16進RGB形式)。デフォルトは884444。--bgcolor BGCOLOR: 背景色(16進RGB形式)。デフォルトは00dddd。--bgalpha BGALPHA: 背景の透明度(0.0〜1.0)。デフォルトは0.6。
コマンドラインでの具体的な使用例
1. add モードでの字幕追加
入力ファイル presentation.pptx のノートを読み込み、緑の背景に白文字で半透明の字幕を追加し、presentation-note-added.pptx として出力します。
python add_notes_pptx.py presentation.pptx --mode add --font_name "Yu Gothic UI" --font_size 14 --font_color FFFFFF --bgcolor 008800 --bgalpha 0.7
実行結果の説明:
presentation.pptx の各スライドのノート内容が、スライド下部に新しいテキストボックスとして追加されます。このテキストボックスは「Yu Gothic UI」フォント、サイズ14pt、白色の文字、濃い緑色(008800)の背景、透明度70%(0.7)で表示されます。出力ファイルは presentation-note-added.pptx という名前で保存されます。
2. replace モードでのプレースホルダー置換
入力ファイル template.pptx 内の {{key}} プレースホルダーを、replace_data.txt の内容と各スライドのノート内容で置換し、template-replaced.pptx として出力します。
replace_data.txt の内容例:
project_name = "新製品ローンチ計画"
client_name = "XYZ株式会社"
template.pptx の1枚目のスライドに「{{project_name}}へようこそ」というテキストがあり、そのスライドのノートに「今後の計画」と書かれていると仮定します。
python add_notes_pptx.py template.pptx --mode replace --replace replace_data.txt -o output_final.pptx
実行結果の説明:
replace_data.txt に定義された project_name と client_name の値が読み込まれます。
template.pptx のスライドを走査し、例えば「{{project_name}}へようこそ」というテキストは「新製品ローンチ計画へようこそ」に置換されます。
また、各スライドのノート内容が {{supertitle}} キーに対応するため、スライド内に {{supertitle}} があれば、そのスライドのノート内容(例:「今後の計画」)で置換されます。
元のテキストのフォント、サイズ、色などの書式設定は維持されたまま置換が行われます。出力ファイルは -o オプションで指定された output_final.pptx として保存されます。
実行後のコンソールには、置換された箇所の総数が表示され、「注:ノートを置換する場合は {{supertitle}} を使ってください」というメッセージも表示されます。