« Leopard に引っ越し | トップページ | nib2ibstr.rb で ibtool に乗り換え »

2007.10.29

nibtool の辞書ファイルを ibtool 用に変換する

どうやら nibtool がなくなって ibtool になったようだ。man ibtool(1) を見た感じでは、オプションの書きかたが違うだけで、機能的にはほぼ同じもののようだ。あんまり使ってなかったけれど、ローカライズにちょっと使っていたりした。その辞書ファイルの形式が変わっているのだ。

たとえば nibtool では

 /* NSMenuItem : <title:Copy> (oid:290) */
 "Copy" = "コピー";

となっていたものが、

 /* Class = "NSMenuItem"; title = "Copy"; ObjectID = "290"; */
 "290.title" = "Copy";

となっていて、表記から ObjectID に対象の特定方法が変わったようだ。「まあ、もとのファイルの oid もあるし、変換すりゃいいか」とやってみたものの、一部の項目でエラーとなる。

  • テーブルビューの列ヘッダは title でなく、headerCell.title
  • NSTextField は NSTextFieldCell に

など、単純には変換できないものがある。特に後者は ObjectID が変わるし、nibtool のときには存在しないので追っかけようがない。

仕方ないので、一度 ibtool で生成した辞書を元に、表記基準で一致するものを差し替えていくようにしてみた。Ruby で UTF16 を BOM 付きで出力する方法がわからなかったので無理やり。手元では使えたけれど、あんま複雑な nib がないので、ヨソでも大丈夫かはわからん。つーか、標準のツールがあるような気がしてしかたがない…

コピペするのがめんどうなひとはこちらから nibstrmerge.rb.txt

(2007/10/31 追記:少し進化 nib2ibstr.rb

 #!/usr/bin/ruby
 #
 #   Usage: 
 #   1. generate ibtool string 
 #     ibtool --generate-stringsfile ibtool-orig.strings MyNibFile.nib
 #   2. merge nibtool strings into ibtool strings 
 #     nibstrmerge.rb nibtool.strings ibtool-orig.strings > ibtool-new.strings
 #
 # $Id: nibstrmerge.rb 601 2007-10-29 13:38:56Z kimuraw $
 require 'iconv'
 FILE_ENC = 'UTF-16'
 FILE_ENC_O = 'UTF-16LE'
 WORK_ENC = 'UTF-8'
 $KCODE = 'u' # utf8
 
 # READ NIB STRINGS
 NibItem = Struct.new(:klass, :attr, :key, :oid, :key2, :string)
 class NibItem
   NIBLINE_1 = '/\* (\S+) (\(.+\) )?: <(\S+):(.+)> \(oid:(\d+)\) \*/' + "\n"
   NIBLINE_2 = '"(.+)" = "(.*)";' + "\n"
   class <<self
     def read(path)
       pattern = Regexp.new(NIBLINE_1 + NIBLINE_2)
       input = Iconv.conv(WORK_ENC, FILE_ENC, File.open(path).read)
       dict = {}
       while input.slice!(pattern) do
         item = NibItem.new($1, $3, $4, $5, $6, $7)
         dict[item.key2] = item
       end
       dict
     end
   end
 end
 
 # READ TEMPLATE IB STRINGS and REPLACE LOCALIZED STRING
 class IbItem
   IBLINE_1 = '/\* Class = "(\S+)"; (\S+) = "(.*)"; ObjectID = "(\d+)"; \*/' + "\n"
   IBLINE_2 = '"(\d+)\.(\S+)" = "(.*)";' + "\n"
   class <<self
     def convert(path, dict, out=$stdout)
       input = Iconv.conv(WORK_ENC, FILE_ENC, File.open(path).read)
       pattern = Regexp.new(IBLINE_1 + IBLINE_2)
       result = ""
       while input.slice!(pattern) do 
         str = if item = dict[$3] 
           then item.string 
           else $3 
           end
         result << 
            %Q!/* Class = "#{$1}"; #{$2} = "#{$3}"; ObjectID = "#{$4}"; */\n! <<
            %Q!"#{$5}.#{$6}" = "#{str}";\n! <<
            "\n"
       end
       out <<
         "\xff\xfe" <<
         "\x0a\00" <<
         Iconv.conv(FILE_ENC_O, WORK_ENC, result)
     end
   end
 end
 
 dict = NibItem.read(ARGV[0])
 IbItem.convert(ARGV[1], dict)

|

« Leopard に引っ越し | トップページ | nib2ibstr.rb で ibtool に乗り換え »