汎用絵文字ライブラリ Somemoji

image

ここ最近絵文字で遊んでいて、Somemoji というライブラリをつくったので知見を共有します。

さまざまな絵文字セット

様々なプラットフォームのために、様々な組織が、様々な絵文字セット (絵文字画像の集合) を提供しています。

  • Apple
  • emojidex
  • EmojiOne
  • Facebook
  • Google
  • HTC
  • LG
  • Microsoft
  • Mozilla
  • Samsung
  • Twitter

大抵の絵文字セットはUnicodeのEmojiの仕様に則って実装されていて、このコードポイントに対応する絵文字画像はこれ、というように互換性があります。Unicode 6.0, Unicode 7.0, Unicode 8.0, ... とバージョンが増えるに従って定義されるEmojiの数も増えていっているので、それぞれの絵文字セットごとに対応具合はまちまちという状況ではあるものの、よく使う主要なものについては大体カバーされています。

オープンソースの絵文字セット

最近は寛容なライセンスで提供される絵文字セットも増えてきていて、それぞれのライセンスに従って自分のサービスで絵文字画像を利用できるようになってきています。

汎用絵文字ライブラリ

https://github.com/r7kamura/somemoji

さまざまな絵文字セットがあり、それぞれの絵文字セットごとにさまざまなライブラリがあるものの、ライブラリで出来ることもまちまちで、サービスの都合で使う絵文字セットを切り替えたりしようと思うと簡単にはいきません。なので、ライブラリも含めた絵文字セットの選定の段階が非常に大事で、そこでミスると面倒で辛い状態になってしまいます。そこで、絵文字セットに関わらず利用できる汎用絵文字ライブラリ Somemoji を開発することにしました。

Somemojiには、以下のファイルが同梱されています。

  • それぞれの絵文字の属性情報を定義したJSON
  • それぞれの絵文字セットで対応している絵文字を定義したJSON
  • 絵文字画像を手元に持ってくるためのコマンドラインツール
  • Ruby用のライブラリ

使い方

絵文字画像を一括ダウンロードする

somemoji というコマンドラインツールが同梱されていて、これを利用して絵文字画像を手元にダウンロードしてくることができます。例えば、デプロイ前にAmazon S3に絵文字画像を配置するときに利用したりします。なお、絵文字セットによってはMaxCDNなどから配信されている絵文字画像が利用できたりするので、Webサービスで利用する場合は必ずしもダウンロードしてくる必要はありません。

$ somemoji --help Usage: somemoji extract [options] -p, --provider (required) apple, emoji\_one, noto, or twemoji -d, --destination (required) directory path to locate extracted image files -f, --format png or svg (default: png) -s, --size Some providers have different size image files -h, --help Display this help message

Twemojiの画像データを ./images/emoji 以下に持ってくるにはこう。

somemoji extract --provider=twemoji --destination=./images/emoji

文中に含まれる絵文字コードを画像に置換する

"I :heart: Emoji"heart の部分の名前のことを絵文字コードと言ったりするんですが (主にSlackなどはそう呼称している)、文中に含まれる絵文字コードをHTMLのimg要素に置き換えてみるというコードの例がこれです。EmojiOneで利用可能な絵文字について、置換を試みています。

Somemoji.emoji\_one\_emoji\_collection.replace\_code("I :heart: Emoji") do |emoji| %(\<img alt="#{emoji.character}" class="emoji" src="/assets/emoji/#{emoji.base\_path}.png"\>)end#=\> 'I \<img alt="❤" class="emoji" src="/assets/emoji/unicode/2764.png"\> Emoji'

文中に含まれる絵文字を画像に置換する

文中に含まれる絵文字を、先述の例と同様にimg要素に置き換えてみるというコードの例がこれです。例えば、サービス上で表示する絵文字は全てTwitterの絵文字画像に統一したいなあ、みたいなときに使えます。

Somemoji.twemoji\_emoji\_collection.replace\_character("I 💗 Emoji") do |emoji| %(\<img alt="#{emoji.character}" class="emoji" src="/assets/emoji/#{emoji.base\_path}.png"\>)end#=\> 'I \<img alt="💗" class="emoji" src="/assets/emoji/unicode/1f497.png"\> Emoji'

独自の絵文字を追加する

サービスによっては、自社のアイコンなど独自の絵文字を追加したい場合もあると思います。そういう場合のために、ランタイムで絵文字を追加できるような機能を持っています。

custom\_emoji\_collection = Somemoji.emoji\_one\_emoji\_collection + Somemoji::EmojiCollection.new( [Somemoji::Emoji.new(code: "foo"), Somemoji::Emoji.new(code: "bar"),] ) custom\_emoji\_collection.find\_by\_code("foo").class #=\> Somemoji::Emojicustom\_emoji\_collection.find\_by\_code("bar").class #=\> Somemoji::Emojicustom\_emoji\_collection.find\_by\_code("100").class #=\> Somemoji::Emojicustom\_emoji\_collection.replace\_code("I :bar: Emoji") do |emoji| %(\<img alt="#{emoji.character || emoji.code}" class="emoji" src="/images/emoji/#{emoji.base\_path}.png"\>)end #=\> 'I \<img alt="bar" class="emoji" src="/images/emoji/bar.png"\> Emoji'

Markdown内の絵文字を置換する

RubyでMarkdownの変換処理を構造的にやる場合、恐らく HTML::Pipeline を使うことになると思います。絵文字コードを置換するようなHTML::Pipelineのフィルターを書くのも、以下のように実現できます。HTML::Pipelineについては Markdownを拡張して独自記法をつくる という記事を前に書いたので良ければご覧ください。

class EmojiFilter \< ::HTML::Pipeline::FilterIGNORED\_ANCESTOR\_ELEMENT\_NAMES = %w( code pre tt)# @note Implementation for HTML::Pipeline::Filterdef call doc.search(".//text()").each do |node| unless has\_ancestor?(node, IGNORED\_ANCESTOR\_ELEMENT\_NAMES) node.replace( ::Somemoji.twemoji\_emoji\_collection.replace\_code(node.to\_html) do |emoji| %W( \<img alt="#{emoji.code}" class="emoji" height="20" src="/images/emoji/#{emoji.base\_path}.png" title=":#{emoji.code}:" width="20"\>).join(" ") end ) endend doc endend

おわり

Somemoji 開発の背景や使い方を説明しました。今後の展開として、JavaScript環境で使えるようにする対応と、絵文字画像ダウンロードの高速化、サポートする絵文字セットの増加、絵文字セットごとの利用できる文字種とライセンスの明示、絵文字定義ファイルの追加を考えています。

追記

Somemojiつかって掲示板に絵文字切り替え機能つけてみた pic.twitter.com/T9RPI9zlVI

— 完全週休七日制 (@r7kamura) 2016年10月9日