上のテキストを見てほしい。西洋中心主義者たちの無自覚なふるまいによってめちゃくちゃにされた、見るも無惨な日本語の姿である(参考)。
もう二度とこうした悲劇が起きないよう、Googleは近年、BudouX 🍇 というライブラリを作った。これは軽量ながら、日本語・中国語・タイ語等の改行位置をうまいこと判定してくれるという優れものである。
Chromium系(v119-)のブラウザにはすでにこの機能が組み込まれていて、word-break: auto-phrase
を指定すると利用できる。しかしFirefoxやSafariではまだ使えない。そこで、Astro製のサイトにBudouXを組み込み、ブラウザを問わず綺麗な折り返しができるようにした。
なお、ここで紹介する方法をとらずとも、公式で提供されているWeb Componentsを使えばもっと簡便に同じ表示を実現できる。ただしその場合、余分なJS1をバンドルに含める必要があるうえ、せっかくサイトを静的生成しているのにクライアント側で処理を走らせる羽目になる。そのため、ここではビルド時にすべての処理を済ませてしまう方針をとる。
準備
まずはBudouXのJavaScriptモジュールをインストールしておく。
READMEによると、JavaScript向けにParser.parse()
やHTMLProcessingParser.applyToElement()
など、いくつかのメソッドが提供されている。今回は本文のHTMLを処理するため、HTMLProcessingParser.translateHTMLString()
を使う。
さて、.translateHTMLString()
の実装を見てみると、デフォルトでは改行可能な位置にU+200B
(ゼロ幅スペース)を挿入するようになっている(HTMLProcessorOptions.separator
)。これは一見問題なさそうだが、実はゼロ幅スペースはページ上でテキストを選択した際に文字として含まれてしまうため、あまり嬉しくない。代わりに、ゼロ幅スペースに相当するHTML要素(<wbr>
)を挿入すると、この問題を回避できる2。
また、デフォルトでは出力されるHTMLにword-break: keep-all; overflow-wrap: anywhere;
というスタイルがインラインで付加されるが、HTMLProcessorOptions.className
を指定しておくと、代わりに任意のクラスを付与できる。今回はbudoux
というクラスを付与しておき、あとからグローバルCSSで同様のスタイルを当てることにする。
以上を適当な関数にまとめると以下のようになる。
グローバルCSSも忘れずに書いておく。
本文(Markdown / MDX)
MarkdownやMDXで記述したコンテンツについては、rehypeプラグインで自動的に処理を行う。対象にしたい要素(<p>
や<li>
)をHTML化し、BudouXの処理を適用し、元の要素を置き換えるだけ3。
本文(上記以外)
それ以外の箇所については、<Budoux />
コンポーネントを作成し、適宜インポートして利用する。<Budoux />
コンポーネントは受け取った子要素をHTML化し4、BudouXの処理を適用し、その出力を直接HTMLとしてセットしている。
OpenGraph画像
本文だけでなく、satori等を使用して生成している画像内の日本語についても、BudouXを使ってまっとうな改行をさせることができる。このトピックについてはすでに数多書かれているのでそちらを参照した。
おわりに
BudouXの公式サイト曰く、
Google の使命は、世界中の情報を整理し、世界中の人がアクセスできて使えるようにすることです。
とのこと。