Pythonでコマンドライン引数のオプションを引き受ける
前回作ったミニスクリプト、結構便利なのですが、まず###が異常に出てくるので、それを省くようにしました。
ただ、これ執筆が続いてくと、章の中の見出しがだだーと増えすぎてしまって、章だけの構成が追いにくくなるなと思い至りました。
ということは、拾う見出しのレベルを変えるようにできればもっと使いやすくなりそうです。つまり、h1~h2を拾うバージョンと、h1~h3を拾うバージョンを作るわけです。
とは言え、二つのスクリプトを作るのはあまり効率的とは言えません。そこで、コマンドラインによくある「オプション」をつけてみるとしましょう。簡単に言えば、
python hoge -c
とかやると、動作が変わるイメージです。
で、動きはイメージできるのですが、さてどうやるかというと「Python コマンドライン引数 オプション」あたりで検索します。
どうやら、sys.argvではなく、argparseモジュールを使うとオプション処理がきれいにできる模様。では、実装しましょう。
やりたいのは、普通に実行したら、h3までのアウトラインが作られて、-cをつけて実行したら、h2までのアウトラインが作られるものです。
で、こうなりました。
import re
import argparse
parser = argparse.ArgumentParser(description='複数のmdファイルから見出しを抜粋します')
parser.add_argument('file',nargs='+',help='マークダウンファイルを指定してください')
parser.add_argument('--c',action='store_false')
args = parser.parse_args()
a = args.file
tocfilepaty = 'toc.txt'
mainbody = [] #見出し行を入れる
for tfilepath in a:
with open(tfilepath) as f:
l = f.readlines()
for line in l:
h1 = re.match(r'^#[\t ]?(?P<body>[^#][^\n]*?)#*$', line)
if h1:
mainbody.append('『' + h1.group('body') + '』')
h2 = re.match(r'^#{2}[\t ]?(?P<body>[^#][^\n]*?)#*$', line)
if h2:
mainbody.append(h2.group('body'))
h3 = re.match(r'^#{3}[\t ]?(?P<body>[^#][^\n]*?)#*$', line)
if h3 and args.c:
mainbody.append('・' + h3.group('body'))
synopsis = re.match(r'<div class="epigraph" style="font-style:italic;">(?P<body>.*?)</div>', line)
if synopsis:
mainbody.append('\t' + synopsis.group('body') )
with open(tocfilepaty, mode='w') as f:
f.writelines('\n'.join(mainbody))
「sys」ではなく「argparse」をインポートしています。
で、rgparse.ArgumentParserで入力を受け取って、args = parser.parse_args() パースする流れです。
使いたいのは、「複数のファイルを受け取る引数」と「オプションでつく--c」です。
複数ファイルは配列で受け取りたいので、「nargs='+'」をつけます(これがわからずにだいぶ苦戦しました)。
で、--cが付いた場合はデフォルトでそれを「false」にします(action='store_false'がその部分です。これはtrueに置き換えることもできます)。
で、h3の見出しを取得するときに、args.cの中身(true or false)を見て、それによって拾うか拾わないかと判断しています。
より深い見出しを作る場合は、さらなるオプションを加えることもできそうですが、とりあえずはこれでOKですね。
この記事が気に入ったらサポートをしてみませんか?