Vimと日本語編集: 長文の中の見出しだけを抽出する

以前にすでに書いたような気がしていたが、ブログ内を検索しても出てこなかったので書いておく。
最近とくによくやる作業。

課題と前提

たとえば以下のような文書があったとする。

# 見出し1
本文
# 見出し2
本文
# 見出し3
本文
(略)
# 見出し100
本文

「本文」とあるところは何十行も続いているとして、この中から「見出し」の行だけを集めたいという場合、手動でポチポチ拾っていくのはなかなかつらいものがある。

というか、そういう手動対応はミスの介在する余地も大きいし、肉体だけでなくメンタル面でも消耗の度合いが大きいので、やらずに済めばその方がよい。

では、これをみんな大好きVimで解決するにはどうすればいいかというと、『実践Vim』の「TIP99」を使えばいい。

実践Vim 思考のスピードで編集しよう!

実践Vim 思考のスピードで編集しよう!

※同書は上記のAmazonからだと単行本またはKindleで購入できるが、達人出版会に行けばPDF+EPUBの形式でも購入できる。(たしかDRMナシ)
実践Vim【委託】 - 達人出版会
※ぼくはKoRoNさんから献本して頂いた単行本の他、なぜかKindle版も達人出版会配布のPDF+EPUB版も買ってしまった。どんだけ……。

実践: 最小限の工程

まずは、任意のレジスタをクリアする。

『実践Vim』の例ではレジスタaを使うので「qaq」と打つように言っているが、ぼくはこの用途のときは毎回何も考えずに済むよう「qqq」と打ってレジスタqを空けている。

その上で、コマンドラインモードで以下を入力。

:g /\v^# 見出し\d+/yank Q

これでレジスタqに「# 見出し(+整数)」の行が溜まっている。

次に、溜めたそれを吐き出す。
具体的には、同バッファ内で(または分割ウィンドウで別バッファを出して)以下を打鍵する。

"qp

結果。

# 見出し1
# 見出し2
# 見出し3
# 見出し100

上のサンプルを対象に実行するとこの4行が出てくるが、ほんとに100個の見出しがあれば100行になる。

工程上のポイントとしては、exコマンドの最後で小文字の「q」ではなく大文字の「Q」を入れること。
これは大文字にすることによりマッチした行がレジスタへ追記されていくからで、小文字にするとどんどん上書きされて最後にマッチしたものしか残らない。

また、レジスタqに入れているので吐き出すときは「"qp」だが、レジスタaとかbとかならそれぞれ「"ap」とか「"bp」になる。

また、この方法を使い始めた当初はよく最初のレジスタクリアをし忘れて、以前にコピーした内容も一緒に出てきてその都度けっこう驚いた。
致命的なミスではないが、毎回クリアしてから収集するのを忘れないように。

応用: 夏目漱石草枕」より

上ではけっこう厳密な正規表現を書いて対象を指定しているが、結局は正規表現で拾っているだけなので、指定をゆるくすればそれに応じた結果(対象語句を含む行)が入ってくる。

出典であるところの『実践Vim』では「TODOアイテムを収集する」というテーマになっていて、コード内でコメントアウトして書かれたTODOの行を集めるという前提で、以下のコマンドが示されている。

:g /TODO/yank A

よってたとえば、いつもお世話になっています夏目漱石先生の「草枕」より、

夏目漱石 草枕

1センテンス1行に分解した上で、「夢」を含む行だけを収集するならこんな感じになる。

:g /夢/yank Q

結果。

雨が動くのか、木が動くのか、夢が動くのか、何となく不思議な心持ちだ。
眠りながら、夢に隣りの臼の音に誘われるような心持ちである。
やがて長閑のどかな馬子唄まごうたが、春に更ふけた空山一路くうざんいちろの夢を破る。
夢に。
妙に雅俗混淆がぞくこんこうな夢を見たものだと思った。
昔し宋そうの大慧禅師だいえぜんじと云う人は、悟道の後のち、何事も意のごとくに出来ん事はないが、ただ夢の中では俗念が出て困ると、長い間これを苦にされたそうだが、なるほどもっともだ。
文芸を性命せいめいにするものは今少しうつくしい夢を見なければ幅はばが利きかない。
こんな夢では大部分画にも詩にもならんと思いながら、寝返りを打つと、いつの間にか障子しょうじに月がさして、木の枝が二三本斜ななめに影をひたしている。
夢のなかの歌が、この世へ抜け出したのか、あるいはこの世の声が遠き夢の国へ、うつつながらに紛まぎれ込んだのかと耳を峙そばだてる。
自然の色を夢の手前てまえまでぼかして、ありのままの宇宙を一段、霞かすみの国へ押し流す。
夢中に書き流した句を、朝見たらどんな具合だろうと手に取る。
しかし夢のように、三尺の幅を、すうと抜ける影を見るや否いなや、何だか口が聴きけなくなる。
この夢のような詩のような春の里に、啼なくは鳥、落つるは花、湧わくは温泉いでゆのみと思い詰つめていたのは間違である。
しかしてその青年は、夢みる事よりほかに、何らの価値を、人生に認め得ざる一画工の隣りに坐っている。
「あの山の向うを、あなたは越していらしった」と女が白い手を舷ふなばたから外へ出して、夢のような春の山を指さす。

全3212行のうち、上記15行にヒットした。

工夫: マッピングに仕込む

慣れるまではなかなか覚えられない技だが、最近はこんなマッピングを仕込んで、とくにコマンドを思い出さなくても使えるようにしている。

nnoremap <Leader>qy  :<C-u>g //yank Q

便利。

別解: tagbarを使う

これと近いニーズで、「見出し行を集めるのではなく、ただザラッと全見出しを閲覧したいだけ」とか、「任意の見出し行にジャンプしたい」という場合もあり、そういうときはtagbarというプラグインMarkdown用のプラグインと組み合わせて以下のようにしているのだけど、

f:id:note103:20160903145618p:plain

これについてはまた時間のあるときに。

まとめ

ということで、普段、日本語の長文テキストを編集しているときに多用している技(というか)をさらっと(でもないが)紹介してみた。

Vimで日本語のテキストを編集しているなどと言うと、時々「それはない」という反応があるが、このように非常に便利なのでそれを示したかったというのもある。

実際には、こういう便利さは対象を「日本語」に限定しなくても、英語でも中国語でも同様に享受できるわけだけど、とはいえプログラミングにおけるVimの便利さとは少し性質も違うだろうと思ったのであえて「Vimと日本語編集」というシリーズタイトル的なものにしてみた。