普段emacsをputtyからUTF-8で使うことが多いのですが、最近よくとある絵文字の表示に遭遇すると表示が崩れるという事態にあったので、なんとかできないかと対処してみました。
.@knok izonmoji-mode.elが参考にならないでしょうか。Emacsで独自 coding systemを定義する方法は私も知りたい。cp5022x.elが参考になるのだろうか? Wanderlustで iso-2022-jpを cp50220に置き変えてる。
— ふみやす%シェルまおう的なにか@通販生活 (@satoh_fumiyasu) 2015, 4月 2
前提として、https://github.com/kachie/emacs.d/blob/master/init.d/w32-init.elと同様の設定をしています。この設定では、いくつかの文字をputtyのUTF-8設定で正しく表示できるようなutf-8-for-puttyというエンコーディングを定義しています。その中でcp5022x.elという機種依存文字を表示させるためのelispも使われているのですが、その中身を見ながら見よう見まねで書いてみました。
変換テーブルの定義
置き換えの対象となる絵文字のテーブルを自作します。
(define-translation-table 'emoji-to-ascii '((#x1F440 . #x3013))) ;; eyes -> geta
#x1F440は絵文字の目玉で、これをゲタ(〓 #x3013)に置き換えるテーブルです。
エンコーディングの定義
utf-8-for-puttyエンコーディングの定義部分を修正します。
(apply 'define-coding-system 'utf-8-for-putty "UTF-8 (translate jis to cp932)" :encode-translation-table ;; (get 'japanese-ucs-jis-to-cp932-map 'translation-table) ;; original '(emoji-to-ascii (get 'japanese-ucs-jis-to-cp932-map 'translation-table)) (coding-system-plist 'utf-8))
表示幅の定義
オリジナルのset-east-asian-ambiguous-widthテーブルに目玉のコードポイントを追加します。
(defun set-east-asian-ambiguous-width (width) (while (char-table-parent char-width-table) (setq char-width-table (char-table-parent char-width-table))) (let ((table (make-char-table nil))) (dolist (range '(#x00A1 #x00A4 (#x00A7 . #x00A8) #x00AA (#x00AD . #x00AE) (中略) ;; #xFFFD ;; original #xFFFD #x1F440 ;; 変換前のコードポイントを指定 )) (set-char-table-range table range width)) (optimize-char-table table) (set-char-table-parent table char-width-table) (setq char-width-table table))) (set-east-asian-ambiguous-width 2)
これで自分が望む出力が得られるようになりました。
非tty Emacsの場合
今回の目的には合いませんでしたが、画像が表示できる環境ではemoji.elが良いようです。こちらを使うと、絵文字がイメージとして表示されます。キャリア別の絵文字も扱えるようで、なかなか高機能です。
@knok emoji.el はどうでしょうか?
https://t.co/XwaX0Ta2wo
— Shinichiro HIDA (@_shinichiro_) 2015, 4月 2