NCC Advent Calendar 2020 21日目の記事です(遅刻)。
Discordで使う読み上げボイスボットなどを作る際、絵文字を読ませるには「🤔:考える顔」のように絵文字と読み方の対応表が必要になります。
ググればすぐ見つかるでしょ、とか思っていたんですが、意外と見つからなかったのでこの記事を書きました。
##元データ
結論から言うと、Unicode.orgのこのサイトに表があります。
この表はGitHub上のcldrリポジトリにあるxmlファイルを元にしている(と思われる)ので、このxmlを用いれば良さそうです。
このxmlデータには、絵文字とショートネーム及びキーワードの対応が載っています。「🤔」の場合、ショートネームは「考える顔」、キーワードは「考える顔 | うーん | 考える | 考え中 | 顔」となっています。なお、読み上げにはショートネームだけあれば十分です。
##jsonへの整形
JavaScriptではxmlフォーマットのデータは扱いづらいため、jsonに整形します。xmlパーサライブラリを用い、必要なデータだけを取り出します。
ということで作成したものが[emoji-pronunciation-ja]
(https://github.com/elecdeer/emoji-pronunciation-ja)です。下図の様なjsonデータになっています。
##注意点
単純に文字列をreplaceするだけでは、想定した読み方にならない場合があります。
絵文字にマッチする正規表現として、/\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu
が有名ですが、これにマッチするものをjsonデータで置換、のようにするとうまくいきません。
const emojiReg = /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu;
const emojiReplace = text => {
return text.replace(emojiReg, (match => {
return emojiAnnotation[match];
}))
}
例えば、「🐈⬛」が「ねこ 黒四角特大」と読まれてしまいます。「🐈⬛」はU+1F408 U+200D U+2B1B
という「🐈」と「⬛」のUnicodeの組み合わせで表現されています。この色付き正方形文字との組み合わせで色を変更する表現方法は、最近Unicodeに追加されてたものであるため、この正規表現はそれに対応できていません。よって、結合された絵文字ではなく、「🐈」と「⬛」別々の絵文字としてマッチしてしまい、この様な事態が起こります。
修正方法に関してはまだ確立できていないため、できたら追記しようと思います。
このあたりの話は以下の記事に詳しいです。
Unicode 絵文字にまつわるあれこれ (絵文字の標準とプログラム上でのハンドリング)
(追記)
環境によっては記事上の黒猫の絵文字がちゃんと表示されないようです。マジか...
##まとめ
Unicodeはえらいけどつらい。
##参考にしたもの
https://github.com/yagays/emoji-ja
以上です。