experteer-gettext 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +55 -0
- data/ChangeLog +57 -0
- data/ChangeLog-1 +2016 -0
- data/NEWS-1 +414 -0
- data/README.rdoc +251 -0
- data/Rakefile +260 -0
- data/VERSION +2 -0
- data/bin/rgettext +24 -0
- data/bin/rmsgfmt +24 -0
- data/bin/rmsgmerge +24 -0
- data/gettext.gemspec +494 -0
- data/lib/gettext/cgi.rb +39 -0
- data/lib/gettext/class_info.rb +67 -0
- data/lib/gettext/core_ext/iconv.rb +112 -0
- data/lib/gettext/core_ext/string.rb +84 -0
- data/lib/gettext/locale_path.rb +123 -0
- data/lib/gettext/mofile.rb +330 -0
- data/lib/gettext/parser/erb.rb +54 -0
- data/lib/gettext/parser/glade.rb +100 -0
- data/lib/gettext/parser/ruby.rb +193 -0
- data/lib/gettext/poparser.rb +355 -0
- data/lib/gettext/textdomain.rb +179 -0
- data/lib/gettext/textdomain_group.rb +24 -0
- data/lib/gettext/textdomain_manager.rb +212 -0
- data/lib/gettext/tools/rgettext.rb +236 -0
- data/lib/gettext/tools/rmsgfmt.rb +84 -0
- data/lib/gettext/tools/rmsgmerge.rb +498 -0
- data/lib/gettext/tools.rb +195 -0
- data/lib/gettext/translation_target.rb +93 -0
- data/lib/gettext/utils.rb +37 -0
- data/lib/gettext/version.rb +12 -0
- data/lib/gettext.rb +312 -0
- data/po/bg/rgettext.po +130 -0
- data/po/bs/rgettext.po +131 -0
- data/po/ca/rgettext.po +129 -0
- data/po/cs/rgettext.po +132 -0
- data/po/de/rgettext.po +137 -0
- data/po/el/rgettext.po +128 -0
- data/po/eo/rgettext.po +129 -0
- data/po/es/rgettext.po +130 -0
- data/po/et/rgettext.po +127 -0
- data/po/fr/rgettext.po +133 -0
- data/po/hr/rgettext.po +131 -0
- data/po/hu/rgettext.po +129 -0
- data/po/it/rgettext.po +130 -0
- data/po/ja/rgettext.po +129 -0
- data/po/ko/rgettext.po +129 -0
- data/po/lv/rgettext.po +130 -0
- data/po/nb/rgettext.po +131 -0
- data/po/nl/rgettext.po +130 -0
- data/po/pt_BR/rgettext.po +132 -0
- data/po/rgettext.pot +121 -0
- data/po/ru/rgettext.po +131 -0
- data/po/sr/rgettext.po +130 -0
- data/po/sv/rgettext.po +123 -0
- data/po/ua/rgettext.po +134 -0
- data/po/vi/rgettext.po +128 -0
- data/po/zh/rgettext.po +129 -0
- data/po/zh_TW/rgettext.po +128 -0
- data/samples/README +16 -0
- data/samples/cgi/README +43 -0
- data/samples/cgi/Rakefile +27 -0
- data/samples/cgi/cookie.cgi +64 -0
- data/samples/cgi/gettext.css +116 -0
- data/samples/cgi/helloerb.rhtml +28 -0
- data/samples/cgi/helloerb1.cgi +58 -0
- data/samples/cgi/helloerb2.cgi +51 -0
- data/samples/cgi/hellolib.rb +20 -0
- data/samples/cgi/http.rb +51 -0
- data/samples/cgi/index.cgi +111 -0
- data/samples/cgi/other.rhtml +20 -0
- data/samples/cgi/po/bg/helloerb1.po +59 -0
- data/samples/cgi/po/bg/helloerb2.po +51 -0
- data/samples/cgi/po/bg/hellolib.po +23 -0
- data/samples/cgi/po/bg/main.po +83 -0
- data/samples/cgi/po/bs/helloerb1.po +59 -0
- data/samples/cgi/po/bs/helloerb2.po +51 -0
- data/samples/cgi/po/bs/hellolib.po +23 -0
- data/samples/cgi/po/bs/main.po +83 -0
- data/samples/cgi/po/ca/helloerb1.po +59 -0
- data/samples/cgi/po/ca/helloerb2.po +51 -0
- data/samples/cgi/po/ca/hellolib.po +23 -0
- data/samples/cgi/po/ca/main.po +83 -0
- data/samples/cgi/po/cs/helloerb1.po +61 -0
- data/samples/cgi/po/cs/helloerb2.po +52 -0
- data/samples/cgi/po/cs/hellolib.po +25 -0
- data/samples/cgi/po/cs/main.po +85 -0
- data/samples/cgi/po/de/helloerb1.po +61 -0
- data/samples/cgi/po/de/helloerb2.po +52 -0
- data/samples/cgi/po/de/hellolib.po +24 -0
- data/samples/cgi/po/de/main.po +86 -0
- data/samples/cgi/po/el/helloerb1.po +60 -0
- data/samples/cgi/po/el/helloerb2.po +51 -0
- data/samples/cgi/po/el/hellolib.po +23 -0
- data/samples/cgi/po/el/main.po +84 -0
- data/samples/cgi/po/eo/helloerb1.po +60 -0
- data/samples/cgi/po/eo/helloerb2.po +52 -0
- data/samples/cgi/po/eo/hellolib.po +24 -0
- data/samples/cgi/po/eo/main.po +84 -0
- data/samples/cgi/po/es/helloerb1.po +59 -0
- data/samples/cgi/po/es/helloerb2.po +50 -0
- data/samples/cgi/po/es/hellolib.po +22 -0
- data/samples/cgi/po/es/main.po +83 -0
- data/samples/cgi/po/fr/helloerb1.po +59 -0
- data/samples/cgi/po/fr/helloerb2.po +51 -0
- data/samples/cgi/po/fr/hellolib.po +22 -0
- data/samples/cgi/po/fr/main.po +85 -0
- data/samples/cgi/po/helloerb1.pot +60 -0
- data/samples/cgi/po/helloerb2.pot +52 -0
- data/samples/cgi/po/hellolib.pot +24 -0
- data/samples/cgi/po/hr/helloerb1.po +59 -0
- data/samples/cgi/po/hr/helloerb2.po +51 -0
- data/samples/cgi/po/hr/hellolib.po +23 -0
- data/samples/cgi/po/hr/main.po +83 -0
- data/samples/cgi/po/hu/helloerb1.po +59 -0
- data/samples/cgi/po/hu/helloerb2.po +51 -0
- data/samples/cgi/po/hu/hellolib.po +23 -0
- data/samples/cgi/po/hu/main.po +82 -0
- data/samples/cgi/po/it/helloerb1.po +60 -0
- data/samples/cgi/po/it/helloerb2.po +52 -0
- data/samples/cgi/po/it/hellolib.po +24 -0
- data/samples/cgi/po/it/main.po +84 -0
- data/samples/cgi/po/ja/helloerb1.po +60 -0
- data/samples/cgi/po/ja/helloerb2.po +52 -0
- data/samples/cgi/po/ja/hellolib.po +24 -0
- data/samples/cgi/po/ja/main.po +85 -0
- data/samples/cgi/po/ko/helloerb1.po +59 -0
- data/samples/cgi/po/ko/helloerb2.po +51 -0
- data/samples/cgi/po/ko/hellolib.po +23 -0
- data/samples/cgi/po/ko/main.po +84 -0
- data/samples/cgi/po/lv/helloerb1.po +65 -0
- data/samples/cgi/po/lv/helloerb2.po +52 -0
- data/samples/cgi/po/lv/hellolib.po +24 -0
- data/samples/cgi/po/lv/main.po +77 -0
- data/samples/cgi/po/main.pot +80 -0
- data/samples/cgi/po/nb/helloerb1.po +60 -0
- data/samples/cgi/po/nb/helloerb2.po +52 -0
- data/samples/cgi/po/nb/hellolib.po +24 -0
- data/samples/cgi/po/nb/main.po +84 -0
- data/samples/cgi/po/nl/helloerb1.po +61 -0
- data/samples/cgi/po/nl/helloerb2.po +52 -0
- data/samples/cgi/po/nl/hellolib.po +24 -0
- data/samples/cgi/po/nl/main.po +86 -0
- data/samples/cgi/po/pt_BR/helloerb1.po +59 -0
- data/samples/cgi/po/pt_BR/helloerb2.po +51 -0
- data/samples/cgi/po/pt_BR/hellolib.po +23 -0
- data/samples/cgi/po/pt_BR/main.po +84 -0
- data/samples/cgi/po/ru/helloerb1.po +58 -0
- data/samples/cgi/po/ru/helloerb2.po +50 -0
- data/samples/cgi/po/ru/hellolib.po +22 -0
- data/samples/cgi/po/ru/main.po +82 -0
- data/samples/cgi/po/sr/helloerb1.po +60 -0
- data/samples/cgi/po/sr/helloerb2.po +52 -0
- data/samples/cgi/po/sr/hellolib.po +24 -0
- data/samples/cgi/po/sr/main.po +80 -0
- data/samples/cgi/po/ua/helloerb1.po +62 -0
- data/samples/cgi/po/ua/helloerb2.po +54 -0
- data/samples/cgi/po/ua/hellolib.po +26 -0
- data/samples/cgi/po/ua/main.po +84 -0
- data/samples/cgi/po/vi/helloerb1.po +65 -0
- data/samples/cgi/po/vi/helloerb2.po +52 -0
- data/samples/cgi/po/vi/hellolib.po +24 -0
- data/samples/cgi/po/vi/main.po +77 -0
- data/samples/cgi/po/zh/helloerb1.po +60 -0
- data/samples/cgi/po/zh/helloerb2.po +52 -0
- data/samples/cgi/po/zh/hellolib.po +24 -0
- data/samples/cgi/po/zh/main.po +80 -0
- data/samples/cgi/po/zh_TW/helloerb1.po +67 -0
- data/samples/cgi/po/zh_TW/helloerb2.po +54 -0
- data/samples/cgi/po/zh_TW/hellolib.po +26 -0
- data/samples/cgi/po/zh_TW/main.po +79 -0
- data/samples/hello.rb +36 -0
- data/samples/hello2.rb +23 -0
- data/samples/hello_glade2.glade +70 -0
- data/samples/hello_glade2.rb +25 -0
- data/samples/hello_gtk2.rb +27 -0
- data/samples/hello_noop.rb +31 -0
- data/samples/hello_plural.rb +26 -0
- data/samples/hello_tk.rb +19 -0
- data/samples/makemo.rb +4 -0
- data/samples/po/bg/hello.po +24 -0
- data/samples/po/bg/hello2.po +31 -0
- data/samples/po/bg/hello_glade2.po +31 -0
- data/samples/po/bg/hello_gtk.po +23 -0
- data/samples/po/bg/hello_noop.po +27 -0
- data/samples/po/bg/hello_plural.po +25 -0
- data/samples/po/bg/hello_tk.po +23 -0
- data/samples/po/bs/hello.po +23 -0
- data/samples/po/bs/hello2.po +31 -0
- data/samples/po/bs/hello_glade2.po +31 -0
- data/samples/po/bs/hello_gtk.po +23 -0
- data/samples/po/bs/hello_noop.po +27 -0
- data/samples/po/bs/hello_plural.po +26 -0
- data/samples/po/bs/hello_tk.po +23 -0
- data/samples/po/ca/hello.po +23 -0
- data/samples/po/ca/hello2.po +31 -0
- data/samples/po/ca/hello_glade2.po +31 -0
- data/samples/po/ca/hello_gtk.po +23 -0
- data/samples/po/ca/hello_noop.po +27 -0
- data/samples/po/ca/hello_plural.po +25 -0
- data/samples/po/ca/hello_tk.po +23 -0
- data/samples/po/cs/hello.po +23 -0
- data/samples/po/cs/hello2.po +31 -0
- data/samples/po/cs/hello_glade2.po +37 -0
- data/samples/po/cs/hello_gtk.po +23 -0
- data/samples/po/cs/hello_noop.po +27 -0
- data/samples/po/cs/hello_plural.po +26 -0
- data/samples/po/cs/hello_tk.po +23 -0
- data/samples/po/de/hello.po +20 -0
- data/samples/po/de/hello2.po +28 -0
- data/samples/po/de/hello_glade2.po +27 -0
- data/samples/po/de/hello_gtk.po +20 -0
- data/samples/po/de/hello_noop.po +24 -0
- data/samples/po/de/hello_plural.po +25 -0
- data/samples/po/de/hello_tk.po +20 -0
- data/samples/po/el/hello.po +23 -0
- data/samples/po/el/hello2.po +31 -0
- data/samples/po/el/hello_glade2.po +31 -0
- data/samples/po/el/hello_gtk.po +22 -0
- data/samples/po/el/hello_noop.po +27 -0
- data/samples/po/el/hello_plural.po +25 -0
- data/samples/po/el/hello_tk.po +23 -0
- data/samples/po/eo/hello.po +23 -0
- data/samples/po/eo/hello2.po +31 -0
- data/samples/po/eo/hello_glade2.po +32 -0
- data/samples/po/eo/hello_gtk.po +23 -0
- data/samples/po/eo/hello_noop.po +27 -0
- data/samples/po/eo/hello_plural.po +26 -0
- data/samples/po/eo/hello_tk.po +24 -0
- data/samples/po/es/hello.po +21 -0
- data/samples/po/es/hello2.po +28 -0
- data/samples/po/es/hello_glade2.po +28 -0
- data/samples/po/es/hello_gtk.po +20 -0
- data/samples/po/es/hello_noop.po +24 -0
- data/samples/po/es/hello_plural.po +23 -0
- data/samples/po/es/hello_tk.po +20 -0
- data/samples/po/fr/hello.po +18 -0
- data/samples/po/fr/hello2.po +26 -0
- data/samples/po/fr/hello_glade2.po +27 -0
- data/samples/po/fr/hello_gtk.po +18 -0
- data/samples/po/fr/hello_noop.po +22 -0
- data/samples/po/fr/hello_plural.po +21 -0
- data/samples/po/fr/hello_tk.po +18 -0
- data/samples/po/hello.pot +23 -0
- data/samples/po/hello2.pot +31 -0
- data/samples/po/hello_glade2.pot +32 -0
- data/samples/po/hello_gtk.pot +23 -0
- data/samples/po/hello_noop.pot +27 -0
- data/samples/po/hello_plural.pot +26 -0
- data/samples/po/hello_tk.pot +24 -0
- data/samples/po/hr/hello.po +23 -0
- data/samples/po/hr/hello2.po +31 -0
- data/samples/po/hr/hello_glade2.po +31 -0
- data/samples/po/hr/hello_gtk.po +23 -0
- data/samples/po/hr/hello_noop.po +27 -0
- data/samples/po/hr/hello_plural.po +26 -0
- data/samples/po/hr/hello_tk.po +23 -0
- data/samples/po/hu/hello.po +22 -0
- data/samples/po/hu/hello2.po +30 -0
- data/samples/po/hu/hello_glade2.po +31 -0
- data/samples/po/hu/hello_gtk.po +22 -0
- data/samples/po/hu/hello_noop.po +26 -0
- data/samples/po/hu/hello_plural.po +25 -0
- data/samples/po/hu/hello_tk.po +23 -0
- data/samples/po/it/hello.po +20 -0
- data/samples/po/it/hello2.po +28 -0
- data/samples/po/it/hello_glade2.po +28 -0
- data/samples/po/it/hello_gtk.po +21 -0
- data/samples/po/it/hello_noop.po +24 -0
- data/samples/po/it/hello_plural.po +23 -0
- data/samples/po/it/hello_tk.po +21 -0
- data/samples/po/ja/hello.po +20 -0
- data/samples/po/ja/hello2.po +28 -0
- data/samples/po/ja/hello_glade2.po +26 -0
- data/samples/po/ja/hello_gtk.po +19 -0
- data/samples/po/ja/hello_noop.po +23 -0
- data/samples/po/ja/hello_plural.po +21 -0
- data/samples/po/ja/hello_tk.po +19 -0
- data/samples/po/ko/hello.po +18 -0
- data/samples/po/ko/hello2.po +26 -0
- data/samples/po/ko/hello_glade2.po +29 -0
- data/samples/po/ko/hello_gtk.po +18 -0
- data/samples/po/ko/hello_noop.po +22 -0
- data/samples/po/ko/hello_plural.po +25 -0
- data/samples/po/ko/hello_tk.po +19 -0
- data/samples/po/lv/hello.po +24 -0
- data/samples/po/lv/hello2.po +32 -0
- data/samples/po/lv/hello_glade2.po +38 -0
- data/samples/po/lv/hello_gtk.po +24 -0
- data/samples/po/lv/hello_noop.po +28 -0
- data/samples/po/lv/hello_plural.po +26 -0
- data/samples/po/lv/hello_tk.po +24 -0
- data/samples/po/nb/hello.po +23 -0
- data/samples/po/nb/hello2.po +31 -0
- data/samples/po/nb/hello_glade2.po +31 -0
- data/samples/po/nb/hello_gtk.po +23 -0
- data/samples/po/nb/hello_noop.po +27 -0
- data/samples/po/nb/hello_plural.po +26 -0
- data/samples/po/nb/hello_tk.po +24 -0
- data/samples/po/nl/hello.po +24 -0
- data/samples/po/nl/hello2.po +32 -0
- data/samples/po/nl/hello_glade2.po +31 -0
- data/samples/po/nl/hello_gtk.po +24 -0
- data/samples/po/nl/hello_noop.po +28 -0
- data/samples/po/nl/hello_plural.po +25 -0
- data/samples/po/nl/hello_tk.po +24 -0
- data/samples/po/pt_BR/hello.po +21 -0
- data/samples/po/pt_BR/hello2.po +29 -0
- data/samples/po/pt_BR/hello_glade2.po +29 -0
- data/samples/po/pt_BR/hello_gtk.po +21 -0
- data/samples/po/pt_BR/hello_noop.po +25 -0
- data/samples/po/pt_BR/hello_plural.po +23 -0
- data/samples/po/pt_BR/hello_tk.po +21 -0
- data/samples/po/ru/hello.po +22 -0
- data/samples/po/ru/hello2.po +30 -0
- data/samples/po/ru/hello_glade2.po +30 -0
- data/samples/po/ru/hello_gtk.po +22 -0
- data/samples/po/ru/hello_noop.po +26 -0
- data/samples/po/ru/hello_plural.po +28 -0
- data/samples/po/ru/hello_tk.po +22 -0
- data/samples/po/sr/hello.po +22 -0
- data/samples/po/sr/hello2.po +30 -0
- data/samples/po/sr/hello_glade2.po +32 -0
- data/samples/po/sr/hello_gtk.po +22 -0
- data/samples/po/sr/hello_noop.po +26 -0
- data/samples/po/sr/hello_plural.po +26 -0
- data/samples/po/sr/hello_tk.po +24 -0
- data/samples/po/sv/hello.po +20 -0
- data/samples/po/sv/hello2.po +28 -0
- data/samples/po/sv/hello_glade2.po +28 -0
- data/samples/po/sv/hello_gtk.po +20 -0
- data/samples/po/sv/hello_noop.po +24 -0
- data/samples/po/sv/hello_plural.po +23 -0
- data/samples/po/sv/hello_tk.po +20 -0
- data/samples/po/test.rb +11 -0
- data/samples/po/ua/hello.po +22 -0
- data/samples/po/ua/hello2.po +30 -0
- data/samples/po/ua/hello_glade2.po +34 -0
- data/samples/po/ua/hello_gtk.po +22 -0
- data/samples/po/ua/hello_noop.po +26 -0
- data/samples/po/ua/hello_plural.po +29 -0
- data/samples/po/ua/hello_tk.po +26 -0
- data/samples/po/vi/hello.po +23 -0
- data/samples/po/vi/hello2.po +31 -0
- data/samples/po/vi/hello_glade2.po +38 -0
- data/samples/po/vi/hello_gtk.po +23 -0
- data/samples/po/vi/hello_noop.po +27 -0
- data/samples/po/vi/hello_plural.po +26 -0
- data/samples/po/vi/hello_tk.po +24 -0
- data/samples/po/zh/hello.po +23 -0
- data/samples/po/zh/hello2.po +31 -0
- data/samples/po/zh/hello_glade2.po +31 -0
- data/samples/po/zh/hello_gtk.po +23 -0
- data/samples/po/zh/hello_noop.po +27 -0
- data/samples/po/zh/hello_plural.po +25 -0
- data/samples/po/zh/hello_tk.po +23 -0
- data/samples/po/zh_TW/hello.po +26 -0
- data/samples/po/zh_TW/hello2.po +34 -0
- data/samples/po/zh_TW/hello_glade2.po +40 -0
- data/samples/po/zh_TW/hello_gtk.po +25 -0
- data/samples/po/zh_TW/hello_noop.po +30 -0
- data/samples/po/zh_TW/hello_plural.po +28 -0
- data/samples/po/zh_TW/hello_tk.po +26 -0
- data/test/README +1 -0
- data/test/Rakefile +17 -0
- data/test/po/cr/plural.po +23 -0
- data/test/po/da/plural.po +22 -0
- data/test/po/da/plural_error.po +22 -0
- data/test/po/fr/plural.po +28 -0
- data/test/po/fr/plural_error.po +20 -0
- data/test/po/fr/test1.po +23 -0
- data/test/po/fr/test2.po +19 -0
- data/test/po/ir/plural.po +23 -0
- data/test/po/ja/npgettext.po +46 -0
- data/test/po/ja/nsgettext.po +65 -0
- data/test/po/ja/pgettext.po +41 -0
- data/test/po/ja/plural.po +28 -0
- data/test/po/ja/plural_error.po +20 -0
- data/test/po/ja/rubyparser.po +43 -0
- data/test/po/ja/sgettext.po +47 -0
- data/test/po/ja/test1.po +23 -0
- data/test/po/ja/test2.po +19 -0
- data/test/po/ja/test3.po +19 -0
- data/test/po/la/plural.po +23 -0
- data/test/po/la/plural_error.po +21 -0
- data/test/po/li/plural.po +23 -0
- data/test/po/li/plural_error.po +27 -0
- data/test/po/po/plural.po +23 -0
- data/test/po/sl/plural.po +24 -0
- data/test/test_class_info.rb +83 -0
- data/test/test_gettext.rb +311 -0
- data/test/test_locale_path.rb +50 -0
- data/test/test_parser.rb +157 -0
- data/test/test_po_generation.rb +20 -0
- data/test/test_string.rb +65 -0
- data/test/test_textdomain_bind.rb +37 -0
- data/test/test_textdomain_multi.rb +80 -0
- data/test/test_textdomain_toplevel.rb +42 -0
- data/test/test_thread.rb +41 -0
- data/test/test_translation_target.rb +29 -0
- data/test/testlib/N_.rb +66 -0
- data/test/testlib/erb.rhtml +15 -0
- data/test/testlib/erb.rxml +16 -0
- data/test/testlib/gettext.rb +113 -0
- data/test/testlib/gladeparser.glade +183 -0
- data/test/testlib/helper.rb +11 -0
- data/test/testlib/multi_textdomain.rb +131 -0
- data/test/testlib/ngettext.rb +79 -0
- data/test/testlib/npgettext.rb +31 -0
- data/test/testlib/nsgettext.rb +42 -0
- data/test/testlib/pgettext.rb +36 -0
- data/test/testlib/sgettext.rb +46 -0
- data/test/testlib/simple.rb +14 -0
- data/test/tools/files/app.pot +0 -0
- data/test/tools/files/de/app.po +0 -0
- data/test/tools/files/en/app.po +0 -0
- data/test/tools/files/en/test.po +21 -0
- data/test/tools/files/simple_1.po +2 -0
- data/test/tools/files/simple_2.po +2 -0
- data/test/tools/files/simple_translation.rb +1 -0
- data/test/tools/files/version.po +7 -0
- data/test/tools/test.pot +21 -0
- data/test/tools/test_tools.rb +61 -0
- metadata +510 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
=begin
|
|
3
|
+
iconv.rb - Pseudo Iconv class. Supports Iconv.iconv, Iconv.conv.
|
|
4
|
+
|
|
5
|
+
For Matz Ruby:
|
|
6
|
+
If you don't have iconv but glib2, this library uses glib2 iconv functions.
|
|
7
|
+
|
|
8
|
+
For JRuby:
|
|
9
|
+
Use Java String class to convert strings.
|
|
10
|
+
|
|
11
|
+
Copyright (C) 2004-2007 Masao Mutoh
|
|
12
|
+
|
|
13
|
+
You may redistribute it and/or modify it under the same
|
|
14
|
+
license terms as Ruby.
|
|
15
|
+
|
|
16
|
+
$Id: iconv.rb,v 1.6 2007/11/08 14:21:22 mutoh Exp $
|
|
17
|
+
=end
|
|
18
|
+
|
|
19
|
+
begin
|
|
20
|
+
require 'iconv.so'
|
|
21
|
+
rescue LoadError
|
|
22
|
+
# Pseudo Iconv class
|
|
23
|
+
#
|
|
24
|
+
# ==== For Matz Ruby:
|
|
25
|
+
# If you don't have iconv but Ruby/GLib2, this library uses Ruby/GLib2's
|
|
26
|
+
# iconv functions.
|
|
27
|
+
#
|
|
28
|
+
# Ruby/GLib is a module which is provided from Ruby-GNOME2 Project.
|
|
29
|
+
# You can get binaries for Win32(One-Click Ruby Installer).
|
|
30
|
+
# <URL: http://ruby-gnome2.sourceforge.jp/>
|
|
31
|
+
# ==== For JRuby:
|
|
32
|
+
# Use Java String class to convert strings.
|
|
33
|
+
class Iconv
|
|
34
|
+
module Failure; end
|
|
35
|
+
class InvalidEncoding < ArgumentError; include Failure; end
|
|
36
|
+
class IllegalSequence < ArgumentError; include Failure; end
|
|
37
|
+
class InvalidCharacter < ArgumentError; include Failure; end
|
|
38
|
+
|
|
39
|
+
if RUBY_PLATFORM =~ /java/
|
|
40
|
+
def self.conv(to, from, str)
|
|
41
|
+
raise InvalidCharacter, "the 3rd argument is nil" unless str
|
|
42
|
+
begin
|
|
43
|
+
str = java.lang.String.new(str.unpack("C*").to_java(:byte), from)
|
|
44
|
+
str.getBytes(to).to_ary.pack("C*")
|
|
45
|
+
rescue java.io.UnsupportedEncodingException
|
|
46
|
+
raise InvalidEncoding
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
begin
|
|
51
|
+
require 'glib2'
|
|
52
|
+
|
|
53
|
+
def self.check_glib_version?(major, minor, micro) # :nodoc:
|
|
54
|
+
(GLib::BINDING_VERSION[0] > major ||
|
|
55
|
+
(GLib::BINDING_VERSION[0] == major &&
|
|
56
|
+
GLib::BINDING_VERSION[1] > minor) ||
|
|
57
|
+
(GLib::BINDING_VERSION[0] == major &&
|
|
58
|
+
GLib::BINDING_VERSION[1] == minor &&
|
|
59
|
+
GLib::BINDING_VERSION[2] >= micro))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
if check_glib_version?(0, 11, 0)
|
|
63
|
+
# This is a function equivalent of Iconv.iconv.
|
|
64
|
+
# * to: encoding name for destination
|
|
65
|
+
# * from: encoding name for source
|
|
66
|
+
# * str: strings to be converted
|
|
67
|
+
# * Returns: Returns an Array of converted strings.
|
|
68
|
+
def self.conv(to, from, str)
|
|
69
|
+
begin
|
|
70
|
+
GLib.convert(str, to, from)
|
|
71
|
+
rescue GLib::ConvertError => e
|
|
72
|
+
case e.code
|
|
73
|
+
when GLib::ConvertError::NO_CONVERSION
|
|
74
|
+
raise InvalidEncoding.new(str)
|
|
75
|
+
when GLib::ConvertError::ILLEGAL_SEQUENCE
|
|
76
|
+
raise IllegalSequence.new(str)
|
|
77
|
+
else
|
|
78
|
+
raise InvalidCharacter.new(str)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
else
|
|
83
|
+
def self.conv(to, from, str) # :nodoc:
|
|
84
|
+
begin
|
|
85
|
+
GLib.convert(str, to, from)
|
|
86
|
+
rescue
|
|
87
|
+
raise IllegalSequence.new(str)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
rescue LoadError
|
|
92
|
+
def self.conv(to, from, str) # :nodoc:
|
|
93
|
+
warn "Iconv was not found." if $DEBUG
|
|
94
|
+
str
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
def self.iconv(to, from, str)
|
|
99
|
+
conv(to, from, str).split(//)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
if __FILE__ == $0
|
|
105
|
+
puts Iconv.iconv("EUC-JP", "UTF-8", "ほげ").join
|
|
106
|
+
begin
|
|
107
|
+
puts Iconv.iconv("EUC-JP", "EUC-JP", "ほげ").join
|
|
108
|
+
rescue Iconv::Failure
|
|
109
|
+
puts $!
|
|
110
|
+
puts $!.class
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
string.rb - Extension for String.
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2005-2009 Masao Mutoh
|
|
5
|
+
|
|
6
|
+
You may redistribute it and/or modify it under the same
|
|
7
|
+
license terms as Ruby.
|
|
8
|
+
=end
|
|
9
|
+
|
|
10
|
+
# Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError.
|
|
11
|
+
#
|
|
12
|
+
# String#% method which accept "named argument". The translator can know
|
|
13
|
+
# the meaning of the msgids using "named argument" instead of %s/%d style.
|
|
14
|
+
class String
|
|
15
|
+
|
|
16
|
+
unless instance_methods.find {|m| m.to_s == 'bytesize'}
|
|
17
|
+
# For older ruby (such as ruby-1.8.5)
|
|
18
|
+
alias :bytesize :size
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
alias :_old_format_m :% # :nodoc:
|
|
22
|
+
|
|
23
|
+
PERCENT_MATCH_RE = Regexp.union(
|
|
24
|
+
/%%/,
|
|
25
|
+
/%\{(.+?)\}/,
|
|
26
|
+
/%<(.+?)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# call-seq:
|
|
30
|
+
# %(arg)
|
|
31
|
+
# %(hash)
|
|
32
|
+
#
|
|
33
|
+
# Format - Uses str as a format specification, and returns the result of applying it to arg.
|
|
34
|
+
# If the format specification contains more than one substitution, then arg must be
|
|
35
|
+
# an Array containing the values to be substituted. See Kernel::sprintf for details of the
|
|
36
|
+
# format string. This is the default behavior of the String class.
|
|
37
|
+
# * arg: an Array or other class except Hash.
|
|
38
|
+
# * Returns: formatted String
|
|
39
|
+
#
|
|
40
|
+
# (e.g.) "%s, %s" % ["Masao", "Mutoh"]
|
|
41
|
+
#
|
|
42
|
+
# Also you can use a Hash as the "named argument". This is recommanded way for Ruby-GetText
|
|
43
|
+
# because the translators can understand the meanings of the msgids easily.
|
|
44
|
+
# * hash: {:key1 => value1, :key2 => value2, ... }
|
|
45
|
+
# * Returns: formatted String
|
|
46
|
+
#
|
|
47
|
+
# (e.g.)
|
|
48
|
+
# For strings.
|
|
49
|
+
# "%{firstname}, %{familyname}" % {:firstname => "Masao", :familyname => "Mutoh"}
|
|
50
|
+
#
|
|
51
|
+
# With field type to specify format such as d(decimal), f(float),...
|
|
52
|
+
# "%<age>d, %<weight>.1f" % {:age => 10, :weight => 43.4}
|
|
53
|
+
def %(args)
|
|
54
|
+
if args.kind_of?(Hash)
|
|
55
|
+
ret = dup
|
|
56
|
+
ret.gsub!(PERCENT_MATCH_RE) {|match|
|
|
57
|
+
if match == '%%'
|
|
58
|
+
'%'
|
|
59
|
+
elsif $1
|
|
60
|
+
key = $1.to_sym
|
|
61
|
+
args.has_key?(key) ? args[key] : match
|
|
62
|
+
elsif $2
|
|
63
|
+
key = $2.to_sym
|
|
64
|
+
args.has_key?(key) ? sprintf("%#{$3}", args[key]) : match
|
|
65
|
+
end
|
|
66
|
+
}
|
|
67
|
+
ret
|
|
68
|
+
else
|
|
69
|
+
ret = gsub(/%([{<])/, '%%\1')
|
|
70
|
+
begin
|
|
71
|
+
ret._old_format_m(args)
|
|
72
|
+
rescue ArgumentError => e
|
|
73
|
+
if $DEBUG
|
|
74
|
+
$stderr.puts " The string:#{ret}"
|
|
75
|
+
$stderr.puts " args:#{args.inspect}"
|
|
76
|
+
puts e.backtrace
|
|
77
|
+
else
|
|
78
|
+
raise ArgumentError, e.message
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
locale_path.rb - GetText::LocalePath
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2001-2009 Masao Mutoh
|
|
5
|
+
|
|
6
|
+
You may redistribute it and/or modify it under the same
|
|
7
|
+
license terms as Ruby.
|
|
8
|
+
|
|
9
|
+
=end
|
|
10
|
+
|
|
11
|
+
require 'rbconfig'
|
|
12
|
+
require 'gettext/core_ext/string'
|
|
13
|
+
|
|
14
|
+
module GetText
|
|
15
|
+
# Treats locale-path for mo-files.
|
|
16
|
+
class LocalePath
|
|
17
|
+
include Locale::Util::Memoizable
|
|
18
|
+
|
|
19
|
+
# The default locale paths.
|
|
20
|
+
CONFIG_PREFIX = Config::CONFIG['prefix'].gsub(/\/local/, "")
|
|
21
|
+
DEFAULT_RULES = [
|
|
22
|
+
"./locale/%{lang}/LC_MESSAGES/%{name}.mo",
|
|
23
|
+
"./locale/%{lang}/%{name}.mo",
|
|
24
|
+
"#{Config::CONFIG['datadir']}/locale/%{lang}/LC_MESSAGES/%{name}.mo",
|
|
25
|
+
"#{Config::CONFIG['datadir'].gsub(/\/local/, "")}/locale/%{lang}/LC_MESSAGES/%{name}.mo",
|
|
26
|
+
"#{CONFIG_PREFIX}/share/locale/%{lang}/LC_MESSAGES/%{name}.mo",
|
|
27
|
+
"#{CONFIG_PREFIX}/local/share/locale/%{lang}/LC_MESSAGES/%{name}.mo"
|
|
28
|
+
].uniq
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
include Locale::Util::Memoizable
|
|
32
|
+
|
|
33
|
+
# Add default locale path. Usually you should use GetText.add_default_locale_path instead.
|
|
34
|
+
# * path: a new locale path. (e.g.) "/usr/share/locale/%{lang}/LC_MESSAGES/%{name}.mo"
|
|
35
|
+
# ('locale' => "ja_JP", 'name' => "textdomain")
|
|
36
|
+
# * Returns: the new DEFAULT_LOCALE_PATHS
|
|
37
|
+
def add_default_rule(path)
|
|
38
|
+
DEFAULT_RULES.unshift(path)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Returns path rules as an Array.
|
|
42
|
+
# (e.g.) ["/usr/share/locale/%{lang}/LC_MESSAGES/%{name}.mo", ...]
|
|
43
|
+
def default_path_rules
|
|
44
|
+
default_path_rules = []
|
|
45
|
+
|
|
46
|
+
if ENV["GETTEXT_PATH"]
|
|
47
|
+
ENV["GETTEXT_PATH"].split(/,/).each {|i|
|
|
48
|
+
default_path_rules = ["#{i}/%{lang}/LC_MESSAGES/%{name}.mo", "#{i}/%{lang}/%{name}.mo"]
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
default_path_rules += DEFAULT_RULES
|
|
53
|
+
|
|
54
|
+
load_path = $LOAD_PATH
|
|
55
|
+
if defined? ::Gem
|
|
56
|
+
load_path += Gem.all_load_paths
|
|
57
|
+
end
|
|
58
|
+
load_path.map!{|v| v.match(/(.*?)(\/lib)*?$/); $1}
|
|
59
|
+
load_path.each {|path|
|
|
60
|
+
default_path_rules += [
|
|
61
|
+
"#{path}/data/locale/%{lang}/LC_MESSAGES/%{name}.mo",
|
|
62
|
+
"#{path}/data/locale/%{lang}/%{name}.mo",
|
|
63
|
+
"#{path}/locale/%{lang}/%{name}.mo"]
|
|
64
|
+
}
|
|
65
|
+
# paths existed only.
|
|
66
|
+
default_path_rules = default_path_rules.select{|path|
|
|
67
|
+
Dir.glob(path % {:lang => "*", :name => "*"}).size > 0}.uniq
|
|
68
|
+
default_path_rules
|
|
69
|
+
end
|
|
70
|
+
memoize_dup :default_path_rules
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
attr_reader :locale_paths, :supported_locales
|
|
74
|
+
|
|
75
|
+
# Creates a new GetText::TextDomain.
|
|
76
|
+
# * name: the textdomain name.
|
|
77
|
+
# * topdir: the locale path ("%{topdir}/%{lang}/LC_MESSAGES/%{name}.mo") or nil.
|
|
78
|
+
def initialize(name, topdir = nil)
|
|
79
|
+
@name = name
|
|
80
|
+
|
|
81
|
+
if topdir
|
|
82
|
+
path_rules = ["#{topdir}/%{lang}/LC_MESSAGES/%{name}.mo", "#{topdir}/%{lang}/%{name}.mo"]
|
|
83
|
+
else
|
|
84
|
+
path_rules = self.class.default_path_rules
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
@locale_paths = {}
|
|
89
|
+
path_rules.each do |rule|
|
|
90
|
+
this_path_rules = rule % {:lang => "([^\/]+)", :name => name}
|
|
91
|
+
Dir.glob(rule %{:lang => "*", :name => name}).each do |path|
|
|
92
|
+
if /#{this_path_rules}/ =~ path
|
|
93
|
+
@locale_paths[$1] = path unless @locale_paths[$1]
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
@supported_locales = @locale_paths.keys.sort
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Gets the current path.
|
|
101
|
+
# * lang: a Locale::Tag.
|
|
102
|
+
def current_path(lang)
|
|
103
|
+
lang_candidates = lang.to_posix.candidates
|
|
104
|
+
search_files = []
|
|
105
|
+
|
|
106
|
+
lang_candidates.each do |tag|
|
|
107
|
+
path = @locale_paths[tag.to_s]
|
|
108
|
+
warn "GetText::TextDomain#load_mo: mo-file is #{path}" if $DEBUG
|
|
109
|
+
return path if path
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
if $DEBUG
|
|
113
|
+
warn "MO file is not found in"
|
|
114
|
+
@locale_paths.each do |path|
|
|
115
|
+
warn " #{path[1]}"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
nil
|
|
119
|
+
end
|
|
120
|
+
memoize :current_path
|
|
121
|
+
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
mofile.rb - A simple class for operating GNU MO file.
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2003-2009 Masao Mutoh
|
|
5
|
+
Copyright (C) 2002 Masahiro Sakai, Masao Mutoh
|
|
6
|
+
Copyright (C) 2001 Masahiro Sakai
|
|
7
|
+
|
|
8
|
+
Masahiro Sakai <s01397ms at sfc.keio.ac.jp>
|
|
9
|
+
Masao Mutoh <mutomasa at gmail.com>
|
|
10
|
+
|
|
11
|
+
You can redistribute this file and/or modify it under the same term
|
|
12
|
+
of Ruby. License of Ruby is included with Ruby distribution in
|
|
13
|
+
the file "README".
|
|
14
|
+
|
|
15
|
+
=end
|
|
16
|
+
|
|
17
|
+
require 'gettext/core_ext/iconv'
|
|
18
|
+
require 'stringio'
|
|
19
|
+
|
|
20
|
+
module GetText
|
|
21
|
+
class MOFile < Hash
|
|
22
|
+
class InvalidFormat < RuntimeError; end;
|
|
23
|
+
|
|
24
|
+
attr_reader :filename
|
|
25
|
+
|
|
26
|
+
Header = Struct.new(:magic,
|
|
27
|
+
:revision,
|
|
28
|
+
:nstrings,
|
|
29
|
+
:orig_table_offset,
|
|
30
|
+
:translated_table_offset,
|
|
31
|
+
:hash_table_size,
|
|
32
|
+
:hash_table_offset)
|
|
33
|
+
|
|
34
|
+
# The following are only used in .mo files
|
|
35
|
+
# with minor revision >= 1.
|
|
36
|
+
class HeaderRev1 < Header
|
|
37
|
+
attr_accessor :n_sysdep_segments,
|
|
38
|
+
:sysdep_segments_offset,
|
|
39
|
+
:n_sysdep_strings,
|
|
40
|
+
:orig_sysdep_tab_offset,
|
|
41
|
+
:trans_sysdep_tab_offset
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
MAGIC_BIG_ENDIAN = "\x95\x04\x12\xde"
|
|
45
|
+
MAGIC_LITTLE_ENDIAN = "\xde\x12\x04\x95"
|
|
46
|
+
|
|
47
|
+
def self.open(arg = nil, output_charset = nil)
|
|
48
|
+
result = self.new(output_charset)
|
|
49
|
+
result.load(arg)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def initialize(output_charset = nil)
|
|
53
|
+
@filename = nil
|
|
54
|
+
@last_modified = nil
|
|
55
|
+
@little_endian = true
|
|
56
|
+
@output_charset = output_charset
|
|
57
|
+
@plural_proc = nil
|
|
58
|
+
super()
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def update!
|
|
62
|
+
if FileTest.exist?(@filename)
|
|
63
|
+
st = File.stat(@filename)
|
|
64
|
+
load(@filename) unless (@last_modified == [st.ctime, st.mtime])
|
|
65
|
+
else
|
|
66
|
+
warn "#{@filename} was lost." if $DEBUG
|
|
67
|
+
clear
|
|
68
|
+
end
|
|
69
|
+
self
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def load(arg)
|
|
73
|
+
if arg.kind_of? String
|
|
74
|
+
begin
|
|
75
|
+
st = File.stat(arg)
|
|
76
|
+
@last_modified = [st.ctime, st.mtime]
|
|
77
|
+
rescue Exception
|
|
78
|
+
end
|
|
79
|
+
load_from_file(arg)
|
|
80
|
+
else
|
|
81
|
+
load_from_stream(arg)
|
|
82
|
+
end
|
|
83
|
+
@filename = arg
|
|
84
|
+
self
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def load_from_stream(io)
|
|
88
|
+
magic = io.read(4)
|
|
89
|
+
case magic
|
|
90
|
+
when MAGIC_BIG_ENDIAN
|
|
91
|
+
@little_endian = false
|
|
92
|
+
when MAGIC_LITTLE_ENDIAN
|
|
93
|
+
@little_endian = true
|
|
94
|
+
else
|
|
95
|
+
raise InvalidFormat.new(sprintf("Unknown signature %s", magic.dump))
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
endian_type6 = @little_endian ? 'V6' : 'N6'
|
|
99
|
+
endian_type_astr = @little_endian ? 'V*' : 'N*'
|
|
100
|
+
|
|
101
|
+
header = HeaderRev1.new(magic, *(io.read(4 * 6).unpack(endian_type6)))
|
|
102
|
+
|
|
103
|
+
if header.revision == 1
|
|
104
|
+
# FIXME: It doesn't support sysdep correctly.
|
|
105
|
+
header.n_sysdep_segments = io.read(4).unpack(endian_type6)
|
|
106
|
+
header.sysdep_segments_offset = io.read(4).unpack(endian_type6)
|
|
107
|
+
header.n_sysdep_strings = io.read(4).unpack(endian_type6)
|
|
108
|
+
header.orig_sysdep_tab_offset = io.read(4).unpack(endian_type6)
|
|
109
|
+
header.trans_sysdep_tab_offset = io.read(4).unpack(endian_type6)
|
|
110
|
+
elsif header.revision > 1
|
|
111
|
+
raise InvalidFormat.new(sprintf("file format revision %d isn't supported", header.revision))
|
|
112
|
+
end
|
|
113
|
+
io.pos = header.orig_table_offset
|
|
114
|
+
orig_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
|
|
115
|
+
|
|
116
|
+
io.pos = header.translated_table_offset
|
|
117
|
+
trans_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
|
|
118
|
+
|
|
119
|
+
original_strings = Array.new(header.nstrings)
|
|
120
|
+
for i in 0...header.nstrings
|
|
121
|
+
io.pos = orig_table_data[i * 2 + 1]
|
|
122
|
+
original_strings[i] = io.read(orig_table_data[i * 2 + 0])
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
clear
|
|
126
|
+
for i in 0...header.nstrings
|
|
127
|
+
io.pos = trans_table_data[i * 2 + 1]
|
|
128
|
+
str = io.read(trans_table_data[i * 2 + 0])
|
|
129
|
+
|
|
130
|
+
if (! original_strings[i]) || original_strings[i] == ""
|
|
131
|
+
if str
|
|
132
|
+
@charset = nil
|
|
133
|
+
@nplurals = nil
|
|
134
|
+
@plural = nil
|
|
135
|
+
str.each_line{|line|
|
|
136
|
+
if /^Content-Type:/i =~ line and /charset=((?:\w|-)+)/i =~ line
|
|
137
|
+
@charset = $1
|
|
138
|
+
elsif /^Plural-Forms:\s*nplurals\s*\=\s*(\d*);\s*plural\s*\=\s*([^;]*)\n?/ =~ line
|
|
139
|
+
@nplurals = $1
|
|
140
|
+
@plural = $2
|
|
141
|
+
end
|
|
142
|
+
break if @charset and @nplurals
|
|
143
|
+
}
|
|
144
|
+
@nplurals = "1" unless @nplurals
|
|
145
|
+
@plural = "0" unless @plural
|
|
146
|
+
end
|
|
147
|
+
else
|
|
148
|
+
if @output_charset
|
|
149
|
+
begin
|
|
150
|
+
str = Iconv.conv(@output_charset, @charset, str) if @charset
|
|
151
|
+
rescue Iconv::Failure
|
|
152
|
+
if $DEBUG
|
|
153
|
+
warn "@charset = ", @charset
|
|
154
|
+
warn"@output_charset = ", @output_charset
|
|
155
|
+
warn "msgid = ", original_strings[i]
|
|
156
|
+
warn "msgstr = ", str
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
self[original_strings[i]] = str.freeze
|
|
162
|
+
end
|
|
163
|
+
self
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def prime?(number)
|
|
167
|
+
('1' * number) !~ /^1?$|^(11+?)\1+$/
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
begin
|
|
171
|
+
require 'prime'
|
|
172
|
+
def next_prime(seed)
|
|
173
|
+
Prime.instance.find{|x| x > seed }
|
|
174
|
+
end
|
|
175
|
+
rescue LoadError
|
|
176
|
+
def next_prime(seed)
|
|
177
|
+
require 'mathn'
|
|
178
|
+
prime = Prime.new
|
|
179
|
+
while current = prime.succ
|
|
180
|
+
return current if current > seed
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
HASHWORDBITS = 32
|
|
186
|
+
# From gettext-0.12.1/gettext-runtime/intl/hash-string.h
|
|
187
|
+
# Defines the so called `hashpjw' function by P.J. Weinberger
|
|
188
|
+
# [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
|
|
189
|
+
# 1986, 1987 Bell Telephone Laboratories, Inc.]
|
|
190
|
+
def hash_string(str)
|
|
191
|
+
hval = 0
|
|
192
|
+
i = 0
|
|
193
|
+
str.each_byte do |b|
|
|
194
|
+
break if b == '\0'
|
|
195
|
+
hval <<= 4
|
|
196
|
+
hval += b.to_i
|
|
197
|
+
g = hval & (0xf << (HASHWORDBITS - 4))
|
|
198
|
+
if (g != 0)
|
|
199
|
+
hval ^= g >> (HASHWORDBITS - 8)
|
|
200
|
+
hval ^= g
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
hval
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
#Save data as little endian format.
|
|
207
|
+
def save_to_stream(io)
|
|
208
|
+
header_size = 4 * 7
|
|
209
|
+
table_size = 4 * 2 * size
|
|
210
|
+
|
|
211
|
+
hash_table_size = next_prime((size * 4) / 3)
|
|
212
|
+
hash_table_size = 3 if hash_table_size <= 2
|
|
213
|
+
header = Header.new(
|
|
214
|
+
MAGIC_LITTLE_ENDIAN, # magic
|
|
215
|
+
0, # revision
|
|
216
|
+
size, # nstrings
|
|
217
|
+
header_size, # orig_table_offset
|
|
218
|
+
header_size + table_size, # translated_table_offset
|
|
219
|
+
hash_table_size, # hash_table_size
|
|
220
|
+
header_size + table_size * 2 # hash_table_offset
|
|
221
|
+
)
|
|
222
|
+
io.write(header.to_a.pack('a4V*'))
|
|
223
|
+
|
|
224
|
+
ary = to_a
|
|
225
|
+
ary.sort!{|a, b| a[0] <=> b[0]} # sort by original string
|
|
226
|
+
|
|
227
|
+
pos = header.hash_table_size * 4 + header.hash_table_offset
|
|
228
|
+
|
|
229
|
+
orig_table_data = Array.new()
|
|
230
|
+
ary.each{|item, _|
|
|
231
|
+
orig_table_data.push(item.bytesize)
|
|
232
|
+
orig_table_data.push(pos)
|
|
233
|
+
pos += item.bytesize + 1 # +1 is <NUL>
|
|
234
|
+
}
|
|
235
|
+
io.write(orig_table_data.pack('V*'))
|
|
236
|
+
|
|
237
|
+
trans_table_data = Array.new()
|
|
238
|
+
ary.each{|_, item|
|
|
239
|
+
trans_table_data.push(item.bytesize)
|
|
240
|
+
trans_table_data.push(pos)
|
|
241
|
+
pos += item.bytesize + 1 # +1 is <NUL>
|
|
242
|
+
}
|
|
243
|
+
io.write(trans_table_data.pack('V*'))
|
|
244
|
+
|
|
245
|
+
hash_tab = Array.new(hash_table_size)
|
|
246
|
+
j = 0
|
|
247
|
+
ary[0...size].each {|key, _|
|
|
248
|
+
hash_val = hash_string(key)
|
|
249
|
+
idx = hash_val % hash_table_size
|
|
250
|
+
if hash_tab[idx] != nil
|
|
251
|
+
incr = 1 + (hash_val % (hash_table_size - 2))
|
|
252
|
+
begin
|
|
253
|
+
if (idx >= hash_table_size - incr)
|
|
254
|
+
idx -= hash_table_size - incr
|
|
255
|
+
else
|
|
256
|
+
idx += incr
|
|
257
|
+
end
|
|
258
|
+
end until (hash_tab[idx] == nil)
|
|
259
|
+
end
|
|
260
|
+
hash_tab[idx] = j + 1
|
|
261
|
+
j += 1
|
|
262
|
+
}
|
|
263
|
+
hash_tab.collect!{|i| i ? i : 0}
|
|
264
|
+
|
|
265
|
+
io.write(hash_tab.pack('V*'))
|
|
266
|
+
|
|
267
|
+
ary.each{|item, _| io.write(item); io.write("\0") }
|
|
268
|
+
ary.each{|_, item| io.write(item); io.write("\0") }
|
|
269
|
+
|
|
270
|
+
self
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def load_from_file(filename)
|
|
274
|
+
@filename = filename
|
|
275
|
+
begin
|
|
276
|
+
File.open(filename, 'rb'){|f| load_from_stream(f)}
|
|
277
|
+
rescue => e
|
|
278
|
+
e.set_backtrace("File: #{@filename}")
|
|
279
|
+
raise e
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def save_to_file(filename)
|
|
284
|
+
File.open(filename, 'wb'){|f| save_to_stream(f)}
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def set_comment(msgid_or_sym, comment)
|
|
288
|
+
#Do nothing
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def plural_as_proc
|
|
292
|
+
unless @plural_proc
|
|
293
|
+
@plural_proc = Proc.new{|n| eval(@plural)}
|
|
294
|
+
begin
|
|
295
|
+
@plural_proc.call(1)
|
|
296
|
+
rescue
|
|
297
|
+
@plural_proc = Proc.new{|n| 0}
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
@plural_proc
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
attr_accessor :little_endian, :path, :last_modified
|
|
304
|
+
attr_reader :charset, :nplurals, :plural
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# Test
|
|
310
|
+
|
|
311
|
+
if $0 == __FILE__
|
|
312
|
+
if (ARGV.include? "-h") or (ARGV.include? "--help")
|
|
313
|
+
STDERR.puts("mo.rb [filename.mo ...]")
|
|
314
|
+
exit
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
ARGV.each{ |item|
|
|
318
|
+
mo = GetText::MOFile.open(item)
|
|
319
|
+
puts "------------------------------------------------------------------"
|
|
320
|
+
puts "charset = \"#{mo.charset}\""
|
|
321
|
+
puts "nplurals = \"#{mo.nplurals}\""
|
|
322
|
+
puts "plural = \"#{mo.plural}\""
|
|
323
|
+
puts "------------------------------------------------------------------"
|
|
324
|
+
mo.each do |key, value|
|
|
325
|
+
puts "original message = #{key.inspect}"
|
|
326
|
+
puts "translated message = #{value.inspect}"
|
|
327
|
+
puts "--------------------------------------------------------------------"
|
|
328
|
+
end
|
|
329
|
+
}
|
|
330
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
parser/erb.rb - parser for ERB
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2005 Masao Mutoh
|
|
5
|
+
|
|
6
|
+
You may redistribute it and/or modify it under the same
|
|
7
|
+
license terms as Ruby.
|
|
8
|
+
|
|
9
|
+
$Id: erb.rb,v 1.5 2007/08/01 01:39:14 mutoh Exp $
|
|
10
|
+
=end
|
|
11
|
+
|
|
12
|
+
require 'erb'
|
|
13
|
+
require 'gettext/parser/ruby.rb'
|
|
14
|
+
|
|
15
|
+
module GetText
|
|
16
|
+
module ErbParser
|
|
17
|
+
extend self
|
|
18
|
+
|
|
19
|
+
@config = {
|
|
20
|
+
:extnames => ['.rhtml', '.erb','.html','.plain']
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# Sets some preferences to parse ERB files.
|
|
24
|
+
# * config: a Hash of the config. It can takes some values below:
|
|
25
|
+
# * :extnames: An Array of target files extension. Default is [".rhtml"].
|
|
26
|
+
def init(config)
|
|
27
|
+
config.each{|k, v|
|
|
28
|
+
@config[k] = v
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def parse(file, targets = []) # :nodoc:
|
|
33
|
+
src = ERB.new(IO.readlines(file).join).src
|
|
34
|
+
# Remove magic comment prepended by erb in Ruby 1.9.
|
|
35
|
+
src.sub!(/\A#.*?coding[:=].*?\n/, '') if src.respond_to?(:encode)
|
|
36
|
+
erb = src.split(/$/)
|
|
37
|
+
RubyParser.parse_lines(file, erb, targets)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def target?(file) # :nodoc:
|
|
41
|
+
@config[:extnames].each do |v|
|
|
42
|
+
return true if File.extname(file) == v
|
|
43
|
+
end
|
|
44
|
+
false
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if __FILE__ == $0
|
|
50
|
+
# ex) ruby glade.rhtml foo.rhtml bar.rhtml
|
|
51
|
+
ARGV.each do |file|
|
|
52
|
+
p GetText::ErbParser.parse(file)
|
|
53
|
+
end
|
|
54
|
+
end
|