いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Pythonメモ-56 (pygments で色付き cat コマンドみたいなの作る) (pygments, highlight, get_lexer_for_filename, TerminalFormatter)

概要

前回

devlights.hatenablog.com

ってことで、pygments ってライブラリを初めて使ってみたのですが

面白かったので、もう少し遊んでみました。

ドキュメント見ると、いろいろ関数があって、Lexer を推定して作ってくれる系のものがあります。

その中にget_lexer_for_filename という関数があったので

これで、「色付きのcatコマンドみたいなもの」を作ってみました。といっても大事な部分は

全部pygmentsさんにおまかせしているので、何もしていないのですがw

サンプル

以下、サンプルです。

"""
pygments に関するサンプルです。
pygments に備わっている ファイル名からの予想機能 をつかって 色付きcatコマンド みたいなのを実装しています。

usage:
  $ python -m trypython.extlib.pygments02 ファイルパス

  ファイルのエンコーディングを指定したい場合は以下のようにします。デフォルトは utf-8 です。

  $ python -m trypython.extlib.pygments02 ファイルパス --encoding euc-jp
"""
import argparse
import os

from pygments import highlight
from pygments.formatters.terminal import TerminalFormatter
from pygments.lexers import get_lexer_for_filename

from trypython.common.commoncls import SampleBase


class Sample(SampleBase):
    """
    pygments に関するサンプルです。
    pygments に備わっている ファイル名からの予想機能 をつかって 色付きcatコマンド みたいなのを実装しています。
    """

    def __init__(self, file_path: str, encoding: str) -> None:
        """
        オブジェクトを初期化します。

        :param file_path: ファイルパス
        :param encoding: エンコーディング
        """
        super().__init__()
        self.file_path = file_path
        self.encoding = encoding

    def exec(self) -> None:
        """
        処理を実行します。

        :return: なし
        """
        with open(self.file_path, mode='r', encoding=self.encoding) as in_fp:
            code = in_fp.read()

        lexer = get_lexer_for_filename(self.file_path)
        formatter = TerminalFormatter(bg='dark')
        result = highlight(code, lexer, formatter)

        print(result)


def go(file_path: str, encoding: str) -> None:
    """
    サンプルを実行します。

    :param file_path: ファイルパス
    :param encoding: エンコーディング
    :return: なし
    """
    if not os.path.exists(file_path):
        raise FileNotFoundError(f'target file is not found [{file_path}]')
    if os.path.isdir(file_path):
        raise ValueError(f'file_path should be file, NOT directory [{file_path}]')

    try:
        'helloworld'.encode(encoding)
    except LookupError:
        raise ValueError(f'invalid encoding [{encoding}]')

    obj = Sample(file_path, encoding)
    obj.exec()


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('file_path', type=str, help='target file path')
    parser.add_argument('--encoding', type=str, default='utf-8', help='file encoding (default: utf-8)')

    args = parser.parse_args()
    go(args.file_path, args.encoding)

try-python/pygments02.py at master · devlights/try-python · GitHub

動かしてみた

Windowsでcmder上で実行した結果が、こんな感じです。

f:id:gsf_zero1:20180118130053p:plain
python -m trypython.extlib.pygments02 /tmp/pytmp/hello.py

f:id:gsf_zero1:20180118130106p:plain
python -m trypython.extlib.pygments02 trypython/extlib/pygments02.py

いいんじゃないでしょうかね。Styleとか調整したらもうちょいましな色付きできるかも。

参考情報

pygmentsでcatとか調べてみたら、以下の情報がありました。すでに やってらっしゃる方もいらっしゃるんですね。

havelog.ayumusato.com

こちらのページでは less も出来るように調整されています。pygmentizeコマンドを使われています。


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。