青山です。
ちょっと抽象的な説明でわかりにくかったようなので、実際に試せるコードを
用意してみました。
まず、適当に置換などで、=begin を、=begin RD LANG=en のように変更した
ファイルを用意します。既存のファイルを置換して用意するのではなく、
=begin RD LANG=en
=end
これだけでも OK 日本語の場合は LANG=ja のように
そして、そのファイルを(添付コードの名前を rd とすると)
$ rd none foo.rb
のようにして RD の含まれたファイルを処理すると、英語の RD は削除され、
=begin RD LANG=none となります。
そして、
$ rd en foo.rb
これで LANG=en の RD を復帰できます。さらに、
$ rd ja foo.rb
これで LANG=ja の RD になります。この時、LANG=en の状態で変更があって
も、それも反映されます。ここで適当に =begin, =end 内に文書を書いて、
$ rd none foo.rb
これでやはり LANG=none になり、
$ rd en foo.rb
LANG=en に、と、自由に行き来できます。
この説明もちょっとわかりにくいですが、実際に試されてみると気持は伝わる
と思います。
つまり、各言語のファイルを別に用意するという事ではなく、人が読み書きす
るのは常に *.rb で、各言語の情報はツールによって自動生成、更新にするわ
けです。
これにより、
* めんどくさい
--> 触るのは今までと同じくソースだけなので、簡単
* どれがエンコードされてるのかわからない
--> 各言語の情報はソースとは別のデータファイル(今回の場合 *.rbd)にまと
まっているのでわかりやすい
* ビューアやエディタでそのまま見えるのがRDのいいところ
--> ソースは今までと同じ扱いなので、この特徴もそのまま OK
パッチを出す時も、LANG=none でお願いね。とかすれば問題無いでしょう。
つまり、配布形態としては、LANG=none の *.rb と、各言語の情報が入った
(今回の場合) *.rbd の2つをセットという感じです。
#!/usr/local/bin/ruby
require "pstore"
new_lang = ARGV.shift
ARGV.each do |file_name|
rd = PStore.new(file_name + "d")
rd.transaction do
rd[new_lang] = [] unless rd.roots.include?(new_lang)
File.rename(file_name, file_name + ".org")
open(file_name, "w") do |out_file|
open(file_name + ".org") do |in_file|
lang = nil
no = nil
buf = ""
in_file.each do |line|
if (/^=begin\s+RD/ === line) .. (/^=end/ === line)
if /^=begin\s+RD(?:\s+LANG=(\S+))?(?:\s+#(\d+))?/ === line
lang = $1.dup if $1
rd[lang] = [] unless rd.roots.include?(lang)
no = $2 ? Integer($2) : rd[lang].size
rd[lang][no] = "" unless rd[lang][no]
next
end
if /^=end/ === line
rd[lang][no] = buf
buf = ""
out_file.print "=begin RD LANG=#{new_lang} ##{no}\n"
out_file.print (rd[new_lang][no] || "")
out_file.print "=end\n"
next
end
buf.concat(line)
else
out_file.print line
end
end
end
end
end
end
--
青山 和光 Wakou Aoyama <wakou / fsinet.or.jp>