ブログ等のWebサイトにおいて、日本語の中に英単語が混ざるような文章を書くことは多い。可読性を上げるために、日本語と英語の境界部分には空白を挿入したい。しかし、文章を書くときにその都度空白を挿入するのは面倒なので、できたら自動で挿入したい。この記事では、JavaScriptを使用して自動で空白を挿入する方法を紹介する。

JavaScriptで空白を挿入

結論から言うと、以下のスクリプトで日本語と英語の境界に空白を挿入できる。<head>タグ内や<body>タグ内の末尾などにコードをそのままコピペすると誰でも使用できるはずだ。JavaScriptコードをバンドルしている場合も、適切に以下の関数を定義して実行してもらえるとよい。

<script>
const addSpace = function() {
  const elements = document.querySelectorAll('p');
  elements.forEach(element => {
    element.innerHTML = element.innerHTML
      .replace(/([\u3040-\u30FF\u4E00-\u9FFF])([a-zA-Z])/g, '$1 $2')
      .replace(/([a-zA-Z])([\u3040-\u30FF\u4E00-\u9FFF])/g, '$1 $2');
  });
};
document.addEventListener("DOMContentLoaded", addSpace);
</script>

このスクリプトでは、addSpaceという関数を定義して、addEventListenerによってDOMContentLoadedイベントでこの関数が呼ばれるように登録をしている。DOMContentLoadedはDOMが完全に読み込まれたときに発火するイベントだ。

addSpace関数はHTML内の全ての<p>タグ内のテキストに対して、日本語と英語の間に空白を追加する。querySelectorAll('p')は、pタグのNodeListを全て返す。もし、<p>タグ以外に含まれるテキストも置換したい場合は、例えばquerySelectorAll('p,h1,h2')のように指定すると良い。その後、取得した各要素について、replace関数を用いて文字列の置換を行う。1つ目のreplaceでは、日本語文字(ひらがな、カタカナ、漢字など)に続く英字の間に空白を挿入している。また、2つ目のreplaceでは、英字に続く日本語文字の間に空白を挿入している。

正規表現部分をもう少し深掘りすると、\u3040-\u30FF\u4E00-\u9FFFが日本語文字の範囲を表している。a-zA-Zは言わずもがなアルファベットの範囲だ。[...]は、正規表現で...部分のうちいずれか1文字にマッチすることを示す。(...)...部分を$1にキャプチャする際に使われる(2つ目以降のキャプチャは$2, $3と続く)。つまり、日本語文字とアルファベットが連続している場所を正規表現で見つけて、それぞれを$1$2にキャプチャし、"$1 $2"($1$2の間に半角スペースが入っている)に置換するという処理をしている。

ちなみに、この方法では空白が二重で挿入されることはない。正規表現部分で、すでに空白が入っているものは一致しないようになっているからだ。そのため、複数人の編集者がいてスタイルが混在してしまっているような場合にも上記のスクリプトは有用だと思われる。

CSSのtext-autospaceを用いる方法

text-autospaceは、特にCJK(中国語、日本語、韓国語)文字とラテン文字の間に適切な間隔を自動的に挿入することを目的としたCSSプロパティだ。値に ideograph-alpha を指定するとCJK文字とラテン文字の間にスペースが挿入される。例えば、<p> タグに適用するには以下のように記述する。

p {
  text-autospace: ideograph-alpha;
}

しかし、text-autospaceはCSSの標準仕様から外れた非標準のプロパティとして扱われるため、サポートされているブラウザは限られており、現在はほとんどのブラウザで対応されていない。一応、Google ChromeではExperimental Web Platform featuresというフラグを有効にすることで使用できる。(Chromeで chrome://flags/#enable-experimental-web-platform-features にアクセスすることで設定可能)

表示する側の環境依存になってしまうので、今のところは先述のJavaScriptを用いた方法を利用するのが良いだろう。