ぼやき

0

WordPress にて日本語文中で半角英数字の使用するとき前後に狭いスペース   を自動で挿入し文字間隔(字送り)を調節する関数をつくりました。変な位置での改行がなくなるし、半角英数字の前後に少し間が開くので文章も読みやすくなります。

変な位置で改行されてしまう問題

WordPressにて日本語文中で半角英数字の使用するとき前後に狭いスペース<code>&amp;thinsp;</code>を自動で挿入する関数をPHPで書いた。

例えば上記のような文章を HTML で表示した場合、下の図のように「スペース」の最後の「ス」の字が次の行になってしまうことがあります。 Mac Firefox 54.0.1 にて。

Firefox	でのスペースありなしでの改行の位置と狭いスペースの幅

それを防止するために半角スペースを入れて文章を書いていたのですが、なんとなく間延びしてしまうのでもう少しどうにかならないかと思っていました。調べてみると HTML の特殊文字に普通の半角スペースよりも狭い幅のスペースである &thinsp; というのがあるのを知ったので、それを自動で挿入するように WordPress で関数を書きました。

上の例文が下記のように変換されます。

WordPress&thinsp;にて日本語文中で半角英数字の使用するとき前後に狭いスペース&thinsp;<code>&amp;thinsp;</code>&thinsp;を自動で挿入する関数を&thinsp;PHP&thinsp;で書いた。

特殊文字で表現するいろいろなスペース

HTML の空白の種類
HTML 記述 コメント
&#32; ■■ ■■ 半角スペースキーでの空白 
ASCII コードの 10 進の 32 、 16 進の 20
&thinsp; ■■ ■■ 通常の半角スペースよち狭い空白 
thin ( 薄い ) sp (space : 空白 ) という意味
&ensp; ■■ ■■ 通常の半角スペースより少し広めの空白 
en (n : エヌの幅の ) sp (space : 空白 ) という意味
&emsp; ■■ ■■ 通常の半角スペースよりさらに広めの空白 
em (m : エムの幅の ) sp (space : 空白 ) という意味
&nbsp; ■■ ■■ 通常の半角スペースと同じサイズの空白 
nb (no break/non breaking : 改行しない ) sp (space : 空白 ) という意味

→こだわりの HTML :空白編
→みんなの知識ちょっと便利帳:使いたいときの HTML 特殊文字 & 機種依存文字

ちなみに text-autospace:ideograph-alpha; という CSS もあるようですが、 IE でしか動作しないようなので実質使えません。

日本語文中で半角英数字の使用するとき前後に狭いスペースを自動で挿入する関数

function add_space_full_width_half_width( $content ){
	//<pre>タグで分割
	$content_arr = preg_split('/(<pre\s*(?:"[^"]*"|\'[^\']*\'|[^\'">])*>.*?<\/pre>)/is', $content, -1, PREG_SPLIT_DELIM_CAPTURE);
	
	$content = '';
		
	foreach($content_arr as &$value){
		if(strpos($value,'<pre') === false){
		  //<>[]"'改行を除く半角英数字と隣り合ってるとき狭いスペースを挿入、タグの接するときはタグを覗いたパターンで判断
		  $content .= preg_replace( array( '/(?<![!-~\s]|^)((?:<("[^"]*"|\'[^\']*\'|[^\'">])*>)*)(?=[!#-&(-;=-Z\\\-~])/', '/(?<=[!#-&(-=?-\\\^-~])((?:<\/[a-zA-Z0-9]+>)*)(?![!-~\s]|$)/', '/(?<![!-~\s]) +(?=[!-~])/', '/(?<=[!-~]) +(?![!-~\s])/' ) , array( ' $1', '$1 ', '&thinsp;', '&thinsp;' ) , $value );
			} else {
			$content .= $value;
		}
	}
	
	return $content;
}
add_filter( 'the_content', 'add_space_full_width_half_width', 5);
add_filter( 'comment_text' , 'add_space_full_width_half_width', 5 );
add_filter( 'the_title' , 'add_space_full_width_half_width', 5 );

半角英数字と日本語文字が隣り合ってる場合とその間に半角スペースが入っている場合の両方に対応しています。正規表現の先読みと後読みを使って半角英数字かそうでないかを判断しています。半角英数字は [!-~] で基本判断していますが、 < 、 > 、[ 、 ]、 " 、 ' 、改行などを適宜除いています。また <pre> タグで囲まれた部分は変換しないようにしています。 <code> タグなどで囲まれた場合はタグを除いた状態の前後で判断しています。

キャプチャしないグループ化と先読み、後読み
(?:pattern) 部分正規表現のグルーピング(キャプチャなし)
(?=pattern) pattern がこの位置の右側に存在する場合にマッチ
(肯定の先読み) … 位置にマッチ
(?!pattern) pattern がこの位置の右に存在しない場合にマッチ
(否定先読み)
(?<=pattern) pattern がこの位置の左に存在する場合にマッチ
(肯定戻り読み)
(?<!pattern) pattern がこの位置の左に存在しない場合にマッチ
(否定戻り読み)
(?>pattern) マッチ文字列に対するバックトラックを禁止する

→ CXMedia : PHP 正規表現 (Perl 互換): PCRE
→あらびき日記:正規表現の先読み・後読みを極める!

PHP で戻り読みの場合は * 、 + 、 {x,y} を使った可変長の文字列には対応していないようです。 Compilation failed というエラーが出ます。先読みは可変長の文字列でもエラーは出ません。

→考える人、コードを書く人:可変長テキストの戻り読み

各ブラウザでの挙動の違い

ちなみに Mac Safari 10.1.1 の場合、狭いスペースを入れたとき「スペース」の「ス」が次の行に落ちてしまっています。

Safari	でのスペースありなしでの改行の位置と狭いスペースの幅

Mac Google Chrome はどのパターンでも改行の位置は変わりません。スペースの幅は変わります。

Google Chrome	でのスペースありなしでの改行の位置と狭いスペースの幅

実装するのに時間がかかったけれど、かなり自己満足な変更ですね。

by カエレバ

関連記事