Smultron-3.5.1 + NKFCocoaの仕様検討中
年度末ドタバタしている中SmultronへのNKFCocoaを組み込み中です。迷っているのはUnicode変換表にない文字を含むファイルの扱い。一応、NKFCocoaによるエンコードの判定そのものは組み込んだのですが、Shift_JISを正しく判定することができているにも関わらず読み込めないファイルがいくつかあって収まりが悪い。
NSStringの内部表現はUnicodeですから読み込むテキストをオリジナルのエンコードからUnicodeへと変換する必要があります。そのとき、例えばShift_JIS(0x81ad)などのUnicodeの変換(JIS0208.TXT)表にない文字が使われていたりすると、NSStringに取り込むことができずエラーになるわけです。NSStringはエディタのためのクラスではないしUnicodeの仕様に厳密であるという点で正しい実装なので、ここから先はプログラマの仕事ということになりますがこれがなかなかシンドイ。JeditXではこのような変換表にない文字はREPLACEMENT CHARACTER(U+FFFD)に置換して表示していますがそこまでやるかどうかが問題です。置換するとなると変換表を取り込んで一文字ずつスキャンしていくことになるのですがいかにも所詮は変換できない文字のためにそこまでやるのもムダな気がします。
それで色々悩んでいるうちに気がついたのですがこういうデータをnkf -Swとかするとちゃんと変換できるんですね。で、変換表にない文字はどうなるかというと思い切りよく捨てられていました。エディタとして情報落ちするという欠点はあるにせよ次善策としてnkfで変換すればいいことに気がつきました。
ただ、この方式で注意が必要なのは、NKFで-Swした場合、先の変換表にない文字をすべてカットしてくれるわけでもないようで、例えば13区-94の0x879eを-Swすると0xe38a99(U+3299:マル秘)に変換されてしまいます。つまり書き戻すことのできないコードに変換されてしまったわけです。なぜ、こういう変換がなされるのか?他にもこのような(誤)変換があるのか?実際、下記のように実験してみると”nkf -Sw | nkf -Ws”と行って帰ってきても元ファイルと同じ内容にはなりませんからnkfのバグだろうといえるのですが、現実的にはなにか対策が必要になります。
%> od -x 13.txt
0000000 879e 0d0a
%> nkf -Sw 13.txt | od -x
0000000 e38a 990d 0a00
%> nkf -Sw 13.txt | nkf -Ws | od -x
0000000 0d0aまあ、それでいろいろ悩んだわけですが詰まるところ読み込み時に変換不能文字として捨てることを許容するのであれば、書き込み時も同じように変換不能文字をカットしてもいいだろうという(逃げの)結論に達してしまいました。(^^ゞ
つまりもう一度変換してやるってことです。
修正の概要を整理すると、
- guessEncodingFromData:NSDataによるエンコード判定
- 1.で判定不能の場合stringWithContentsOfFile:usedEncoding:errorでエンコードを調べる
- 1または2で判定したエンコードを使いinitWithContentsOfFile:encoding:errorで読み込み
- 何かごにょごにょと編集
- canBeConvertedToEncoding:で保存可能か否か調べる
- 5.でエラーの場合stringByNKFWithOptions:で変換する
- writeToURL:atomically:encoding:errorで書き込み
という流れを考えています。
保存時の変換には何らかのアラートを出すことも考えています。オリジナルの実装でもこのケースはアラートが表示されますが、単に”UTF-8とか違うエンコードで保存しなよ”というだけでそこからエンコードを指定できるわけではないのでちょっと不親切。できればエンコードを再選択するかあるいはNKFCocoaで変換するかを選択できるようなインタフェース(JeditX風に)にしたいなぁ(という希望)。これから実装するので今はなんとでも書けるから気楽ですが。何か?それにしても、単なる「不便だなぁ」からこのSmultronへの修正が本格化してきましたねぇ。
**ここに書いてるのはnkf-2.0.8ベースのことです。






最近のコメント
34 weeks 5 days ago
51 weeks 5 days ago
51 weeks 5 days ago
1年 16 weeks ago
1年 16 weeks ago
1年 17 weeks ago
1年 28 weeks ago
1年 28 weeks ago
2 years 8 weeks ago
2 years 17 weeks ago