VC9とutf-8 (BOM付きUTF-8)、VC9とUTF-8 (BOM付きUTF-8)別解の続き、とでも言うかな。「答え合わせ」とでも言うか。
utf-8-sig ってさ、Google さんを召還すれば、いくらでも出てくるよ。Python での扱い方は。あたしのサイトのばやい、大抵裏テーマがあって、具体的には例えば「screencastが普及して欲しい」とかがあるよ。ので案外見かけ上「メインテーマ」にみえる部分に重きを置いていない場合がある。だからね、ここであえて「アタシの解」を書くことに価値があるんだろうか、とは思うわけ。
そうなんだけど、ちと個人用途でほんとに自分で「それ」をすることになったんで、ま、「解の一つ」としてあげとこうかと。そもそも「困って検索して」結果あたしのサイトにたどり着くのであろうから、まぁなんかしらの答えは持ち帰ってもらった方が気分よかろ?
何の話か? こういうこと:
- Unix向けが主役の C++を書いている
- コーディング規約的なことで、ソースコードは BOM なし utf-8 である必要がある
- Windows でもビルド出来るようにしておくと、品質が高くなる(思わぬ潜在バグに気付けるので)
- ので、簡単に utf-8-sig との行き来を出来るようにしておきたい
- が、変更もないのにタイムスタンプが変わることは避けたい
つまりは、
VC9とutf-8 (BOM付きUTF-8)で書いた以下:
1 import codecs
2 with codecs.getwriter("utf-8-sig")(open("test3.cpp", "wb")) as fo:
3 fo.write(open("test1.cpp", "rb").read().decode("utf-8"))
の「よりちゃんとしたやつ」が欲しくね? ってハナシ。
あたしの解は以下です:
1 class UTF8Converter(object):
2 def __init__(self, target):
3 if target == 'msvc':
4 self._dest_enc = 'utf-8-sig'
5 else:
6 self._dest_enc = 'utf-8'
7
8 def __call__(self, sf):
9 import os
10 import codecs
11 import tempfile
12
13 cnt_in = open(sf, "rb").read()
14 tf = tempfile.NamedTemporaryFile(delete=False)
15 with codecs.getwriter(self._dest_enc)(tf) as fo:
16 fo.write(cnt_in.decode("utf-8-sig"))
17 cnt_out = open(tf.name, "rb").read()
18 if cnt_in != cnt_out:
19 open(sf, "wb").write(cnt_out)
20 else:
21 os.unlink(tf.name)
22
23 if __name__ == '__main__':
24 import sys
25 cnv = UTF8Converter(sys.argv[1])
26 for fn in sys.argv[2:]:
27 cnv(fn)
注意して欲しいのは、「any from-to utf-8系」 ではない ってこと。あくまでも「テキストエディタが utf-8(系)で書き出せる能力を持っていて、かつ、開発者は自覚的にutf-8(系)で書き出す」ことを前提としてるってこと。ので、utf-8 以外を与えれば当然 Unicode 例外起こります。
ところでこれ、例によってというか。10分で書き上げるつもりが、なぜか1時間以上かかってしまった。つまらんことでミスって。あたしってばいつもそうだ