8月の絵文字界隈
なかなか面白いトピックが多かったのでちょこっとまとめてみました。
Unicode11.0の絵文字プロポーザル
8/3にワーキングドラフトが公開されました。新たに64種類の絵文字が候補に挙がっています。
http://www.unicode.org/L2/L2017/17284-emoji-recs.pdf
注目はL2/17-082で提案された頭髪絵文字でしょうか。これは既存の絵文字と頭髪絵文字を組み合わせることで髪型を表現しようというものです。
赤毛や白髪、カールした髪型やツルツルピカピカな頭を表現するための文字が提案されています。
http://www.unicode.org/L2/L2017/17082-natural-hair-color.pdf
一部の絵文字については、固有のコードポイントを割り当てるのか、それとも合字やZWJとして表現するのかで議論が紛糾している印象です。
たとえばSMILING FACE WITH CAPE
というスーパーマン的ヒーローを表す顔絵文字が提案されているのですが、「一般的に顔絵文字はEmotion
を表すものだが、これはRole
を表すものなので単体の絵文字ではなくZWJで表すべきである」という意見などが挙がっています。
いわば絵文字セマンティクス的な概念が誕生しているような気がしてなかなか興味深いです。意味的には単体の絵文字にするべきではないような気もしますが、かといってZWJが理想的かというとそうでもなく、フォントへの依存を高めてしまうのでなかなかに悩ましい問題ではあります。
Android 8.0 Oreoのリリースと収録された絵文字
Android 8.0 OreoではUnicode Emoji 5.0がフルサポートされ、新たに69種類の絵文字が加わりました。
Face Vomiting
などは気分を害した際に積極的に使っていきたい感じがあります。
ハッシュタグ10周年とhashflag
Twitterのハッシュタグが10周年です。
あまり知られていない気がするのですが、Twiiterでは特定のハッシュタグの末尾に自動的に(Twitterオリジナルの)絵文字が追加されます。
これはhashflags
と呼ばれるもので、一覧は下記で確認できます。
メールで絵文字を使うと「仕事ができない」とみなされるという傾向があるという調査結果
調査によれば、笑顔の写真付きメールを受け取った場合、受信者は相手の温かさと能力を高く評価する傾向があるものの、スマイル入りメールを受け取った場合は温かさを高く、能力を低く評価する傾向があるということです。
「職場で顔文字や絵文字を使用したい場合は、職場の文化をまず理解してください」はまあそのとおりだと思います。
Facebook Emojiにblack peopleの家族絵文字が追加
Facebook Emojiに新しくblack peopleの家族を表現する絵文字が125種類追加されました。
ちなみにこの分野はMicrosoft Emojiが先行していて、昨年のWindows10には52,000種類の家族絵文字が追加されています。
実際にはコードポイントのレベルで絵文字が追加されているわけではなく、ZWJに対応するフォントが増えた形ですね。
このあたりの仕組みの話は去年のEmoji Advent Calendarで記事を書きました。
Adobeのジェンダーレス絵文字
デザイナーのポール・ハントさんはEmojiconでも登壇をしていました。
デザインからジェンダーを切り離すことがいかに難しいかを実感させられますが、それでも理想の状態を追い求める姿には胸を打たれるものがあります。
絵文字というのは社会学・政治学とテクノロジーの交差点にあたる分野なのかも知れません。自分が絵文字を面白いと思う理由はそのあたりにあるのかなという気もしました。
9月もいろいろあったらまとめるかもしれません…
sbtからMaven Centralにライブラリをpublishする
毎回ググり直している気がするのでメモを…
初回のpublishはsbtのドキュメント通りにやれば問題ない(なかったと思う)です。
sbt Reference Manual — Using Sonatype
2回目以降の手順については以下。
1. sbtからpublishSignedタスクを実行する
$ sbt publishSigned
2. PGPパスフレーズを入力
Please enter PGP passphrase (or ENTER to abort)
と聞かれるのでを入力。
パスフレーズは初回時に自分で設定しているはずなので頑張って思い出す。
3. SonatypeからCentral Repositoryにリリース
2が成功するとSonatype社のリポジトリにリリースがされる。
ここからMaven Centralに向けて再度リリースをする。
ここからの手順はこちらを参考に。 central.sonatype.org
まずはSonotypeのリポジトリにアクセスしてログイン。
左側のメニューからStaging Repositories
を選択し、先ほどリリースした自分のライブラリにチェックを入れる。
チェックを入れたら上のメニューのClose
をクリック。しばらく待って完了したらRelease
をクリックしてMaven Centralへリリースを行う。
絵文字URL短縮サービスをつくりました😎
※ 2020年5月現在、サービスは停止中です。
Unicode Emojiを利用したURL短縮サービスを作ってみました。
何かしら絵文字を使ったサービスを作ってみたいなーとは以前から考えていたのですが、「絵文字の種類数を基数としたN進数でURLを短縮するのはどうだろう?」と思いついたのでやってみました。
バックエンドはScala + PlayをElastic Beanstalkで動かしています。短縮URLのリダイレクトにはS3のWebsite Redirect Location機能を使っています。 (今考えればAWS JavaScript SDK + Cognito + S3でサーバーレスにしてもよかったかも知れません...)
遊び半分で作ってみたものなのでずっとサービスとして提供し続けられるかは分かりませんが、ふとした折に使っていただけると幸いですw
Scala Days 2017 Copenhagen 3日目
とうとう最終日です。
Keynote: Open source is just about the source, isn’t it?
Stuff open source projects need to care about that aren’t code:
— Jan Lehnardt (@janl) 2016年3月23日
- People
- Name & trademark enforcement
- Copyright
- License
- Patents
- PR
最終日のキーノートはApache Mahoutのファウンダーである@mainecさんによるOSSについてのセッションです。
続きを読む長時間のフライトで役立ったグッズ
Scala Daysに参加するため、昨日からコペンハーゲンに来ています。
日本からのフライトは10時間ほどかかるのですが、昨年のサンフランシスコへのフライト(13時間!)では完全に腰を撃破されてしまったため、今回は快適に過ごせるように便利グッズをいくつか持ち込んでみました。
Rock Dan(収納ケース付き)フットレスト
座席前のテーブルに引っ掛け、足を乗せて使うものです。見た目も構造も簡素なのですが大変効果がありました。足を投げ出せるだけでだいぶ違います。
もともとは¥8,000ほどするものらしいですが、今は83%オフ(!)で¥1,000ちょっとなのでエイヤーと買ってしまいました。このくらいの価格で買えるなら2~3時間のフライトでも持っていて損はないと思います。
HOMECUBE 改良版 エアーピロー
膨らませて使う大型の枕です。大型と言ってもそこまで大量に息を吹き込む必要はありませんでした。
折りたたんだ状態では小さい水筒ほどのサイズなので、カバンにぽんと入れて持っていきました。(使った後自分でたたむのはなかなか大変でしたが…)
飛行機の座席を倒しづらいシーンはままあると思うのですが(いかついお兄さんが後ろに座ってるとか)、そういう際にこういう枕があると非常に便利だと思います。
中がちょっとした空洞になっているので、中でスマホや携帯ゲーム機を使ったりもできます。以前にちょっと話題になった1人ダンボールシアターと同じ要領ですね。
腰も無事フライトに耐えきったので、今日からのScala Daysを楽しみたいと思います!
「JSONにコメント書きたい!」って思ったあなたにはHjsonがおすすめ。
JSONにコメントを残したいなあと思うことは多々あるかと思います。 特に設定ファイルの場合、「なぜこの値にしているのか」「取りうる値の範囲」などの情報を残しておけるとありがたそうですね。
先日、Hjsonなるものを発見しました。コメントが残せる以外にも、末尾のカンマやクオーテーションが不要だったりと、なかなか快適そうです。
Javaでの実装があるので、これをScalaから利用してみます。
hjson-java
出力
Name: Shunsuke Tadokoro Colors: ["red","green","blue"] Greet: Hello, HJSON! Regex: ^\d{2,4}\.\w+?-\d+ HTML: <h1>HTML Element</h1> 若さ 若さってなんだ ふりむかないことさ 愛ってなんだ ためらわないことさ
ここまで簡潔に書きたいならそもそもYAMLでいいのではという気もしますが、 通常のJSONもHjsonとしてパースできるという後方互換性(?)があるので、 JSONを扱う既存のコードにすんなりと組み込めるという点ではこちらに分がありそうです。
ScalaでウェブページのCharsetを取得する
サイトのエンコードは、
- HTML, head内のmeta charset
- レスポンスヘッダのContent-Type内
の2箇所に記述してあるケースが多いのですが、前者はサイト作成者の記述ミスが多々あるため信用できず、後者もまれにエンコード名として異常な文字列が入っていることがあります。
(以前、charset=%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89
という胸騒ぎがする指定を発見し、いざデコードしてみるとcharset=文字コード
が出てくるというハートウォーミングな出来事がありました。マジかよ。)
そのため、エンコードを判定する機能が必要になります。
今回、判定にはMozilla製エンコード検出ライブラリuniversalchardetのJava実装版であるjuniversalchardetを利用しました。
juniversalchardet - Google Code Archive
エンコードを判別したいバイト列をUniversalDetectorクラスのインスタンスにハンドリングさせエンコード名を取得、と利用するようです。
Javaから利用するサンプルコードが公式にあります。
ただなんでもかんでもこいつに判定させるのはパフォーマンス的によろしくなさそうなので、 あくまでも「Content-Typeのcharsetが存在しない、もしくはエンコードとして扱えない文字列が指定されている場合」のみ判定をを行うのがよさそうです。
import java.nio.charset.Charset import scala.util.{Failure, Success, Try} import org.mozilla.universalchardet.UniversalDetector /** * Content-Typeヘッダからcharsetを取得する。 * ただし、Content-Typeで指定されたcharsetがエンコーディング名として不正な場合は、渡されたバイト列からcharsetを検出する。 * エンコーディング名として正しいcharsetがContent-Typeから取得できず、渡されたバイト列からも検出できない場合はNoneを返す。 */ protected def getCharset(contentType: String, bytes: Array[Byte]): Option[String] = { def _detect(bytes: Array[Byte]): Option[String] = { val ud = new UniversalDetector(null) ud.handleData(bytes, 0, 1024) // パフォーマンスを考慮し、先頭1024バイトのみで判定する ud.dataEnd() Option(ud.getDetectedCharset) } """.*charset=(.+)""".r.findAllIn(contentType).matchData .map(_.group(1)).toList.headOption.flatMap { charsetName => Try { Charset.forName(charsetName) } match { case Success(_) => Some(charsetName) case Failure(_) => _detect(bytes) } } } val res = ... // レスポンス val contentType: String = res.getContentType val bodyAsBytes: Array[Byte] = res.getResponseBodyAsBytes val charset: Option[String] = getCharset(contentType, bodyAsBytes)
まだ改良の余地はありますが、これでひとまず判定ができるようになります。