INI Viewer (iniview.pyw) 技術ドキュメント

プログラムの動作

iniview.pyw は、INI形式のファイルや一般的なテキストファイルを視覚的に閲覧および解析するためのグラフィカルユーザーインターフェース (GUI) ツールです。特に、従来のINIパーサーでは扱いにくい複数行の値(3重引用符で囲まれたテキストブロック)を含むINIファイルの閲覧に特化しています。

主な機能は以下の通りです。

  • ファイル読み込み: INIファイル、Pythonスクリプト、C/C++ソースコード、Fortranソースコードなど、指定されたファイルを読み込み、その内容を表示します。

  • INIファイル解析と表示:

    • キーと値のペアをツリービューで階層的に表示します。キーは \ を区切り文字として解釈され、ツリー構造を形成します。

    • 値が「3重引用符」で囲まれた複数行のテキストである場合でも、その内容を正しく解析し、エディタペインに表示します。

  • 汎用テキストファイル表示: .ini 以外の拡張子のファイルを読み込んだ場合、そのファイルの内容全体を単一のテキストとしてエディタペインに表示します。

  • 検索機能: キーまたは値の内容に基づいてツリービュー内の項目を検索し、結果をハイライトしてナビゲートできます。

  • コピー機能: ツリービューで選択された項目の値をクリップボードにコピーしたり、エディタペイン内の選択範囲をコピーしたりできます。

  • 表示オプション: エディタペインのテキスト折り返し(ワードラップ)のON/OFFを切り替えることができます。

  • ウィンドウ設定の永続化: ウィンドウのサイズと位置、ペインの分割位置、最後に開いたファイルのパスを iniview.ini ファイルに保存し、次回の起動時に復元します。

  • 外部ツール連携: 設定ファイル iniview.ini に外部コマンドを登録することで、ツールのメニューから直接、登録された外部プログラムを実行できます。

  • ファイルロケーション/ターミナル: 現在開いているファイルの場所をエクスプローラ/ファインダーで開いたり、そのディレクトリでターミナルを起動したりする機能を提供します。

  • 文字エンコーディング自動検出: chardet ライブラリを使用して、ファイルの読み込み時に最適な文字エンコーディングを自動的に検出します。

本プログラムは、複雑な設定ファイルやログファイル、ソースコードなどを迅速に確認し、必要な情報を抽出する作業を効率化することを目的としています。

原理

iniview.pyw は、Pythonの標準GUIライブラリ tkinter とそのテーマ拡張である ttkbootstrap を利用してGUIを構築しています。

  1. INIファイル解析 (parse_multiline_ini):

    • 通常の configparser ではなく、独自のロジックでINIファイルを解析します。これは、値が「3重引用符」で囲まれた複数行のテキストを適切に処理するためです。

    • ファイルを開く前に chardet ライブラリを使用してファイルのエンコーディングを自動的に検出し、適切なエンコーディングでファイルを読み込みます。

    • ファイルの内容を一行ずつ読み込みます。

    • 行の先頭が # の場合はコメントとしてスキップします。

    • = が含まれる行はキーと値のペアとして解析されます。

    • 値が """ で始まる場合、in_multiline フラグを立て、次の """ が現れるまで複数の行をまとめて1つの値として扱います。

    • キーが \ を含む場合(例: Section\Key)、このプログラムではこれを階層構造として解釈します。

    • .ini 以外の拡張子を持つファイルが指定された場合、ファイルの内容全体を単一の「all」というキーの値として扱います。

  2. GUI構造:

    • tk.PanedWindow を使用して、左ペイン(ツリービュー)と右ペイン(テキストエディタ)に分割されたレイアウトを作成します。これにより、ユーザーはペインの境界をドラッグしてサイズを調整できます。

    • 左ペインには ttk.Treeview が配置され、解析されたINIファイルのキーを階層構造で表示します。

    • 右ペインには tk.Text ウィジェットが配置され、ツリービューで選択されたキーに対応する値を表示します。

    • 各ペインにはスクロールバーが関連付けられており、内容が多い場合でも全体を閲覧できます。

  3. イベント処理:

    • <<TreeviewSelect>> イベント(ツリービューの項目が選択されたとき)が発生すると、on_select メソッドが呼び出され、選択されたキーの値が右ペインのエディタに表示されます。

    • メニューやコンテキストメニューの項目が選択されると、対応するメソッド(select_file, search_item, copy_value など)が実行されます。

  4. 設定の永続化:

    • configparser モジュールを使用して、iniview.ini ファイルから設定(ウィンドウのジオメトリ、最後に開いたファイル、ペインの分割位置、外部コマンド)を読み込み、プログラム終了時に保存します。

    • 外部コマンドの設定は external_cmdX_nameexternal_cmdX_path の形式で連番で指定され、動的にメニューに追加されます。

  5. 外部コマンド実行 (_run_external_command):

    • 設定ファイルで定義された外部コマンドを実行するために subprocess.Popen を使用します。

    • コマンドテンプレート内の {{file_path}} は現在開いているファイルのパスに置換されます。

    • {{VAR_NAME}} の形式で指定されたプレースホルダーは、現在ロードされているINI設定のキーの値、または環境変数の値に置換されます。

    • コマンドは shell=True で実行され、実行ディレクトリは現在開いているファイルのディレクトリ、またはスクリプトのディレクトリに設定されます。

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

