OSDN Git Service

Install i18n gem
authorAkihiro Ono <a-ono@users.sourceforge.jp>
Sat, 29 Jan 2011 16:32:04 +0000 (01:32 +0900)
committerAkihiro Ono <a-ono@users.sourceforge.jp>
Sat, 29 Jan 2011 16:32:04 +0000 (01:32 +0900)
39 files changed:
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/CHANGELOG.textile [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/MIT-LICENSE [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/README.textile [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record/missing.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record/store_procs.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record/translation.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/base.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/cache.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/cascade.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/chain.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/cldr.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/fallbacks.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/flatten.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/gettext.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/interpolation_compiler.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/key_value.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/memoize.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/metadata.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/pluralization.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/simple.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/transliterator.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/config.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/core_ext/hash.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/core_ext/string/interpolate.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/exceptions.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/gettext.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/gettext/helpers.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/gettext/po_parser.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/fallbacks.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag/parents.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag/rfc4646.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag/simple.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/version.rb [new file with mode: 0644]
ruby/lib/ruby/gems/1.8/specifications/i18n-0.4.2.gemspec [new file with mode: 0644]

diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/CHANGELOG.textile b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/CHANGELOG.textile
new file mode 100644 (file)
index 0000000..31b4fb2
--- /dev/null
@@ -0,0 +1,143 @@
+h1. Changelog
+
+h2. 0.4.2 (2010-10-26)
+
+* "Improve UTF8 handling":http://github.com/svenfuchs/i18n/commit/e8d5820a3b08eeca28de1a2b9c8a6ad2b9e6476c
+* "Expose I18n::VERSION":http://github.com/svenfuchs/i18n/commit/b832037bac94c7144f45f3ff5e3b4e4089781726
+* "Better deprecation output":http://github.com/svenfuchs/i18n/commit/2bee924464b8a9c33d3d7852eb1c8423aa38cc25
+
+h2. 0.4.1 (2010-06-05)
+
+* "Fix interpolation failure on Ruby 1.9":http://github.com/svenfuchs/i18n/commit/8d45bedb11c4136c00e853d104b00a8e67ec4894
+
+h2. 0.4.0 (2010-05-27)
+
+* "The localization proc also receives the object as option":http://github.com/svenfuchs/i18n/commit/4a8cd9fa660daaa3078e24c5851353ca377d9213
+
+h2. 0.4.0.beta1 (2010-05-03)
+
+* "Renamed Fast backend to Memoize backend":http://github.com/svenfuchs/i18n/commit/f7f7dc12c00a19d3876223771e14f8671ff313cd
+
+* "Deprecate {{}} as interpolation syntax":http://github.com/svenfuchs/i18n/commit/8894ee521ef5788c415b625a6daf522af4c416e0
+
+* "Allow nil translation to be stored again":http://github.com/svenfuchs/i18n/commit/f2074f1e82d10c2e9a801c8cc2f2a0c7c30703ba
+
+h2. 0.4.0.beta (2010-04-30)
+
+* "Added a KeyValue backend":http://github.com/svenfuchs/i18n/commit/28ca5f53ade7f545f8c0804e93564d4686b416a4
+
+* "Added transliteration support":http://github.com/svenfuchs/i18n/commit/928fdb4794959e779e90f360eb01ba043672d8d5
+
+* "Create Flatten backend module to aid handling flatten translations":http://github.com/svenfuchs/i18n/commit/2ec9d6998aa8facd7b15a3ef47a96cf2471cd8a1
+
+* "Decouple the external separator (used when storing translations) from the internal separator in Fast and ActiveRecord backends":http://github.com/svenfuchs/i18n/commit/274cb4daa0ca5e3b2bd23b45eb7f9fc58f75a79d
+
+h2. 0.3.7 (2010-04-17)
+
+* "Speed up I18n.normalize_keys by caching reused normalizations and producing less garbage":http://github.com/svenfuchs/i18n/commit/819dac0fea9c29e6545801aa107e63e355728cd4
+
+h2. 0.3.6 (2010-03-23)
+
+* "Move gettext po parser to lib":http://github.com/svenfuchs/i18n/commit/b2f038663b55727ac2327e6f07a46ba5d69d600c
+
+* "Move I18n configuration to I18n.config":http://github.com/svenfuchs/i18n/commit/4a7baea86663ead8c681008c3e80a622f0546b07
+
+h2. 0.3.5 (2010-02-26)
+
+* "Delegate I18n.normalize_translation_keys to I18n.normalize_keys and deprecate 
+the former":http://github.com/svenfuchs/i18n/commit/7284b04d5f5dd9679cb68875515cdd0cdfc96fef
+
+h2. 0.3.4 (2010-02-25)
+
+* "Rename I18n.normalize_translation_keys to I18n.normalize_keys and finally make it public":http://github.com/svenfuchs/i18n/commit/20b05fe5802df6c90fb70a4e3760b2b851b791b3
+
+* "Added CLDR supoprt":http://github.com/svenfuchs/i18n/commit/860eadf671a231e7f5dffb1bb27fa318ff7a8786
+
+h2. 0.3.3 (2009-12-29)
+
+* "Use lib/i18n/version":http://github.com/svenfuchs/i18n/commit/ff426c8e7a2438b814cb303adadec292dacb752e
+
+* "Added a benchmark suite":http://github.com/svenfuchs/i18n/commit/f9b5b9b113097724638bdab96862ffa404e67e70
+
+* "Ensure links can be handled recursively":http://github.com/svenfuchs/i18n/commit/2c50bd209f3fc24fe9dfa694c81be64340f09b7d
+
+* "Make sure we can lookup false values as translation data":http://github.com/svenfuchs/i18n/commit/561c82ba4b8921d03bfdf56cb2d0c2f287629001
+
+* "Added Fast backend module":http://github.com/svenfuchs/i18n/commit/bd2f09f0a251ca793b0e8ecc7e32177a2f091c23
+
+* "Added InterpolationCompiler backend module":http://github.com/svenfuchs/i18n/commit/91810887d1abfb28996a9183bc9004678290d28b
+
+h2. 0.3.2 (2009-12-12)
+
+* "Added Cascade backend":http://github.com/svenfuchs/i18n/commit/8009aef293e9ef8564c9005090d8380feabcaf6f
+
+h2. 0.3.1 (2009-12-11)
+
+* "Add PoParser to gemspec":http://github.com/svenfuchs/i18n/commit/d6b2763f39c932f66adb039b96882a472f883c51
+* "Enable custom separators for ActiveRecord backend":http://github.com/svenfuchs/i18n/commit/9341d3fcfc951cc31807ba672d2b5d90909ef3e5
+* "Pass interpolation values to interpolation procs":http://github.com/svenfuchs/i18n/commit/39c2ed8fbad645671cd5520ce7ad0aeefe2b0cca
+* "Fix that ngettext supports keys with dots":http://github.com/svenfuchs/i18n/commit/7362a43c34364d500de8899cfcca6bf1a5e6d1c8
+
+h2. 0.3.0 (2009-11-30)
+
+* "Gettext backend and helpers":http://github.com/svenfuchs/i18n/commit/35a1740d2f10b808548af352006950da4017e374
+* "Metadata module":http://github.com/svenfuchs/i18n/commit/2677208555179b36fcbe958c0e8bc642cf5bc020
+* "Basic ActiveRecord backend":http://github.com/svenfuchs/i18n/commit/786632d0b42de423ecf0969622efc87f1691e2a2
+* "Set encoding to UTF8 for all files":http://github.com/svenfuchs/i18n/commit/9be3d4a311b5bf583eec5d39986176cc40c112f2
+* "Chain backend":http://github.com/svenfuchs/i18n/commit/08259ffb88b3005403648d77bc1cbca0b92f3cf5
+* "Backend/cache implementation":http://github.com/svenfuchs/i18n/commit/e7bf15351cd2e27f5972eb40e65a5dd6f4a0feed
+* "Pluralization module":http://github.com/svenfuchs/i18n/commit/9ca4c9ed52d4706566a6abeb2d78722dcc5d4764
+* "add and adapt Globalize2 fallback implementation":http://github.com/svenfuchs/i18n/commit/1b37a303b27d6222b17162804b06323e5628768f
+* "move Simple backend implementation to a Base backend class and extend Simple from Base.":http://github.com/svenfuchs/i18n/commit/32ddc80a04e6aa247f6d6613bde7f78c73396cb4
+
+h2. 0.2.0 (2009-07-12)
+
+* "Allow using Ruby 1.9 syntax for string interpolation (API addition)":http://github.com/svenfuchs/i18n/commit/c6e0b06d512f2af57199a843a1d8a40241b32861
+* "Allow configuring the default scope separator, allow to pass a custom scope separator(API addition)":http://github.com/svenfuchs/i18n/commit/5b75bfbc348061adc11e3790187a187275bfd471 (e.g. I18n.t(:'foo|bar', :separator => '|') 
+* "Pass :format option to #translate for #localize more useful lambda support":http://github.com/svenfuchs/i18n/commit/e277711b3c844fe7589b8d3f9af0f7d1b969a273
+* "Refactor Simple backend #resolve to #default and #resolve for more consistency. Now allows to pass lambdas as defaults and re-resolve Symbols":http://github.com/svenfuchs/i18n/commit/8c4ce3d923ce5fa73e973fe28217e18165549aba
+* "Add lambda support to #translate (API addition)":http://github.com/svenfuchs/i18n/commit/c90e62d8f7d3d5b78f34cfe328d871b58884f115
+* "Add lambda support to #localize (API addition)":http://github.com/svenfuchs/i18n/commit/9d390afcf33f3f469bb95e6888147152f6cc7442
+
+h2. 0.1.3 (2009-02-27)
+
+* "Remove unnecessary string encoding handling in the i18n simple backend which made the backend break on Ruby 1.9":http://github.com/svenfuchs/i18n/commit/4c3a970783861a94f2e89f46714fb3434e4f4f8d
+
+h2. 0.1.2 (2009-01-09)
+
+* "added #available_locales (returns an array of locales for which translations are available)":http://github.com/svenfuchs/i18n/commit/411f8fe7c8f3f89e9b6b921fa62ed66cb92f3af4
+* "flatten load_path before using it so that a nested array of paths won't throw up":http://github.com/svenfuchs/i18n/commit/d473a068a2b90aba98135deb225d6eb6d8104d70
+
+h2. 0.1.1 (2008-11-20)
+
+* "Use :'en' as a default locale (in favor of :'en-US')":http://github.com/svenfuchs/i18n/commit/c4b10b246aecf7da78cb2568dd0d2ab7e6b8a230
+* "Add #reload! to Simple backend":http://github.com/svenfuchs/i18n/commit/36dd2bd9973b9e1559728749a9daafa44693e964
+
+h2. 0.1.0 (2008-10-25)
+
+* "Fix Simple backend to distinguish false from nil values":http://github.com/svenfuchs/i18n/commit/39d9a47da14b5f3ba126af48923af8c30e135166
+* "Add #load_path to public api, add initialize to simple backend and remove #load_translations from public api":http://github.com/svenfuchs/i18n/commit/c4c5649e6bc8f020f1aaf5a5470bde048e22c82d
+* "Speed up Backend::Simple#interpolate":http://github.com/svenfuchs/i18n/commit/9e1ac6bf8833304e036323ec9932b9f33c468a35
+* "Remove #populate and #store_translations from public API":http://github.com/svenfuchs/i18n/commit/f4e514a80be7feb509f66824ee311905e2940900
+* "Use :other instead of :many as a plural key":http://github.com/svenfuchs/i18n/commit/0f8f20a2552bf6a2aa758d8fdd62a7154e4a1bf6
+* "Use a class instead of a module for Simple backend":http://github.com/svenfuchs/i18n/commit/08f051aa61320c17debde24a83268bc74e33b995
+* "Make Simple backend #interpolate deal with non-ASCII string encodings":http://github.com/svenfuchs/i18n/commit/d84a3f3f55543c084d5dc5d1fed613b8df148789
+* "Fix default arrays of non-existant keys returning the default array":http://github.com/svenfuchs/i18n/commit/6c04ca86c87f97dc78f07c2a4023644e5ba8b839
+
+h2. Initial implementation (June/July 2008)
+
+Initial implementation by "Sven Fuchs":http://www.workingwithrails.com/person/9963-sven-fuchs based on previous discussion/consensus of the rails-i18n team (alphabetical order) and many others:
+
+* "Matt Aimonetti":http://railsontherun.com
+* "Sven Fuchs":http://www.workingwithrails.com/person/9963-sven-fuchs
+* "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey
+* "Saimon Moore":http://saimonmoore.net
+* "Stephan Soller":http://www.arkanis-development.de
+
+h2. More information
+
+* "Homepage":http://rails-i18n.org
+* "Wiki":http://rails-i18n.org/wiki
+* "Mailinglist":http://groups.google.com/group/rails-i18n
+* "About the project/history":http://www.artweb-design.de/2008/7/18/finally-ruby-on-rails-gets-internationalized
+* "Initial API Intro":http://www.artweb-design.de/2008/7/18/the-ruby-on-rails-i18n-core-api
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/MIT-LICENSE b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/MIT-LICENSE
new file mode 100644 (file)
index 0000000..ed8e9ee
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2008 The Ruby I18n team
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/README.textile b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/README.textile
new file mode 100644 (file)
index 0000000..7c8ce0f
--- /dev/null
@@ -0,0 +1,116 @@
+h1. Ruby I18n
+
+Ruby Internationalization and localization solution.
+
+Features:
+
+* translation and localization
+* interpolation of values to translations (Ruby 1.9 compatible syntax)
+* pluralization (CLDR compatible)
+* customizable transliteration to ASCII
+* flexible defaults
+* bulk lookup
+* lambdas as translation data
+* custom key/scope separator
+* custom exception handlers
+* extensible architecture with a swappable backend
+
+Pluggable features:
+
+* Cache
+* Pluralization: lambda pluralizers stored as translation data
+* Locale fallbacks, RFC4647 compliant (optionally: RFC4646 locale validation)
+* Gettext support
+* Translation metadata
+
+Alternative backends:
+
+* Chain
+* ActiveRecord (optionally: ActiveRecord::Missing and ActiveRecord::StoreProcs)
+* KeyValue (uses active_support/json and cannot store procs)
+
+For more information and lots of resources see: "http://ruby-i18n.org/wiki":http://ruby-i18n.org/wiki
+
+h2. Installation
+
+gem install i18n
+
+h4. Rails version warning
+
+On Rails < 2.3.6 the method I18n.localize will fail with MissingInterpolationArgument (issue "20":http://github.com/svenfuchs/i18n/issues/issue/20). Upgrade to Rails 2.3.6 or higher (2.3.8 preferably) is recommended.
+
+h3. Installation on Rails < 2.3.5 (deprecated)
+
+Up to version 2.3.4 Rails will not accept i18n gems > 0.1.3. There is an unpacked
+gem inside of active_support/lib/vendor which gets loaded unless gem 'i18n', '~> 0.1.3'.
+This requirement is relaxed in "6da03653":http://github.com/rails/rails/commit/6da03653
+
+The new i18n gem can be loaded from vendor/plugins like this:
+
+<pre>
+  def reload_i18n!
+    raise "Move to i18n version 0.2.0 or greater" if Rails.version > "2.3.4"
+
+    $:.grep(/i18n/).each { |path| $:.delete(path) }
+    I18n::Backend.send :remove_const, "Simple"
+    $: << Rails.root.join('vendor', 'plugins', 'i18n', 'lib').to_s
+  end
+</pre>
+
+Then you can `reload_i18n!` inside an i18n initializer.
+
+h2. Tests
+
+You can run tests both with
+
+* `rake test` or just `rake`
+* run any test file directly, e.g. `ruby test/api/simple_test.rb`
+* run all tests with `ruby test/all.rb`
+
+You can parametrize the test suite for using different sets of dependencies by
+using:
+
+.pre `ruby test/all.rb -w DEPENDENCIES`
+
+... where DEPENDENCIES is a comma-separated list of:
+
+* r23 or rails-2.3.x
+* r3 or rails-3.x
+* no-rails
+* sqlite
+* mysql
+
+So, e.g. this would run the test suite against Rails 2.3.x using mysql:
+
+.pre `ruby test/all.rb -w r23,mysql`
+
+The structure of the test suite is a bit unusual as it uses modules to reuse
+particular tests in different test cases.
+
+The reason for this is that we need to enforce the I18n API across various
+combinations of extensions. E.g. the Simple backend alone needs to support
+the same API as any combination of feature and/or optimization modules included
+to the Simple backend. We test this by reusing the same API defition (implemented
+as test methods) in test cases with different setups.
+
+You can find the test cases that enforce the API in test/api. And you can find
+the API definition test methods in test/api/tests.
+
+All other test cases (e.g. as defined in test/backend, test/core\_ext) etc.
+follow the usual test setup and should be easy to grok.
+
+h2. Authors
+
+* "Sven Fuchs":http://www.artweb-design.de
+* "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey
+* "Stephan Soller":http://www.arkanis-development.de
+* "Saimon Moore":http://saimonmoore.net
+* "Matt Aimonetti":http://railsontherun.com
+
+h2. Contributors
+
+http://github.com/svenfuchs/i18n/contributors
+
+h2. License
+
+MIT License. See the included MIT-LICENSE file.
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n.rb
new file mode 100644 (file)
index 0000000..5be3a79
--- /dev/null
@@ -0,0 +1,331 @@
+# encoding: utf-8
+
+# Authors::   Sven Fuchs (http://www.artweb-design.de),
+#             Joshua Harvey (http://www.workingwithrails.com/person/759-joshua-harvey),
+#             Stephan Soller (http://www.arkanis-development.de/),
+#             Saimon Moore (http://saimonmoore.net),
+#             Matt Aimonetti (http://railsontherun.com/)
+# Copyright:: Copyright (c) 2008 The Ruby i18n Team
+# License::   MIT
+require 'i18n/version'
+require 'i18n/exceptions'
+require 'i18n/core_ext/string/interpolate'
+
+module I18n
+  autoload :Backend, 'i18n/backend'
+  autoload :Config,  'i18n/config'
+  autoload :Gettext, 'i18n/gettext'
+  autoload :Locale,  'i18n/locale'
+
+  class << self
+    # Gets I18n configuration object.
+    def config
+      Thread.current[:i18n_config] ||= I18n::Config.new
+    end
+
+    # Sets I18n configuration object.
+    def config=(value)
+      Thread.current[:i18n_config] = value
+    end
+
+    # Write methods which delegates to the configuration object
+    %w(locale backend default_locale available_locales default_separator
+      exception_handler load_path).each do |method|
+      module_eval <<-DELEGATORS, __FILE__, __LINE__ + 1
+        def #{method}
+          config.#{method}
+        end
+
+        def #{method}=(value)
+          config.#{method} = (value)
+        end
+      DELEGATORS
+    end
+
+    # Tells the backend to reload translations. Used in situations like the
+    # Rails development environment. Backends can implement whatever strategy
+    # is useful.
+    def reload!
+      config.backend.reload!
+    end
+
+    # Translates, pluralizes and interpolates a given key using a given locale,
+    # scope, and default, as well as interpolation values.
+    #
+    # *LOOKUP*
+    #
+    # Translation data is organized as a nested hash using the upper-level keys
+    # as namespaces. <em>E.g.</em>, ActionView ships with the translation:
+    # <tt>:date => {:formats => {:short => "%b %d"}}</tt>.
+    #
+    # Translations can be looked up at any level of this hash using the key argument
+    # and the scope option. <em>E.g.</em>, in this example <tt>I18n.t :date</tt>
+    # returns the whole translations hash <tt>{:formats => {:short => "%b %d"}}</tt>.
+    #
+    # Key can be either a single key or a dot-separated key (both Strings and Symbols
+    # work). <em>E.g.</em>, the short format can be looked up using both:
+    #   I18n.t 'date.formats.short'
+    #   I18n.t :'date.formats.short'
+    #
+    # Scope can be either a single key, a dot-separated key or an array of keys
+    # or dot-separated keys. Keys and scopes can be combined freely. So these
+    # examples will all look up the same short date format:
+    #   I18n.t 'date.formats.short'
+    #   I18n.t 'formats.short', :scope => 'date'
+    #   I18n.t 'short', :scope => 'date.formats'
+    #   I18n.t 'short', :scope => %w(date formats)
+    #
+    # *INTERPOLATION*
+    #
+    # Translations can contain interpolation variables which will be replaced by
+    # values passed to #translate as part of the options hash, with the keys matching
+    # the interpolation variable names.
+    #
+    # <em>E.g.</em>, with a translation <tt>:foo => "foo %{bar}"</tt> the option
+    # value for the key +bar+ will be interpolated into the translation:
+    #   I18n.t :foo, :bar => 'baz' # => 'foo baz'
+    #
+    # *PLURALIZATION*
+    #
+    # Translation data can contain pluralized translations. Pluralized translations
+    # are arrays of singluar/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
+    #
+    # Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
+    # pluralization rules. Other algorithms can be supported by custom backends.
+    #
+    # This returns the singular version of a pluralized translation:
+    #   I18n.t :foo, :count => 1 # => 'Foo'
+    #
+    # These both return the plural version of a pluralized translation:
+    #   I18n.t :foo, :count => 0 # => 'Foos'
+    #   I18n.t :foo, :count => 2 # => 'Foos'
+    #
+    # The <tt>:count</tt> option can be used both for pluralization and interpolation.
+    # <em>E.g.</em>, with the translation
+    # <tt>:foo => ['%{count} foo', '%{count} foos']</tt>, count will
+    # be interpolated to the pluralized translation:
+    #   I18n.t :foo, :count => 1 # => '1 foo'
+    #
+    # *DEFAULTS*
+    #
+    # This returns the translation for <tt>:foo</tt> or <tt>default</tt> if no translation was found:
+    #   I18n.t :foo, :default => 'default'
+    #
+    # This returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt> if no
+    # translation for <tt>:foo</tt> was found:
+    #   I18n.t :foo, :default => :bar
+    #
+    # Returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt>
+    # or <tt>default</tt> if no translations for <tt>:foo</tt> and <tt>:bar</tt> were found.
+    #   I18n.t :foo, :default => [:bar, 'default']
+    #
+    # *BULK LOOKUP*
+    #
+    # This returns an array with the translations for <tt>:foo</tt> and <tt>:bar</tt>.
+    #   I18n.t [:foo, :bar]
+    #
+    # Can be used with dot-separated nested keys:
+    #   I18n.t [:'baz.foo', :'baz.bar']
+    #
+    # Which is the same as using a scope option:
+    #   I18n.t [:foo, :bar], :scope => :baz
+    #
+    # *LAMBDAS*
+    #
+    # Both translations and defaults can be given as Ruby lambdas. Lambdas will be
+    # called and passed the key and options.
+    #
+    # E.g. assuming the key <tt>:salutation</tt> resolves to:
+    #   lambda { |key, options| options[:gender] == 'm' ? "Mr. %{options[:name]}" : "Mrs. %{options[:name]}" }
+    #
+    # Then <tt>I18n.t(:salutation, :gender => 'w', :name => 'Smith') will result in "Mrs. Smith".
+    #
+    # It is recommended to use/implement lambdas in an "idempotent" way. E.g. when
+    # a cache layer is put in front of I18n.translate it will generate a cache key
+    # from the argument values passed to #translate. Therefor your lambdas should
+    # always return the same translations/values per unique combination of argument
+    # values.
+    def translate(*args)
+      options = args.last.is_a?(Hash) ? args.pop : {}
+      key     = args.shift
+      backend = config.backend
+      locale  = options.delete(:locale) || config.locale
+      raises  = options.delete(:raise)
+
+      raise I18n::ArgumentError if key.is_a?(String) && key.empty?
+
+      if key.is_a?(Array)
+        key.map { |k| backend.translate(locale, k, options) }
+      else
+        backend.translate(locale, key, options)
+      end
+    rescue I18n::ArgumentError => exception
+      raise exception if raises
+      handle_exception(exception, locale, key, options)
+    end
+    alias :t :translate
+
+    def translate!(key, options={})
+      translate(key, options.merge(:raise => true))
+    end
+    alias :t! :translate!
+
+    # Transliterates UTF-8 characters to ASCII. By default this method will
+    # transliterate only Latin strings to an ASCII approximation:
+    #
+    #    I18n.transliterate("Ærøskøbing")
+    #    # => "AEroskobing"
+    #
+    #    I18n.transliterate("日本語")
+    #    # => "???"
+    #
+    # It's also possible to add support for per-locale transliterations. I18n
+    # expects transliteration rules to be stored at
+    # <tt>i18n.transliterate.rule</tt>.
+    #
+    # Transliteration rules can either be a Hash or a Proc. Procs must accept a
+    # single string argument. Hash rules inherit the default transliteration
+    # rules, while Procs do not.
+    #
+    # *Examples*
+    #
+    # Setting a Hash in <locale>.yml:
+    #
+    #    i18n:
+    #      transliterate:
+    #        rule:
+    #          ü: "ue"
+    #          ö: "oe"
+    #
+    # Setting a Hash using Ruby:
+    #
+    #     store_translations(:de, :i18n => {
+    #       :transliterate => {
+    #         :rule => {
+    #           "ü" => "ue",
+    #           "ö" => "oe"
+    #         }
+    #       }
+    #     )
+    #
+    # Setting a Proc:
+    #
+    #     translit = lambda {|string| MyTransliterator.transliterate(string) }
+    #     store_translations(:xx, :i18n => {:transliterate => {:rule => translit})
+    #
+    # Transliterating strings:
+    #
+    #     I18n.locale = :en
+    #     I18n.transliterate("Jürgen") # => "Jurgen"
+    #     I18n.locale = :de
+    #     I18n.transliterate("Jürgen") # => "Juergen"
+    #     I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen"
+    #     I18n.transliterate("Jürgen", :locale => :de) # => "Juergen"
+    def transliterate(*args)
+      options      = args.pop if args.last.is_a?(Hash)
+      key          = args.shift
+      locale       = options && options.delete(:locale) || config.locale
+      raises       = options && options.delete(:raise)
+      replacement  = options && options.delete(:replacement)
+      config.backend.transliterate(locale, key, replacement)
+    rescue I18n::ArgumentError => exception
+      raise exception if raises
+      handle_exception(exception, locale, key, options)
+    end
+
+    # Localizes certain objects, such as dates and numbers to local formatting.
+    def localize(object, options = {})
+      locale = options.delete(:locale) || config.locale
+      format = options.delete(:format) || :default
+      config.backend.localize(locale, object, format, options)
+    end
+    alias :l :localize
+
+    # Executes block with given I18n.locale set.
+    def with_locale(tmp_locale = nil)
+      if tmp_locale
+        current_locale = self.locale
+        self.locale    = tmp_locale
+      end
+      yield
+    ensure
+      self.locale = current_locale if tmp_locale
+    end
+
+
+    # Merges the given locale, key and scope into a single array of keys.
+    # Splits keys that contain dots into multiple keys. Makes sure all
+    # keys are Symbols.
+    def normalize_keys(locale, key, scope, separator = nil)
+      separator ||= I18n.default_separator
+
+      keys = []
+      keys.concat normalize_key(locale, separator)
+      keys.concat normalize_key(scope, separator)
+      keys.concat normalize_key(key, separator)
+      keys
+    end
+
+  # making these private until Ruby 1.9.2 can send to protected methods again
+  # see http://redmine.ruby-lang.org/repositories/revision/ruby-19?rev=24280
+  private
+
+    # Handles exceptions raised in the backend. All exceptions except for
+    # MissingTranslationData exceptions are re-raised. When a MissingTranslationData
+    # was caught and the option :raise is not set the handler returns an error
+    # message string containing the key/scope.
+    def default_exception_handler(exception, locale, key, options)
+      return exception.message if MissingTranslationData === exception
+      raise exception
+    end
+
+    # Any exceptions thrown in translate will be sent to the @@exception_handler
+    # which can be a Symbol, a Proc or any other Object.
+    #
+    # If exception_handler is a Symbol then it will simply be sent to I18n as
+    # a method call. A Proc will simply be called. In any other case the
+    # method #call will be called on the exception_handler object.
+    #
+    # Examples:
+    #
+    #   I18n.exception_handler = :default_exception_handler             # this is the default
+    #   I18n.default_exception_handler(exception, locale, key, options) # will be called like this
+    #
+    #   I18n.exception_handler = lambda { |*args| ... }                 # a lambda
+    #   I18n.exception_handler.call(exception, locale, key, options)    # will be called like this
+    #
+    #  I18n.exception_handler = I18nExceptionHandler.new                # an object
+    #  I18n.exception_handler.call(exception, locale, key, options)     # will be called like this
+    def handle_exception(exception, locale, key, options)
+      case config.exception_handler
+      when Symbol
+        send(config.exception_handler, exception, locale, key, options)
+      else
+        config.exception_handler.call(exception, locale, key, options)
+      end
+    end
+
+    # Deprecated. Will raise a warning in future versions and then finally be
+    # removed. Use I18n.normalize_keys instead.
+    def normalize_translation_keys(locale, key, scope, separator = nil)
+      normalize_keys(locale, key, scope, separator)
+    end
+
+    def normalize_key(key, separator)
+      normalized_key_cache[separator][key] ||=
+        case key
+        when Array
+          key.map { |k| normalize_key(k, separator) }.flatten
+        else
+          keys = key.to_s.split(separator)
+          keys.delete('')
+          keys.map!{ |k| k.to_sym }
+          keys
+        end
+    end
+
+    def normalized_key_cache
+      @normalized_key_cache ||= Hash.new { |h,k| h[k] = {} }
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend.rb
new file mode 100644 (file)
index 0000000..fe65fb4
--- /dev/null
@@ -0,0 +1,20 @@
+module I18n
+  module Backend
+    autoload :ActiveRecord,          'i18n/backend/active_record'
+    autoload :Base,                  'i18n/backend/base'
+    autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler'
+    autoload :Cache,                 'i18n/backend/cache'
+    autoload :Cascade,               'i18n/backend/cascade'
+    autoload :Chain,                 'i18n/backend/chain'
+    autoload :Cldr,                  'i18n/backend/cldr'
+    autoload :Fallbacks,             'i18n/backend/fallbacks'
+    autoload :Flatten,               'i18n/backend/flatten'
+    autoload :Gettext,               'i18n/backend/gettext'
+    autoload :KeyValue,              'i18n/backend/key_value'
+    autoload :Memoize,               'i18n/backend/memoize'
+    autoload :Metadata,              'i18n/backend/metadata'
+    autoload :Pluralization,         'i18n/backend/pluralization'
+    autoload :Simple,                'i18n/backend/simple'
+    autoload :Transliterator,        'i18n/backend/transliterator'
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record.rb
new file mode 100644 (file)
index 0000000..b60f138
--- /dev/null
@@ -0,0 +1,61 @@
+require 'i18n/backend/base'
+require 'i18n/backend/active_record/translation'
+
+module I18n
+  module Backend
+    class ActiveRecord
+      autoload :Missing,     'i18n/backend/active_record/missing'
+      autoload :StoreProcs,  'i18n/backend/active_record/store_procs'
+      autoload :Translation, 'i18n/backend/active_record/translation'
+
+      module Implementation
+        include Base, Flatten
+
+        def available_locales
+          begin
+            Translation.available_locales
+          rescue ::ActiveRecord::StatementInvalid
+            []
+          end
+        end
+
+        def store_translations(locale, data, options = {})
+          escape = options.fetch(:escape, true)
+          flatten_translations(locale, data, escape, false).each do |key, value|
+            Translation.locale(locale).lookup(expand_keys(key)).delete_all
+            Translation.create(:locale => locale.to_s, :key => key.to_s, :value => value)
+          end
+        end
+
+      protected
+
+        def lookup(locale, key, scope = [], options = {})
+          key = normalize_flat_keys(locale, key, scope, options[:separator])
+          result = Translation.locale(locale).lookup(key).all
+
+          if result.empty?
+            nil
+          elsif result.first.key == key
+            result.first.value
+          else
+            chop_range = (key.size + FLATTEN_SEPARATOR.size)..-1
+            result = result.inject({}) do |hash, r|
+              hash[r.key.slice(chop_range)] = r.value
+              hash
+            end
+            result.deep_symbolize_keys
+          end
+        end
+
+        # For a key :'foo.bar.baz' return ['foo', 'foo.bar', 'foo.bar.baz']
+        def expand_keys(key)
+          key.to_s.split(FLATTEN_SEPARATOR).inject([]) do |keys, key|
+            keys << [keys.last, key].compact.join(FLATTEN_SEPARATOR)
+          end
+        end
+      end
+
+      include Implementation
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record/missing.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record/missing.rb
new file mode 100644 (file)
index 0000000..ef34055
--- /dev/null
@@ -0,0 +1,65 @@
+#  This extension stores translation stub records for missing translations to
+#  the database.
+#
+#  This is useful if you have a web based translation tool. It will populate
+#  the database with untranslated keys as the application is being used. A
+#  translator can then go through these and add missing translations.
+#
+#  Example usage:
+#
+#     I18n::Backend::Chain.send(:include, I18n::Backend::ActiveRecord::Missing)
+#     I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n::Backend::Simple.new)
+#
+#  Stub records for pluralizations will also be created for each key defined
+#  in i18n.plural.keys.
+#
+#  For example:
+#
+#    # en.yml
+#    en:
+#      i18n:
+#        plural:
+#          keys: [:zero, :one, :other]
+#
+#    # pl.yml
+#    pl:
+#      i18n:
+#        plural:
+#          keys: [:zero, :one, :few, :other]
+#
+#  It will also persist interpolation keys in Translation#interpolations so
+#  translators will be able to review and use them.
+module I18n
+  module Backend
+    class ActiveRecord
+      module Missing
+        include Flatten
+
+        def store_default_translations(locale, key, options = {})
+          count, scope, default, separator = options.values_at(:count, :scope, :default, :separator)
+          separator ||= I18n.default_separator
+          key = normalize_flat_keys(locale, key, scope, separator)
+
+          unless ActiveRecord::Translation.locale(locale).lookup(key).exists?
+            interpolations = options.keys - Base::RESERVED_KEYS
+            keys = count ? I18n.t('i18n.plural.keys', :locale => locale).map { |k| [key, k].join(FLATTEN_SEPARATOR) } : [key]
+            keys.each { |key| store_default_translation(locale, key, interpolations) }
+          end
+        end
+
+        def store_default_translation(locale, key, interpolations)
+          translation = ActiveRecord::Translation.new :locale => locale.to_s, :key => key
+          translation.interpolations = interpolations
+          translation.save
+        end
+
+        def translate(locale, key, options = {})
+          super
+        rescue I18n::MissingTranslationData => e
+          self.store_default_translations(locale, key, options)
+          raise e
+        end
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record/store_procs.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record/store_procs.rb
new file mode 100644 (file)
index 0000000..652b1aa
--- /dev/null
@@ -0,0 +1,38 @@
+# This module is intended to be mixed into the ActiveRecord backend to allow
+# storing Ruby Procs as translation values in the database.
+#
+#   I18n.backend = I18n::Backend::ActiveRecord.new
+#   I18n::Backend::ActiveRecord::Translation.send(:include, I18n::Backend::ActiveRecord::StoreProcs)
+#
+# The StoreProcs module requires the ParseTree and ruby2ruby gems and therefor
+# was extracted from the original backend.
+#
+# ParseTree is not compatible with Ruby 1.9.
+
+begin
+  require 'ruby2ruby'
+  require 'parse_tree'
+  require 'parse_tree_extensions'
+rescue LoadError => e
+  puts "can't use StoreProcs because: #{e.message}"
+end
+
+module I18n
+  module Backend
+    class ActiveRecord
+      module StoreProcs
+        def value=(v)
+          case v
+          when Proc
+            write_attribute(:value, v.to_ruby)
+            write_attribute(:is_proc, true)
+          else
+            write_attribute(:value, v)
+          end
+        end
+
+        Translation.send(:include, self) if method(:to_s).respond_to?(:to_ruby)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record/translation.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/active_record/translation.rb
new file mode 100644 (file)
index 0000000..f373043
--- /dev/null
@@ -0,0 +1,110 @@
+require 'active_record'
+
+module I18n
+  module Backend
+    # ActiveRecord model used to store actual translations to the database.
+    #
+    # This model expects a table like the following to be already set up in
+    # your the database:
+    #
+    #   create_table :translations do |t|
+    #     t.string :locale
+    #     t.string :key
+    #     t.text   :value
+    #     t.text   :interpolations
+    #     t.boolean :is_proc, :default => false
+    #   end
+    #
+    # This model supports to named scopes :locale and :lookup. The :locale
+    # scope simply adds a condition for a given locale:
+    #
+    #   I18n::Backend::ActiveRecord::Translation.locale(:en).all
+    #   # => all translation records that belong to the :en locale
+    #
+    # The :lookup scope adds a condition for looking up all translations
+    # that either start with the given keys (joined by an optionally given
+    # separator or I18n.default_separator) or that exactly have this key.
+    #
+    #   # with translations present for :"foo.bar" and :"foo.baz"
+    #   I18n::Backend::ActiveRecord::Translation.lookup(:foo)
+    #   # => an array with both translation records :"foo.bar" and :"foo.baz"
+    #
+    #   I18n::Backend::ActiveRecord::Translation.lookup([:foo, :bar])
+    #   I18n::Backend::ActiveRecord::Translation.lookup(:"foo.bar")
+    #   # => an array with the translation record :"foo.bar"
+    #
+    # When the StoreProcs module was mixed into this model then Procs will
+    # be stored to the database as Ruby code and evaluated when :value is
+    # called.
+    #
+    #   Translation = I18n::Backend::ActiveRecord::Translation
+    #   Translation.create \
+    #     :locale => 'en'
+    #     :key    => 'foo'
+    #     :value  => lambda { |key, options| 'FOO' }
+    #   Translation.find_by_locale_and_key('en', 'foo').value
+    #   # => 'FOO'
+    class ActiveRecord
+      class Translation < ::ActiveRecord::Base
+        TRUTHY_CHAR = "\001"
+        FALSY_CHAR = "\002"
+
+        set_table_name 'translations'
+        attr_protected :is_proc, :interpolations
+
+        serialize :value
+        serialize :interpolations, Array
+
+        class << self
+          def locale(locale)
+            scoped(:conditions => { :locale => locale.to_s })
+          end
+
+          def lookup(keys, *separator)
+            column_name = connection.quote_column_name('key')
+            keys = Array(keys).map! { |key| key.to_s }
+
+            unless separator.empty?
+              warn "[DEPRECATION] Giving a separator to Translation.lookup is deprecated. " <<
+                "You can change the internal separator by overwriting FLATTEN_SEPARATOR."
+            end
+
+            namespace = "#{keys.last}#{I18n::Backend::Flatten::FLATTEN_SEPARATOR}%"
+            scoped(:conditions => ["#{column_name} IN (?) OR #{column_name} LIKE ?", keys, namespace])
+          end
+
+          def available_locales
+            Translation.find(:all, :select => 'DISTINCT locale').map { |t| t.locale.to_sym }
+          end
+        end
+
+        def interpolates?(key)
+          self.interpolations.include?(key) if self.interpolations
+        end
+
+        def value
+          value = read_attribute(:value)
+          if is_proc
+            Kernel.eval(value)
+          elsif value == FALSY_CHAR
+            false
+          elsif value == TRUTHY_CHAR
+            true
+          else
+            value
+          end
+        end
+
+        def value=(value)
+          if value === false
+            value = FALSY_CHAR
+          elsif value === true
+            value = TRUTHY_CHAR
+          end
+
+          write_attribute(:value, value)
+        end
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/base.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/base.rb
new file mode 100644 (file)
index 0000000..f780371
--- /dev/null
@@ -0,0 +1,215 @@
+# encoding: utf-8
+
+require 'yaml'
+require 'i18n/core_ext/hash'
+
+module I18n
+  module Backend
+    module Base
+      include I18n::Backend::Transliterator
+
+      RESERVED_KEYS = [:scope, :default, :separator, :resolve, :object, :fallback]
+      RESERVED_KEYS_PATTERN = /%\{(#{RESERVED_KEYS.join("|")})\}/
+      DEPRECATED_INTERPOLATION_SYNTAX_PATTERN = /(\\)?\{\{([^\}]+)\}\}/
+
+      # Accepts a list of paths to translation files. Loads translations from
+      # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
+      # for details.
+      def load_translations(*filenames)
+        filenames = I18n.load_path.flatten if filenames.empty?
+        filenames.each { |filename| load_file(filename) }
+      end
+
+      # This method receives a locale, a data hash and options for storing translations.
+      # Should be implemented
+      def store_translations(locale, data, options = {})
+        raise NotImplementedError
+      end
+
+      def translate(locale, key, options = {})
+        raise InvalidLocale.new(locale) unless locale
+        entry = key && lookup(locale, key, options[:scope], options)
+
+        if options.empty?
+          entry = resolve(locale, key, entry, options)
+        else
+          count, default = options.values_at(:count, :default)
+          values = options.except(*RESERVED_KEYS)
+          entry = entry.nil? && default ?
+            default(locale, key, default, options) : resolve(locale, key, entry, options)
+        end
+
+        raise(I18n::MissingTranslationData.new(locale, key, options)) if entry.nil?
+        entry = entry.dup if entry.is_a?(String)
+
+        entry = pluralize(locale, entry, count) if count
+        entry = interpolate(locale, entry, values) if values
+        entry
+      end
+
+      # Acts the same as +strftime+, but uses a localized version of the
+      # format string. Takes a key from the date/time formats translations as
+      # a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
+      def localize(locale, object, format = :default, options = {})
+        raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
+
+        if Symbol === format
+          key  = format
+          type = object.respond_to?(:sec) ? 'time' : 'date'
+          options = options.merge(:raise => true, :object => object, :locale => locale)
+          format  = I18n.t(:"#{type}.formats.#{key}", options)
+        end
+
+        # format = resolve(locale, object, format, options)
+        format = format.to_s.gsub(/%[aAbBp]/) do |match|
+          case match
+          when '%a' then I18n.t(:"date.abbr_day_names",                  :locale => locale, :format => format)[object.wday]
+          when '%A' then I18n.t(:"date.day_names",                       :locale => locale, :format => format)[object.wday]
+          when '%b' then I18n.t(:"date.abbr_month_names",                :locale => locale, :format => format)[object.mon]
+          when '%B' then I18n.t(:"date.month_names",                     :locale => locale, :format => format)[object.mon]
+          when '%p' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format) if object.respond_to? :hour
+          end
+        end
+
+        object.strftime(format)
+      end
+
+      # Returns an array of locales for which translations are available
+      # ignoring the reserved translation meta data key :i18n.
+      def available_locales
+        raise NotImplementedError
+      end
+
+      def reload!
+        @skip_syntax_deprecation = false
+      end
+
+      protected
+
+        # The method which actually looks up for the translation in the store.
+        def lookup(locale, key, scope = [], options = {})
+          raise NotImplementedError
+        end
+
+        # Evaluates defaults.
+        # If given subject is an Array, it walks the array and returns the
+        # first translation that can be resolved. Otherwise it tries to resolve
+        # the translation directly.
+        def default(locale, object, subject, options = {})
+          options = options.dup.reject { |key, value| key == :default }
+          case subject
+          when Array
+            subject.each do |item|
+              result = resolve(locale, object, item, options) and return result
+            end and nil
+          else
+            resolve(locale, object, subject, options)
+          end
+        end
+
+        # Resolves a translation.
+        # If the given subject is a Symbol, it will be translated with the
+        # given options. If it is a Proc then it will be evaluated. All other
+        # subjects will be returned directly.
+        def resolve(locale, object, subject, options = {})
+          return subject if options[:resolve] == false
+          case subject
+          when Symbol
+            I18n.translate(subject, options.merge(:locale => locale, :raise => true))
+          when Proc
+            date_or_time = options.delete(:object) || object
+            resolve(locale, object, subject.call(date_or_time, options))
+          else
+            subject
+          end
+        rescue MissingTranslationData
+          nil
+        end
+
+        # Picks a translation from an array according to English pluralization
+        # rules. It will pick the first translation if count is not equal to 1
+        # and the second translation if it is equal to 1. Other backends can
+        # implement more flexible or complex pluralization rules.
+        def pluralize(locale, entry, count)
+          return entry unless entry.is_a?(Hash) && count
+
+          key = :zero if count == 0 && entry.has_key?(:zero)
+          key ||= count == 1 ? :one : :other
+          raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
+          entry[key]
+        end
+
+        # Interpolates values into a given string.
+        #
+        #   interpolate "file %{file} opened by %%{user}", :file => 'test.txt', :user => 'Mr. X'
+        #   # => "file test.txt opened by %{user}"
+        #
+        # Note that you have to double escape the <tt>\\</tt> when you want to escape
+        # the <tt>{{...}}</tt> key in a string (once for the string and once for the
+        # interpolation).
+        def interpolate(locale, string, values = {})
+          return string unless string.is_a?(::String) && !values.empty?
+
+          string = string.gsub(DEPRECATED_INTERPOLATION_SYNTAX_PATTERN) do
+            escaped, key = $1, $2.to_sym
+            if escaped
+              "{{#{key}}}"
+            else
+              warn_syntax_deprecation!(locale, string)
+              "%{#{key}}"
+            end
+          end
+
+          values.each do |key, value|
+            value = value.call(values) if interpolate_lambda?(value, string, key)
+            value = value.to_s unless value.is_a?(::String)
+            values[key] = value
+          end
+
+          string % values
+        rescue KeyError => e
+          if string =~ RESERVED_KEYS_PATTERN
+            raise ReservedInterpolationKey.new($1.to_sym, string)
+          else
+            raise MissingInterpolationArgument.new(values, string)
+          end
+        end
+
+        # returns true when the given value responds to :call and the key is
+        # an interpolation placeholder in the given string
+        def interpolate_lambda?(object, string, key)
+          object.respond_to?(:call) && string =~ /%\{#{key}\}|%\<#{key}>.*?\d*\.?\d*[bBdiouxXeEfgGcps]\}/
+        end
+
+        # Loads a single translations file by delegating to #load_rb or
+        # #load_yml depending on the file extension and directly merges the
+        # data to the existing translations. Raises I18n::UnknownFileType
+        # for all other file extensions.
+        def load_file(filename)
+          type = File.extname(filename).tr('.', '').downcase
+          raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}", true)
+          data = send(:"load_#{type}", filename)
+          raise InvalidLocaleData.new(filename) unless data.is_a?(Hash)
+          data.each { |locale, d| store_translations(locale, d || {}) }
+        end
+
+        # Loads a plain Ruby translations file. eval'ing the file must yield
+        # a Hash containing translation data with locales as toplevel keys.
+        def load_rb(filename)
+          eval(IO.read(filename), binding, filename)
+        end
+
+        # Loads a YAML translations file. The data must have locales as
+        # toplevel keys.
+        def load_yml(filename)
+          YAML.load_file(filename)
+        end
+
+        def warn_syntax_deprecation!(locale, string) #:nodoc:
+          return if @skip_syntax_deprecation
+          warn "The {{key}} interpolation syntax in I18n messages is deprecated. Please use %{key} instead.\n#{locale} - #{string}\n"
+          @skip_syntax_deprecation = true
+        end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/cache.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/cache.rb
new file mode 100644 (file)
index 0000000..c0d78e6
--- /dev/null
@@ -0,0 +1,104 @@
+# encoding: utf-8
+
+# This module allows you to easily cache all responses from the backend - thus
+# speeding up the I18n aspects of your application quite a bit.
+#
+# To enable caching you can simply include the Cache module to the Simple
+# backend - or whatever other backend you are using:
+#
+#   I18n::Backend::Simple.send(:include, I18n::Backend::Cache)
+#
+# You will also need to set a cache store implementation that you want to use:
+#
+#   I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
+#
+# You can use any cache implementation you want that provides the same API as
+# ActiveSupport::Cache (only the methods #fetch and #write are being used).
+#
+# The cache_key implementation assumes that you only pass values to
+# I18n.translate that return a valid key from #hash (see
+# http://www.ruby-doc.org/core/classes/Object.html#M000337).
+#
+# If you use a lambda as a default value in your translation like this:
+#
+#   I18n.t(:"date.order", :default => lambda {[:month, :day, :year]})
+#
+# Then you will always have a cache miss, because each time this method
+# is called the lambda will have a different hash value. If you know
+# the result of the lambda is a constant as in the example above, then
+# to cache this you can make the lambda a constant, like this:
+#
+#   DEFAULT_DATE_ORDER = lambda {[:month, :day, :year]}
+#   ...
+#   I18n.t(:"date.order", :default => DEFAULT_DATE_ORDER)
+#
+# If the lambda may result in different values for each call then consider
+# also using the Memoize backend.
+#
+module I18n
+  class << self
+    @@cache_store = nil
+    @@cache_namespace = nil
+
+    def cache_store
+      @@cache_store
+    end
+
+    def cache_store=(store)
+      @@cache_store = store
+    end
+
+    def cache_namespace
+      @@cache_namespace
+    end
+
+    def cache_namespace=(namespace)
+      @@cache_namespace = namespace
+    end
+
+    def perform_caching?
+      !cache_store.nil?
+    end
+  end
+
+  module Backend
+    # TODO Should the cache be cleared if new translations are stored?
+    module Cache
+      def translate(locale, key, options = {})
+        I18n.perform_caching? ? fetch(cache_key(locale, key, options)) { super } : super
+      end
+
+      protected
+
+        def fetch(cache_key, &block)
+          result = fetch_storing_missing_translation_exception(cache_key, &block)
+          raise result if result.is_a?(Exception)
+          result = result.dup if result.frozen? rescue result
+          result
+        end
+
+        def fetch_storing_missing_translation_exception(cache_key, &block)
+          fetch_ignoring_procs(cache_key, &block)
+        rescue MissingTranslationData => exception
+          I18n.cache_store.write(cache_key, exception)
+          exception
+        end
+
+        def fetch_ignoring_procs(cache_key, &block)
+          I18n.cache_store.read(cache_key) || yield.tap do |result|
+            I18n.cache_store.write(cache_key, result) unless result.is_a?(Proc)
+          end
+        end
+
+        def cache_key(locale, key, options)
+          # This assumes that only simple, native Ruby values are passed to I18n.translate.
+          "i18n/#{I18n.cache_namespace}/#{locale}/#{key.hash}/#{USE_INSPECT_HASH ? options.inspect.hash : options.hash}"
+        end
+
+      private
+        # In Ruby < 1.9 the following is true: { :foo => 1, :bar => 2 }.hash == { :foo => 2, :bar => 1 }.hash
+        # Therefore we must use the hash of the inspect string instead to avoid cache key colisions.
+        USE_INSPECT_HASH = RUBY_VERSION <= "1.9"
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/cascade.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/cascade.rb
new file mode 100644 (file)
index 0000000..370fb48
--- /dev/null
@@ -0,0 +1,57 @@
+# encoding: utf-8
+
+# EXPERIMENTAL
+#
+# The Cascade module adds the ability to do cascading lookups to backends that
+# are compatible to the Simple backend.
+#
+# By cascading lookups we mean that for any key that can not be found the
+# Cascade module strips one segment off the scope part of the key and then
+# tries to look up the key in that scope.
+#
+# E.g. when a lookup for the key :"foo.bar.baz" does not yield a result then
+# the segment :bar will be stripped off the scope part :"foo.bar" and the new
+# scope :foo will be used to look up the key :baz. If that does not succeed
+# then the remaining scope segment :foo will be omitted, too, and again the
+# key :baz will be looked up (now with no scope).
+#
+# To enable a cascading lookup one passes the :cascade option:
+#
+#   I18n.t(:'foo.bar.baz', :cascade => true)
+#
+# This will return the first translation found for :"foo.bar.baz", :"foo.baz"
+# or :baz in this order.
+#
+# The cascading lookup takes precedence over resolving any given defaults.
+# I.e. defaults will kick in after the cascading lookups haven't succeeded.
+#
+# This behavior is useful for libraries like ActiveRecord validations where
+# the library wants to give users a bunch of more or less fine-grained options
+# of scopes for a particular key.
+#
+# Thanks to Clemens Kofler for the initial idea and implementation! See
+# http://github.com/clemens/i18n-cascading-backend
+
+module I18n
+  module Backend
+    module Cascade
+      def lookup(locale, key, scope = [], options = {})
+        return super unless cascade = options[:cascade]
+
+        separator = options[:separator] || I18n.default_separator
+        skip_root = cascade.has_key?(:skip_root) ? cascade[:skip_root] : true
+        step      = cascade[:step]
+
+        keys   = I18n.normalize_keys(nil, key, nil, separator)
+        offset = options[:cascade][:offset] || keys.length
+        scope  = I18n.normalize_keys(nil, nil, scope, separator) + keys
+        key    = scope.slice!(-offset, offset).join(separator)
+
+        begin
+          result = super
+          return result unless result.nil?
+        end while !scope.empty? && scope.slice!(-step, step) && (!scope.empty? || !skip_root)
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/chain.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/chain.rb
new file mode 100644 (file)
index 0000000..9aa3eea
--- /dev/null
@@ -0,0 +1,82 @@
+# encoding: utf-8
+
+module I18n
+  module Backend
+    # Backend that chains multiple other backends and checks each of them when
+    # a translation needs to be looked up. This is useful when you want to use
+    # standard translations with a Simple backend but store custom application
+    # translations in a database or other backends.
+    #
+    # To use the Chain backend instantiate it and set it to the I18n module.
+    # You can add chained backends through the initializer or backends
+    # accessor:
+    #
+    #   # preserves the existing Simple backend set to I18n.backend
+    #   I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
+    #
+    # The implementation assumes that all backends added to the Chain implement
+    # a lookup method with the same API as Simple backend does.
+    class Chain
+      module Implementation
+        include Base
+
+        attr_accessor :backends
+
+        def initialize(*backends)
+          self.backends = backends
+        end
+
+        def reload!
+          backends.each { |backend| backend.reload! }
+        end
+
+        def store_translations(locale, data, options = {})
+          backends.first.store_translations(locale, data, options = {})
+        end
+
+        def available_locales
+          backends.map { |backend| backend.available_locales }.flatten.uniq
+        end
+
+        def translate(locale, key, default_options = {})
+          namespace = nil
+          options = default_options.except(:default)
+
+          backends.each do |backend|
+            begin
+              options = default_options if backend == backends.last
+              translation = backend.translate(locale, key, options)
+              if namespace_lookup?(translation, options)
+                namespace ||= {}
+                namespace.merge!(translation)
+              elsif !translation.nil?
+                return translation
+              end
+            rescue MissingTranslationData
+            end
+          end
+
+          return namespace if namespace
+          raise(I18n::MissingTranslationData.new(locale, key, options))
+        end
+
+        def localize(locale, object, format = :default, options = {})
+          backends.each do |backend|
+            begin
+              result = backend.localize(locale, object, format, options) and return result
+            rescue MissingTranslationData
+            end
+          end
+          raise(I18n::MissingTranslationData.new(locale, format, options))
+        end
+
+        protected
+          def namespace_lookup?(result, options)
+            result.is_a?(Hash) && !options.has_key?(:count)
+          end
+      end
+
+      include Implementation
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/cldr.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/cldr.rb
new file mode 100644 (file)
index 0000000..d702f22
--- /dev/null
@@ -0,0 +1,100 @@
+# encoding: utf-8
+require 'cldr'
+
+module I18n
+  module Backend
+    module Cldr
+      include ::Cldr::Format
+
+      def localize(locale, object, format = :default, options = {})
+        options[:as] ||= detect_type(object, options)
+        send(:"format_#{options[:as]}", locale, object, format, options)
+      end
+
+      def format_decimal(locale, object, format = :default, options = {})
+        formatter(locale, :decimal, format).apply(object, options)
+      end
+
+      def format_integer(locale, object, format = :default, options = {})
+        format_object(number, options.merge(:precision => 0))
+      end
+
+      def format_currency(locale, object, format = :default, options = {})
+        options.merge!(:currency => lookup_currency(locale, options[:currency], object)) if options[:currency].is_a?(Symbol)
+        formatter(locale, :currency, format).apply(object, options)
+      end
+
+      def format_percent(locale, object, format = :default, options = {})
+        formatter(locale, :percent, format).apply(object, options)
+      end
+
+      def format_date(locale, object, format = :default, options = {})
+        formatter(locale, :date, format).apply(object, options)
+      end
+
+      def format_time(locale, object, format = :default, options = {})
+        formatter(locale, :time, format).apply(object, options)
+      end
+
+      def format_datetime(locale, object, format = :default, options = {})
+        key  = :"calendars.gregorian.formats.datetime.#{format}.pattern"
+        date = I18n.l(object, :format => options[:date_format] || format, :locale => locale, :as => :date)
+        time = I18n.l(object, :format => options[:time_format] || format, :locale => locale, :as => :time)
+        I18n.t(key, :date => date, :time => time, :locale => locale, :raise => true)
+      end
+
+      protected
+
+        def detect_type(object, options)
+          options.has_key?(:currency) ? :currency : case object
+          when ::Numeric
+            :decimal
+          when ::Date, ::DateTime, ::Time
+            object.class.name.downcase.to_sym
+          else
+            raise_unspecified_format_type!
+          end
+        end
+
+        def formatter(locale, type, format)
+          (@formatters ||= {})[:"#{locale}.#{type}.#{format}"] ||= begin
+            format = lookup_format(locale, type, format)
+            data   = lookup_format_data(locale, type)
+            ::Cldr::Format.const_get(type.to_s.camelize).new(format, data)
+          end
+        end
+
+        def lookup_format(locale, type, format)
+          key = case type
+          when :date, :time, :datetime
+            :"calendars.gregorian.formats.#{type}.#{format}.pattern"
+          else
+            :"numbers.formats.#{type}.patterns.#{format || :default}"
+          end
+          I18n.t(key, :locale => locale, :raise => true)
+        end
+
+        def lookup_format_data(locale, type)
+          key = case type
+          when :date, :time, :datetime
+            :'calendars.gregorian'
+          else
+            :'numbers.symbols'
+          end
+          I18n.t(key, :locale => locale, :raise => true)
+        end
+
+        def lookup_currency(locale, currency, count)
+          I18n.t(:"currencies.#{currency}", :locale => locale, :count => count)
+        end
+
+        def raise_unspecified_format_type!
+          raise ArgumentError.new("You have to specify a format type, e.g. :as => :number.")
+        end
+
+        def raise_unspecified_currency!
+          raise ArgumentError.new("You have to specify a currency, e.g. :currency => 'EUR'.")
+        end
+    end
+  end
+end
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/fallbacks.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/fallbacks.rb
new file mode 100644 (file)
index 0000000..596d396
--- /dev/null
@@ -0,0 +1,72 @@
+# encoding: utf-8
+
+# I18n locale fallbacks are useful when you want your application to use
+# translations from other locales when translations for the current locale are
+# missing. E.g. you might want to use :en translations when translations in
+# your applications main locale :de are missing.
+#
+# To enable locale fallbacks you can simply include the Fallbacks module to
+# the Simple backend - or whatever other backend you are using:
+#
+#   I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
+module I18n
+  @@fallbacks = nil
+
+  class << self
+    # Returns the current fallbacks implementation. Defaults to +I18n::Locale::Fallbacks+.
+    def fallbacks
+      @@fallbacks ||= I18n::Locale::Fallbacks.new
+    end
+
+    # Sets the current fallbacks implementation. Use this to set a different fallbacks implementation.
+    def fallbacks=(fallbacks)
+      @@fallbacks = fallbacks
+    end
+  end
+
+  module Backend
+    module Fallbacks
+      # Overwrites the Base backend translate method so that it will try each
+      # locale given by I18n.fallbacks for the given locale. E.g. for the
+      # locale :"de-DE" it might try the locales :"de-DE", :de and :en
+      # (depends on the fallbacks implementation) until it finds a result with
+      # the given options. If it does not find any result for any of the
+      # locales it will then raise a MissingTranslationData exception as
+      # usual.
+      #
+      # The default option takes precedence over fallback locales
+      # only when it's a Symbol. When the default contains a String or a Proc
+      # it is evaluated last after all the fallback locales have been tried.
+      def translate(locale, key, options = {})
+        return super if options[:fallback]
+        default = extract_string_or_lambda_default!(options) if options[:default]
+
+        options[:fallback] = true
+        I18n.fallbacks[locale].each do |fallback|
+          begin
+            result = super(fallback, key, options)
+            return result unless result.nil?
+          rescue I18n::MissingTranslationData
+          end
+        end
+        options.delete(:fallback)
+
+        return super(locale, nil, options.merge(:default => default)) if default
+        raise(I18n::MissingTranslationData.new(locale, key, options))
+      end
+
+      def extract_string_or_lambda_default!(options)
+        defaults = Array(options[:default])
+        if index = find_first_string_or_lambda_default(defaults)
+          options[:default] = defaults[0, index]
+          defaults[index]
+        end
+      end
+
+      def find_first_string_or_lambda_default(defaults)
+        defaults.each_with_index { |default, ix| return ix if String === default || Proc === default }
+        nil
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/flatten.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/flatten.rb
new file mode 100644 (file)
index 0000000..c23f7c1
--- /dev/null
@@ -0,0 +1,113 @@
+module I18n
+  module Backend
+    # This module contains several helpers to assist flattening translations.
+    # You may want to flatten translations for:
+    #
+    #   1) speed up lookups, as in the Memoize backend;
+    #   2) In case you want to store translations in a data store, as in ActiveRecord backend;
+    #
+    # You can check both backends above for some examples.
+    # This module also keeps all links in a hash so they can be properly resolved when flattened.
+    module Flatten
+      SEPARATOR_ESCAPE_CHAR = "\001"
+      FLATTEN_SEPARATOR = "."
+
+      # normalize_keys the flatten way. This method is significantly faster
+      # and creates way less objects than the one at I18n.normalize_keys.
+      # It also handles escaping the translation keys.
+      def self.normalize_flat_keys(locale, key, scope, separator)
+        keys = [scope, key].flatten.compact
+        separator ||= I18n.default_separator
+
+        if separator != FLATTEN_SEPARATOR
+          keys.map! do |k|
+            k.to_s.tr("#{FLATTEN_SEPARATOR}#{separator}",
+              "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}")
+          end
+        end
+
+        keys.join(".")
+      end
+
+      # Receives a string and escape the default separator.
+      def self.escape_default_separator(key) #:nodoc:
+        key.to_s.tr(FLATTEN_SEPARATOR, SEPARATOR_ESCAPE_CHAR)
+      end
+
+      # Shortcut to I18n::Backend::Flatten.normalize_flat_keys
+      # and then resolve_links.
+      def normalize_flat_keys(locale, key, scope, separator)
+        key = I18n::Backend::Flatten.normalize_flat_keys(locale, key, scope, separator)
+        resolve_link(locale, key)
+      end
+
+      # Store flattened links.
+      def links
+        @links ||= Hash.new { |h,k| h[k] = {} }
+      end
+
+      # Flatten keys for nested Hashes by chaining up keys:
+      #
+      #   >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind
+      #   => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" }
+      #
+      def flatten_keys(hash, escape, prev_key=nil, &block)
+        hash.each_pair do |key, value|
+          key = escape_default_separator(key) if escape
+          curr_key = [prev_key, key].compact.join(FLATTEN_SEPARATOR).to_sym
+          yield curr_key, value
+          flatten_keys(value, escape, curr_key, &block) if value.is_a?(Hash)
+        end
+      end
+
+      # Receives a hash of translations (where the key is a locale and
+      # the value is another hash) and return a hash with all
+      # translations flattened.
+      #
+      # Nested hashes are included in the flattened hash just if subtree
+      # is true and Symbols are automatically stored as links.
+      def flatten_translations(locale, data, escape, subtree)
+        hash = {}
+        flatten_keys(data, escape) do |key, value|
+          if value.is_a?(Hash)
+            hash[key] = value if subtree
+          else
+            store_link(locale, key, value) if value.is_a?(Symbol)
+            hash[key] = value
+          end
+        end
+        hash
+      end
+
+      protected
+
+        def store_link(locale, key, link)
+          links[locale.to_sym][key.to_s] = link.to_s
+        end
+
+        def resolve_link(locale, key)
+          key, locale = key.to_s, locale.to_sym
+          links = self.links[locale]
+
+          if links.key?(key)
+            links[key]
+          elsif link = find_link(locale, key)
+            store_link(locale, key, key.gsub(*link))
+          else
+            key
+          end
+        end
+
+        def find_link(locale, key) #:nodoc:
+          links[locale].each do |from, to|
+            return [from, to] if key[0, from.length] == from
+          end && nil
+        end
+
+        def escape_default_separator(key) #:nodoc:
+          I18n::Backend::Flatten.escape_default_separator(key)
+        end
+
+    end
+  end
+end
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/gettext.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/gettext.rb
new file mode 100644 (file)
index 0000000..4ff15f9
--- /dev/null
@@ -0,0 +1,73 @@
+# encoding: utf-8
+
+require 'i18n/gettext'
+require 'i18n/gettext/po_parser'
+
+# Experimental support for using Gettext po files to store translations.
+#
+# To use this you can simply include the module to the Simple backend - or
+# whatever other backend you are using.
+#
+#   I18n::Backend::Simple.send(:include, I18n::Backend::Gettext)
+#
+# Now you should be able to include your Gettext translation (*.po) files to
+# the I18n.load_path so they're loaded to the backend and you can use them as
+# usual:
+#
+#  I18n.load_path += Dir["path/to/locales/*.po"]
+#
+# Following the Gettext convention this implementation expects that your
+# translation files are named by their locales. E.g. the file en.po would
+# contain the translations for the English locale.
+module I18n
+  module Backend
+    module Gettext
+      class PoData < Hash
+        def set_comment(msgid_or_sym, comment)
+          # ignore
+        end
+      end
+
+      protected
+        def load_po(filename)
+          locale = ::File.basename(filename, '.po').to_sym
+          data = normalize(locale, parse(filename))
+          { locale => data }
+        end
+
+        def parse(filename)
+          GetText::PoParser.new.parse(::File.read(filename), PoData.new)
+        end
+
+        def normalize(locale, data)
+          data.inject({}) do |result, (key, value)|
+            unless key.nil? || key.empty?
+              key, value = normalize_pluralization(locale, key, value) if key.index("\000")
+
+              parts = key.split('|').reverse
+              normalized = parts.inject({}) do |normalized, part|
+                normalized = { part => normalized.empty? ? value : normalized }
+              end
+
+              result.deep_merge!(normalized)
+            end
+            result
+          end
+        end
+
+        def normalize_pluralization(locale, key, value)
+          # FIXME po_parser includes \000 chars that can not be turned into Symbols
+          key = key.gsub("\000", I18n::Gettext::PLURAL_SEPARATOR).split(I18n::Gettext::PLURAL_SEPARATOR).first
+
+          keys = I18n::Gettext.plural_keys(locale)
+          values = value.split("\000")
+          raise "invalid number of plurals: #{values.size}, keys: #{keys.inspect}" if values.size != keys.size
+
+          result = {}
+          values.each_with_index { |value, ix| result[keys[ix]] = value }
+          [key, result]
+        end
+
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/interpolation_compiler.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/interpolation_compiler.rb
new file mode 100644 (file)
index 0000000..8c7c9c9
--- /dev/null
@@ -0,0 +1,123 @@
+# encoding: utf-8
+
+# The InterpolationCompiler module contains optimizations that can tremendously
+# speed up the interpolation process on the Simple backend.
+#
+# It works by defining a pre-compiled method on stored translation Strings that
+# already bring all the knowledge about contained interpolation variables etc.
+# so that the actual recurring interpolation will be very fast.
+#
+# To enable pre-compiled interpolations you can simply include the
+# InterpolationCompiler module to the Simple backend:
+#
+#   I18n::Backend::Simple.send(:include, I18n::Backend::InterpolationCompiler)
+#
+# Note that InterpolationCompiler does not yield meaningful results and consequently
+# should not be used with Ruby 1.9 (YARV) but improves performance everywhere else
+# (jRuby, Rubinius and 1.8.7).
+module I18n
+  module Backend
+    module InterpolationCompiler
+      module Compiler
+        extend self
+
+        TOKENIZER                    = /(%%\{[^\}]+\}|%\{[^\}]+\})/
+        INTERPOLATION_SYNTAX_PATTERN = /(%)?(%\{([^\}]+)\})/
+
+        def compile_if_an_interpolation(string)
+          if interpolated_str?(string)
+            string.instance_eval <<-RUBY_EVAL, __FILE__, __LINE__
+              def i18n_interpolate(v = {})
+                "#{compiled_interpolation_body(string)}"
+              end
+            RUBY_EVAL
+          end
+
+          string
+        end
+
+        def interpolated_str?(str)
+          str.kind_of?(::String) && str =~ INTERPOLATION_SYNTAX_PATTERN
+        end
+
+        protected
+        # tokenize("foo %{bar} baz %%{buz}") # => ["foo ", "%{bar}", " baz ", "%%{buz}"]
+        def tokenize(str)
+          str.split(TOKENIZER)
+        end
+
+        def compiled_interpolation_body(str)
+          tokenize(str).map do |token|
+            (matchdata = token.match(INTERPOLATION_SYNTAX_PATTERN)) ? handle_interpolation_token(token, matchdata) : escape_plain_str(token)
+          end.join
+        end
+
+        def handle_interpolation_token(interpolation, matchdata)
+          escaped, pattern, key = matchdata.values_at(1, 2, 3)
+          escaped ? pattern : compile_interpolation_token(key.to_sym)
+        end
+
+        def compile_interpolation_token(key)
+          "\#{#{interpolate_or_raise_missing(key)}}"
+        end
+
+        def interpolate_or_raise_missing(key)
+          escaped_key = escape_key_sym(key)
+          Base::RESERVED_KEYS.include?(key) ? reserved_key(escaped_key) : interpolate_key(escaped_key)
+        end
+
+        def interpolate_key(key)
+          [direct_key(key), nil_key(key), missing_key(key)].join('||')
+        end
+
+        def direct_key(key)
+          "((t = v[#{key}]) && t.respond_to?(:call) ? t.call : t)"
+        end
+
+        def nil_key(key)
+          "(v.has_key?(#{key}) && '')"
+        end
+
+        def missing_key(key)
+          "raise(MissingInterpolationArgument.new(#{key}, self))"
+        end
+
+        def reserved_key(key)
+          "raise(ReservedInterpolationKey.new(#{key}, self))"
+        end
+
+        def escape_plain_str(str)
+          str.gsub(/"|\\|#/) {|x| "\\#{x}"}
+        end
+
+        def escape_key_sym(key)
+          # rely on Ruby to do all the hard work :)
+          key.to_sym.inspect
+        end
+      end
+
+      def interpolate(locale, string, values)
+        if string.respond_to?(:i18n_interpolate)
+          string.i18n_interpolate(values)
+        elsif values
+          super
+        else
+          string
+        end
+      end
+
+      def store_translations(locale, data, options = {})
+        compile_all_strings_in(data)
+        super
+      end
+
+      protected
+      def compile_all_strings_in(data)
+        data.each_value do |value|
+          Compiler.compile_if_an_interpolation(value)
+          compile_all_strings_in(value) if value.kind_of?(Hash)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/key_value.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/key_value.rb
new file mode 100644 (file)
index 0000000..d0265ab
--- /dev/null
@@ -0,0 +1,102 @@
+# encoding: utf-8
+
+require 'i18n/backend/base'
+require 'active_support/json'
+
+module I18n
+  module Backend
+    # This is a basic backend for key value stores. It receives on
+    # initialization the store, which should respond to three methods:
+    #
+    # * store#[](key)         - Used to get a value
+    # * store#[]=(key, value) - Used to set a value
+    # * store#keys            - Used to get all keys
+    #
+    # Since these stores only supports string, all values are converted
+    # to JSON before being stored, allowing it to also store booleans,
+    # hashes and arrays. However, this store does not support Procs.
+    #
+    # As the ActiveRecord backend, Symbols are just supported when loading
+    # translations from the filesystem or through explicit store translations.
+    #
+    # Also, avoid calling I18n.available_locales since it's a somehow
+    # expensive operation in most stores.
+    #
+    # == Example
+    #
+    # To setup I18n to use TokyoCabinet in memory is quite straightforward:
+    #
+    #   require 'rufus/tokyo/cabinet' # gem install rufus-tokyo
+    #   I18n.backend = I18n::Backend::KeyValue.new(Rufus::Tokyo::Cabinet.new('*'))
+    #
+    # == Performance
+    #
+    # You may make this backend even faster by including the Memoize module.
+    # However, notice that you should properly clear the cache if you change
+    # values directly in the key-store.
+    #
+    # == Subtrees
+    #
+    # In most backends, you are allowed to retrieve part of a translation tree:
+    #
+    #   I18n.backend.store_translations :en, :foo => { :bar => :baz }
+    #   I18n.t "foo" #=> { :bar => :baz }
+    #
+    # This backend supports this feature by default, but it slows down the storage
+    # of new data considerably and makes hard to delete entries. That said, you are
+    # allowed to disable the storage of subtrees on initialization:
+    #
+    #   I18n::Backend::KeyValue.new(@store, false)
+    #
+    # This is useful if you are using a KeyValue backend chained to a Simple backend.
+    class KeyValue
+      module Implementation
+        attr_accessor :store
+
+        include Base, Flatten
+
+        def initialize(store, subtrees=true)
+          @store, @subtrees = store, subtrees
+        end
+
+        def store_translations(locale, data, options = {})
+          escape = options.fetch(:escape, true)
+          flatten_translations(locale, data, escape, @subtrees).each do |key, value|
+            key = "#{locale}.#{key}"
+
+            case value
+            when Hash
+              if @subtrees && (old_value = @store[key])
+                old_value = ActiveSupport::JSON.decode(old_value)
+                value = old_value.deep_symbolize_keys.deep_merge!(value) if old_value.is_a?(Hash)
+              end
+            when Proc
+              raise "Key-value stores cannot handle procs"
+            end
+
+            @store[key] = ActiveSupport::JSON.encode(value) unless value.is_a?(Symbol)
+          end
+        end
+
+        def available_locales
+          locales = @store.keys.map { |k| k =~ /\./; $` }
+          locales.uniq!
+          locales.compact!
+          locales.map! { |k| k.to_sym }
+          locales
+        end
+
+      protected
+
+        def lookup(locale, key, scope = [], options = {})
+          key   = normalize_flat_keys(locale, key, scope, options[:separator])
+          value = @store["#{locale}.#{key}"]
+          value = ActiveSupport::JSON.decode(value) if value
+          value.is_a?(Hash) ? value.deep_symbolize_keys : value
+        end
+      end
+
+      include Implementation
+    end
+  end
+end
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/memoize.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/memoize.rb
new file mode 100644 (file)
index 0000000..6e811d1
--- /dev/null
@@ -0,0 +1,48 @@
+# encoding: utf-8
+#
+# Memoize module simply memoizes the values returned by lookup using
+# a flat hash and can tremendously speed up the lookup process in a backend.
+#
+# To enable it you can simply include the Memoize module to your backend:
+#
+#   I18n::Backend::Simple.send(:include, I18n::Backend::Memoize)
+#
+# Notice that it's the responsibility of the backend to define whenever the
+# cache should be cleaned.
+module I18n
+  module Backend
+    module Memoize
+      def available_locales
+        @memoized_locales ||= super
+      end
+
+      def store_translations(locale, data, options = {})
+        reset_memoizations!(locale)
+        super
+      end
+
+      def reload!
+        reset_memoizations!
+        super
+      end
+
+      protected
+
+        def lookup(locale, key, scope = nil, options = {})
+          flat_key  = I18n::Backend::Flatten.normalize_flat_keys(locale,
+            key, scope, options[:separator]).to_sym
+          flat_hash = memoized_lookup[locale.to_sym]
+          flat_hash.key?(flat_key) ? flat_hash[flat_key] : (flat_hash[flat_key] = super)
+        end
+
+        def memoized_lookup
+          @memoized_lookup ||= Hash.new { |h, k| h[k] = {} }
+        end
+
+        def reset_memoizations!(locale=nil)
+          @memoized_locales = nil
+          (locale ? memoized_lookup[locale.to_sym] : memoized_lookup).clear
+        end
+    end
+  end
+end
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/metadata.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/metadata.rb
new file mode 100644 (file)
index 0000000..5237b4d
--- /dev/null
@@ -0,0 +1,65 @@
+# I18n translation metadata is useful when you want to access information
+# about how a translation was looked up, pluralized or interpolated in
+# your application.
+#
+#   msg = I18n.t(:message, :default => 'Hi!', :scope => :foo)
+#   msg.translation_metadata
+#   # => { :key => :message, :scope => :foo, :default => 'Hi!' }
+#
+# If a :count option was passed to #translate it will be set to the metadata.
+# Likewise, if any interpolation variables were passed they will also be set.
+#
+# To enable translation metadata you can simply include the Metadata module
+# into the Simple backend class - or whatever other backend you are using:
+#
+#   I18n::Backend::Simple.send(:include, I18n::Backend::Metadata)
+#
+module I18n
+  module Backend
+    module Metadata
+      class << self
+        def included(base)
+          Object.class_eval do
+            def translation_metadata
+              @translation_metadata ||= {}
+            end
+
+            def translation_metadata=(translation_metadata)
+              @translation_metadata = translation_metadata
+            end
+          end unless Object.method_defined?(:translation_metadata)
+        end
+      end
+
+      def translate(locale, key, options = {})
+        metadata = {
+          :locale    => locale,
+          :key       => key,
+          :scope     => options[:scope],
+          :default   => options[:default],
+          :separator => options[:separator],
+          :values    => options.reject { |name, value| Base::RESERVED_KEYS.include?(name) }
+        }
+        with_metadata(metadata) { super }
+      end
+
+      def interpolate(locale, entry, values = {})
+        metadata = entry.translation_metadata.merge(:original => entry)
+        with_metadata(metadata) { super }
+      end
+
+      def pluralize(locale, entry, count)
+        with_metadata(:count => count) { super }
+      end
+
+      protected
+
+        def with_metadata(metadata, &block)
+          result = yield
+          result.translation_metadata = result.translation_metadata.merge(metadata) if result
+          result
+        end
+
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/pluralization.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/pluralization.rb
new file mode 100644 (file)
index 0000000..33a2aff
--- /dev/null
@@ -0,0 +1,57 @@
+# encoding: utf-8
+
+# I18n locale fallbacks are useful when you want your application to use
+# translations from other locales when translations for the current locale are
+# missing. E.g. you might want to use :en translations when translations in
+# your applications main locale :de are missing.
+#
+# To enable locale specific pluralizations you can simply include the
+# Pluralization module to the Simple backend - or whatever other backend you
+# are using.
+#
+#   I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
+#
+# You also need to make sure to provide pluralization algorithms to the
+# backend, i.e. include them to your I18n.load_path accordingly.
+module I18n
+  module Backend
+    module Pluralization
+      # Overwrites the Base backend translate method so that it will check the
+      # translation meta data space (:i18n) for a locale specific pluralization
+      # rule and use it to pluralize the given entry. I.e. the library expects
+      # pluralization rules to be stored at I18n.t(:'i18n.plural.rule')
+      #
+      # Pluralization rules are expected to respond to #call(entry, count) and
+      # return a pluralization key. Valid keys depend on the translation data
+      # hash (entry) but it is generally recommended to follow CLDR's style,
+      # i.e., return one of the keys :zero, :one, :few, :many, :other.
+      #
+      # The :zero key is always picked directly when count equals 0 AND the
+      # translation data has the key :zero. This way translators are free to
+      # either pick a special :zero translation even for languages where the
+      # pluralizer does not return a :zero key.
+      def pluralize(locale, entry, count)
+        return entry unless entry.is_a?(Hash) and count
+
+        pluralizer = pluralizer(locale)
+        if pluralizer.respond_to?(:call)
+          key = count == 0 && entry.has_key?(:zero) ? :zero : pluralizer.call(count)
+          raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
+          entry[key]
+        else
+          super
+        end
+      end
+
+      protected
+
+        def pluralizers
+          @pluralizers ||= {}
+        end
+
+        def pluralizer(locale)
+          pluralizers[locale] ||= I18n.t(:'i18n.plural.rule', :locale => locale, :resolve => false)
+        end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/simple.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/simple.rb
new file mode 100644 (file)
index 0000000..25b8c02
--- /dev/null
@@ -0,0 +1,87 @@
+# encoding: utf-8
+
+module I18n
+  module Backend
+    # A simple backend that reads translations from YAML files and stores them in
+    # an in-memory hash. Relies on the Base backend.
+    #
+    # The implementation is provided by a Implementation module allowing to easily
+    # extend Simple backend's behavior by including modules. E.g.:
+    #
+    # module I18n::Backend::Pluralization
+    #   def pluralize(*args)
+    #     # extended pluralization logic
+    #     super
+    #   end
+    # end
+    #
+    # I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
+    class Simple
+      module Implementation
+        include Base
+
+        def initialized?
+          @initialized ||= false
+        end
+
+        # Stores translations for the given locale in memory.
+        # This uses a deep merge for the translations hash, so existing
+        # translations will be overwritten by new ones only at the deepest
+        # level of the hash.
+        def store_translations(locale, data, options = {})
+          locale = locale.to_sym
+          translations[locale] ||= {}
+          data = data.deep_symbolize_keys
+          translations[locale].deep_merge!(data)
+        end
+
+        # Get available locales from the translations hash
+        def available_locales
+          init_translations unless initialized?
+          translations.inject([]) do |locales, (locale, data)|
+            locales << locale unless (data.keys - [:i18n]).empty?
+            locales
+          end
+        end
+
+        # Clean up translations hash and set initialized to false on reload!
+        def reload!
+          @initialized = false
+          @translations = nil
+          super
+        end
+
+      protected
+
+        def init_translations
+          load_translations
+          @initialized = true
+        end
+
+        def translations
+          @translations ||= {}
+        end
+
+        # Looks up a translation from the translations hash. Returns nil if
+        # eiher key is nil, or locale, scope or key do not exist as a key in the
+        # nested translations hash. Splits keys or scopes containing dots
+        # into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
+        # <tt>%w(currency format)</tt>.
+        def lookup(locale, key, scope = [], options = {})
+          init_translations unless initialized?
+          keys = I18n.normalize_keys(locale, key, scope, options[:separator])
+
+          keys.inject(translations) do |result, _key|
+            _key = _key.to_sym
+            return nil unless result.is_a?(Hash) && result.has_key?(_key)
+            result = result[_key]
+            result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
+            result
+          end
+        end
+      end
+
+      include Implementation
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/transliterator.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/backend/transliterator.rb
new file mode 100644 (file)
index 0000000..2ce2cc8
--- /dev/null
@@ -0,0 +1,98 @@
+# encoding: utf-8
+module I18n
+  module Backend
+    module Transliterator
+      DEFAULT_REPLACEMENT_CHAR = "?"
+
+      # Given a locale and a UTF-8 string, return the locale's ASCII
+      # approximation for the string.
+      def transliterate(locale, string, replacement = nil)
+        @transliterators ||= {}
+        @transliterators[locale] ||= Transliterator.get I18n.t(:'i18n.transliterate.rule',
+          :locale => locale, :resolve => false, :default => {})
+        @transliterators[locale].transliterate(string, replacement)
+      end
+
+      # Get a transliterator instance.
+      def self.get(rule = nil)
+        if !rule || rule.kind_of?(Hash)
+          HashTransliterator.new(rule)
+        elsif rule.kind_of? Proc
+          ProcTransliterator.new(rule)
+        else
+          raise I18n::ArgumentError, "Transliteration rule must be a proc or a hash."
+        end
+      end
+
+      # A transliterator which accepts a Proc as its transliteration rule.
+      class ProcTransliterator
+        def initialize(rule)
+          @rule = rule
+        end
+
+        def transliterate(string, replacement = nil)
+          @rule.call(string)
+        end
+      end
+
+      # A transliterator which accepts a Hash of characters as its translation
+      # rule.
+      class HashTransliterator
+        DEFAULT_APPROXIMATIONS = {
+          "À"=>"A", "Á"=>"A", "Â"=>"A", "Ã"=>"A", "Ä"=>"A", "Å"=>"A", "Æ"=>"AE",
+          "Ç"=>"C", "È"=>"E", "É"=>"E", "Ê"=>"E", "Ë"=>"E", "Ì"=>"I", "Í"=>"I",
+          "Î"=>"I", "Ï"=>"I", "Ð"=>"D", "Ñ"=>"N", "Ò"=>"O", "Ó"=>"O", "Ô"=>"O",
+          "Õ"=>"O", "Ö"=>"O", "×"=>"x", "Ø"=>"O", "Ù"=>"U", "Ú"=>"U", "Û"=>"U",
+          "Ü"=>"U", "Ý"=>"Y", "Þ"=>"Th", "ß"=>"ss", "à"=>"a", "á"=>"a", "â"=>"a",
+          "ã"=>"a", "ä"=>"a", "å"=>"a", "æ"=>"ae", "ç"=>"c", "è"=>"e", "é"=>"e",
+          "ê"=>"e", "ë"=>"e", "ì"=>"i", "í"=>"i", "î"=>"i", "ï"=>"i", "ð"=>"d",
+          "ñ"=>"n", "ò"=>"o", "ó"=>"o", "ô"=>"o", "õ"=>"o", "ö"=>"o", "ø"=>"o",
+          "ù"=>"u", "ú"=>"u", "û"=>"u", "ü"=>"u", "ý"=>"y", "þ"=>"th", "ÿ"=>"y",
+          "Ā"=>"A", "ā"=>"a", "Ă"=>"A", "ă"=>"a", "Ą"=>"A", "ą"=>"a", "Ć"=>"C",
+          "ć"=>"c", "Ĉ"=>"C", "ĉ"=>"c", "Ċ"=>"C", "ċ"=>"c", "Č"=>"C", "č"=>"c",
+          "Ď"=>"D", "ď"=>"d", "Đ"=>"D", "đ"=>"d", "Ē"=>"E", "ē"=>"e", "Ĕ"=>"E",
+          "ĕ"=>"e", "Ė"=>"E", "ė"=>"e", "Ę"=>"E", "ę"=>"e", "Ě"=>"E", "ě"=>"e",
+          "Ĝ"=>"G", "ĝ"=>"g", "Ğ"=>"G", "ğ"=>"g", "Ġ"=>"G", "ġ"=>"g", "Ģ"=>"G",
+          "ģ"=>"g", "Ĥ"=>"H", "ĥ"=>"h", "Ħ"=>"H", "ħ"=>"h", "Ĩ"=>"I", "ĩ"=>"i",
+          "Ī"=>"I", "ī"=>"i", "Ĭ"=>"I", "ĭ"=>"i", "Į"=>"I", "į"=>"i", "İ"=>"I",
+          "ı"=>"i", "IJ"=>"IJ", "ij"=>"ij", "Ĵ"=>"J", "ĵ"=>"j", "Ķ"=>"K", "ķ"=>"k",
+          "ĸ"=>"k", "Ĺ"=>"L", "ĺ"=>"l", "Ļ"=>"L", "ļ"=>"l", "Ľ"=>"L", "ľ"=>"l",
+          "Ŀ"=>"L", "ŀ"=>"l", "Ł"=>"L", "ł"=>"l", "Ń"=>"N", "ń"=>"n", "Ņ"=>"N",
+          "ņ"=>"n", "Ň"=>"N", "ň"=>"n", "ʼn"=>"'n", "Ŋ"=>"NG", "ŋ"=>"ng",
+          "Ō"=>"O", "ō"=>"o", "Ŏ"=>"O", "ŏ"=>"o", "Ő"=>"O", "ő"=>"o", "Œ"=>"OE",
+          "œ"=>"oe", "Ŕ"=>"R", "ŕ"=>"r", "Ŗ"=>"R", "ŗ"=>"r", "Ř"=>"R", "ř"=>"r",
+          "Ś"=>"S", "ś"=>"s", "Ŝ"=>"S", "ŝ"=>"s", "Ş"=>"S", "ş"=>"s", "Š"=>"S",
+          "š"=>"s", "Ţ"=>"T", "ţ"=>"t", "Ť"=>"T", "ť"=>"t", "Ŧ"=>"T", "ŧ"=>"t",
+          "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u", "Ů"=>"U",
+          "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W", "ŵ"=>"w",
+          "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z", "ż"=>"z",
+          "Ž"=>"Z", "ž"=>"z"
+        }
+
+        def initialize(rule = nil)
+          @rule = rule
+          add DEFAULT_APPROXIMATIONS
+          add rule if rule
+        end
+
+        def transliterate(string, replacement = nil)
+          string.gsub(/[^\x00-\x7f]/u) do |char|
+            approximations[char] || replacement || DEFAULT_REPLACEMENT_CHAR
+          end
+        end
+
+        private
+
+          def approximations
+            @approximations ||= {}
+          end
+
+          # Add transliteration rules to the approximations hash.
+          def add(hash)
+            hash.keys.each {|key| hash[key.to_s] = hash.delete(key).to_s}
+            approximations.merge! hash
+          end
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/config.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/config.rb
new file mode 100644 (file)
index 0000000..e393292
--- /dev/null
@@ -0,0 +1,86 @@
+module I18n
+  class Config
+    # The only configuration value that is not global and scoped to thread is :locale.
+    # It defaults to the default_locale.
+    def locale
+      @locale ||= default_locale
+    end
+
+    # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
+    def locale=(locale)
+      @locale = locale.to_sym rescue nil
+    end
+
+    # Returns the current backend. Defaults to +Backend::Simple+.
+    def backend
+      @@backend ||= Backend::Simple.new
+    end
+
+    # Sets the current backend. Used to set a custom backend.
+    def backend=(backend)
+      @@backend = backend
+    end
+
+    # Returns the current default locale. Defaults to :'en'
+    def default_locale
+      @@default_locale ||= :en
+    end
+
+    # Sets the current default locale. Used to set a custom default locale.
+    def default_locale=(locale)
+      @@default_locale = locale.to_sym rescue nil
+    end
+
+    # Returns an array of locales for which translations are available.
+    # Unless you explicitely set these through I18n.available_locales=
+    # the call will be delegated to the backend.
+    def available_locales
+      @@available_locales ||= nil
+      @@available_locales || backend.available_locales
+    end
+
+    # Sets the available locales.
+    def available_locales=(locales)
+      @@available_locales = Array(locales).map {|locale| locale.to_sym}
+      @@available_locales = nil if @@available_locales.empty?
+    end
+
+    # Returns the current default scope separator. Defaults to '.'
+    def default_separator
+      @@default_separator ||= '.'
+    end
+
+    # Sets the current default scope separator.
+    def default_separator=(separator)
+      @@default_separator = separator
+    end
+
+    # Return the current exception handler. Defaults to :default_exception_handler.
+    def exception_handler
+      @@exception_handler ||= :default_exception_handler
+    end
+
+    # Sets the exception handler.
+    def exception_handler=(exception_handler)
+      @@exception_handler = exception_handler
+    end
+
+    # Allow clients to register paths providing translation data sources. The
+    # backend defines acceptable sources.
+    #
+    # E.g. the provided SimpleBackend accepts a list of paths to translation
+    # files which are either named *.rb and contain plain Ruby Hashes or are
+    # named *.yml and contain YAML data. So for the SimpleBackend clients may
+    # register translation files like this:
+    #   I18n.load_path << 'path/to/locale/en.yml'
+    def load_path
+      @@load_path ||= []
+    end
+
+    # Sets the load path instance. Custom implementations are expected to
+    # behave like a Ruby Array.
+    def load_path=(load_path)
+      @@load_path = load_path
+    end
+  end
+end
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/core_ext/hash.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/core_ext/hash.rb
new file mode 100644 (file)
index 0000000..f2a2422
--- /dev/null
@@ -0,0 +1,29 @@
+class Hash
+  def slice(*keep_keys)
+    h = {}
+    keep_keys.each { |key| h[key] = fetch(key) }
+    h
+  end unless Hash.method_defined?(:slice)
+
+  def except(*less_keys)
+    slice(*keys - less_keys)
+  end unless Hash.method_defined?(:except)
+
+  def deep_symbolize_keys
+    inject({}) { |result, (key, value)|
+      value = value.deep_symbolize_keys if value.is_a?(Hash)
+      result[(key.to_sym rescue key) || key] = value
+      result
+    }
+  end unless Hash.method_defined?(:deep_symbolize_keys)
+
+  # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
+  MERGER = proc do |key, v1, v2|
+    Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
+  end
+  
+  def deep_merge!(data)
+    merge!(data, &MERGER)
+  end unless Hash.method_defined?(:deep_merge!)
+end
+
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/core_ext/string/interpolate.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/core_ext/string/interpolate.rb
new file mode 100644 (file)
index 0000000..585af6f
--- /dev/null
@@ -0,0 +1,98 @@
+# encoding: utf-8
+
+=begin
+  heavily based on Masao Mutoh's gettext String interpolation extension
+  http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
+  Copyright (C) 2005-2009 Masao Mutoh
+  You may redistribute it and/or modify it under the same license terms as Ruby.
+=end
+
+begin
+  raise ArgumentError if ("a %{x}" % {:x=>'b'}) != 'a b'
+rescue ArgumentError
+  # KeyError is raised by String#% when the string contains a named placeholder
+  # that is not contained in the given arguments hash. Ruby 1.9 includes and
+  # raises this exception natively. We define it to mimic Ruby 1.9's behaviour
+  # in Ruby 1.8.x
+  class KeyError < IndexError
+    def initialize(message = nil)
+      super(message || "key not found")
+    end
+  end unless defined?(KeyError)
+
+  # Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError.
+  #
+  # String#% method which accept "named argument". The translator can know
+  # the meaning of the msgids using "named argument" instead of %s/%d style.
+  class String
+    # For older ruby versions, such as ruby-1.8.5
+    alias :bytesize :size unless instance_methods.find {|m| m.to_s == 'bytesize'}
+    alias :interpolate_without_ruby_19_syntax :% # :nodoc:
+
+    INTERPOLATION_PATTERN = Regexp.union(
+      /%\{(\w+)\}/,                               # matches placeholders like "%{foo}"
+      /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/  # matches placeholders like "%<foo>.d"
+    )
+
+    INTERPOLATION_PATTERN_WITH_ESCAPE = Regexp.union(
+      /%%/,
+      INTERPOLATION_PATTERN
+    )
+
+    # % uses self (i.e. the String) as a format specification and returns the
+    # result of applying it to the given arguments. In other words it interpolates
+    # the given arguments to the string according to the formats the string
+    # defines.
+    #
+    # There are three ways to use it:
+    #
+    # * Using a single argument or Array of arguments.
+    #
+    #   This is the default behaviour of the String class. See Kernel#sprintf for
+    #   more details about the format string.
+    #
+    #   Example:
+    #
+    #     "%d %s" % [1, "message"]
+    #     # => "1 message"
+    #
+    # * Using a Hash as an argument and unformatted, named placeholders.
+    #
+    #   When you pass a Hash as an argument and specify placeholders with %{foo}
+    #   it will interpret the hash values as named arguments.
+    #
+    #   Example:
+    #
+    #     "%{firstname}, %{lastname}" % {:firstname => "Masao", :lastname => "Mutoh"}
+    #     # => "Masao Mutoh"
+    #
+    # * Using a Hash as an argument and formatted, named placeholders.
+    #
+    #   When you pass a Hash as an argument and specify placeholders with %<foo>d
+    #   it will interpret the hash values as named arguments and format the value
+    #   according to the formatting instruction appended to the closing >.
+    #
+    #   Example:
+    #
+    #     "%<integer>d, %<float>.1f" % { :integer => 10, :float => 43.4 }
+    #     # => "10, 43.3"
+    def %(args)
+      if args.kind_of?(Hash)
+        dup.gsub(INTERPOLATION_PATTERN_WITH_ESCAPE) do |match|
+          if match == '%%'
+            '%'
+          else
+            key = ($1 || $2).to_sym
+            raise KeyError unless args.has_key?(key)
+            $3 ? sprintf("%#{$3}", args[key]) : args[key]
+          end
+        end
+      elsif self =~ INTERPOLATION_PATTERN
+        raise ArgumentError.new('one hash required')
+      else
+        result = gsub(/%([{<])/, '%%\1')
+        result.send :'interpolate_without_ruby_19_syntax', args
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/exceptions.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/exceptions.rb
new file mode 100644 (file)
index 0000000..98e6a78
--- /dev/null
@@ -0,0 +1,71 @@
+# encoding: utf-8
+
+class KeyError < IndexError
+  def initialize(message = nil)
+    super(message || "key not found")
+  end
+end unless defined?(KeyError)
+
+module I18n
+  class ArgumentError < ::ArgumentError; end
+
+  class InvalidLocale < ArgumentError
+    attr_reader :locale
+    def initialize(locale)
+      @locale = locale
+      super "#{locale.inspect} is not a valid locale"
+    end
+  end
+
+  class InvalidLocaleData < ArgumentError
+    attr_reader :filename
+    def initialize(filename)
+      @filename = filename
+      super "can not load translations from #{filename}, expected it to return a hash, but does not"
+    end
+  end
+
+  class MissingTranslationData < ArgumentError
+    attr_reader :locale, :key, :options
+    def initialize(locale, key, opts = nil)
+      @key, @locale, @options = key, locale, opts.dup || {}
+      options.each { |k, v| options[k] = v.inspect if v.is_a?(Proc) }
+
+      keys = I18n.normalize_keys(locale, key, options[:scope])
+      keys << 'no key' if keys.size < 2
+      super "translation missing: #{keys.join(', ')}"
+    end
+  end
+
+  class InvalidPluralizationData < ArgumentError
+    attr_reader :entry, :count
+    def initialize(entry, count)
+      @entry, @count = entry, count
+      super "translation data #{entry.inspect} can not be used with :count => #{count}"
+    end
+  end
+
+  class MissingInterpolationArgument < ArgumentError
+    attr_reader :values, :string
+    def initialize(values, string)
+      @values, @string = values, string
+      super "missing interpolation argument in #{string.inspect} (#{values.inspect} given)"
+    end
+  end
+
+  class ReservedInterpolationKey < ArgumentError
+    attr_reader :key, :string
+    def initialize(key, string)
+      @key, @string = key, string
+      super "reserved key #{key.inspect} used in #{string.inspect}"
+    end
+  end
+
+  class UnknownFileType < ArgumentError
+    attr_reader :type, :filename
+    def initialize(type, filename)
+      @type, @filename = type, filename
+      super "can not load translations from #{filename}, the file type #{type} is not known"
+    end
+  end
+end
\ No newline at end of file
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/gettext.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/gettext.rb
new file mode 100644 (file)
index 0000000..a824aa5
--- /dev/null
@@ -0,0 +1,27 @@
+# encoding: utf-8
+
+module I18n
+  module Gettext
+    PLURAL_SEPARATOR  = "\001"
+    CONTEXT_SEPARATOR = "\004"
+
+    autoload :Helpers, 'i18n/gettext/helpers'
+
+    @@plural_keys = { :en => [:one, :other] }
+
+    class << self
+      # returns an array of plural keys for the given locale so that we can
+      # convert from gettext's integer-index based style
+      # TODO move this information to the pluralization module
+      def plural_keys(locale)
+        @@plural_keys[locale] || @@plural_keys[:en]
+      end
+
+      def extract_scope(msgid, separator)
+        scope = msgid.to_s.split(separator)
+        msgid = scope.pop
+        [scope, msgid]
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/gettext/helpers.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/gettext/helpers.rb
new file mode 100644 (file)
index 0000000..6a97814
--- /dev/null
@@ -0,0 +1,65 @@
+# encoding: utf-8
+require 'i18n/gettext'
+
+module I18n
+  module Gettext
+    # Implements classical Gettext style accessors. To use this include the
+    # module to the global namespace or wherever you want to use it.
+    #
+    #   include I18n::Gettext::Helpers
+    module Helpers
+      def gettext(msgid, options = {})
+        I18n.t(msgid, { :default => msgid, :separator => '|' }.merge(options))
+      end
+      alias _ gettext
+
+      def sgettext(msgid, separator = '|')
+        scope, msgid = I18n::Gettext.extract_scope(msgid, separator)
+        I18n.t(msgid, :scope => scope, :default => msgid, :separator => separator)
+      end
+      alias s_ sgettext
+
+      def pgettext(msgctxt, msgid)
+        separator = I18n::Gettext::CONTEXT_SEPARATOR
+        sgettext([msgctxt, msgid].join(separator), separator)
+      end
+      alias p_ pgettext
+
+      def ngettext(msgid, msgid_plural, n = 1)
+        nsgettext(msgid, msgid_plural, n)
+      end
+      alias n_ ngettext
+
+      # Method signatures:
+      #   nsgettext('Fruits|apple', 'apples', 2)
+      #   nsgettext(['Fruits|apple', 'apples'], 2)
+      def nsgettext(msgid, msgid_plural, n = 1, separator = '|')
+        if msgid.is_a?(Array)
+          msgid, msgid_plural, n, separator = msgid[0], msgid[1], msgid_plural, n
+          separator = '|' unless separator.is_a?(::String)
+        end
+
+        scope, msgid = I18n::Gettext.extract_scope(msgid, separator)
+        default = { :one => msgid, :other => msgid_plural }
+        I18n.t(msgid, :default => default, :count => n, :scope => scope, :separator => separator)
+      end
+      alias ns_ nsgettext
+
+      # Method signatures:
+      #   npgettext('Fruits', 'apple', 'apples', 2)
+      #   npgettext('Fruits', ['apple', 'apples'], 2)
+      def npgettext(msgctxt, msgid, msgid_plural, n = 1)
+        separator = I18n::Gettext::CONTEXT_SEPARATOR
+
+        if msgid.is_a?(Array)
+          msgid_plural, msgid, n = msgid[1], [msgctxt, msgid[0]].join(separator), msgid_plural
+        else
+          msgid = [msgctxt, msgid].join(separator)
+        end
+
+        nsgettext(msgid, msgid_plural, n, separator)
+      end
+      alias np_ npgettext
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/gettext/po_parser.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/gettext/po_parser.rb
new file mode 100644 (file)
index 0000000..547df6a
--- /dev/null
@@ -0,0 +1,329 @@
+=begin
+  poparser.rb - Generate a .mo
+
+  Copyright (C) 2003-2009 Masao Mutoh <mutoh at highway.ne.jp>
+
+  You may redistribute it and/or modify it under the same
+  license terms as Ruby.
+=end
+
+#MODIFIED
+# removed include GetText etc
+# added stub translation method _(x)
+require 'racc/parser'
+
+module GetText
+
+  class PoParser < Racc::Parser
+
+    def _(x)
+      x
+    end
+
+module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 108
+  def unescape(orig)
+    ret = orig.gsub(/\\n/, "\n")
+    ret.gsub!(/\\t/, "\t")
+    ret.gsub!(/\\r/, "\r")
+    ret.gsub!(/\\"/, "\"")
+    ret
+  end
+  
+  def parse(str, data, ignore_fuzzy = true)
+    @comments = []
+    @data = data
+    @fuzzy = false
+    @msgctxt = ""
+    $ignore_fuzzy = ignore_fuzzy
+
+    str.strip!
+    @q = []
+    until str.empty? do
+      case str
+      when /\A\s+/
+       str = $'
+      when /\Amsgctxt/
+       @q.push [:MSGCTXT, $&]
+       str = $'
+      when /\Amsgid_plural/
+       @q.push [:MSGID_PLURAL, $&]
+       str = $'
+      when /\Amsgid/
+       @q.push [:MSGID, $&]
+       str = $'
+      when /\Amsgstr/
+       @q.push [:MSGSTR, $&]
+       str = $'
+      when /\A\[(\d+)\]/
+       @q.push [:PLURAL_NUM, $1]
+       str = $'
+      when /\A\#~(.*)/
+       $stderr.print _("Warning: obsolete msgid exists.\n")
+       $stderr.print "         #{$&}\n"
+       @q.push [:COMMENT, $&]
+       str = $'
+      when /\A\#(.*)/
+       @q.push [:COMMENT, $&]
+       str = $'      
+      when /\A\"(.*)\"/
+       @q.push [:STRING, $1]
+       str = $'
+      else
+       #c = str[0,1]
+       #@q.push [:STRING, c]
+       str = str[1..-1]
+      end
+    end 
+    @q.push [false, '$end']
+    if $DEBUG
+      @q.each do |a,b|
+      puts "[#{a}, #{b}]"
+      end
+    end
+    @yydebug = true if $DEBUG
+    do_parse
+
+    if @comments.size > 0
+      @data.set_comment(:last, @comments.join("\n"))
+    end
+    @data
+  end
+  
+  def next_token
+    @q.shift
+  end
+
+  def on_message(msgid, msgstr)
+    if msgstr.size > 0
+      @data[msgid] = msgstr
+      @data.set_comment(msgid, @comments.join("\n"))
+    end
+    @comments.clear
+    @msgctxt = ""
+  end
+      
+  def on_comment(comment)
+    @fuzzy = true if (/fuzzy/ =~ comment)
+    @comments << comment
+  end 
+
+
+..end src/poparser.ry modeval..id7a99570e05
+
+##### racc 1.4.5 generates ###
+
+racc_reduce_table = [
+ 0, 0, :racc_error,
+ 0, 10, :_reduce_none,
+ 2, 10, :_reduce_none,
+ 2, 10, :_reduce_none,
+ 2, 10, :_reduce_none,
+ 2, 12, :_reduce_5,
+ 1, 13, :_reduce_none,
+ 1, 13, :_reduce_none,
+ 4, 15, :_reduce_8,
+ 5, 16, :_reduce_9,
+ 2, 17, :_reduce_10,
+ 1, 17, :_reduce_none,
+ 3, 18, :_reduce_12,
+ 1, 11, :_reduce_13,
+ 2, 14, :_reduce_14,
+ 1, 14, :_reduce_15 ]
+
+racc_reduce_n = 16
+
+racc_shift_n = 26
+
+racc_action_table = [
+     3,    13,     5,     7,     9,    15,    16,    17,    20,    17,
+    13,    17,    13,    13,    11,    17,    23,    20,    13,    17 ]
+
+racc_action_check = [
+     1,    16,     1,     1,     1,    12,    12,    12,    18,    18,
+     7,    14,    15,     9,     3,    19,    20,    21,    23,    25 ]
+
+racc_action_pointer = [
+   nil,     0,   nil,    14,   nil,   nil,   nil,     3,   nil,     6,
+   nil,   nil,     0,   nil,     4,     5,    -6,   nil,     2,     8,
+     8,    11,   nil,    11,   nil,    12 ]
+
+racc_action_default = [
+    -1,   -16,    -2,   -16,    -3,   -13,    -4,   -16,    -6,   -16,
+    -7,    26,   -16,   -15,    -5,   -16,   -16,   -14,   -16,    -8,
+   -16,    -9,   -11,   -16,   -10,   -12 ]
+
+racc_goto_table = [
+    12,    22,    14,     4,    24,     6,     2,     8,    18,    19,
+    10,    21,     1,   nil,   nil,   nil,    25 ]
+
+racc_goto_check = [
+     5,     9,     5,     3,     9,     4,     2,     6,     5,     5,
+     7,     8,     1,   nil,   nil,   nil,     5 ]
+
+racc_goto_pointer = [
+   nil,    12,     5,     2,     4,    -7,     6,     9,    -7,   -17 ]
+
+racc_goto_default = [
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil ]
+
+racc_token_table = {
+ false => 0,
+ Object.new => 1,
+ :COMMENT => 2,
+ :MSGID => 3,
+ :MSGCTXT => 4,
+ :MSGID_PLURAL => 5,
+ :MSGSTR => 6,
+ :STRING => 7,
+ :PLURAL_NUM => 8 }
+
+racc_use_result_var = true
+
+racc_nt_base = 9
+
+Racc_arg = [
+ racc_action_table,
+ racc_action_check,
+ racc_action_default,
+ racc_action_pointer,
+ racc_goto_table,
+ racc_goto_check,
+ racc_goto_default,
+ racc_goto_pointer,
+ racc_nt_base,
+ racc_reduce_table,
+ racc_token_table,
+ racc_shift_n,
+ racc_reduce_n,
+ racc_use_result_var ]
+
+Racc_token_to_s_table = [
+'$end',
+'error',
+'COMMENT',
+'MSGID',
+'MSGCTXT',
+'MSGID_PLURAL',
+'MSGSTR',
+'STRING',
+'PLURAL_NUM',
+'$start',
+'msgfmt',
+'comment',
+'msgctxt',
+'message',
+'string_list',
+'single_message',
+'plural_message',
+'msgstr_plural',
+'msgstr_plural_line']
+
+Racc_debug_parser = true
+
+##### racc system variables end #####
+
+ # reduce 0 omitted
+
+ # reduce 1 omitted
+
+ # reduce 2 omitted
+
+ # reduce 3 omitted
+
+ # reduce 4 omitted
+
+module_eval <<'.,.,', 'src/poparser.ry', 25
+  def _reduce_5( val, _values, result )
+    @msgctxt = unescape(val[1]) + "\004"
+   result
+  end
+.,.,
+
+ # reduce 6 omitted
+
+ # reduce 7 omitted
+
+module_eval <<'.,.,', 'src/poparser.ry', 48
+  def _reduce_8( val, _values, result )
+    if @fuzzy and $ignore_fuzzy 
+      if val[1] != ""
+        $stderr.print _("Warning: fuzzy message was ignored.\n")
+        $stderr.print "         msgid '#{val[1]}'\n"
+      else
+        on_message('', unescape(val[3]))
+      end
+      @fuzzy = false
+    else
+      on_message(@msgctxt + unescape(val[1]), unescape(val[3]))
+    end
+    result = ""
+   result
+  end
+.,.,
+
+module_eval <<'.,.,', 'src/poparser.ry', 65
+  def _reduce_9( val, _values, result )
+    if @fuzzy and $ignore_fuzzy
+      if val[1] != ""
+        $stderr.print _("Warning: fuzzy message was ignored.\n")
+        $stderr.print "msgid = '#{val[1]}\n"
+      else
+        on_message('', unescape(val[3]))
+      end
+      @fuzzy = false
+    else
+      on_message(@msgctxt + unescape(val[1]) + "\000" + unescape(val[3]), unescape(val[4]))
+    end
+    result = ""
+   result
+  end
+.,.,
+
+module_eval <<'.,.,', 'src/poparser.ry', 76
+  def _reduce_10( val, _values, result )
+    if val[0].size > 0
+      result = val[0] + "\000" + val[1]
+    else
+      result = ""
+    end
+   result
+  end
+.,.,
+
+ # reduce 11 omitted
+
+module_eval <<'.,.,', 'src/poparser.ry', 84
+  def _reduce_12( val, _values, result )
+    result = val[2]
+   result
+  end
+.,.,
+
+module_eval <<'.,.,', 'src/poparser.ry', 91
+  def _reduce_13( val, _values, result )
+    on_comment(val[0])
+   result
+  end
+.,.,
+
+module_eval <<'.,.,', 'src/poparser.ry', 99
+  def _reduce_14( val, _values, result )
+    result = val.delete_if{|item| item == ""}.join
+   result
+  end
+.,.,
+
+module_eval <<'.,.,', 'src/poparser.ry', 103
+  def _reduce_15( val, _values, result )
+    result = val[0]
+   result
+  end
+.,.,
+
+ def _reduce_none( val, _values, result )
+  result
+ end
+
+  end   # class PoParser
+
+end   # module GetText
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale.rb
new file mode 100644 (file)
index 0000000..4f9d026
--- /dev/null
@@ -0,0 +1,6 @@
+module I18n
+  module Locale
+  autoload :Fallbacks, 'i18n/locale/fallbacks'
+  autoload :Tag,       'i18n/locale/tag'
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/fallbacks.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/fallbacks.rb
new file mode 100644 (file)
index 0000000..11dcf8c
--- /dev/null
@@ -0,0 +1,98 @@
+# encoding: utf-8
+
+# Locale Fallbacks
+#
+# Extends the I18n module to hold a fallbacks instance which is set to an
+# instance of I18n::Locale::Fallbacks by default but can be swapped with a
+# different implementation.
+#
+# Locale fallbacks will compute a number of fallback locales for a given locale.
+# For example:
+#
+# <pre><code>
+# I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :en] </code></pre>
+#
+# Locale fallbacks always fall back to
+#
+#   * all parent locales of a given locale (e.g. :es for :"es-MX") first,
+#   * the current default locales and all of their parents second
+#
+# The default locales are set to [I18n.default_locale] by default but can be
+# set to something else.
+#
+# One can additionally add any number of additional fallback locales manually.
+# These will be added before the default locales to the fallback chain. For
+# example:
+#
+#   # using the default locale as default fallback locale
+#
+#   I18n.default_locale = :"en-US"
+#   I18n.fallbacks = I18n::Fallbacks.new(:"de-AT" => :"de-DE")
+#   I18n.fallbacks[:"de-AT"] # => [:"de-AT", :"de-DE", :de, :"en-US", :en]
+#
+#   # using a custom locale as default fallback locale
+#
+#   I18n.fallbacks = I18n::Fallbacks.new(:"en-GB", :"de-AT" => :de, :"de-CH" => :de)
+#   I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"en-GB", :en]
+#   I18n.fallbacks[:"de-CH"] # => [:"de-CH", :de, :"en-GB", :en]
+#
+#   # mapping fallbacks to an existing instance
+#
+#   # people speaking Catalan also speak Spanish as spoken in Spain
+#   fallbacks = I18n.fallbacks
+#   fallbacks.map(:ca => :"es-ES")
+#   fallbacks[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en]
+#
+#   # people speaking Arabian as spoken in Palestine also speak Hebrew as spoken in Israel
+#   fallbacks.map(:"ar-PS" => :"he-IL")
+#   fallbacks[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en]
+#   fallbacks[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en]
+#
+#   # people speaking Sami as spoken in Finnland also speak Swedish and Finnish as spoken in Finnland
+#   fallbacks.map(:sms => [:"se-FI", :"fi-FI"])
+#   fallbacks[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en]
+
+module I18n
+  module Locale
+    class Fallbacks < Hash
+      def initialize(*mappings)
+        @map = {}
+        map(mappings.pop) if mappings.last.is_a?(Hash)
+        self.defaults = mappings.empty? ? [I18n.default_locale.to_sym] : mappings
+      end
+
+      def defaults=(defaults)
+        @defaults = defaults.map { |default| compute(default, false) }.flatten
+      end
+      attr_reader :defaults
+
+      def [](locale)
+        raise InvalidLocale.new(locale) if locale.nil?
+        locale = locale.to_sym
+        super || store(locale, compute(locale))
+      end
+
+      def map(mappings)
+        mappings.each do |from, to|
+          from, to = from.to_sym, Array(to)
+          to.each do |to|
+            @map[from] ||= []
+            @map[from] << to.to_sym
+          end
+        end
+      end
+
+      protected
+
+      def compute(tags, include_defaults = true)
+        result = Array(tags).collect do |tag|
+          tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym }
+          tags.each { |tag| tags += compute(@map[tag]) if @map[tag] }
+          tags
+        end.flatten
+        result.push(*defaults) if include_defaults
+        result.uniq
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag.rb
new file mode 100644 (file)
index 0000000..a640b44
--- /dev/null
@@ -0,0 +1,28 @@
+# encoding: utf-8
+
+module I18n
+  module Locale
+    module Tag
+      autoload :Parents, 'i18n/locale/tag/parents'
+      autoload :Rfc4646, 'i18n/locale/tag/rfc4646'
+      autoload :Simple,  'i18n/locale/tag/simple'
+
+      class << self
+        # Returns the current locale tag implementation. Defaults to +I18n::Locale::Tag::Simple+.
+        def implementation
+          @@implementation ||= Simple
+        end
+
+        # Sets the current locale tag implementation. Use this to set a different locale tag implementation.
+        def implementation=(implementation)
+          @@implementation = implementation
+        end
+
+        # Factory method for locale tags. Delegates to the current locale tag implementation.
+        def tag(tag)
+          implementation.tag(tag)
+        end
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag/parents.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag/parents.rb
new file mode 100644 (file)
index 0000000..a094468
--- /dev/null
@@ -0,0 +1,24 @@
+# encoding: utf-8
+
+module I18n
+  module Locale
+    module Tag
+      module Parents
+        def parent
+          @parent ||= begin
+            segs = to_a.compact
+            segs.length > 1 ? self.class.tag(*segs[0..(segs.length-2)].join('-')) : nil
+          end
+        end
+
+        def self_and_parents
+          @self_and_parents ||= [self] + parents
+        end
+
+        def parents
+          @parents ||= ([parent] + (parent ? parent.parents : [])).compact
+        end
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag/rfc4646.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag/rfc4646.rb
new file mode 100644 (file)
index 0000000..c20d35a
--- /dev/null
@@ -0,0 +1,76 @@
+# encoding: utf-8
+
+# RFC 4646/47 compliant Locale tag implementation that parses locale tags to
+# subtags such as language, script, region, variant etc.
+#
+# For more information see by http://en.wikipedia.org/wiki/IETF_language_tag
+#
+# Rfc4646::Parser does not implement grandfathered tags.
+
+module I18n
+  module Locale
+    module Tag
+      RFC4646_SUBTAGS = [ :language, :script, :region, :variant, :extension, :privateuse, :grandfathered ]
+      RFC4646_FORMATS = { :language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase }
+
+      class Rfc4646 < Struct.new(*RFC4646_SUBTAGS)
+        class << self
+          # Parses the given tag and returns a Tag instance if it is valid.
+          # Returns false if the given tag is not valid according to RFC 4646.
+          def tag(tag)
+            matches = parser.match(tag)
+            new(*matches) if matches
+          end
+
+          def parser
+            @@parser ||= Rfc4646::Parser
+          end
+
+          def parser=(parser)
+            @@parser = parser
+          end
+        end
+
+        include Parents
+
+        RFC4646_FORMATS.each do |name, format|
+          define_method(name) { self[name].send(format) unless self[name].nil? }
+        end
+
+        def to_sym
+          to_s.to_sym
+        end
+
+        def to_s
+          @tag ||= to_a.compact.join("-")
+        end
+
+        def to_a
+          members.collect { |attr| self.send(attr) }
+        end
+
+        module Parser
+          PATTERN = %r{\A(?:
+            ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language
+            (?:-([a-z]{4}))?                                        # script
+            (?:-([a-z]{2}|\d{3}))?                                  # region
+            (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))*                     # variant
+            (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))*                   # extension
+            (?:-(x(?:-[0-9a-z]{1,8})+))?|                           # privateuse subtag
+            (x(?:-[0-9a-z]{1,8})+)|                                 # privateuse tag
+            /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */               # grandfathered
+            )\z}xi
+
+          class << self
+            def match(tag)
+              c = PATTERN.match(tag.to_s).captures
+              c[0..4] << (c[5].nil? ? c[6] : c[5])  << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here?
+            rescue
+              false
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag/simple.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/locale/tag/simple.rb
new file mode 100644 (file)
index 0000000..0fddb36
--- /dev/null
@@ -0,0 +1,41 @@
+# encoding: utf-8
+
+# Simple Locale tag implementation that computes subtags by simply splitting
+# the locale tag at '-' occurences.
+module I18n
+  module Locale
+    module Tag
+      class Simple
+        class << self
+          def tag(tag)
+            new(tag)
+          end
+        end
+
+        include Parents
+
+        attr_reader :tag
+
+        def initialize(*tag)
+          @tag = tag.join('-').to_sym
+        end
+
+        def subtags
+          @subtags = tag.to_s.split('-').map { |subtag| subtag.to_s }
+        end
+
+        def to_sym
+          tag
+        end
+
+        def to_s
+          tag.to_s
+        end
+
+        def to_a
+          subtags
+        end
+      end
+    end
+  end
+end
diff --git a/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/version.rb b/ruby/lib/ruby/gems/1.8/gems/i18n-0.4.2/lib/i18n/version.rb
new file mode 100644 (file)
index 0000000..33721b9
--- /dev/null
@@ -0,0 +1,3 @@
+module I18n
+  VERSION = "0.4.2"
+end
diff --git a/ruby/lib/ruby/gems/1.8/specifications/i18n-0.4.2.gemspec b/ruby/lib/ruby/gems/1.8/specifications/i18n-0.4.2.gemspec
new file mode 100644 (file)
index 0000000..d7d53ca
--- /dev/null
@@ -0,0 +1,28 @@
+# -*- encoding: utf-8 -*-\r
+\r
+Gem::Specification.new do |s|\r
+  s.name = %q{i18n}\r
+  s.version = "0.4.2"\r
+\r
+  s.required_rubygems_version = Gem::Requirement.new(">= 1.3.5") if s.respond_to? :required_rubygems_version=\r
+  s.authors = ["Sven Fuchs", "Joshua Harvey", "Matt Aimonetti", "Stephan Soller", "Saimon Moore"]\r
+  s.date = %q{2010-10-26}\r
+  s.description = %q{New wave Internationalization support for Ruby.}\r
+  s.email = %q{rails-i18n@googlegroups.com}\r
+  s.files = ["lib/i18n.rb", "lib/i18n/backend.rb", "lib/i18n/backend/active_record.rb", "lib/i18n/backend/active_record/missing.rb", "lib/i18n/backend/active_record/store_procs.rb", "lib/i18n/backend/active_record/translation.rb", "lib/i18n/backend/base.rb", "lib/i18n/backend/cache.rb", "lib/i18n/backend/cascade.rb", "lib/i18n/backend/chain.rb", "lib/i18n/backend/cldr.rb", "lib/i18n/backend/fallbacks.rb", "lib/i18n/backend/flatten.rb", "lib/i18n/backend/gettext.rb", "lib/i18n/backend/interpolation_compiler.rb", "lib/i18n/backend/key_value.rb", "lib/i18n/backend/memoize.rb", "lib/i18n/backend/metadata.rb", "lib/i18n/backend/pluralization.rb", "lib/i18n/backend/simple.rb", "lib/i18n/backend/transliterator.rb", "lib/i18n/config.rb", "lib/i18n/core_ext/hash.rb", "lib/i18n/core_ext/string/interpolate.rb", "lib/i18n/exceptions.rb", "lib/i18n/gettext.rb", "lib/i18n/gettext/helpers.rb", "lib/i18n/gettext/po_parser.rb", "lib/i18n/locale.rb", "lib/i18n/locale/fallbacks.rb", "lib/i18n/locale/tag.rb", "lib/i18n/locale/tag/parents.rb", "lib/i18n/locale/tag/rfc4646.rb", "lib/i18n/locale/tag/simple.rb", "lib/i18n/version.rb", "README.textile", "MIT-LICENSE", "CHANGELOG.textile"]\r
+  s.homepage = %q{http://github.com/svenfuchs/i18n}\r
+  s.require_paths = ["lib"]\r
+  s.rubyforge_project = %q{[none]}\r
+  s.rubygems_version = %q{1.3.5}\r
+  s.summary = %q{New wave Internationalization support for Ruby}\r
+\r
+  if s.respond_to? :specification_version then\r
+    current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION\r
+    s.specification_version = 3\r
+\r
+    if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then\r
+    else\r
+    end\r
+  else\r
+  end\r
+end\r