MacJapanese と UTF-8 を相互変換する gem をつくりました

まず使い方。

gem install mac_japanese
require "mac_japanese"
MacJapanese.to_utf8("\x82\x9F") #=> "あ"
MacJapanese.to_mac_japanese("あ") #=> "\x82\x9F"

MacJapanese では 1 文字で Unicode では複数文字に分割される文字の場合、私用領域 (PUA, Private Use Area) の文字を使うかどうかをオプションで指定できます。これを使用すると、対応した環境では合成された文字で表示され、可逆変換も可能となりますが、対応しない環境では ? などで表示されてしまいます。

デフォルトでは PUA を使用しますが、use_pua: false を指定することでこれを抑制することができます。

MacJapanese.to_utf8("\x85\91F") #=> "?0." (1 文字目は U+F860)
MacJapanese.to_utf8("\x85\91F", use_pua: false) #=> "0."

ちなみに Ruby 1.9 でないと動きません。

解説

MacJapanese は Mac OS 7 から 9 あたりまで、Mac OS で一般的だった文字コードです。あまり触れる機会はありませんが、それだけに UTF-8 などに変換したいという需要はそれなりにあると思います。

Ruby 1.9 では Encoding::MacJapanese というエンコーディングがあり、ASCII 文字列とマッチしたり、1 文字づつに分割したりできますが、他のエンコーディングに変換することはできません (他のエンコーディングの文字列から MacJapanese に変換することもできません)。

上でも述べたとおり MacJapanese と Unicode では 1 文字対複数文字の変換が必要であり、現在の Ruby の実装とやや相性が悪く、そこまで需要がないために変換できないようになっているようです。

参考

MacJapanese と Unicode の対応表は Apple が作成した JAPANESE.TXT を利用しています。

合成文字については下記の記事が大変わかりやすく、とても参考になりました。