iniview.pyw を実行するには、以下の非標準Pythonライブラリが必要です。

  • chardet: ファイルの文字エンコーディングを自動検出するために使用されます。

  • ttkbootstrap: tkinter アプリケーションにモダンなテーマとウィジェットを提供するために使用されます。

これらのライブラリは、Pythonのパッケージマネージャーである pip を使用してインストールできます。

pip install chardet ttkbootstrap

必要な入力ファイル

iniview.pyw は、以下の種類のファイルを入力として受け付けます。

  1. INIファイル (.ini)

    • 形式: [Section], Key = Value の形式でデータが記述されたテキストファイル。

    • データ構造:

      • 行頭に # がある行はコメントとして無視されます。

      • = で区切られたキーと値のペアを解析します。

      • キーにバックスラッシュ (\) が含まれる場合、それを階層構造の区切り文字として扱い、ツリービューでネストされた項目として表示します (例: Path\SubKey = ValuePath の子として SubKey を表示)。

      • マルチライン値: 値が「3重引用符」(""")で始まる場合、次の「3重引用符」が現れるまでの複数行のテキストを一つの値として扱います。 例:

        [Settings]
        MyKey = MyValue
        MultiLineText = """
        This is a long piece of text
        that spans multiple lines
        within the INI file.
        """
        Database\ConnectionString = Server=my_db;Port=5432;
        
  2. 汎用テキストファイル (.p?, .c, .f, .txt, .log など)**

    • 形式: 任意のプレーンテキストファイル。

    • データ構造: .ini 以外の拡張子のファイルが選択された場合、ファイルの内容全体が単一の「all」というキーの値として扱われ、エディタペインに表示されます。これは、ソースコード、ログファイル、設定ファイルなど、様々なテキストベースのファイルを迅速に閲覧するのに役立ちます。

  3. 設定ファイル (iniview.ini)

    • 形式: 標準のINIファイル形式。プログラムの起動時に自動的にロードされ、終了時に更新されます。

    • データ構造:

      • [Window] セクション:

        • geometry: ウィンドウのサイズと位置 (例: 800x600+100+50)。

        • last_file: 最後に開いたファイルのフルパス。

        • sash: ペイン分割バーの水平位置(ピクセル単位)。

      • [paths] セクション:

        • file_manager_path: ファイルマネージャーのパス(現在未使用、OSの標準コマンドを使用)。

        • terminal_path: ターミナルのパス(現在未使用、OSの標準コマンドを使用)。

        • external_cmdX_name: メニューに表示される外部コマンドの名前 (Xは1からの連番)。

        • external_cmdX_path: 実行する外部コマンドのパスと引数。引数には {{file_path}} (現在開いているファイルのパス) や {{VAR_NAME}} (INIファイル内の変数、または環境変数) のプレースホルダーを使用できます。 例:

        [Window]
        geometry = 1024x768+50+50
        last_file = C:/Users/User/Documents/my_config.ini
        sash = 300
        
        [paths]
        external_cmd1_name = VS Codeで開く
        external_cmd1_path = code.exe "{{file_path}}"
        external_cmd2_name = Notepadで開く
        external_cmd2_path = notepad.exe "{{file_path}}"
        external_cmd3_name = 環境変数PATHを表示
        external_cmd3_path = echo {{PATH}}
        

生成される出力ファイル

iniview.pyw は、プログラムの終了時に以下の設定ファイルを自動的に生成または更新します。

  • ファイル名: iniview.ini

  • 場所: iniview.pyw スクリプトと同じディレクトリに保存されます。

  • 内容: プログラムの実行状態やユーザー設定を保存し、次回の起動時にその状態を復元するために使用されます。

    • [Window] セクション:

      • geometry: プログラム終了時のメインウィンドウのサイズと画面上の位置を $W \times H + X + Y$ 形式で保存します。ここで、\(W\) は幅、\(H\) は高さ、\(X\) はX座標、\(Y\) はY座標です。

      • last_file: 最後に開いていたファイルのフルパスを保存します。次回の起動時にこのファイルが自動的にロードされます(ファイルが存在する場合)。

      • sash: ペイン分割ウィンドウのサッシュ(分割バー)の水平位置(左端からのピクセル数)を保存します。

    • [paths] セクション:

      • file_manager_path: ファイルマネージャーのパス(現在の実装では使用されていませんが、将来的な拡張のために残されています)。

      • terminal_path: ターミナルのパス(現在の実装では使用されていませんが、将来的な拡張のために残されています)。

      • external_cmdX_name / external_cmdX_path: ユーザーが定義した外部コマンドの名前と実行パスを保存します。X は1から始まる連番です。

iniview.ini の例:

[Window]
geometry = 1000x700+200+100
last_file = C:\Users\YourUser\Documents\example.ini
sash = 350

[paths]
file_manager_path = 
terminal_path = 
external_cmd1_name = Open with VS Code
external_cmd1_path = code.exe "{{file_path}}"
external_cmd2_name = Run custom script
external_cmd2_path = C:\Scripts\my_script.bat "{{MySetting}}"

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

iniview.pyw は、Pythonインタープリタを使用して実行します。オプションで、起動時に開くINIファイルまたはテキストファイルのパスを引数として渡すことができます。

基本的な実行コマンド:

python iniview.pyw [ファイルパス]
  • python: Pythonインタープリタを呼び出すコマンドです。

  • iniview.pyw: 実行するスクリプトファイルの名前です。

  • [ファイルパス]: (オプション)起動時に読み込むINIファイルまたはテキストファイルへのパスです。この引数を省略した場合、プログラムはGUIを起動し、ユーザーは「ファイル読み込み」メニューからファイルを選択できます。

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

1. GUIを起動し、手動でファイルを選択する場合

ファイルパスを引数として指定せずに iniview.pyw を実行すると、INI ViewerのGUIウィンドウが起動します。この場合、ユーザーはメニューバーの「操作」→「ファイル読み込み」を選択してファイルダイアログからファイルを選択する必要があります。

python iniview.pyw

実行結果: INI Viewerアプリケーションのウィンドウが起動します。ウィンドウのサイズや位置は iniview.ini に保存された前回の設定が適用されます。iniview.inilast_file が設定されており、そのファイルが存在する場合は、そのファイルが自動的にロードされて表示されます。それ以外の場合は空の状態で起動し、ユーザーが手動でファイルを選択するのを待ちます。

2. 特定のINIファイルを指定して起動する場合

起動時に特定のINIファイルの内容をすぐに表示したい場合は、そのファイルのパスを引数として渡します。

python iniview.pyw C:\path\to\your_config.ini

実行結果: your_config.ini ファイルが自動的にロードされ、その内容がINI Viewerのツリービューおよびエディタペインに表示された状態でアプリケーションが起動します。ウィンドウタイトルには開かれたファイル名が含まれます。

3. 一般的なテキストファイルを指定して起動する場合

INIファイルではない任意のテキストファイル(例: ソースコードやログファイル)を起動時に表示することも可能です。

python iniview.pyw C:\Projects\MyApplication\main.log

実行結果: main.log ファイルがロードされ、ファイル全体の内容が右ペインのエディタに表示された状態でINI Viewerアプリケーションが起動します。左ペインのツリービューには「all」という単一の項目が表示され、それが選択されている状態になります。