トイレのうず

WordPressにて日本語と半角英数字の間に狭いスペースを自動で挿入する

当記事はアフィリエイト広告を掲載しています。

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 でのスペースありなしでの改行の位置と狭いスペースの幅

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

関連記事

WordPress 3.3.1 の投稿エディタのフォントを変更する
WordPress
WordPress 3.3.1で投稿エディタの全角と半角の区別がつかない
WordPress 2.6 日本語版リリース
WordPress
thumbnail
WordPress コメント表示に Get Recent Comments を使ってみる
WordPress
thumbnail
WordPress ではタイトルの最初の 22 文字(全角)が同じだとインポートできない
WordPress
パーマリンク設定
WordPress でエスケープしたショートコードが自動抜粋時に実行される不具合に対処
WordPress
thumbnail
WordPress でインポートに失敗する件【解決】
WordPress
thumbnail

コメント (4)

  • 會澤賢一

    Web を徘徊していてたどり着きました。私自身大変困っていたので、早速コピペしました。ありがとうございます。ちゃんと動作しています。
    導入したよ。というのを WordPress で記事にしました。事後報告になりますが、よろしくお願いいたします。

    本当にありがとうございました。助かりました!

  • あさこん

    ◇會澤賢一さん◇
    コメントありがとうございます。
    お役に立ててよかったです。
    もし既存記事で英単語の前後のスペースを入れてないなら
    置換の正規表現を少し改造すると早く動きますよ。

  • ショウヘイ

    はじめまして、あさこん様。

    WordPress の記事の英単語の両端に半角スペースを入れる処理の自動化を検討していたころ、こちらの記事を拝見しました。

    さっそく、自分のブログにもコードを導入してみました。思い描いたとおりに半角スペースが入ってくれて、とても助かりました。

    記事の形式で役立つコードを公開してくださり、ありがとうございます。

  • あさこん

    ◇ショウヘイさん◇
    コメントありがとうございます。
    英字と日本語の文字の間、気になりますよね。
    お役に立ててよかったです。

コメントを書く