Pythonスクリプト files2md_tags.py の技術ドキュメント

プログラムの動作

files2md_tags.py は、指定されたファイルパターンに合致するファイルを走査し、特に画像ファイルに対してはサムネイルを生成した上で、Markdown形式の画像タグとファイルリンクを標準出力に生成するスクリプトです。画像ファイル以外のファイルについては、Markdown形式のファイルリンクを生成します。

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

  • 複数のワイルドカードの処理: 位置引数として複数のワイルドカードパターンを受け取り、合致するファイルを一括で処理します。

  • 画像ファイルのサムネイル生成: 画像ファイルと判定された場合、指定された幅(デフォルト200px)でサムネイル画像を生成します。

  • Markdownの画像一覧出力: 生成されたサムネイルと元の画像へのリンクを含むMarkdown形式の画像タグ([![説明](サムネイル)] (元の画像))とリンクを標準出力に生成します。

  • Markdownのデータファイル一覧出力: 画像ファイルではないと判定されたファイルに対しては、ファイル名とファイルへのリンクを含むMarkdown形式のリストを標準出力に生成します。

  • 既存サムネイルの扱い: update オプションまたは overwrite オプションにより、既存のサムネイルファイルを更新・上書きするかどうかの挙動を制御できます。

  • Sphinx/Markdown互換: 生成されるMarkdownの出力形式は、Sphinxや一般的なMarkdownパーサで使いやすい構成になっています。

このスクリプトは、ドキュメントに画像やデータファイルのリストを効率的に埋め込みたい場合に、手作業でタグを作成する手間を省き、自動化することを目的としています。

原理

