Vimで#RRGGBBからrgb(r,g,b)に変換

CSSでrgba()を使うようになったので、#RRGGBBで書いていた色もrgb()で書き直すことにした。手作業でやるのはとても面倒なので、Vimスクリプトの勉強がてら#RRGGBBからrgb(r, g, b)に変換する関数を作って変換した。

function! HexToFunc(hex)
  let color = matchlist(a:hex, '\([0-9A-F]\{2\}\)\([0-9A-F]\{2\}\)\([0-9A-F]\{2\}\)')
  return 'rgb(' . printf('%d', '0x' . color[1]) . ', ' . printf('%d', '0x' . color[2]) . ', ' . printf('%d', '0x' . color[3]) . ')'
endfunction

matchlist()で2桁づつ区切ってやり、それぞれをprintf()で10進数に変換するというもの。matchlist()の使い方がなんとなくわかった気がする。面倒だったので#RGBとかいう3桁の書き方には対応してない。

あとはCSSファイルを開いて置換でこの関数を呼んでやる。

:%s/\(#[0-9A-F]\{6\}\)/\=HexToFunc(submatch(1))/gi

\=で関数を呼ぶ場合はサブマッチをsubmatch()で拾うことを知らなくて、最初は\=HexToFunc(\1)とか書いて全然動かなかった……。

あとでワンライナーでも書けるかなとちょっと頑張ってみたら結構簡単にできた。Vimすごい!

:%s/#\([0-9A-F]\{2\}\)\([0-9A-F]\{2\}\)\([0-9A-F]\{2\}\)/\='rgb('.printf('%d','0x'.submatch(1)).', '.printf('%d','0x'.submatch(2)).', '.printf('%d','0x'.submatch(3)).')'/gi

こんなワンライナーがさっと書けるようになりたい。