Chienomi

Unicode Word Joinerとウェブブラウザ

技術::web

Word Joiner

Unicodeは文字という概念を著しく拡張している。 Unicodeを理解している人間にとってはコンピュータにおける文字という概念と共に自然に受け入れられることであっても、それを説明したときに誰もがすんなりと受け入れられるものではない。

だから、実はUnicodeの普及によって従来ソフトウェア的な(あるいはデータフォーマット的な)機能として実装する必要があったものでも、「文字として」表現可能になったものというのが結構多い。

わかりやすいところで言えばHTML参照である。

webページをShift JISで書いていた頃はISO-8859-1の文字というのはShift JISで表せないものがかなり色々とあり、úみたいな参照をどうしても使う必要があった。 ISO-2022-JP-2を使うみたいな方法もあったが、最も安全なのは文字参照だ。 もっと一般的だったのは だろう。

ところが、今やこのような必要性は全くない。むしろ、XMLではこれらの文字参照が使えないことを鑑みれば、UTF-8やUTF-16で書かれたページであるならば、文字として書く方が確実に表示できる。

さて、これは文字として理解しやすい部類にあるものだが、不可視のものを「文字として」認識するのはより難しい。 ましてや「幅ゼロ」であるものならなおさらだ。

幅ゼロの文字で最も身近なものは…というのは難しいところだが、一番よく見るのはU+FE0F VARIATION SELECTOR-16と、U+FE0E VARIATION SELECTOR-15だろう。 これは絵文字のスタイルを切り替えるもので、絵文字に続いて前者がある場合はカラーの絵文字スタイルに、後者がある場合は線画のテキスト絵文字スタイルになる。(もちろん、環境的に対応していれば)

これは文字としては結合するものなので、ありなしすら分からない場合が多い。

もうちょっと積極的なのがU+200B ZERO WIDTH SPACEとU+00AD SOFT HYPHENだ。 一般的に英語などではワード中での改行は可能な限り避け、ホワイトスペースで改行(折返し)するようにする。 だが、あまりスペースがないところで長い単語が入るときには、折り返すべき望ましい位置が存在することがある。

ゼロ幅スペースは普段は見えないが、ホワイトスペースであるから単語を収める幅がないとき、ゼロ幅スペースの位置で折り返される。ソフトハイフンはそれだけでなく(可能ならば)ハイフンを入れて折り返す。

HTMLではソフトハイフンは­によって以前から表現可能ではあったが、ゼロ幅スペースを表すために単語境界を示すwbrタグを利用する必要があった。 wbrタグは現在も利用可能だが、HTML規格に含まれる「フォーマット上の機能」であったのに対し、Unicodeによってこの表現を「文字として」行うことができるようになったわけだ。 これは例えば、LaTeXにおいても\hspace{0pt}のようなことをしなくてよくなったことを意味する。

そして今回扱うWord Joinerはこのゼロ幅スペースの逆を行うものだ。 Word Joinerはその前後で折り返さないことを求める。 つまり、 「い(WORD JOINER)ろ」 という状態にあるとき、WORD JOINERの前は「“い”の後」、WORD JOINERの後は「“ろ”の前」であり、なおかつWORD JOINERには幅がないので、結果としては「“い”と”ろ”の間では折り返さない」という挙動になる。

このような挙動はHTMLではnobrというタグで表現できた。 現在は<span style="white-space: nowrap;">いろ</span>のような表現によって折り返さないことを明示できる。 だが、見てわかるとおり、これは文書が相当汚くなる。非本質的なところにものすごく余計なものをたくさん書くことになるからだ。

だが実際のところ、このような機能が必要であるシーンは割とある。 特に表においては、特に見出しとなるような列において幅がなく、頻繁に折り返されるような状況が発生する。 このとき、可能であれば単語区切りで切りたいものだ。折り返されるときに単語が保たれるのであれば、折り返されたとしても読みやすい。

