miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

Mac OS Xの濁点ファイルがやってきた

一ヶ月ほど前の話。Mac OS X を使っている人から Skype で送られてきた Excel ファイルが WinMerge でうまく開けなくて。「xdoc2txt が .xlsx に対応してない?いやそんなはずは・・・」とかいろいろ調べてて、ふと思い立って dir すると

こんな感じと。今まで仕事で Mac OS X を使っている人には出会ったことがなかったので、「これが噂の濁点問題かー」とちょっと嬉しくなって、このファイルをいじりまわして遊んだのでそのお話。

簡単に現象&用語を説明

詳しいことは

あたりを読んでいただくのが確実なんですが、今回問題になった濁点まわりに限定してかいつまんで説明すると・・・。

  • Unicode で「が」という文字を表したい場合、以下の二種類の表現方法がある
    1. 「が」(U+304C)の一文字で表す方法
      • すべての文字がこの方法で統一された形式を NFC(Normalization Form C。C は Composition=合成 の意味)と呼ぶ
    2. 「か」(U+304B)+「゙   」(U+3099)の二文字で表す方法
      • すべての文字がこの方法で統一された形式を NFD(Normalization Form D。D は Decomposition=分解 の意味)と呼ぶ
  • Windows 上で通常の操作を行う場合、NFC 形式の文字列にしか出会うことがない
  • Mac OS X でよく使われている HFS+ というファイルシステム上では NFD で正規化される ※1
  • Windows ユーザが Mac OS X からファイルを受け取ると、名前が NFD で正規化されたファイルができあがる
    • アプリケーションによってはこのファイルを正しく扱えないため問題になる

という感じです。

(2013-01-07 追記)
※1コメント欄で指摘いただいたのですが、正確には NFD と同様には正規化されないそうです。元記事を引用しておきます。

ただし Mac の 正規化は NFD と同じではないため、単純ではありません。NFD の仕様で正規化対象になるべき文字の一部が正規化対象になっていません。
その結果 Mac のファイル名の正規化関しては「UTF-8-MAC」(iconv)や「UTF-8-HFS」(Emacs)等の呼称で扱われています。

(2013-01-07 追記 ここまで)

ちなみに今回のプロジェクトはリポジトリとして Subversion を使っていますが、上記 2 つめの URL に Mac OS X 上で NFC ファイル名を扱える Subversion の紹介があり、Mac OS X ユーザにはこれを使ってもらうことになっているので、通常のフローでは問題は発生しないはずです。リポジトリを介さずに Skype で気軽に受け取ったのがよくなかったですね。

Windows 上の挙動について

Windows 7 上で適当にいじり倒してみました。

NFC と NFD のファイルは共存しても大丈夫みたいです。


結合できる文字は Explorer 上で結合された状態で表示されるので、見た目だけでこの二つを見区別することはできません。

濁点を複数付加することもできます。


二つ目以降の濁点は文字の右側に付加され、三つ目以降の濁点も表示位置が変わらないので、どんどん上書きされて濃く表示されてるようになります。

合成できない文字に濁点を付加した場合、文字は合成されますが見た目上は結合されず、文字の右側に濁点が表示されます。ひらがな、カタカナ等一部の文字については右側でなく上側に濁点が表示されるようです。


NFD 形式の見分け方

上記のように dir コマンド等で調べると一目瞭然ですが、それ以外の方法について。

Explorer 上で見分けるには

NFD 形式の結合済み文字は、カーソル移動時は一文字として扱われますが、この文字の右側にカーソルを置いて BackSpace すると濁点だけ消すことができます。この挙動の違いで見分けることが可能です。

Dropbox の管理フォルダに移動する

Dropbox の管理フォルダに置くと、
「ログ出力.xlsx」

「ログ出力_ (Unicode 形式の問題).xlsx」
のように勝手にリネームされますので、この方法で見分けてもいいかもしれません。

Windows 上での結合文字列(「゙   」等)の入力方法

どうやったら簡単に濁点を入力できるか調べていたら、こちらでいくつか紹介されていました。

Character map and copy/paste. If I know the code point in advance, I simply do [char]2662 in PowerShell and copy from there. Or I use an instance of RichEdit (Word, various other programs) and type the code point value and hit Alt+X/Alt+C.

  1. 文字コード表(charmap.exe)を起動して該当の文字を探してコピーする
  2. PowerShell を立ち上げて [char]0x3099 のように入力する
  3. ワードパッド(wordpad.exe)等リッチエディットを立ち上げて 3099 と入力して Alt+X を押す

といった方法で入力できるそうです。

文字コードを元に特定の文字を入力する方法として Alt+(テンキーの数字) というのをたまに見かけますが、ASCII 外の文字はちゃんと動作しないことが多かったと思います。いちおうリンクを貼っておきます。

文字コードがわかっているなら、こういうサイトからコピペするのが一番早いかもしれません。