JavaFX Scriptの簡単なローカリゼーション機能

またまたしばらく間が空いてしまいましたが、ここ最近はずっとJavaFX Scriptの国際化についての仕事をしています。JavaFX ScriptはJavaをベースにしたスクリプト言語なわけで、もちろんJavaに本来備わっている国際化に関する機能はすべて使えるわけですが、JavaFX ScriptからいちいちJavaの機能を呼び出して国際化関連のことを行うのはスクリプト言語らしくないし、さらにJava言語とJavaFX言語が混在してバグの元になりかねません。そこでJavaFX言語の仕様策定中ということもあり、その中に入れてしまいたいのがリテラル文字列を簡単にローカライズできる仕組みです。ある文字列をローカライズする場合、Javaでは普通、

    import java.util.ResourceBundle;

    static final String GREETINGS_KEY = "HELLO_WORLD";

    String greetings;
    try {
        ResourceBundle rb = ResourceBundle.getBundle("foo.bar.resources.My_Resource");
        greetings = rb.getString(GREETINGS_KEY);
    } catch (MissingResourceException mre) {
        greetings = "Hello, World!";
    }

の様に書くと思いますが、いま模索中なのがGNUのgettext()関数のように、引数となる文字列がそのままデフォルトの翻訳になるような仕組みです。上のコードをそのシンタックスで表記すると、

    var greetings = ##"Hello, World!";

たったの一行。シンプルでしょ?ここで"##"はリテラル文字列に働く単項演算子のような役割をします。この演算子がつくと実行時にこのリテラル文字列"Hello, World!"をキーとして適当な翻訳を探します。お気づきの方もいると思いますが、PropertyResourceBundleはホワイトスペース' 'をデリミタとして解釈するため、実は"Hello, World!"はキーとはなり得ないんです。そこで提案したいのがJavaFX Script用の新しいリソースバンドルのフォーマット。このフォーマットは単純に次のようなフォームを取ります。

    <JavaFX string literal> = <JavaFX string literal>
e.g.,
    "Hello, World!" = "こんにちは、世界!"

さらにボーナスとして考えているのは、このFX propertiesのデフォルトのエンコーディングを"UTF-8"にしようというもの。これで今まで頭を痛めてきた"ISO-8859-1" & native2asciiの呪縛から解放されるでしょう。他のエンコーディングを指定したい場合は、ファイルの頭にCSS形式のエンコーディング宣言(@charset "<IANA defined charset name>";)を入れてあげればそれに従うようにします。

ただこの方式には問題が一つあり、スクリプト内に同じリテラル文字列があり、それぞれ別の翻訳をさせたい場合(例えば2つの"File"というリテラル文字列をそれぞれ名詞、動詞として翻訳したい場合)に困ってしまいます。この問題を解決するためにオプションとしてキーを明示的に指定できるようにしました。#[FILE_NOUN]"File"のように、大括弧でくくって明示的なキーを指定します。

まあこんな所ですが、プロポーザル(英語です)とプロトタイプ実装をPlanet JFX wikiに置いてみたんで、どうぞおためしください。それとコメント、感想もよろしく!

Comments:

文字列に変数を埋め込む場合はどうするんですか?
つまり、
var nation: String = "World";
var hello:String = "Hello, {nation}!";
と定義して、かつ hello をリソースバンドルで扱いたい場合などです。
できれば、文字列の変数埋め込みも可能にしたまま、リソースバンドルで扱える方がいいと思います。

Posted by yuichi.sakuraba on January 10, 2008 at 12:40 PM PST #

Embedded expression は、printf の変換に置き換えられます。"Hello, {nation}!" は "Hello, %s!" に変更されて、これをキーにしてリソースを持ってきます。例えば日本語のリソースが、

"Hello, %s!" = "%s こんにちは!"

であれば、最終的に、

String.format("%s こんにちは!", nation);

という呼び出しになります。ここで問題になるのは、Java の printf の国際化機能がいまひとつ弱いことですが、## の件が一段落したら printf の強化に取り組む予定です。

Posted by masayoshi.okutsu on January 10, 2008 at 01:27 PM PST #

okutsuさんの返答に追加です。

Embedded expression、デフォルトでは%sへの置き換えになりますが、他にも明示的に、

##"Calendar of {%tB Calendar.getInstance()}."; (FXのソース)
"Calendar of %tB." = "%tBのカレンダー" (日本語用FXプロパティファイル)

とすれば、「一月のカレンダー」の様に表示されます。

Posted by Naoto Sato on January 11, 2008 at 05:31 AM PST #

Post a Comment:
Comments are closed for this entry.
About

naotoj

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
News

No bookmarks in folder

Blogroll