# 指定された幅にトリミングするフィルタ(文字種を考慮) package MT::Plugin::Trimj2; use MT::Template::Context; use MT::ConfigMgr; MT::Template::Context->add_global_filter(trimj2_to => sub { my($str, $nstr, $ctx) = @_; my $sippo = '...'; # 幅定数設定 my($zenwid, $ucwid, $lcwid, $digwid, $symwid) = (2, 1.8, 1, 1, 0.8); my $tmpstr = $str; my $c = MT::ConfigMgr->instance->PublishCharset; my $conv_in; if (lc $c eq lc 'Shift_JIS') { $conv_in = 'sjis'; } elsif (lc $c eq lc 'ISO-2022-JP') { $conv_in = 'jis'; } elsif (lc $c eq lc 'UTF-8') { $conv_in = 'utf8'; } elsif (lc $c eq lc 'EUC-JP') { $conv_in = 'euc'; } my $jcnv; eval 'use Jcode;'; if($@){ require 'jcode.pl'; $jcnv = 'jcode::convert'; }else{ $jcnv = 'Jcode::convert'; } if ($conv_in ne 'euc') { &$jcnv(\$str, 'euc', $conv_in); } # 明らかに短い場合は終了 my $lenstr = length($str); if($lenstr <= $nstr) { return $tmpstr; } my $wid = 0; my $out = ''; my @chrs = split(//, $str); my $code; for (my $i = 0; $wid < $nstr && $i <= $#chrs; $i++) { $code = ord($chrs[$i]); if($code == 0x8f) { # 半角かな $wid+=$ucwid; $out .= $chrs[$i] . $chrs[$i+1]; $i+=2; } elsif ($code >= 0x80) { # 全角 $wid+=$zenwid; $out .= $chrs[$i]; $i++; } elsif ($code <= 0x7a && $code >= 0x61) { # 小文字 $wid+=$lcwid; } elsif ($code <= 0x5a && $code >= 0x41) { # 大文字 $wid+=$ucwid; } elsif ($code <= 0x39 && $code >= 0x30) { # 数字 $wid+=$digwid; } else { # 記号(その他) $wid+=$symwid; } $out .= $chrs[$i]; } # 尻尾を付けたくない場合は、コメントアウトのこと。 if($out ne $str) { $out .= $sippo; } if ($conv_in ne 'euc') { &$jcnv(\$out, $conv_in, 'euc'); } return $out; }); 1;