しろもじメモランダム

文字についてあれこれと。

Firefoxなどで半角濁点が前の文字と一緒に選択される理由

Firefox などで下の半角濁点「゙」・半角半濁点「゚」を選択してみてほしい。

いくら半角(半)濁点だけを選択しようとしても、前の文字まで(それがスペースだろうが記号だろうが)一緒に選択されてしまうと思う。もう少し正確に言えば選択されるのは [^゙゚][゙゚]* にマッチする部分で、カーソルの移動の際にも [^゙゚][゙゚]* が一文字として扱われる。delete キーを押すと [^゙゚][゙゚]* が一気に消えるが、backspace キーでは半角(半)濁点がひとつずつ消える。

Windows のメモ帳*1など昔ながらのアプリケーションでは普通に半角(半)濁点が1文字として扱われ、半角(半)濁点のみを選択・削除できるのに、いつの間にかこんな実装が広まっているようだ。昔の挙動に慣れているとちょっと戸惑う。便利なような、便利でないような。

なんでこんな風になったのかと思って調べてみたら、どうやらこの話題、既出だった模様。

鍵はこのあたり。

UAX #29: Unicode Text Segmentation とやらを見てみると、第3節の Grapheme Cluster Boundaries に詳しいことが書いてある。grapheme cluster(書記素のカタマリ)というものが選択・削除・カーソル移動などの基本的な単位となっていて、その境界をどのように決めるか(=カタマリをどうやって切り分けるか)、ルールが定められている。

Table 2. Grapheme_Cluster_Break Property Values には境界の決定に用いるプロパティの一覧があるが、どの文字がどのプロパティかを調べるには GraphemeBreakProperty.txt を見ればよい。半角(半)濁点については、ここに

FF9E..FF9F    ; Extend # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK

とあるので、Extend というプロパティが与えられていることがわかる。

UAX #29 に戻って Grapheme Cluster Boundary Rules というところを見てみると、境界決定のルールがいろいろと定められているが、

Do not break before extending characters.
GB9.  × Extend

UAX #29: Unicode Text Segmentation

上記の通り、「Extend の前に grapheme cluster の境界は来ない」というルールがある。Firefox はこれらのルールに則った実装をしているらしく、だから半角(半)濁点の前にはカーソルが来ないというわけだ*2。もちろん、この UAX #29 に書かれているルールは規定ではないので、これに沿った実装をしなければならないというわけではない。

「ガ」を1文字のように扱うというのは文字本来のあり方(なんか大げさな言い方だ)としてはごく自然な発想かもしれないが、「半角カナ」の慣習に浸ってしまった自分としては馴れるまで時間がかかりそう。

*1:XPを使っているのでVistaや7ではどうだかわかりませんが。

*2:ちなみに上に書いた [^゙゚][゙゚]* という表現は、対象を半角(半)濁点に限って単純化した話なので注意。半角(半)濁点以外にもいろいろなプロパティが与えられており、また境界決定のルールも10個ほどあるので、実際はもっと複雑になる。