とあるperlのテキストの最初の方にtab2spaceというタブをスペースに変換するルーチンが載っていました。これをRubyに書き直してみて、とりあえずちゃんと動いているのですが、なんか気持ちよくないので考え中です。
# tab2space.rb tabwidth = 8 while line = gets while line =~ /\t/ line = line.sub(/\t/, " " * (tabwidth - ($`).length % tabwidth)) end puts line end
Rubyレシピブックにuntabifyというのがあって、これにあたると思います。
#untabify.rb def untabify(str, tabstop = 8) str.gsub(/(.*?)\t/n){ $1 + " " * (tabstop - ($1.length % tabstop)) } end
考察:
1.どちらにせよ2byte文字対応していない。utf-8も無理。(/(.*?)\t/nとあるのの最後の"n"は、eならばeucとか。nは文字コード無視かな?
2.tabはインデントに使われるので、tab2spaceにする際、行頭のタブは1 tab => 2 spacesにしたい。
3.一方、行末やリストにtabを入れて列(column)の頭をそろえるのについては、対応したい。
計画:
1.testドリブンにする。例を先に考える。
2.2byte文字対応はあとにする。=> 先に考えた方がよさそう
3.行の後ろに入れるコメントやコラムの頭揃えに対応するために行の処理を頭からでなく後ろからやる必要があるのではないか。=> 後ろからやるのではなく、行頭と行頭以外に分けるのがいいと思う。
4.仕様自体に若干無理があるのは承知。
5.split(//)を使う。入れ子の配列を使う"あ", 2, 0 => [文字、バイト数、位置(2バイト換算)]
6.irbでトライアンドエラーが必要