縦書きフォーマット変更スクリプト修正版
追記:もうちょい改良しました => 原稿の縦書き整形スクリプトを修正 - takepierrot Editor Note
先日、縦書きフォーマットように半角英数字を変換するvimスクリプトを書きました。
選択範囲の文字を縦書き用にフォーマット - takepierrotのメモ
このスクリプト、英数字をいったんすべて全角に変換後、6文字以上の英数字を半角に戻すという形で処理しています。
しかし、行頭に全角スペース+英数字が入る場合、スペースに誤爆して5文字の英数字を6文字のスペース入り英数字と謝って判定。本来全角に変換すべきところが、半角に処理されてしまっていました。しかも、行頭のスペースも半角に変換されています。
ENIACプロジェクト //本来こうなるべきが ↓ ENIACプロジェクト //このように変換されてしまう
これは微妙……ということで修正版を作ってみました。
基本的なロジックは前のと同じですが、取得したテキストデータを"\n"でsplitしてから置換を行っています。行頭のスペース+英数字の判定処理をしやすくするのが目的です。
function! Tategaki() range let str = getline(a:firstline, a:lastline) let firstline = a:firstline perl << EOF use strict; use warnings; use utf8; use open IO => qw/:utf8 :std/; use Encode qw/encode decode/; my $text = decode('utf-8', VIM::Eval('str')); my $firstline = VIM::Eval('firstline'); my $han_str = " 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; my $zen_str = " 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; my $han_eisu = "[ 0-9a-zA-Z]"; my $zen_eisu = "[ 0-9a-zA-Z]"; my $zen_suji = "[0-9]"; my @list = (); foreach my $str (split /\n/, $text) { 1 while $str =~ s/($han_eisu+)/get_str($1)/e; 1 while $str =~ s/($zen_eisu{6,})/get_str($1)/e; 1 while $str =~ s/^ \K($han_eisu{1,5})/get_str($1)/e; 1 while $str =~ s/(?<!$zen_suji)($zen_suji{2})(?!$zen_suji)/get_str($1)/e; $str =~ s/^ /<e3><80><80>/; # ↑文字化けしてますが全角スペースに置換しています push @list, $str; } sub get_str { my $key = shift; my $res =""; if ($key =~ m|$han_eisu+|) { for my $x (split //, $key){ my $num = index $han_str, $x; $res .= substr $zen_str, $num, 1; } } else { for my $x (split //, $key){ my $num = index $zen_str, $x; $res .= substr $han_str, $num, 1; } } return $res; } $main::curbuf->Set($firstline, @list); EOF execute "normal " . a:lastline . "gg" endfunction
気になったのですが、正規表現の検索文字列の指定で
$han_eisu{,5}
と入力するとエラーが出ますね。なんかハッシュと判定されたみたいです。
面倒ですが、
$han_eisu{1,5}