MT4.2で長いタイトルをトリミングするプラグイン 

Movable Typeで長い文字列をトリミングするにはtrim_toというフィルタが用意されています。
ただ、このtrim_toは半角英数字も日本語も、同じ1文字と数えてしまうので
見た目で同じ長さにはなりません。

文字数を半角文字数で指定するプラグインもありましたが、MT4.2で動作しなくなってしまったので、ルーチン的には邪道っぽいけど、自作してみました。
そのうち、きちんと文字数を数えるバージョンを作ろうと思ってたけど、
動いてるからいいや(笑

# ver0.02 09.12.17: 英語の大文字は幅が広いので全角文字として計算
# ver0.03 09.12.19: パターンマッチ方法を修正
# ver0.04 09.12.19: 英語の大文字のうちIは除外

TTrim 0.04
1.ダウンロードしたファイルを解凍して、"plugins" フォルダにアップします。
2.ttrim_to="半角文字数"で切り取る文字数を指定します。
例:<mt:entryTitle ttrim_to="24">

動作環境
Movable Type 4.2
文字コード:UTF-8

package MT::Plugin::TTrim;

use strict;
use MT;
use MT::Plugin;
use MT::I18N;
use MT::Template::Context;


my $VERSION = '0.04';


@MT::Plugin::TTrim::ISA = qw(MT::Plugin);

my $plugin = new MT::Plugin::TTrim({
	name => 'TTrim',
	version => $VERSION,
	doc_link => '',
	description => "文字数ではなく、半角文字数分を指定して切り取り",
	author_name => 'Takayama',
	author_link => 'http://www.chosyu.jp/',
});

MT->add_plugin($plugin);

MT::Template::Context->add_global_filter(ttrim_to => sub {
	my($str, $nstr, $ctx) = @_;

	my $out = $str;
	my $cut_num = 0;	# 切り取る文字数

	# 2byte半角スペースを1byte半角スペースに変換
	$out =~ s/ /x20/g;
	# アスキーコード(半角文字)以外を ` に変換
	$out =~ s/[A-HJ-Z]/全/g;		# 英語の大文字は幅が広いので全角文字として計算(Iは除外)
	$out =~ tr/[\x00-\x7F]/`/c;		# UTF-8の日本語は3Byteなので ` が3つになる
	
	# 全角を2Byteとするために変換(終端文字を ^ へ)
	$out =~ s/```/`^/g;
	
	# 文字数が指定より少ない場合は、元の文字列を返す
	if( MT::I18N::length_text($out) <= $nstr ){
		return $str;
	}
	
	# 半角の文字数で切る
	$nstr = $nstr - 2;	# ... の文字分を戻す(全角1文字分)適当に調整
	if( $nstr < 0 ){
		$nstr = 0;
	}
	$out = MT::I18N::substr_text($out, 0, $nstr);

	# 切り取る文字数を取得
	# ` を削除(全角文字の途中で切られた場合も、ここで削除される)
	$out =~ s/`//g;
	# 切り取る文字数を取得(日本語は ^ としてカウント)
	$cut_num = MT::I18N::length_text($out);


	# 切り取り
	$out = MT::I18N::substr_text($str, 0, $cut_num);
	# ...を追加
	$out .= '...';

	return $out;
});

perlの得意な文字列置換を利用した、なんちゃってアルゴリズム。
UTF-8の日本語コードが3byteでありASCIIコードとかぶらない性質を利用。
半角文字数が端数だった場合も、文字化けしないようにきちんと切り取ってくれます。
半角スペースが2byteコードになっているので1byteへ変換しています。

まぁ、プロポーショナルフォントの場合、どちらにせよ半角と全角で文字の長さは合わないんだけど。
 



 

コメントをお願いします 

Name:   ※必須(ニックネームでOK)
 名前を記憶
コメント:(HTMLタグは使用できません)