マークダウンで書いた記事のPythonコード部分だけをautopep8コマンドで整形する


投稿されていた記事をPEP8準拠に整形したいなぁと思って作りました。

autopep8コマンド準備

autopep8コマンドはautopep8モジュールをインストールすると使えます。

$ pip install autopep8

または

$ python -m pip install autopep8

使い方

下記autopep8md.pyスクリプトを保存して、実行時の引数にマークダウンファイルを指定するか、指定しなければ標準入力から読み込みます。
変換結果は標準出力に表示するので、ファイルに保存するなり、クリップボードに送るなりしてください。

マークダウンファイルを引数に指定する
$ python autopep8md.py INPUT_MARKDOWN_FILE > OUTPUT_MARKDOWN_FILE

または、

標準入力から読み込む
$ cat INPUT_MARKDOWN_FILE | python autopep8md.py > OUTPUT_MARKDOWN_FILE

スクリプト

autopep8md.py
import os
import sys
import subprocess
import tempfile


def autopep8(code):
    with tempfile.NamedTemporaryFile('w', delete=False) as f:
        f.write(code)
        code_file_name = f.name
    subprocess.run(['autopep8', '-i', code_file_name])
    with open(code_file_name) as f:
        code = f.read()
    os.unlink(code_file_name)
    return code


def autopep8markdown(lines):
    in_code_block = False
    for line in lines:
        if not in_code_block:
            yield line
            if '```py' in line:
                in_code_block = True
                code = ''
        else:
            if '```' not in line:
                code += line
            else:
                yield autopep8(code)
                yield line
                in_code_block = False


def input_lines():
    if len(sys.argv) == 1:
        return sys.stdin.readlines()
    else:
        return open(sys.argv[1]).readlines()


def output_lines(lines):
    for line in lines:
        print(line, end='')


def main():
    output_lines(autopep8markdown(input_lines()))


if __name__ == '__main__':
    main()