route127の日記: 漢字横倍角化スクリプト
こないだの倍角化スレ見ていて作りたくなった。
既にクサチュー文字への変換マクロは存在したが、漢字の倍角化には取り組んでいないようだったので。
スクリプトの働きとしてはコマンドライン引数として受け取った入力文字列を走査し辞書(CHISE)に照らして左右分割できるものを置換して表示するというもの。
例1)超絶核爆→走召糸色木亥火暴
例2)精神科に行け→米青示申禾斗へ彳亍け
文字処理のルールを以下のように書き下した。
#1 入力文字が漢字でなければそのまま表示する
#2 入力文字が辞書に含まれていなければそのまま表示する
#3 入力文字が分解不可能であればそのまま表示する(青、虫)
#4 分解後の入力文字が3文字(書記素)でなければそのまま表示する
#5 分解後の入力文字に英数字が含まれていたらそのまま表示する(成)
#6 分解後の入力文字の1文字目が偏旁(U+2FF0)、撓(U+2ffa)でなければそのまま表示する
#7 分解後の入力文字の2文字目以降がIDC(U+2FF0-2FFF)であればそのまま表示する
#3~#5はスクリプトがある程度書き上がってから入力試しつつ後から付け足したのでなんか包含関係が狂ってるような気がするけど今のところ破綻してないので棚上げした。
また今これを書きながら#4~#7はまとめて
/^(\x{2ff0}|\x{2ffa})\p{IDC}{2}/
と書けそうな気がしてきた(棚上げ)。
スクリプト本体(cp932入力UTF-8出力、事前にIDS-UCS-Basic.txtをローカル保存)
use strict;
use warnings;
use utf8;
use Encode;my $kanji = decode('cp932', shift @ARGV);
my @chise2b;
if(open(IN, "<:encoding(UTF-8)", 'IDS-UCS-Basic.txt')){
@chise2b = map{my @t = split("\t", $_);{'unicode' => $t[0], 'kanji' => $t[1], 'element' => $t[2]}}
grep{chomp}<IN>;
close(IN);
}else{
die "cant parse CHISE DB." unless @chise2b;
}foreach my $k (split('', $kanji)){
if($k =~ /\P{Han}/ || !grep{$_->{'kanji'} && $k eq $_->{'kanji'}}@chise2b){ #1,2
print $k;
next;
}
my ($element) = map{$_->{'element'}}grep{$_->{'kanji'} && $k eq $_->{'kanji'}}@chise2b;
$element eq $k || $element !~ /.{3}/ || $element =~ /a-z0-9/ || $element !~ /^(?:\x{2ff0}|\x{2ffa})/ || $element =~ /.\x{2ff0}-\x{2fff}/ ? print $k : $element =~ tr/\x{2ff0}-\x{2fff}//d && print $element;
}
原文の「行」は「彳亍」じゃなくて「彳〒」だけどその辺の置換はしてない。
cp932に収まるような配慮をしてもいいのかも。
CHISEの辞書を作るところは前回より行数減らせた。
ただ今の版も使い捨ての配列をインデックス指定するところとか無駄な気がするしハッシュスライスで
{map{@temp{qw/unicode kanji element/} = split("\t", $_)}}
みたいな感じで書けないかなと考えてみたけど上手く書けなかった。
ところでBS邪神ちゃんが最終回だったが来週はvtuberとなって甦るらしい。
それはともかく邪神ちゃんの作者の別作品『武蔵野線の姉妹』を倍角化のことを考えていて思い出した。
以前加藤夏希(仮面ライダー)主演で映画化されていたのだがポスターに「タヒね」とあったんだよな。
あと割と最近の映画で『夜空はいつでも最高密度の青色だ』というあまり見に行く気のしないタイトルがあったが、この原作詩集の作者も「タヒ」だった。
でつ ←スヌーピー
漢字横倍角化スクリプト More ログイン