本プログラムは以下のアルゴリズムとライブラリを用いて機能を実現しています。

  1. ファイルの収集とフィルタリング:

    • argparse モジュールを使用して、コマンドライン引数で渡されたワイルドカードパターンを収集します。

    • glob.glob() 関数を使用して、これらのパターンを展開し、一致するファイルパスのリストを取得します。

    • pathlib.Path オブジェクトに変換し、重複するパスを除去します。

    • ファイルが実在するファイルであること、およびサムネイルファイル(ファイル名が -s で終わるもの)でないことを確認してフィルタリングします。

  2. 画像ファイルの識別:

    • IMAGE_EXTS というセット(集合)に定義された拡張子(.png, .jpg, .jpeg など)とファイルの拡張子を比較することで、画像ファイルであるかどうかを判定します。比較は小文字に変換して行われます。

  3. サムネイルの生成:

    • 画像ファイルと判定された場合、Pillow (PIL) ライブラリの Image モジュールを使用してサムネイルを生成します。

    • 元の画像 (w, h) のサイズと、指定されたサムネイルの幅 width に基づいて、新しい高さ new_h を計算します。 $\( new\_h = \max(1, \text{int}(h \times \frac{width}{w})) \)$

    • Image.resize() メソッドに Image.LANCZOS フィルタを指定して高品質なリサイズを行います。

    • Image.save() メソッドで、元のファイル名に -s を付加した新しいファイル名(例: original.png -> original-s.png)でサムネイルを保存します。

    • update または overwrite 引数が指定された場合、以下のロジックでサムネイルの生成・スキップを判断します。

      • overwrite が真の場合: 常に既存のサムネイルを上書きします。

      • update が真の場合: 既存のサムネイルの最終更新時刻が元画像の最終更新時刻よりも新しい場合にのみスキップします。

      • いずれでもない場合: 既存のサムネイルがあればスキップします。

  4. Markdownの出力:

    • 収集されたファイルを「画像ファイル」と「データファイル」に分類します。

    • データファイルセクション: format_data_section 関数は、データファイルのリストをMarkdownの第二段階見出し「## 生成されたデータファイル」の下に、[ファイル名](ファイル名) 形式のリンクとして出力します。

    • 画像ファイルセクション: format_image_section 関数は、画像ファイルのリストをMarkdownの第二段階見出し「## 生成された画像一覧」の下に、以下の形式で出力します。

      • 第三段階見出し (###) で元のファイル名(拡張子なし)を記述します。

      • [![説明](サムネイルファイル名)](元のファイル名) 形式の画像タグを生成します。ここで、「説明」は元のファイル名(拡張子なし)を使用します。

      • [link](元のファイル名) 形式の直接リンクも追加します。

    • 生成された両セクションが存在する場合、それらを結合し、標準出力にMarkdownテキストとして出力します。

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

このプログラムは、画像処理のために Pillow ライブラリを使用します。

インストールは pip コマンドで簡単に行えます。

pip install Pillow

必要な入力ファイル

プログラムの入力は、コマンドライン引数で指定される1つ以上のファイルパスのワイルドカードパターンです。これらのパターンに合致するファイルが入力として処理されます。

  • 画像ファイル: サムネイルを生成したい画像ファイル(例: *.png, *.jpg, *.gif など)。サポートされる形式は png, jpg, jpeg, gif, bmp, tif, tiff, webp です。

  • データファイル: 画像以外の任意のファイル(例: *.txt, *.csv, *.pdf など)。これらはMarkdownのリンクとして出力されます。

プログラムは、指定されたパターンに合致する既存のファイルのみを処理対象とします。

生成される出力ファイル

files2md_tags.py は、以下の2種類の出力を生成します。

  1. サムネイル画像ファイル:

    • 画像ファイルが入力として与えられた場合、元の画像ファイルと同じディレクトリに、元のファイル名に -s を付加した新しいファイル名でサムネイル画像が生成されます。

    • 例: image_original.png -> image_original-s.png

    • サムネイルの幅は --width 引数で指定されたピクセル数になります。

  2. 標準出力へのMarkdownテキスト:

    • 処理されたファイルに基づいて、Markdown形式のテキストが標準出力に書き出されます。

    • このテキストには、「## 生成されたデータファイル」セクションと「## 生成された画像一覧」セクションが含まれる場合があります。

    • Markdownのリンクは相対パスで記述されるため、生成されたMarkdownファイルとサムネイル、元のファイルを同じディレクトリに配置することで、ブラウザ等で正しく表示されます。

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

files2md_tags.py [-h] [--width WIDTH] [--update {0,1}] [--overwrite {0,1}] patterns [patterns ...]

引数:

  • patterns:

    • タイプ: str (可変長引数)

    • 説明: 検索するワイルドカードパターンを1つ以上指定します。例: *.png data/*.txt

  • --width WIDTH:

    • タイプ: int

    • デフォルト: 200

    • 説明: 生成されるサムネイルの幅をピクセル単位で指定します。高さは元の画像の縦横比を維持して自動的に計算されます。

  • --update {0,1}:

    • タイプ: int

    • デフォルト: 0

    • 説明: 1 を指定すると、既存のサムネイルファイルが元画像ファイルよりも新しい場合に限り、サムネイルの生成をスキップします。0 の場合は無条件でスキップします。

  • --overwrite {0,1}:

    • タイプ: int

    • デフォルト: 0

    • 説明: 1 を指定すると、既存のサムネイルファイルがあっても強制的に上書きして再生成します。0 の場合は既存のサムネイルを上書きしません(update1 でない限りスキップ)。

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

以下のファイルがカレントディレクトリにあると仮定します。

example_image1.png
example_image2.jpg
document.txt
report.pdf

実行コマンド

幅150pxでサムネイルを生成し、Markdownを出力します。既存のサムネイルがあっても上書きせず、元画像が新しい場合にのみ更新します。

python files2md_tags.py *.png *.jpg *.txt *.pdf --width 150 --update 1 --overwrite 0

実行される処理

  1. example_image1-s.png (幅150px) が生成されます。

  2. example_image2-s.jpg (幅150px) が生成されます。

  3. document.txtreport.pdf は画像ではないため、サムネイルは生成されません。

  4. 標準出力にMarkdownテキストが出力されます。

実行結果(標準出力)

## 生成されたデータファイル
[document.txt](document.txt)

[report.pdf](report.pdf)


## 生成された画像一覧

### example_image1
[![example_image1](example_image1-s.png)](example_image1.png)
[link](example_image1.png)

### example_image2
[![example_image2](example_image2-s.jpg)](example_image2.jpg)
[link](example_image2.jpg)

この出力結果をMarkdownファイルに保存し、生成されたサムネイルと元のファイルを同じディレクトリに配置することで、上記MarkdownドキュメントはウェブブラウザやMarkdownビューアで正しく表示されます。