ところが、一般的なHTMLレンダラーは日本語の文字間をホワイトスペースと同じ重さで処理する。 だから、単語間にゼロ幅スペースを入れたところで望むように機能しない。

そこで登場するのがU+2060 WORD JOINERである。 このWORD JOINERを単語中の文字間に入れていけば、単語中で折り返されることを回避できる。

ちなみに、U+2060 WORD JOINERと同じ機能を果たすものとして、U+FEFF ZERO WIDTH No-BREAK SPACEというものがあるのだが、これは機能的な理由で入ったというよりも、正当なBOMに差し障りのないような意味を与えたというようなものであり、現在は機能的に使う場合はU+2060を使うことが強く推奨されている。

表示する

文中のテキストはWikipediaから引用させていただいたものであり、自転車ロードレースの国際競技についてである。 大会名について単語中にWORD JOINERを入れた状態にした。

Vivaldi (Chromium)での表示
Firefoxでの表示

どちらも意図した通りに表示される。Word Joinerを使うことで日本語の折返しを制御できるということだ。 しかし…

Dilloでの表示

fltkのUnicodeへの対応が完全ではなく、U+2060が見えてしまっている。

w3m/Gnome Terminalでの表示

こちらはウィンドウリサイズなどによって、単に無視されたり、あるいは変に間が空いてしまったりと不安定な挙動を示す。

比較的メジャーなウェブブラウザですらこの有様だから、音声ブラウザなどではより想定外の問題を発生する可能性が高く、アクセシビリティという点ではかなり問題がありそうに思える。

検索する

「グレート」で検索

Chromium系であるVivaldiではWord Joinerの存在を無視して検索が効くが、FirefoxだとWord Joinerを含んだ文字列はヒットしない。

Word Joinerは不可視なので、「なぜか検索にヒットしない」状態が生まれてしまう。

コピペする

Vivaldi(Chromium), Firefox共にWord Joinerを含む文字列をコピペするとWord Joinerを含んだ状態でコピペされる。

あまり知られていない、不可視文字で、しかも表示上の都合で入れられている文字であることから、これは混乱をきたす可能性が高く、恐らくコピペした際にはWord Joinerは除去されるほうが望ましいだろう。 言い換えれば、コピペによって問題を生じる可能性が高いということだから。

結論: リスキー。使いどころに注意

様々な事情を鑑みればspan要素で改行を阻むほうがまだマシ、という感じであり、かなり問題を生じることがわかった。

ただし、テキスト文書としてみればWORD JOINERは不可視なので一見した状態では邪魔にならない。 WORD JOINERを入れていくのがかなり大変という問題もあるが、どっちが良いかというと悩ましいくらいではある。

だが、例えばMarkdownドキュメントから生成する場合などは、必ずしもHTML的に改行制御が書けるとは限らない。 そうした場合にも有効な方法として重宝しそうではあるのだが、前述のようにアクセシビリティの問題、コピペ時の問題など、やはり「混乱を引き起こしそうな要素」はかなりたくさんある。 正直、ウェブページとして使うことは勧めがたい。

だが、ドキュメントとしては一考の余地がある。

私はドキュメントは基本的にはMarkdown(またはReST)で書き、Pandocで処理する、という形をとっている。 このドキュメントは多岐に渡り、顧客に渡す説明書や配布資料などもこの形式である。

こうしたドキュメントは世界中万人に向けて発信されるウェブページと比べればだいぶ閲読条件を絞り込める。 必要であれば、「ChromeとかChromiumとかVivaldiとかで見てくださいね」とでも一言申し添えれば良い程度だ。

さらに、WORD JOINERを使う手法はPandocで生成されるHTMLだけでなく(LaTeXを経由した)PDFでも機能することから、より汎用性の高い方法として使うことができる。

手間を考えても、アクセシビリティなどの観点からも多用すべきものではないのは明らかだが、表の見出しなど条件を絞って使用するのは、場合によっては悪くないアイディアとなりそうだ。 少なくとも、このような方法があることを知っておくだけでも価値はあるだろう。