diff options
author | Louise Crow <louise.crow@gmail.com> | 2011-02-24 11:26:55 +0000 |
---|---|---|
committer | Louise Crow <louise.crow@gmail.com> | 2011-02-24 11:26:55 +0000 |
commit | 2ace347cda680af483fcb57082a452689f03975a (patch) | |
tree | dfd411c45480c2697573966cec0b00ea48ab02aa | |
parent | 332b70b31411b4eb37210e0b3e3608c4e0ae593d (diff) |
Adding translation via fast_gettext.
96 files changed, 5132 insertions, 1 deletions
diff --git a/config/environment.rb b/config/environment.rb index 896d2e5ea..f3feb4ce2 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -50,9 +50,10 @@ Rails::Initializer.run do |config| # config.log_level = :debug # # Specify gems that this application depends on and have them installed with rake gems:install + config.gem "fast_gettext", :version => '>=0.4.8' config.gem "rack", :version => '1.1.0' - config.gem 'rspec-rails', :lib => false, :version => '1.3.3' config.gem "recaptcha", :lib => "recaptcha/rails" + config.gem 'rspec-rails', :lib => false, :version => '1.3.3' config.gem 'will_paginate', :version => '~> 2.3.11', :source => 'http://gemcutter.org' # Your secret key for verifying cookie session data integrity. diff --git a/config/initializers/fast_gettext.rb b/config/initializers/fast_gettext.rb new file mode 100644 index 000000000..29fb94211 --- /dev/null +++ b/config/initializers/fast_gettext.rb @@ -0,0 +1,3 @@ +FastGettext.add_text_domain 'app', :path => 'locale', :type => :po +FastGettext.default_available_locales = ['en'] #all you want to allow +FastGettext.default_text_domain = 'app'
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/.gitignore b/vendor/gems/fast_gettext-0.5.10/.gitignore new file mode 100644 index 000000000..c735ce431 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/.gitignore @@ -0,0 +1,2 @@ +pkg +benchmark/locle diff --git a/vendor/gems/fast_gettext-0.5.10/.specification b/vendor/gems/fast_gettext-0.5.10/.specification new file mode 100644 index 000000000..7e1bcf3dc --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/.specification @@ -0,0 +1,153 @@ +--- !ruby/object:Gem::Specification +name: fast_gettext +version: !ruby/object:Gem::Version + hash: 31 + prerelease: false + segments: + - 0 + - 5 + - 10 + version: 0.5.10 +platform: ruby +authors: +- Michael Grosser +autorequire: +bindir: bin +cert_chain: [] + +date: 2010-09-16 00:00:00 +01:00 +default_executable: +dependencies: [] + +description: +email: grosser.michael@gmail.com +executables: [] + +extensions: [] + +extra_rdoc_files: +- README.markdown +files: +- .gitignore +- CHANGELOG +- README.markdown +- Rakefile +- VERSION +- benchmark/base.rb +- benchmark/baseline.rb +- benchmark/fast_gettext.rb +- benchmark/i18n_simple.rb +- benchmark/ideal.rb +- benchmark/locale/de.yml +- benchmark/locale/de/LC_MESSAGES/large.mo +- benchmark/misc/threadsave.rb +- benchmark/namespace/fast_gettext.rb +- benchmark/namespace/original.rb +- benchmark/original.rb +- examples/db/migration.rb +- examples/missing_translation_logger.rb +- fast_gettext.gemspec +- lib/fast_gettext.rb +- lib/fast_gettext/VERSION +- lib/fast_gettext/mo_file.rb +- lib/fast_gettext/po_file.rb +- lib/fast_gettext/storage.rb +- lib/fast_gettext/translation.rb +- lib/fast_gettext/translation_repository.rb +- lib/fast_gettext/translation_repository/base.rb +- lib/fast_gettext/translation_repository/chain.rb +- lib/fast_gettext/translation_repository/db.rb +- lib/fast_gettext/translation_repository/db_models/translation_key.rb +- lib/fast_gettext/translation_repository/db_models/translation_text.rb +- lib/fast_gettext/translation_repository/logger.rb +- lib/fast_gettext/translation_repository/mo.rb +- lib/fast_gettext/translation_repository/po.rb +- lib/fast_gettext/translation_repository/yaml.rb +- lib/fast_gettext/vendor/README.rdoc +- lib/fast_gettext/vendor/empty.mo +- lib/fast_gettext/vendor/iconv.rb +- lib/fast_gettext/vendor/mofile.rb +- lib/fast_gettext/vendor/poparser.rb +- lib/fast_gettext/vendor/string.rb +- spec/aa_unconfigued_spec.rb +- spec/fast_gettext/mo_file_spec.rb +- spec/fast_gettext/storage_spec.rb +- spec/fast_gettext/translation_repository/base_spec.rb +- spec/fast_gettext/translation_repository/chain_spec.rb +- spec/fast_gettext/translation_repository/db_spec.rb +- spec/fast_gettext/translation_repository/logger_spec.rb +- spec/fast_gettext/translation_repository/mo_spec.rb +- spec/fast_gettext/translation_repository/po_spec.rb +- spec/fast_gettext/translation_repository/yaml_spec.rb +- spec/fast_gettext/translation_repository_spec.rb +- spec/fast_gettext/translation_spec.rb +- spec/fast_gettext/vendor/fake_load_path/iconv.rb +- spec/fast_gettext/vendor/iconv_spec.rb +- spec/fast_gettext/vendor/string_spec.rb +- spec/fast_gettext_spec.rb +- spec/fuzzy_locale/de/test.po +- spec/locale/de/LC_MESSAGES/test.mo +- spec/locale/de/test.po +- spec/locale/en/LC_MESSAGES/plural_test.mo +- spec/locale/en/LC_MESSAGES/test.mo +- spec/locale/en/plural_test.po +- spec/locale/en/test.po +- spec/locale/yaml/de.yml +- spec/locale/yaml/en.yml +- spec/locale/yaml/notfound.yml +- spec/obsolete_locale/de/test.po +- spec/spec_helper.rb +has_rdoc: true +homepage: http://github.com/grosser/fast_gettext +licenses: [] + +post_install_message: +rdoc_options: +- --charset=UTF-8 +require_paths: +- lib +required_ruby_version: !ruby/object:Gem::Requirement + none: false + requirements: + - - ">=" + - !ruby/object:Gem::Version + hash: 3 + segments: + - 0 + version: "0" +required_rubygems_version: !ruby/object:Gem::Requirement + none: false + requirements: + - - ">=" + - !ruby/object:Gem::Version + hash: 3 + segments: + - 0 + version: "0" +requirements: [] + +rubyforge_project: +rubygems_version: 1.3.7 +signing_key: +specification_version: 3 +summary: A simple, fast and threadsafe implementation of GetText +test_files: +- spec/aa_unconfigued_spec.rb +- spec/fast_gettext/mo_file_spec.rb +- spec/fast_gettext/storage_spec.rb +- spec/fast_gettext/translation_spec.rb +- spec/fast_gettext/translation_repository_spec.rb +- spec/fast_gettext/translation_repository/base_spec.rb +- spec/fast_gettext/translation_repository/chain_spec.rb +- spec/fast_gettext/translation_repository/db_spec.rb +- spec/fast_gettext/translation_repository/po_spec.rb +- spec/fast_gettext/translation_repository/mo_spec.rb +- spec/fast_gettext/translation_repository/logger_spec.rb +- spec/fast_gettext/translation_repository/yaml_spec.rb +- spec/fast_gettext/vendor/string_spec.rb +- spec/fast_gettext/vendor/iconv_spec.rb +- spec/fast_gettext/vendor/fake_load_path/iconv.rb +- spec/spec_helper.rb +- spec/fast_gettext_spec.rb +- examples/db/migration.rb +- examples/missing_translation_logger.rb diff --git a/vendor/gems/fast_gettext-0.5.10/CHANGELOG b/vendor/gems/fast_gettext-0.5.10/CHANGELOG new file mode 100644 index 000000000..c91958694 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/CHANGELOG @@ -0,0 +1,6 @@ +0.4.14 -- "" is translated as "", not as gettext meta information +0.4.0 -- pluralisation_rules is no longer stored in each repository, only retrived. Added Chain and Logger repository. +0.3.6 -- FastGettext.default_locale= +0.3.5 -- FastGettext.default_text_domain= +0.3.4 -- Exceptions are thrown, not returned when translating without text domain +0.3 -- pluralisation methods accept/return n plural forms, contrary to singular/plural before
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/README.markdown b/vendor/gems/fast_gettext-0.5.10/README.markdown new file mode 100644 index 000000000..7d85a3694 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/README.markdown @@ -0,0 +1,200 @@ +FastGettext +=========== +GetText but 3.5 x faster, 560 x less memory, simple, clean namespace (7 vs 34) and threadsave! + +It supports multiple backends (.mo, .po, .yml files, Database(ActiveRecor + any other), Chain, Loggers) and can easily be extended. + +[Example Rails application](https://github.com/grosser/gettext_i18n_rails_example) + +Comparison +========== +<table> + <tr> + <td></td> + <td width="100">Hash</td> + <td width="150">FastGettext</td> + <td width="100">GetText</td> + <td width="100">ActiveSupport I18n::Simple</td> + </tr> + <tr> + <td>Speed*</td> + <td>0.82s</td> + <td>1.36s</td> + <td>4.88s</td> + <td>21.77s</td> + </tr> + <tr> + <td>RAM*</td> + <td>4K</td> + <td>8K</td> + <td>4480K</td> + <td>10100K</td> + </tr> + <tr> + <td>Included backends</td> + <td></td> + <td>db, yml, mo, po, logger, chain</td> + <td>mo</td> + <td>yml</td> + </tr> +</table> +<small>*50.000 translations with ruby enterprise 1.8.6 through `rake benchmark`</small> + +Setup +===== +### 1. Install + sudo gem install fast_gettext + +### 2. Add a translation repository + +From mo files (traditional/default) + FastGettext.add_text_domain('my_app',:path=>'locale') + +Or po files (less maintenance than mo) + FastGettext.add_text_domain('my_app',:path=>'locale', :type=>:po) + # :ignore_fuzzy => true to silence warnings about fuzzy translations + # :ignore_obsolete => true to silence warnings about obsolete translations + +Or yaml files (use I18n syntax/indentation) + FastGettext.add_text_domain('my_app',:path=>'config/locales', :type=>:yaml) + +Or database (scaleable, good for many locales/translators) + # db access is cached <-> only first lookup hits the db + require "fast_gettext/translation_repository/db" + FastGettext::TranslationRepository::Db.require_models #load and include default models + FastGettext.add_text_domain('my_app', :type=>:db, :model=>TranslationKey) + +### 3. Choose text domain and locale for translation +Do this once in every Thread. (e.g. Rails -> ApplicationController) + FastGettext.text_domain = 'my_app' + FastGettext.available_locales = ['de','en','fr','en_US','en_UK'] # only allow these locales to be set (optional) + FastGettext.locale = 'de' + +### 4. Start translating + include FastGettext::Translation + _('Car') == 'Auto' + _('not-found') == 'not-found' + s_('Namespace|no-found') == 'not-found' + n_('Axis','Axis',3) == 'Achsen' #German plural of Axis + + +Managing translations +============ +### mo/po-files +Generate .po or .mo files using GetText parser (example tasks at [gettext_i18n_rails](http://github.com/grosser/gettext_i18n_rails)) + +Tell Gettext where your .mo or .po files lie, e.g. for locale/de/my_app.po and locale/de/LC_MESSAGES/my_app.mo + FastGettext.add_text_domain('my_app',:path=>'locale') + +Use the [original GetText](http://github.com/mutoh/gettext) to create and manage po/mo-files. +(Work on a po/mo parser & reader that is easier to use has started, contributions welcome @ [pomo](http://github.com/grosser/pomo) ) + +###Database +[Example migration for ActiveRecord](http://github.com/grosser/fast_gettext/blob/master/examples/db/migration.rb) +The default plural seperator is `||||` but you may overwrite it (or suggest a better one..). + +This is usable with any model DataMapper/Sequel or any other(non-database) backend, the only thing you need to do is respond to the self.translation(key, locale) call. +If you want to use your own models, have a look at the [default models](http://github.com/grosser/fast_gettext/tree/master/lib/fast_gettext/translation_repository/db_models) to see what you want/need to implement. + +To manage translations via a Web GUI, use a [Rails application and the translation_db_engine](http://github.com/grosser/translation_db_engine) + +Rails +======================= +Try the [gettext_i18n_rails plugin](http://github.com/grosser/gettext_i18n_rails), it simplifies the setup. +Try the [translation_db_engine](http://github.com/grosser/translation_db_engine), to manage your translations in a db. + +Setting `available_locales`,`text_domain` or `locale` will not work inside the `evironment.rb`, +since it runs in a different thread then e.g. controllers, so set them inside your application_controller. + + #environment.rb after initializers + Object.send(:include,FastGettext::Translation) + FastGettext.add_text_domain('accounting',:path=>'locale') + FastGettext.add_text_domain('frontend',:path=>'locale') + ... + + #application_controller.rb + class ApplicationController ... + include FastGettext::Translation + before_filter :set_locale + def set_locale + FastGettext.available_locales = ['de','en',...] + FastGettext.text_domain = 'frontend' + session[:locale] = I18n.locale = FastGettext.set_locale(params[:locale] || session[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en') + end + + +Advanced features +================= +###Abnormal pluralisation +Pluralisation rules can be set directly via a lambda (see specs/), or by using the Gettext +plural definition (see spec/locale/en/test_plural.po or [Plural expressions for all languages](http://translate.sourceforge.net/wiki/l10n/pluralforms). + + +###default_text_domain +If you only use one text domain, setting `FastGettext.default_text_domain = 'app'` +is sufficient and no more `text_domain=` is needed + +###default_locale +If the simple rule of "first `availble_locale` or 'en'" is not suficcient for you, set `FastGettext.default_locale = 'de'`. + +###default_available_locales +Fallback when no available_locales are set + +###Chains +You can use any number of repositories to find a translation. Simply add them to a chain and when +the first cannot translate a given key, the next is asked and so forth. + repos = [ + FastGettext::TranslationRepository.build('new', :path=>'....'), + FastGettext::TranslationRepository.build('old', :path=>'....') + ] + FastGettext.add_text_domain 'combined', :type=>:chain, :chain=>repos + +###Logger +When you want to know which keys could not be translated or were used, add a Logger to a Chain: + repos = [ + FastGettext::TranslationRepository.build('app', :path=>'....') + FastGettext::TranslationRepository.build('logger', :type=>:logger, :callback=>lamda{|key_or_array_of_ids| ... }), + } + FastGettext.add_text_domain 'combined', :type=>:chain, :chain=>repos +If the Logger is in position #1 it will see all translations, if it is in position #2 it will only see the unfound. +Unfound may not always mean missing, if you chose not to translate a word because the key is a good translation, it will appear nevertheless. +A lambda or anything that responds to `call` will do as callback. A good starting point may be `examples/missing_translations_logger.rb`. + +###Plugins +Want a xml version ? +Write your own TranslationRepository! + #fast_gettext/translation_repository/xxx.rb + module FastGettext + module TranslationRepository + class Wtf + define initialize(name,options), [key], plural(*keys) and + either inherit from TranslationRepository::Base or define available_locales and pluralisation_rule + end + end + end + + +FAQ +=== + - [Problems with ActiveRecord messages?](http://wiki.github.com/grosser/fast_gettext/activerecord) + + +TODO +==== + - YML backend that reads ActiveSupport::I18n files + - any ideas ? :D + +Author +====== +Mo/Po-file parsing from Masao Mutoh, see vendor/README + +###Contributors + - [geekq](http://www.innoq.com/blog/vd) + - [Matt Sanford](http://blog.mzsanford.com) + - [Antonio Terceiro](http://softwarelivre.org/terceiro) + - [J. Pablo Fernández](http://pupeno.com) + - Rudolf Gavlas + +[Michael Grosser](http://pragmatig.wordpress.com) +grosser.michael@gmail.com +Hereby placed under public domain, do what you want, just do not hold me accountable... diff --git a/vendor/gems/fast_gettext-0.5.10/Rakefile b/vendor/gems/fast_gettext-0.5.10/Rakefile new file mode 100644 index 000000000..6e5c489c0 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/Rakefile @@ -0,0 +1,32 @@ +task :default => :spec +require 'spec/rake/spectask' +Spec::Rake::SpecTask.new {|t| t.spec_opts = ['--color']} + +task :benchmark do + puts "Running on #{RUBY}" + %w[baseline ideal fast_gettext original i18n_simple].each do |bench| + puts `ruby benchmark/#{bench}.rb` + puts "" + end +end + +task :namespaces do + puts `ruby benchmark/namespace/original.rb` + puts `ruby benchmark/namespace/fast_gettext.rb` +end + +begin + require 'jeweler' + project_name = 'fast_gettext' + Jeweler::Tasks.new do |gem| + gem.name = project_name + gem.summary = "A simple, fast and threadsafe implementation of GetText" + gem.email = "grosser.michael@gmail.com" + gem.homepage = "http://github.com/grosser/#{project_name}" + gem.authors = ["Michael Grosser"] + end + + Jeweler::GemcutterTasks.new +rescue LoadError + puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler" +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/VERSION b/vendor/gems/fast_gettext-0.5.10/VERSION new file mode 100644 index 000000000..50c76ef87 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/VERSION @@ -0,0 +1 @@ +0.5.10 diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/base.rb b/vendor/gems/fast_gettext-0.5.10/benchmark/base.rb new file mode 100644 index 000000000..a3fead192 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/base.rb @@ -0,0 +1,42 @@ +require 'rubygems' +require 'benchmark' + +RUNS = 50_0000 +DEFAULTS = {:memory=>0} + +def locale_folder(domain) + path = case domain + when 'test' then File.join(File.expand_path(File.dirname(__FILE__)),'..','spec','locale') + when 'large' then File.join(File.expand_path(File.dirname(__FILE__)),'locale') + end + + mo = File.join(path,'de','LC_MESSAGES',"#{domain}.mo") + raise unless File.exist?(mo) + path +end + +def results_test(&block) + print "#{(result(&block)).to_s.strip.split(' ').first}s / #{memory}K <-> " +end + +def results_large + print "#{(result {_('login') == 'anmelden'}).to_s.strip.split(' ').first}s / #{memory}K" + puts "" +end + +def result + result =Benchmark.measure do + RUNS.times do + raise "not translated" unless yield + end + end + result +end + +def memory + pid = Process.pid + map = `pmap -d #{pid}` + map.split("\n").last.strip.squeeze(' ').split(' ')[3].to_i - DEFAULTS[:memory] +end + +DEFAULTS[:memory] = memory + 4 #4 => 0 for base calls
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/baseline.rb b/vendor/gems/fast_gettext-0.5.10/benchmark/baseline.rb new file mode 100644 index 000000000..a9eb474ae --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/baseline.rb @@ -0,0 +1,5 @@ +require 'benchmark/base' + +puts "Baseline: (doing nothing in a loop)" +results_test{true} +puts ""
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/fast_gettext.rb b/vendor/gems/fast_gettext-0.5.10/benchmark/fast_gettext.rb new file mode 100644 index 000000000..7832b39cf --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/fast_gettext.rb @@ -0,0 +1,18 @@ +require 'benchmark/base' + +$LOAD_PATH.unshift 'lib' +require 'fast_gettext' +include FastGettext::Translation + +FastGettext.available_locales = ['de','en'] +FastGettext.locale = 'de' + +puts "FastGettext:" +FastGettext.add_text_domain('test',:path=>locale_folder('test')) +FastGettext.text_domain = 'test' +results_test{_('car') == 'Auto'} + +#i cannot add the large file, since its an internal applications mo file +FastGettext.add_text_domain('large',:path=>locale_folder('large')) +FastGettext.text_domain = 'large' +results_large
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/i18n_simple.rb b/vendor/gems/fast_gettext-0.5.10/benchmark/i18n_simple.rb new file mode 100644 index 000000000..9bd35cbc7 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/i18n_simple.rb @@ -0,0 +1,7 @@ +require 'benchmark/base' +require 'activesupport' +I18n.backend = I18n::Backend::Simple.new +I18n.load_path = ['benchmark/locale/de.yml'] +I18n.locale = :de +puts "ActiveSupport I18n::Backend::Simple :" +results_test{I18n.translate('activerecord.models.car')=='Auto'}
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/ideal.rb b/vendor/gems/fast_gettext-0.5.10/benchmark/ideal.rb new file mode 100644 index 000000000..4a0e02265 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/ideal.rb @@ -0,0 +1,24 @@ +require 'benchmark/base' + +$LOAD_PATH.unshift 'lib' + +module FastestGettext + def set_domain(folder,domain,locale) + @data = {} + require 'fast_gettext/vendor/mofile' + FastGettext::GetText::MOFile.open(File.join(folder,locale,'LC_MESSAGES',"#{domain}.mo"), "UTF-8").each{|k,v|@data[k]=v} + end + def _(word) + @data[word] + end +end + + +include FastestGettext +set_domain(locale_folder('test'),'test','de') +puts "Ideal: (primitive Hash lookup)" +results_test{_('car') == 'Auto'} + +#i cannot add the large file, since its an internal applications mo file +set_domain(locale_folder('large'),'large','de') +results_large diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/locale/de.yml b/vendor/gems/fast_gettext-0.5.10/benchmark/locale/de.yml new file mode 100644 index 000000000..19462d6e2 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/locale/de.yml @@ -0,0 +1,127 @@ +# German translations for Ruby on Rails +# by Clemens Kofler (clemens@railway.at) + +de: + date: + formats: + default: "%d.%m.%Y" + short: "%e. %b" + long: "%e. %B %Y" + only_day: "%e" + + day_names: [Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag] + abbr_day_names: [So, Mo, Di, Mi, Do, Fr, Sa] + month_names: [~, Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember] + abbr_month_names: [~, Jan, Feb, Mär, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez] + order: [ :day, :month, :year ] + + time: + formats: + default: "%A, %e. %B %Y, %H:%M Uhr" + short: "%e. %B, %H:%M Uhr" + long: "%A, %e. %B %Y, %H:%M Uhr" + time: "%H:%M" + + am: "vormittags" + pm: "nachmittags" + + datetime: + distance_in_words: + half_a_minute: 'eine halbe Minute' + less_than_x_seconds: + zero: 'weniger als 1 Sekunde' + one: 'weniger als 1 Sekunde' + other: 'weniger als {{count}} Sekunden' + x_seconds: + one: '1 Sekunde' + other: '{{count}} Sekunden' + less_than_x_minutes: + zero: 'weniger als 1 Minute' + one: 'weniger als eine Minute' + other: 'weniger als {{count}} Minuten' + x_minutes: + one: '1 Minute' + other: '{{count}} Minuten' + about_x_hours: + one: 'etwa 1 Stunde' + other: 'etwa {{count}} Stunden' + x_days: + one: '1 Tag' + other: '{{count}} Tage' + about_x_months: + one: 'etwa 1 Monat' + other: 'etwa {{count}} Monate' + x_months: + one: '1 Monat' + other: '{{count}} Monate' + about_x_years: + one: 'etwa 1 Jahr' + other: 'etwa {{count}} Jahre' + over_x_years: + one: 'mehr als 1 Jahr' + other: 'mehr als {{count}} Jahre' + + number: + format: + precision: 2 + separator: ',' + delimiter: '.' + currency: + format: + unit: '€' + format: '%n%u' + separator: + delimiter: + precision: + percentage: + format: + delimiter: "" + precision: + format: + delimiter: "" + human: + format: + delimiter: "" + precision: 1 + + support: + array: + sentence_connector: "und" + skip_last_comma: true + + activerecord: + errors: + template: + header: + one: "Konnte dieses {{model}} Objekt nicht speichern: 1 Fehler." + other: "Konnte dieses {{model}} Objekt nicht speichern: {{count}} Fehler." + body: "Bitte überprüfen Sie die folgenden Felder:" + format: + seperator: ' ' + messages: + inclusion: "ist kein gültiger Wert" + exclusion: "ist nicht verfügbar" + invalid: "ist nicht gültig" + confirmation: "stimmt nicht mit der Bestätigung überein" + accepted: "muss akzeptiert werden" + empty: "muss ausgefüllt werden" + blank: "muss ausgefüllt werden" + too_long: "ist zu lang (nicht mehr als {{count}} Zeichen)" + too_short: "ist zu kurz (nicht weniger als {{count}} Zeichen)" + wrong_length: "hat die falsche Länge (muss genau {{count}} Zeichen haben)" + taken: "ist bereits vergeben" + not_a_number: "ist keine Zahl" + greater_than: "muss größer als {{count}} sein" + greater_than_or_equal_to: "muss größer oder gleich {{count}} sein" + equal_to: "muss genau {{count}} sein" + less_than: "muss kleiner als {{count}} sein" + less_than_or_equal_to: "muss kleiner oder gleich {{count}} sein" + odd: "muss ungerade sein" + even: "muss gerade sein" + models: + car: 'BAUTO' + cars: 'CAUTO' + Car: 'DAUTO' + + models: + car: 'Auto' diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/locale/de/LC_MESSAGES/large.mo b/vendor/gems/fast_gettext-0.5.10/benchmark/locale/de/LC_MESSAGES/large.mo Binary files differnew file mode 100644 index 000000000..e4481b211 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/locale/de/LC_MESSAGES/large.mo diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/misc/threadsave.rb b/vendor/gems/fast_gettext-0.5.10/benchmark/misc/threadsave.rb new file mode 100644 index 000000000..3e65afa7d --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/misc/threadsave.rb @@ -0,0 +1,21 @@ +require 'benchmark' +BASELINE = 0 +def test + result = Benchmark.measure {1_000_000.times{ yield }} + result.to_s.strip.split(' ').first.to_f - BASELINE +end + +BASELINE = (test{}) +Thread.current[:library_name]={} +other = "x" +puts "Ruby #{VERSION}" + +puts "generic:" +puts " Symbol: #{test{Thread.current[:library_name][:just_a_symbol]}}s" +puts " String concat: #{test{Thread.current["xxxxxx"<<other.to_s]}}s" +puts " String add: #{test{Thread.current["xxxxxx"+other.to_s]}}s" +puts " String insert: #{test{Thread.current["xxxxxx#{other}"]}}s" + +puts "single:" +puts " Symbol: #{test{Thread.current[:long_unique_symbol]}}s" +puts " String: #{test{Thread.current["xxxxxx"]}}s"
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/namespace/fast_gettext.rb b/vendor/gems/fast_gettext-0.5.10/benchmark/namespace/fast_gettext.rb new file mode 100644 index 000000000..37b59efa9 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/namespace/fast_gettext.rb @@ -0,0 +1,15 @@ +#Iconv will not be defined, unless it is found -> normalize test results for users that have Iconv/those who do not have it +begin;require 'iconv';rescue;LoadError;end +initial = methods.count + Module.constants.count + +#FastGettext +$LOAD_PATH.unshift File.join(File.dirname(__FILE__),'..','..','lib') +require 'fast_gettext' +FastGettext.locale = 'de' +FastGettext.add_text_domain 'test', :path=>'spec/locale' +FastGettext.text_domain = 'test' +include FastGettext::Translation +raise unless _('car')=='Auto' + +puts "FastGettext" +puts methods.count + Module.constants.count - initial
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/namespace/original.rb b/vendor/gems/fast_gettext-0.5.10/benchmark/namespace/original.rb new file mode 100644 index 000000000..b5ae694ab --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/namespace/original.rb @@ -0,0 +1,14 @@ +require 'rubygems' +initial = methods.count + Module.constants.count + +#GetText +gem 'gettext', '>=2.0.0' +require 'gettext' +GetText.locale = 'de' +GetText.bindtextdomain('test',:path=>'spec/locale') +include GetText +raise unless _('car') == 'Auto' + + +puts "GetText" +puts methods.count + Module.constants.count - initial
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/benchmark/original.rb b/vendor/gems/fast_gettext-0.5.10/benchmark/original.rb new file mode 100644 index 000000000..9060491a4 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/benchmark/original.rb @@ -0,0 +1,19 @@ +require 'benchmark/base' + +begin +gem 'gettext', '>=2.0.0' +rescue LoadError + $LOAD_PATH.unshift 'lib' +end +require 'gettext' +include GetText + +self.locale = 'de' + +puts "GetText #{GetText::VERSION}:" +bindtextdomain('test',:path=>locale_folder('test')) +results_test{_('car') == 'Auto'} + +#i cannot add the large file, since its an internal applications mo file +bindtextdomain('large',:path=>locale_folder('large')) +results_large diff --git a/vendor/gems/fast_gettext-0.5.10/examples/db/migration.rb b/vendor/gems/fast_gettext-0.5.10/examples/db/migration.rb new file mode 100644 index 000000000..049e9f077 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/examples/db/migration.rb @@ -0,0 +1,22 @@ +class CreateTranslationTables < ActiveRecord::Migration + def self.up + create_table :translation_keys do |t| + t.string :key, :unique=>true, :null=>false + t.timestamps + end + add_index :translation_keys, :key #I am not sure if this helps.... + + create_table :translation_texts do |t| + t.text :text + t.string :locale + t.integer :translation_key_id, :null=>false + t.timestamps + end + add_index :translation_texts, :translation_key_id + end + + def self.down + drop_table :translation_keys + drop_table :translation_texts + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/examples/missing_translation_logger.rb b/vendor/gems/fast_gettext-0.5.10/examples/missing_translation_logger.rb new file mode 100644 index 000000000..5b507402a --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/examples/missing_translation_logger.rb @@ -0,0 +1,13 @@ +class MissingTranslationLogger + def call(unfound) + logger.warn "#{FastGettext.locale}: #{unfound}" unless FastGettext.locale == 'en' + end + + private + + def logger + return @logger if @logger + require 'logger' + @logger = Logger.new("log/unfound_translations", 2, 5*(1024**2))#max 2x 5mb logfile + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/fast_gettext.gemspec b/vendor/gems/fast_gettext-0.5.10/fast_gettext.gemspec new file mode 100644 index 000000000..2165fb991 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/fast_gettext.gemspec @@ -0,0 +1,125 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = %q{fast_gettext} + s.version = "0.5.10" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Michael Grosser"] + s.date = %q{2010-09-17} + s.email = %q{grosser.michael@gmail.com} + s.extra_rdoc_files = [ + "README.markdown" + ] + s.files = [ + ".gitignore", + "CHANGELOG", + "README.markdown", + "Rakefile", + "VERSION", + "benchmark/base.rb", + "benchmark/baseline.rb", + "benchmark/fast_gettext.rb", + "benchmark/i18n_simple.rb", + "benchmark/ideal.rb", + "benchmark/locale/de.yml", + "benchmark/locale/de/LC_MESSAGES/large.mo", + "benchmark/misc/threadsave.rb", + "benchmark/namespace/fast_gettext.rb", + "benchmark/namespace/original.rb", + "benchmark/original.rb", + "examples/db/migration.rb", + "examples/missing_translation_logger.rb", + "fast_gettext.gemspec", + "lib/fast_gettext.rb", + "lib/fast_gettext/VERSION", + "lib/fast_gettext/mo_file.rb", + "lib/fast_gettext/po_file.rb", + "lib/fast_gettext/storage.rb", + "lib/fast_gettext/translation.rb", + "lib/fast_gettext/translation_repository.rb", + "lib/fast_gettext/translation_repository/base.rb", + "lib/fast_gettext/translation_repository/chain.rb", + "lib/fast_gettext/translation_repository/db.rb", + "lib/fast_gettext/translation_repository/db_models/translation_key.rb", + "lib/fast_gettext/translation_repository/db_models/translation_text.rb", + "lib/fast_gettext/translation_repository/logger.rb", + "lib/fast_gettext/translation_repository/mo.rb", + "lib/fast_gettext/translation_repository/po.rb", + "lib/fast_gettext/translation_repository/yaml.rb", + "lib/fast_gettext/vendor/README.rdoc", + "lib/fast_gettext/vendor/empty.mo", + "lib/fast_gettext/vendor/iconv.rb", + "lib/fast_gettext/vendor/mofile.rb", + "lib/fast_gettext/vendor/poparser.rb", + "lib/fast_gettext/vendor/string.rb", + "spec/aa_unconfigued_spec.rb", + "spec/fast_gettext/mo_file_spec.rb", + "spec/fast_gettext/storage_spec.rb", + "spec/fast_gettext/translation_repository/base_spec.rb", + "spec/fast_gettext/translation_repository/chain_spec.rb", + "spec/fast_gettext/translation_repository/db_spec.rb", + "spec/fast_gettext/translation_repository/logger_spec.rb", + "spec/fast_gettext/translation_repository/mo_spec.rb", + "spec/fast_gettext/translation_repository/po_spec.rb", + "spec/fast_gettext/translation_repository/yaml_spec.rb", + "spec/fast_gettext/translation_repository_spec.rb", + "spec/fast_gettext/translation_spec.rb", + "spec/fast_gettext/vendor/fake_load_path/iconv.rb", + "spec/fast_gettext/vendor/iconv_spec.rb", + "spec/fast_gettext/vendor/string_spec.rb", + "spec/fast_gettext_spec.rb", + "spec/fuzzy_locale/de/test.po", + "spec/locale/de/LC_MESSAGES/test.mo", + "spec/locale/de/test.po", + "spec/locale/en/LC_MESSAGES/plural_test.mo", + "spec/locale/en/LC_MESSAGES/test.mo", + "spec/locale/en/plural_test.po", + "spec/locale/en/test.po", + "spec/locale/yaml/de.yml", + "spec/locale/yaml/en.yml", + "spec/locale/yaml/notfound.yml", + "spec/obsolete_locale/de/test.po", + "spec/spec_helper.rb" + ] + s.homepage = %q{http://github.com/grosser/fast_gettext} + s.rdoc_options = ["--charset=UTF-8"] + s.require_paths = ["lib"] + s.rubygems_version = %q{1.3.6} + s.summary = %q{A simple, fast and threadsafe implementation of GetText} + s.test_files = [ + "spec/aa_unconfigued_spec.rb", + "spec/fast_gettext/mo_file_spec.rb", + "spec/fast_gettext/storage_spec.rb", + "spec/fast_gettext/translation_spec.rb", + "spec/fast_gettext/translation_repository_spec.rb", + "spec/fast_gettext/translation_repository/base_spec.rb", + "spec/fast_gettext/translation_repository/chain_spec.rb", + "spec/fast_gettext/translation_repository/db_spec.rb", + "spec/fast_gettext/translation_repository/po_spec.rb", + "spec/fast_gettext/translation_repository/mo_spec.rb", + "spec/fast_gettext/translation_repository/logger_spec.rb", + "spec/fast_gettext/translation_repository/yaml_spec.rb", + "spec/fast_gettext/vendor/string_spec.rb", + "spec/fast_gettext/vendor/iconv_spec.rb", + "spec/fast_gettext/vendor/fake_load_path/iconv.rb", + "spec/spec_helper.rb", + "spec/fast_gettext_spec.rb", + "examples/db/migration.rb", + "examples/missing_translation_logger.rb" + ] + + if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + s.specification_version = 3 + + if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then + else + end + else + end +end + diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext.rb new file mode 100644 index 000000000..ea63710f7 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext.rb @@ -0,0 +1,30 @@ +require 'fast_gettext/mo_file' +require 'fast_gettext/storage' +require 'fast_gettext/translation' +require 'fast_gettext/translation_repository' +require 'fast_gettext/vendor/string' + +module FastGettext + include FastGettext::Storage + extend self + + VERSION = File.read( File.join(File.dirname(__FILE__), 'fast_gettext', 'VERSION') ).strip + LOCALE_REX = /^[a-z]{2}$|^[a-z]{2}_[A-Z]{2}$/ + NAMESPACE_SEPERATOR = '|' + + # users should not include FastGettext, since this would conterminate their namespace + # rather use + # FastGettext.locale = .. + # FastGettext.text_domain = .. + # and + # include FastGettext::Translation + FastGettext::Translation.public_instance_methods.each do |method| + define_method method do |*args| + Translation.send(method,*args) + end + end + + def add_text_domain(name,options) + translation_repositories[name] = TranslationRepository.build(name,options) + end +end diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/VERSION b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/VERSION new file mode 100644 index 000000000..4b9fcbec1 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/VERSION @@ -0,0 +1 @@ +0.5.1 diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/mo_file.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/mo_file.rb new file mode 100644 index 000000000..a6508b05d --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/mo_file.rb @@ -0,0 +1,67 @@ +require 'fast_gettext/vendor/mofile' +module FastGettext + # Responsibility: + # - abstract mo files for Mo Repository + class MoFile + PLURAL_SEPERATOR = "\000" + + # file => path or FastGettext::GetText::MOFile + def initialize(file) + if file.is_a? FastGettext::GetText::MOFile + @data = file + else + @data = FastGettext::GetText::MOFile.open(file, "UTF-8") + end + make_singular_and_plural_available + end + + def [](key) + @data[key] + end + + #returns the plural forms or all singular translations that where found + def plural(*msgids) + translations = plural_translations(msgids) + return translations unless translations.empty? + msgids.map{|msgid| self[msgid] || msgid} #try to translate each id + end + + def pluralisation_rule + #gettext uses 0 as default rule, which would turn off all pluralisation, very clever... + #additionally parsing fails when directly accessing po files, so this line was taken from gettext/mofile + (@data['']||'').split("\n").each do |line| + return lambda{|n|eval($2)} if /^Plural-Forms:\s*nplurals\s*\=\s*(\d*);\s*plural\s*\=\s*([^;]*)\n?/ =~ line + end + nil + end + + def self.empty + MoFile.new(File.join(File.dirname(__FILE__),'vendor','empty.mo')) + end + + private + + #(if plural==singular, prefer singular) + def make_singular_and_plural_available + data = {} + @data.each do |key,translation| + next unless key.include? PLURAL_SEPERATOR + singular, plural = split_plurals(key) + translation = split_plurals(translation) + data[singular] ||= translation[0] + data[plural] ||= translation[1] + end + @data.merge!(data){|key,old,new| old} + end + + def split_plurals(singular_plural) + singular_plural.split(PLURAL_SEPERATOR) + end + + # Car, Cars => [Auto,Autos] or [] + def plural_translations(msgids) + plurals = self[msgids*PLURAL_SEPERATOR] + if plurals then split_plurals(plurals) else [] end + end + end +end diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/po_file.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/po_file.rb new file mode 100644 index 000000000..f2afb00ec --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/po_file.rb @@ -0,0 +1,14 @@ +require 'fast_gettext/mo_file' +module FastGettext + # Responsibility: + # - abstract po files for Po Repository + # TODO refactor... + class PoFile + def self.to_mo_file(file, options={}) + require 'fast_gettext/vendor/poparser' + mo_file = FastGettext::GetText::MOFile.new + FastGettext::GetText::PoParser.new.parse(File.read(file), mo_file, !options[:ignore_fuzzy], !options[:ignore_obsolete]) + MoFile.new(mo_file) + end + end +end diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/storage.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/storage.rb new file mode 100644 index 000000000..7c65fd57a --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/storage.rb @@ -0,0 +1,192 @@ +module FastGettext + # Responsibility: + # - store data threadsave + # - provide error messages when repositories are unconfigured + # - accept/reject locales that are set by the user + module Storage + class NoTextDomainConfigured < RuntimeError + def to_s + "Current textdomain (#{FastGettext.text_domain.inspect}) was not added, use FastGettext.add_text_domain !" + end + end + + [:available_locales, :_locale, :text_domain, :pluralisation_rule].each do |method_name| + key = "fast_gettext_#{method_name}".to_sym + define_method method_name do + Thread.current[key] + end + + define_method "#{method_name}=" do |value| + Thread.current[key]=value + update_current_cache + end + end + private :_locale, :_locale= + + + def available_locales + locales = Thread.current[:fast_gettext_available_locales] || default_available_locales + return unless locales + locales.map{|s|s.to_s} + end + + # == cattr_accessor :default_available_locales + @@default_available_locales = nil + def default_available_locales=(avail_locales) + @@default_available_locales = avail_locales + update_current_cache + end + + def default_available_locales + @@default_available_locales + end + + + def text_domain + Thread.current[:fast_gettext_text_domain] || default_text_domain + end + + # == cattr_accessor :default_text_domain + @@default_text_domain = nil + def default_text_domain=(domain) + @@default_text_domain = domain + update_current_cache + end + + def default_text_domain + @@default_text_domain + end + + + # if overwritten by user( FastGettext.pluralisation_rule = xxx) use it, + # otherwise fall back to repo or to default lambda + def pluralisation_rule + Thread.current[:fast_gettext_pluralisation_rule] || current_repository.pluralisation_rule || lambda{|i| i!=1} + end + + def current_cache + Thread.current[:fast_gettext_current_cache] || {} + end + + def current_cache=(cache) + Thread.current[:fast_gettext_current_cache] = cache + end + + #global, since re-parsing whole folders takes too much time... + @@translation_repositories={} + def translation_repositories + @@translation_repositories + end + + # used to speedup simple translations, does not work for pluralisation + # caches[text_domain][locale][key]=translation + @@caches={} + def caches + @@caches + end + + def current_repository + translation_repositories[text_domain] || raise(NoTextDomainConfigured) + end + + def key_exist?(key) + !!(cached_find key) + end + + def cached_find(key) + translation = current_cache[key] + return translation if translation or translation == false #found or was not found before + current_cache[key] = current_repository[key] || false + end + + def cached_plural_find(*keys) + key = '||||' + keys * '||||' + translation = current_cache[key] + return translation if translation or translation == false #found or was not found before + current_cache[key] = current_repository.plural(*keys) || false + end + + def locale + _locale || ( default_locale || (available_locales||[]).first || 'en' ) + end + + def locale=(new_locale) + new_locale = best_locale_in(new_locale) + self._locale = new_locale if new_locale + end + + # for chaining: puts set_locale('xx') == 'xx' ? 'applied' : 'rejected' + # returns the current locale, not the one that was supplied + # like locale=(), whoes behavior cannot be changed + def set_locale(new_locale) + self.locale = new_locale + locale + end + + @@default_locale = nil + def default_locale=(new_locale) + @@default_locale = best_locale_in(new_locale) + update_current_cache + end + + def default_locale + @@default_locale + end + + #Opera: de-DE,de;q=0.9,en;q=0.8 + #Firefox de-de,de;q=0.8,en-us;q=0.5,en;q=0.3 + #IE6/7 de + #nil if nothing matches + def best_locale_in(locales) + formatted_sorted_locales(locales).each do |candidate| + return candidate if not available_locales + return candidate if available_locales.include?(candidate) + return candidate[0..1] if available_locales.include?(candidate[0..1])#available locales include a langauge + end + return nil#nothing found im sorry :P + end + + #turn off translation if none was defined to disable all resulting errors + def silence_errors + require 'fast_gettext/translation_repository/base' + translation_repositories[text_domain] = TranslationRepository::Base.new('x') + end + + private + + # de-de,DE-CH;q=0.9 -> ['de_DE','de_CH'] + def formatted_sorted_locales(locales) + found = weighted_locales(locales).reject{|x|x.empty?}.sort_by{|l|l.last}.reverse #sort them by weight which is the last entry + found.flatten.map{|l| format_locale(l)} + end + + #split the locale and seperate it into different languages + #de-de,de;q=0.9,en;q=0.8 => [['de-de','de','0.5'], ['en','0.8']] + def weighted_locales(locales) + locales = locales.to_s.gsub(/\s/,'') + found = [[]] + locales.split(',').each do |part| + if part =~ /;q=/ #contains language and weight ? + found.last << part.split(/;q=/) + found.last.flatten! + found << [] + else + found.last << part + end + end + found + end + + #de-de -> de_DE + def format_locale(locale) + locale.sub(/^([a-zA-Z]{2})[-_]([a-zA-Z]{2})$/){$1.downcase+'_'+$2.upcase} + end + + def update_current_cache + caches[text_domain] ||= {} + caches[text_domain][locale] ||= {} + caches[text_domain][locale][""] = false #ignore gettext meta key when translating + self.current_cache = caches[text_domain][locale] + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation.rb new file mode 100644 index 000000000..b1e63231f --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation.rb @@ -0,0 +1,57 @@ +module FastGettext + # this module should be included + # Responsibility: + # - direct translation queries to the current repository + # - handle untranslated values + # - understand / enforce namespaces + # - decide which plural form is used + module Translation + extend self + + #make it usable in class definition, e.g. + # class Y + # include FastGettext::Translation + # @@x = _('y') + # end + def self.included(klas) #:nodoc: + klas.extend self + end + + def _(key) + FastGettext.cached_find(key) or key + end + + #translate pluralized + # some languages have up to 4 plural forms... + # n_(singular, plural, plural form 2, ..., count) + # n_('apple','apples',3) + def n_(*keys) + count = keys.pop + translations = FastGettext.cached_plural_find *keys + selected = FastGettext.pluralisation_rule.call(count) + selected = selected ? 1 : 0 unless selected.is_a? Numeric #convert booleans to numbers + translations[selected] || keys[selected] || keys.last + end + + #translate, but discard namespace if nothing was found + # Car|Tire -> Tire if no translation could be found + def s_(key,seperator=nil) + translation = FastGettext.cached_find(key) and return translation + key.split(seperator||NAMESPACE_SEPERATOR).last + end + + #tell gettext: this string need translation (will be found during parsing) + def N_(translate) + translate + end + + #tell gettext: this string need translation (will be found during parsing) + def Nn_(*keys) + keys + end + + def ns_(*args) + n_(*args).split(NAMESPACE_SEPERATOR).last + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository.rb new file mode 100644 index 000000000..baa73290a --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository.rb @@ -0,0 +1,17 @@ +module FastGettext + # Responsibility: + # - decide which repository to choose from given input + module TranslationRepository + extend self + + # only single-word types supported atm (mytype works, MyType will not) + def build(name, options) + type = options[:type] || :mo + class_name = type.to_s.capitalize + unless FastGettext::TranslationRepository.constants.map{|c|c.to_s}.include?(class_name) + require "fast_gettext/translation_repository/#{type}" + end + eval(class_name).new(name,options) + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/base.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/base.rb new file mode 100644 index 000000000..cb398aa33 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/base.rb @@ -0,0 +1,49 @@ +module FastGettext + module TranslationRepository + # Responsibility: + # - base for all repositories + # - fallback as empty repository, that cannot translate anything but does not crash + class Base + def initialize(name,options={}) + @name = name + @options = options + end + + def pluralisation_rule + nil + end + + def available_locales + [] + end + + def [](key) + current_translations[key] + end + + def plural(*keys) + current_translations.plural(*keys) + end + + protected + + def current_translations + MoFile.empty + end + + def find_files_in_locale_folders(relative_file_path,path) + path ||= "locale" + raise "path #{path} cound not be found!" unless File.exist?(path) + + @files = {} + Dir[File.join(path,'*')].each do |locale_folder| + next unless File.basename(locale_folder) =~ LOCALE_REX + file = File.join(locale_folder,relative_file_path) + next unless File.exist? file + locale = File.basename(locale_folder) + @files[locale] = yield(locale,file) + end + end + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/chain.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/chain.rb new file mode 100644 index 000000000..93b2ee7a9 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/chain.rb @@ -0,0 +1,43 @@ +require 'fast_gettext/translation_repository/base' + +module FastGettext + module TranslationRepository + # Responsibility: + # - delegate calls to members of the chain in turn + #TODO cache should be expired after a repo was added + class Chain < Base + attr_accessor :chain + + def initialize(name,options={}) + super + self.chain = options[:chain] + end + + def available_locales + chain.map{|c|c.available_locales}.flatten.uniq + end + + def pluralisation_rule + chain.each do |c| + result = c.pluralisation_rule and return result + end + nil + end + + def [](key) + chain.each do |c| + result = c[key] and return result + end + nil + end + + def plural(*keys) + chain.each do |c| + result = c.plural(*keys) + return result unless result.compact.empty? + end + [] + end + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/db.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/db.rb new file mode 100644 index 000000000..0249a644c --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/db.rb @@ -0,0 +1,62 @@ +require 'active_record' +module FastGettext + module TranslationRepository + # Responsibility: + # - provide access to translations in database through a database abstraction + # + # Options: + # :model => Model that represents your keys + # you can either use the models supplied under db/, extend them or build your own + # only constraints: + # key: find_by_key, translations + # translation: text, locale + class Db + def initialize(name,options={}) + @model = options[:model] + end + + @@seperator = '||||' # string that seperates multiple plurals + def self.seperator=(sep);@@seperator = sep;end + def self.seperator;@@seperator;end + + def available_locales + if @model.respond_to? :available_locales + @model.available_locales || [] + else + [] + end + end + + def pluralisation_rule + if @model.respond_to? :pluralsation_rule + @model.pluralsation_rule + else + nil + end + end + + def [](key) + @model.translation(key, FastGettext.locale) + end + + def plural(*args) + if translation = @model.translation(args*self.class.seperator, FastGettext.locale) + translation.to_s.split(self.class.seperator) + else + [] + end + end + + def self.require_models + folder = "fast_gettext/translation_repository/db_models" + require "#{folder}/translation_key" + require "#{folder}/translation_text" + Module.new do + def self.included(base) + puts "you no longer need to include the result of require_models" + end + end + end + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/db_models/translation_key.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/db_models/translation_key.rb new file mode 100644 index 000000000..3fcc638e5 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/db_models/translation_key.rb @@ -0,0 +1,18 @@ +class TranslationKey < ActiveRecord::Base + has_many :translations, :class_name => 'TranslationText' + + accepts_nested_attributes_for :translations, :allow_destroy => true + + validates_uniqueness_of :key + validates_presence_of :key + + def self.translation(key, locale) + return unless translation_key = find_by_key(key) + return unless translation_text = translation_key.translations.find_by_locale(locale) + translation_text.text + end + + def self.available_locales + @@available_locales ||= TranslationText.count(:group=>:locale).keys.sort + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/db_models/translation_text.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/db_models/translation_text.rb new file mode 100644 index 000000000..3428f82ef --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/db_models/translation_text.rb @@ -0,0 +1,5 @@ +class TranslationText < ActiveRecord::Base + belongs_to :key, :class_name=>'TranslationKey' + validates_presence_of :locale + validates_uniqueness_of :locale, :scope=>:translation_key_id +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/logger.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/logger.rb new file mode 100644 index 000000000..7854a7b1b --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/logger.rb @@ -0,0 +1,27 @@ +require 'fast_gettext/translation_repository/base' + +module FastGettext + module TranslationRepository + # This should be used in a TranslationRepository::Chain, so tat untranslated keys can be found + # Responsibility: + # - log every translation call + class Logger < Base + attr_accessor :callback + + def initialize(name,options={}) + super + self.callback = options[:callback] + end + + def [](key) + callback.call(key) + nil + end + + def plural(*keys) + callback.call(keys) + [] + end + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/mo.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/mo.rb new file mode 100644 index 000000000..fec4dab54 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/mo.rb @@ -0,0 +1,35 @@ +require 'fast_gettext/translation_repository/base' +module FastGettext + module TranslationRepository + # Responsibility: + # - find and store mo files + # - provide access to translations in mo files + class Mo < Base + def initialize(name,options={}) + find_and_store_files(name,options) + super + end + + def available_locales + @files.keys + end + + def pluralisation_rule + current_translations.pluralisation_rule + end + + protected + + def find_and_store_files(name,options) + # parse all .mo files with the right name, that sit in locale/LC_MESSAGES folders + find_files_in_locale_folders(File.join('LC_MESSAGES',"#{name}.mo"), options[:path]) do |locale,file| + @files[locale] = MoFile.new(file) + end + end + + def current_translations + @files[FastGettext.locale] || MoFile.empty + end + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/po.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/po.rb new file mode 100644 index 000000000..dcb6c0889 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/po.rb @@ -0,0 +1,18 @@ +require 'fast_gettext/translation_repository/base' +require 'fast_gettext/translation_repository/mo' +module FastGettext + module TranslationRepository + # Responsibility: + # - find and store po files + # - provide access to translations in po files + class Po < Mo + protected + def find_and_store_files(name, options) + require 'fast_gettext/po_file' + find_files_in_locale_folders("#{name}.po", options[:path]) do |locale,file| + @files[locale] = PoFile.to_mo_file(file, options) + end + end + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/yaml.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/yaml.rb new file mode 100644 index 000000000..3aafac521 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/translation_repository/yaml.rb @@ -0,0 +1,72 @@ +require 'fast_gettext/translation_repository/base' +require 'yaml' + +module FastGettext + module TranslationRepository + # Responsibility: + # - find and store yaml files + # - provide access to translations in yaml files + class Yaml < Base + def initialize(name,options={}) + find_and_store_files(options) + super + end + + def available_locales + @files.keys + end + + def plural(*keys) + ['one', 'other', 'plural2', 'plural3'].map do |name| + self[yaml_dot_notation(keys.first, name)] + end + end + + def pluralisation_rule + self['pluralisation_rule'] ? lambda{|n| eval(self['pluralisation_rule']) } : nil + end + + protected + + MAX_FIND_DEPTH = 10 + + def find_and_store_files(options) + @files = {} + path = options[:path] || 'config/locales' + Dir["#{path}/??.yml"].each do |yaml_file| + locale = yaml_file.match(/([a-z]{2})\.yml$/)[1] + @files[locale] = load_yaml(yaml_file, locale) + end + end + + def current_translations + @files[FastGettext.locale] || super + end + + # Given a yaml file return a hash of key -> translation + def load_yaml(file, locale) + yaml = YAML.load_file(file) + yaml_hash_to_dot_notation(yaml[locale]) + end + + def yaml_hash_to_dot_notation(yaml_hash) + add_yaml_key({}, nil, yaml_hash) + end + + def add_yaml_key(result, prefix, hash) + hash.each_pair do |key, value| + if value.kind_of?(Hash) + add_yaml_key(result, yaml_dot_notation(prefix, key), value) + else + result[yaml_dot_notation(prefix, key)] = value + end + end + result + end + + def yaml_dot_notation(a,b) + a ? "#{a}.#{b}" : b + end + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/README.rdoc b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/README.rdoc new file mode 100644 index 000000000..1067a0fe4 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/README.rdoc @@ -0,0 +1,236 @@ += Ruby-GetText-Package + +Ruby-GetText-Package is a Localization(L10n) library and tool +which is modeled after the GNU gettext package. + +This library translates original messages to localized +messages using client-side locale information(environment +variable or CGI variable). + +The tools for developers support creating, useing, and modifying +localized message files(message catalogs). + +((*Rails*)) +Rails support has been removed. +Rails / ActiveRecord specific code now lives in gettext_rails and gettext_activerecord. + +== Website +* homepage[http://www.yotabanana.com/hiki/ruby-gettext.html] +* on rubyforge[http://gettext/rubyforge.org/] +* on github[http://github.com/gettext/] + +== Features +* Simple APIs(similar to GNU gettext) + +* rgettext creates po-files from + * ruby scripts + * glade-2 XML file(.glade) + * ERB file(.rhtml, .erb) + * Anything (with your own parsers) + * The po-files are compatible to GNU gettext. + +* rmsgfmt creates a mo-file from a po-file. + The mo-file is compatible to GNU gettext(msgfmt). + +* textdomain's scope is adapt to ruby class/module mechanism. + * A class/module can have plural textdomains. + * a message is looked up in its class/module and ancestors. + +* CGI support (gettext/cgi) + * Locale is retrieved from client informations + (HTTP_ACCEPT_LANGUAGE, HTTP_ACCEPT_CHARSET, QUERY_STRING(lang), Cookies(lang)). + +* String%() is extended to use named argument such as <tt>%{foo}" %{:foo => 1}</tt>. + Notes that Ruby-1.9.x supports this format by itself. + +== Requirements +* {Ruby 1.8.3 or later}[http://www.ruby-lang.org] +* {Rubygems}[http://www.rubygems.org/] +* {locale gem}[http://rubyforge.org/projects/locale/] + * $ gem install locale +* (for development only) + * {GNU gettext 0.10.35 or later}[http://www.gnu.org/software/gettext/gettext.html] + * {Racc-1.4.3 or later}[http://www.ruby-lang.org/raa/list.rhtml?name=racc] + * (for compiling src/rmsgfmt.ry only) + +== Install +* Uninstall old gettext if exists. + (sudo/su on POSIX system) + gem uninstall gettext + +* gem + #from github (edge/unstable) + (sudo/su on POSIX system) + gem install locale + gem install mutoh-gettext -s http://gems.github.com/ + + #from rubyforge (stable) + (sudo/su on POSIX system) + gem install locale + gem install gettext + +* download tar-ball + # De-Compress archive and enter its top directory. + (sudo/su on POSIX system) + ruby setup.rb + +You can also install files in your favorite directory by +supplying setup.rb some options. Try <tt>ruby setup.rb --help</tt>. + +== Usage +===Translation +- _: Basic translation method + Translates the message. + _("Hello") + +The gettext methods comes in 3 combinable flavors +- n: Pluralized + Returns singular or plural form, depending on how many you have. + n_("Apple", "%{num} Apples", 3) + n_(["Apple", "%{num} Apples"], 3) + +- p: context aware + A context is a prefix to your translation, usefull when one word has different meanings, depending on its context. + p_("Printer","Open") <=> p_("File","Open") + is the same as s_("Printer|Open") <=> s_("File|Open") + +- s: without context + If a translation could not be found, return the msgid without context. + s_("Printer|Open") => "Öffnen" #translation found + s_("Printer|Open") => "Open" #translation not found + +- combinations + np_("Fruit", "Apple", "%{num} Apples", 3) + ns_("Fruit|Apple","%{num} Apples", 3) + + np_(["Fruit","Apple","%{num} Apples"], 3) + ns_(["Fruit|Apple","%{num} Apples"], 3) + +- N_, Nn_: Makes dynamic translation messages readable for the gettext parser. + <tt>_(fruit)</tt> cannot be understood by the gettext parser. To help the parser find all your translations, + you can add <tt>fruit = N_("Apple")</tt> which does not translate, but tells the parser: "Apple" needs translation. + + fruit = N_("Apple") # same as fruit = "Apple" + _(fruit) # does a normal translation + + fruits = Nn_("Apple", "%{num} Apples") + n_(fruits, 3) + +=== Locale / Domain +GetText stores the locale your are using + GetText.locale = "en_US" # translate into english from now on + GetText.locale # => en_US +Or + include GetText + set_locale "en_US" + +Each locale can have different sets of translations (text domains) (e.g. Financial terms + Human-resource terms) + GetText.bindtextdomain('financial') +Or + include GetText + bindtextdomain('financial') + +For more details and options, have a look at the samples folder or +consult the tutorial[http://www.yotabanana.com/hiki/ruby-gettext-howto.html]. + + +== License +This program is licenced under the same licence as Ruby. +(See the file 'COPYING'.) + +* mofile.rb + * Copyright (C) 2001-2009 Masao Mutoh <mutoh at highwhay.ne.jp> + * Copyright (C) 2001,2002 Masahiro Sakai <s01397ms at sfc.keio.ac.jp> + +* gettext.rb + * Copyright (C) 2001-2009 Masao Mutoh <mutoh at highwhay.ne.jp> + * Copyright (C) 2001,2002 Masahiro Sakai <s01397ms at sfc.keio.ac.jp> + +* rgettext + * Copyright (C) 2001-2009 Masao Mutoh <mutoh at highwhay.ne.jp> + * Copyright (C) 2001,2002 Yasushi Shoji <yashi at atmark-techno.com> + +* setup.rb + * Copyright (C) 2000-2005 Minero Aoki <aamine at loveruby.net> + * This file is released under LGPL. See the top of the install.rb. + +* Others + * Copyright (C) 2001-2009 Masao Mutoh <mutoh at highwhay.ne.jp> + + +== Translators +* Bosnian(bs) - Sanjin Sehic <saserr at gmail.com> +* Bulgarian(bg) - Sava Chankov <sava.chankov at gmail.com> +* Catalan(ca) - Ramon Salvadó <rsalvado at gnuine.com> +* Chinese(Simplified)(zh_CN) + * Yang Bob <bob.yang.dev at gmail.com> (current) + * Yingfeng <blogyingfeng at gmail.com> +* Chinese(Traditional)(zh_TW) + * Yang Bob <bob.yang.dev at gmail.com> (current) + * LIN CHUNG-YI <xmarsh at gmail.com> +* Croatian(hr) - Sanjin Sehic <saserr at gmail.com> +* Czech(cs) - Karel Miarka <kajism at yahoo.com> +* Dutch(nl) - Menno Jonkers <ruby-gettext at jonkers.com> +* Esperanto(eo) - Malte Milatz <malte at gmx-topmail.de> +* Estonian(et) - Erkki Eilonen <erkki at itech.ee> +* French(fr) + * Vincent Isambart <vincent.isambart at gmail.com> (current) + * David Sulc <davidsulc at gmail.com> + * Laurent Sansonetti <laurent.sansonetti at gmail.com> +* German(de) + * Patrick Lenz <patrick at limited-overload.de> (current) + * Detlef Reichl <detlef.reichl at gmx.org> + * Sven Herzberg <herzi at abi02.de> + * Sascha Ebach <se at digitale-wertschoepfung.de> +* Greek(el) - Vassilis Rizopoulos <damphyr at gmx.net> +* Hungarian(hu) - Tamás Tompa <tompata at gmail.com> +* Italian(it) + * Marco Lazzeri <marco.lazzeri at gmail.com> + * Gabriele Renzi <surrender_it at yahoo.it> +* Japanese(ja) - Masao Mutoh <mutoh at highway.ne.jp> +* Korean(ko) - Gyoung-Yoon Noh <nohmad at gmail.com> +* Latvian(lv) - Aivars Akots <aivars.akots at gmail.com> +* Norwegian(nb) - Runar Ingebrigtsen <runar at mopo.no> +* Portuguese(Brazil)(pt_BR) + * Antonio S. de A. Terceiro <terceiro at softwarelivre.org> (current) + * Joao Pedrosa <joaopedrosa at gmail.com> +* Russian(ru) - Yuri Kozlov <kozlov.y at gmail.com> +* Serbian(sr) - Slobodan Paunović" <slobodan.paunovic at gmail.com> +* Spanish(es) + * David Espada <davinci at escomposlinux.org> (current) + * David Moreno Garza <damog at damog.net> +* Swedish(sv) - Nikolai Weibull <mailing-lists.ruby-talk at rawuncut.elitemail.org> +* Ukrainian(ua) - Alex Rootoff <rootoff at pisem.net> +* Vietnamese(vi) - Ngoc Dao Thanh <ngocdaothanh at gmail.com> + +== Status of translations +* Bosnian(bs) - 1.90.0 (old) +* Bulgarian(bg) - 2.0.0pre1 (new) +* Catalan(ca) - 2.0.0pre1 +* Croatian(hr) - 1.90.0 (old) +* Chinese(zh_CN) - 2.0.0pre1 +* Chinese(zh_TW) - 2.0.0pre1 +* Czech(cs) - 1.9.0 (old) +* Dutch(nl) - 1.90.0 (old) +* English(default) - 1.90.0 (old) +* Esperanto(eo) - 2.0.0pre1 +* Estonian(et) - 2.0.0pre1 +* French(fr) - 2.0.0pre1 +* German(de) - 2.0.0pre1 +* Greek(el) - 2.0.0pre1 +* Hungarian(hu) - 2.0.0pre1 +* Italian(it) - 1.6.0 (old) +* Japanese(ja) - 2.0.0pre1 +* Korean(ko) - 1.9.0 (old) +* Latvian(lv) - 2.0.0pre1 (new) +* Norwegian(nb) - 2.0.0pre1 +* Portuguese(Brazil)(pt_BR) - 2.0.0pre1 +* Russian(ru) - 2.0.0pre1 +* Serbian(sr) - 1.91.0 (old) +* Spanish(es) - 2.0.0pre1 +* Swedish(sv) - 0.8.0 (too much old) +* Ukrainian(ua) - 2.0.0pre1 +* Vietnamese(vi) - 2.0.0pre1 + +== Maintainer +Masao Mutoh <mutoh at highway.ne.jp> diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/empty.mo b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/empty.mo Binary files differnew file mode 100644 index 000000000..273edbbbd --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/empty.mo diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/iconv.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/iconv.rb new file mode 100644 index 000000000..a58f64928 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/iconv.rb @@ -0,0 +1,107 @@ +=begin + iconv.rb - Pseudo Iconv class. Supports Iconv.iconv, Iconv.conv. + + For Matz Ruby: + If you don't have iconv but glib2, this library uses glib2 iconv functions. + + For JRuby: + Use Java String class to convert strings. + + Copyright (C) 2004-2007 Masao Mutoh + + You may redistribute it and/or modify it under the same + license terms as Ruby. + + $Id: iconv.rb,v 1.6 2007/11/08 14:21:22 mutoh Exp $ +=end + +#Modifications +#wrapped inside FastGettext namespace to reduce conflic + +begin + require 'iconv' +rescue LoadError + # Provides Iconv.iconv which normally is provided through Ruby/GLib(1) functions. + # This library is required for 'gettext'. + # If you require 'gettext/iconv', it tries to call Ruby/GLib function + # when it doesn't find original Iconv class(iconv.so) it adds a pseudo class. + # + # One-click Ruby Installer for Win32 hadn’t had iconv and there hadn’t been a way to install iconv.so itself for Win32. + # And JRuby hadn’t had Iconv. + # I’ve not checked them currently, but if they’ve supported iconv now, we don’t need this anymore... + # + # (1) Ruby/GLib is a module which is provided from Ruby-GNOME2 Project. + # You can get binaries for Win32(One-Click Ruby Installer). + # <URL: http://ruby-gnome2.sourceforge.jp/> + module FastGettext + class Iconv2 + module Failure; end + class InvalidEncoding < ArgumentError; include Failure; end + class IllegalSequence < ArgumentError; include Failure; end + class InvalidCharacter < ArgumentError; include Failure; end + + if RUBY_PLATFORM =~ /java/ + def self.conv(to, from, str) + raise InvalidCharacter, "the 3rd argument is nil" unless str + begin + str = java.lang.String.new(str.unpack("C*").to_java(:byte), from) + str.getBytes(to).to_ary.pack("C*") + rescue java.io.UnsupportedEncodingException + raise InvalidEncoding + end + end + else + begin + require 'glib2' + + def self.check_glib_version?(major, minor, micro) # :nodoc: + (GLib::BINDING_VERSION[0] > major || + (GLib::BINDING_VERSION[0] == major && + GLib::BINDING_VERSION[1] > minor) || + (GLib::BINDING_VERSION[0] == major && + GLib::BINDING_VERSION[1] == minor && + GLib::BINDING_VERSION[2] >= micro)) + end + + if check_glib_version?(0, 11, 0) + # This is a function equivalent of Iconv.iconv. + # * to: encoding name for destination + # * from: encoding name for source + # * str: strings to be converted + # * Returns: Returns an Array of converted strings. + def self.conv(to, from, str) + begin + GLib.convert(str, to, from) + rescue GLib::ConvertError => e + case e.code + when GLib::ConvertError::NO_CONVERSION + raise InvalidEncoding.new(str) + when GLib::ConvertError::ILLEGAL_SEQUENCE + raise IllegalSequence.new(str) + else + raise InvalidCharacter.new(str) + end + end + end + else + def self.conv(to, from, str) # :nodoc: + begin + GLib.convert(str, to, from) + rescue + raise IllegalSequence.new(str) + end + end + end + rescue LoadError + def self.conv(to, from, str) # :nodoc: + warn "Iconv was not found." if $DEBUG + str + end + end + end + def self.iconv(to, from, str) + conv(to, from, str).split(//) + end + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/mofile.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/mofile.rb new file mode 100644 index 000000000..54221a62b --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/mofile.rb @@ -0,0 +1,296 @@ +=begin + mofile.rb - A simple class for operating GNU MO file. + + Copyright (C) 2003-2008 Masao Mutoh + Copyright (C) 2002 Masahiro Sakai, Masao Mutoh + Copyright (C) 2001 Masahiro Sakai + + Masahiro Sakai <s01397ms at sfc.keio.ac.jp> + Masao Mutoh <mutoh at highway.ne.jp> + + You can redistribute this file and/or modify it under the same term + of Ruby. License of Ruby is included with Ruby distribution in + the file "README". + + $Id: mo.rb,v 1.10 2008/06/17 16:40:52 mutoh Exp $ +=end + +require 'iconv' +require 'stringio' + +#Modifications: +# use Iconv or FastGettext::Icvon + +module FastGettext + module GetText + class MOFile < Hash + class InvalidFormat < RuntimeError; end; + + attr_reader :filename + + Header = Struct.new(:magic, + :revision, + :nstrings, + :orig_table_offset, + :translated_table_offset, + :hash_table_size, + :hash_table_offset) + + # The following are only used in .mo files + # with minor revision >= 1. + class HeaderRev1 < Header + attr_accessor :n_sysdep_segments, + :sysdep_segments_offset, + :n_sysdep_strings, + :orig_sysdep_tab_offset, + :trans_sysdep_tab_offset + end + + MAGIC_BIG_ENDIAN = "\x95\x04\x12\xde" + MAGIC_LITTLE_ENDIAN = "\xde\x12\x04\x95" + + def self.open(arg = nil, output_charset = nil) + result = self.new(output_charset) + result.load(arg) + end + + def initialize(output_charset = nil) + @filename = nil + @last_modified = nil + @little_endian = true + @output_charset = output_charset + super() + end + + def update! + if FileTest.exist?(@filename) + st = File.stat(@filename) + load(@filename) unless (@last_modified == [st.ctime, st.mtime]) + else + warn "#{@filename} was lost." if $DEBUG + clear + end + self + end + + def load(arg) + if arg.kind_of? String + begin + st = File.stat(arg) + @last_modified = [st.ctime, st.mtime] + rescue Exception + end + load_from_file(arg) + else + load_from_stream(arg) + end + @filename = arg + self + end + + def load_from_stream(io) + magic = io.read(4) + case magic + when MAGIC_BIG_ENDIAN + @little_endian = false + when MAGIC_LITTLE_ENDIAN + @little_endian = true + else + raise InvalidFormat.new(sprintf("Unknown signature %s", magic.dump)) + end + + endian_type6 = @little_endian ? 'V6' : 'N6' + endian_type_astr = @little_endian ? 'V*' : 'N*' + + header = HeaderRev1.new(magic, *(io.read(4 * 6).unpack(endian_type6))) + + if header.revision == 1 + # FIXME: It doesn't support sysdep correctly. + header.n_sysdep_segments = io.read(4).unpack(endian_type6) + header.sysdep_segments_offset = io.read(4).unpack(endian_type6) + header.n_sysdep_strings = io.read(4).unpack(endian_type6) + header.orig_sysdep_tab_offset = io.read(4).unpack(endian_type6) + header.trans_sysdep_tab_offset = io.read(4).unpack(endian_type6) + elsif header.revision > 1 + raise InvalidFormat.new(sprintf("file format revision %d isn't supported", header.revision)) + end + io.pos = header.orig_table_offset + orig_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr) + + io.pos = header.translated_table_offset + trans_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr) + + original_strings = Array.new(header.nstrings) + for i in 0...header.nstrings + io.pos = orig_table_data[i * 2 + 1] + original_strings[i] = io.read(orig_table_data[i * 2 + 0]) + end + + clear + for i in 0...header.nstrings + io.pos = trans_table_data[i * 2 + 1] + str = io.read(trans_table_data[i * 2 + 0]) + + if (! original_strings[i]) || original_strings[i] == "" + if str + @charset = nil + @nplurals = nil + @plural = nil + str.each_line{|line| + if /^Content-Type:/i =~ line and /charset=((?:\w|-)+)/i =~ line + @charset = $1 + elsif /^Plural-Forms:\s*nplurals\s*\=\s*(\d*);\s*plural\s*\=\s*([^;]*)\n?/ =~ line + @nplurals = $1 + @plural = $2 + end + break if @charset and @nplurals + } + @nplurals = "1" unless @nplurals + @plural = "0" unless @plural + end + else + if @output_charset + begin + iconv = Iconv || FastGettext::Iconv + str = iconv.conv(@output_charset, @charset, str) if @charset + rescue iconv::Failure + if $DEBUG + warn "@charset = ", @charset + warn"@output_charset = ", @output_charset + warn "msgid = ", original_strings[i] + warn "msgstr = ", str + end + end + end + end + self[original_strings[i]] = str.freeze + end + self + end + + # Is this number a prime number ? + # http://apidock.com/ruby/Prime + def prime?(number) + ('1' * number) !~ /^1?$|^(11+?)\1+$/ + end + + def next_prime(seed) + require 'mathn' + prime = Prime.new + while current = prime.succ + return current if current > seed + end + end + + # From gettext-0.12.1/gettext-runtime/intl/hash-string.h + # Defines the so called `hashpjw' function by P.J. Weinberger + # [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, + # 1986, 1987 Bell Telephone Laboratories, Inc.] + HASHWORDBITS = 32 + def hash_string(str) + hval = 0 + i = 0 + str.each_byte do |b| + break if b == '\0' + hval <<= 4 + hval += b.to_i + g = hval & (0xf << (HASHWORDBITS - 4)) + if (g != 0) + hval ^= g >> (HASHWORDBITS - 8) + hval ^= g + end + end + hval + end + + def save_to_stream(io) + #Save data as little endian format. + header_size = 4 * 7 + table_size = 4 * 2 * size + + hash_table_size = next_prime((size * 4) / 3) + hash_table_size = 3 if hash_table_size <= 2 + header = Header.new( + MAGIC_LITTLE_ENDIAN, # magic + 0, # revision + size, # nstrings + header_size, # orig_table_offset + header_size + table_size, # translated_table_offset + hash_table_size, # hash_table_size + header_size + table_size * 2 # hash_table_offset + ) + io.write(header.to_a.pack('a4V*')) + + ary = to_a + ary.sort!{|a, b| a[0] <=> b[0]} # sort by original string + + pos = header.hash_table_size * 4 + header.hash_table_offset + + orig_table_data = Array.new() + ary.each{|item, _| + orig_table_data.push(item.size) + orig_table_data.push(pos) + pos += item.size + 1 # +1 is <NUL> + } + io.write(orig_table_data.pack('V*')) + + trans_table_data = Array.new() + ary.each{|_, item| + trans_table_data.push(item.size) + trans_table_data.push(pos) + pos += item.size + 1 # +1 is <NUL> + } + io.write(trans_table_data.pack('V*')) + + hash_tab = Array.new(hash_table_size) + j = 0 + ary[0...size].each {|key, _| + hash_val = hash_string(key) + idx = hash_val % hash_table_size + if hash_tab[idx] != nil + incr = 1 + (hash_val % (hash_table_size - 2)) + begin + if (idx >= hash_table_size - incr) + idx -= hash_table_size - incr + else + idx += incr + end + end until (hash_tab[idx] == nil) + end + hash_tab[idx] = j + 1 + j += 1 + } + hash_tab.collect!{|i| i ? i : 0} + + io.write(hash_tab.pack('V*')) + + ary.each{|item, _| io.write(item); io.write("\0") } + ary.each{|_, item| io.write(item); io.write("\0") } + + self + end + + def load_from_file(filename) + @filename = filename + begin + File.open(filename, 'rb'){|f| load_from_stream(f)} + rescue => e + e.set_backtrace("File: #{@filename}") + raise e + end + end + + def save_to_file(filename) + File.open(filename, 'wb'){|f| save_to_stream(f)} + end + + def set_comment(msgid_or_sym, comment) + #Do nothing + end + + + attr_accessor :little_endian, :path, :last_modified + attr_reader :charset, :nplurals, :plural + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/poparser.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/poparser.rb new file mode 100644 index 000000000..e067e268f --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/poparser.rb @@ -0,0 +1,333 @@ +=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 FastGettext +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, show_obsolete = 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\#~(.*)/ + if show_obsolete + $stderr.print _("Warning: obsolete msgid exists.\n") + $stderr.print " #{$&}\n" + end + @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 +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/string.rb b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/string.rb new file mode 100644 index 000000000..4e3610f0d --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/lib/fast_gettext/vendor/string.rb @@ -0,0 +1,76 @@ +#! /usr/bin/ruby +=begin + string.rb - Extension for String. + + Copyright (C) 2005,2006 Masao Mutoh + + You may redistribute it and/or modify it under the same + license terms as Ruby. +=end + +# Extension for String class. This feature is included in Ruby 1.9 or later. +begin + raise ArgumentError if ("a %{x}" % {:x=>'b'}) != 'a b' +rescue ArgumentError + # either we are on vanilla 1.8(call with hash raises ArgumentError) + # or someone else already patched % but did it wrong + class String + alias :_fast_gettext_old_format_m :% # :nodoc: + + PERCENT_MATCH_RE = Regexp.union( + /%%/, + /%\{([-\.\w]+)\}/, + /%<([-\.\w]+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ + ) + + # call-seq: + # %(hash) + # + # Default: "%s, %s" % ["Masao", "Mutoh"] + # Extended: + # "%{firstname}, %{lastname}" % {:firstname=>"Masao",:lastname=>"Mutoh"} == "Masao Mutoh" + # with field type such as d(decimal), f(float), ... + # "%<age>d, %<weight>.1f" % {:age => 10, :weight => 43.4} == "10 43.4" + # This is the recommanded way for Ruby-GetText + # because the translators can understand the meanings of the keys easily. + def %(args) + if args.kind_of? Hash + #stringify keys + replace = {} + args.each{|k,v|replace[k.to_s]=v} + + #replace occurances + ret = dup + ret.gsub!(PERCENT_MATCH_RE) do |match| + if match == '%%' + '%' + elsif $1 + replace.has_key?($1) ? replace[$1] : match + elsif $2 + replace.has_key?($2) ? sprintf("%#{$3}", replace[$2]) : match + end + end + ret + else + ret = gsub(/%([{<])/, '%%\1') + ret._fast_gettext_old_format_m(args) + end + end + end +end + +# 1.9.1 if you misspell a %{key} your whole page would blow up, no thanks... +begin + ("%{b}" % {:a=>'b'}) +rescue KeyError + class String + alias :_fast_gettext_old_format_m :% + def %(*args) + begin + _fast_gettext_old_format_m(*args) + rescue KeyError + self + end + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/aa_unconfigued_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/aa_unconfigued_spec.rb new file mode 100644 index 000000000..7a751107f --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/aa_unconfigued_spec.rb @@ -0,0 +1,21 @@ +require 'spec/spec_helper' + +describe 'unconfigured' do + it "gives a useful error message when trying to just translate" do + FastGettext.text_domain = nil + begin + FastGettext._('x') + "".should == "success!?" + rescue FastGettext::Storage::NoTextDomainConfigured + end + end + + it "gives a useful error message when only locale was set" do + FastGettext.locale = 'de' + begin + FastGettext._('x') + "".should == "success!?" + rescue FastGettext::Storage::NoTextDomainConfigured + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/mo_file_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/mo_file_spec.rb new file mode 100644 index 000000000..f5f2a6d36 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/mo_file_spec.rb @@ -0,0 +1,34 @@ +require 'spec/spec_helper' + +de_file = File.join('spec','locale','de','LC_MESSAGES','test.mo') +de = FastGettext::MoFile.new(de_file) + +describe FastGettext::MoFile do + before :all do + File.exist?(de_file).should == true + end + + it "parses a file" do + de['car'].should == 'Auto' + end + + it "stores untranslated values as nil" do + de['Car|Model'].should == nil + end + + it "finds pluralized values" do + de.plural('Axis','Axis').should == ['Achse','Achsen'] + end + + it "returns singular translations when pluralisation could not be found" do + de.plural('Axis','Axis','Axis').should == ['Achse','Achse','Achse'] + end + + it "returns ids when not plural and singular translations could not be found" do + de.plural('Axis','Axis','NOTFOUND').should == ['Achse','Achse','NOTFOUND'] + end + + it "can access plurals through []" do + de['Axis'].should == 'Achse' #singular + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/storage_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/storage_spec.rb new file mode 100644 index 000000000..8ce59e6c5 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/storage_spec.rb @@ -0,0 +1,313 @@ +require 'spec/spec_helper' + +describe 'Storage' do + include FastGettext::Storage + + before do + #reset everything to nil + self.available_locales = nil + self.default_text_domain = nil + self.default_locale = nil + send(:_locale=,nil)#nil is not allowed to be set... + default_locale.should be_nil + available_locales.should be_nil + locale.should == 'en' + end + + def thread_save(method, value) + send("#{method}=",value) + + # mess around with other threads + 100.times do + Thread.new {FastGettext.send("#{method}=",'en')} + end + + send(method) == value + end + + {:locale=>'de', :available_locales=>['de'], :text_domain=>'xx', :pluralisation_rule=>lambda{|x|x==4}}.each do |method, value| + it "stores #{method} thread-save" do + thread_save(method, value).should == true + end + end + + it "stores translation_repositories non-thread-safe" do + self.translation_repositories[:x]=1 + t = Thread.new{self.translation_repositories[:x]=2} + t.join + self.translation_repositories[:x].should == 2 + end + + describe :pluralisation_rule do + it "defaults to singular-if-1 when it is not set" do + stub!(:current_repository).and_return mock('',:pluralisation_rule=>nil) + self.pluralisation_rule = nil + pluralisation_rule.call(1).should == false + pluralisation_rule.call(0).should == true + pluralisation_rule.call(2).should == true + end + end + + describe :default_locale do + it "stores default_locale non-thread-safe" do + thread_save(:default_locale, 'de').should == false + end + + it "does not overwrite locale" do + self.locale = 'de' + self.default_locale = 'yy' + self.locale.should == 'de' + end + + it "falls back to default if locale is missing" do + self.default_locale = 'yy' + self.locale.should == 'yy' + end + + it "does not set non-available-locales as default" do + self.available_locales = ['xx'] + self.default_locale = 'yy' + self.default_locale.should == nil + end + + it "can set default_locale to nil" do + self.default_locale = 'xx' + self.default_locale = nil + default_locale.should be_nil + end + end + + describe :default_text_domain do + it "stores default_text_domain non-thread-safe" do + thread_save(:default_text_domain, 'xx').should == false + end + + it "uses default_text_domain when text_domain is not set" do + self.text_domain = nil + self.default_text_domain = 'x' + text_domain.should == 'x' + end + + it "does not use default when domain is set" do + self.text_domain = 'x' + self.default_text_domain = 'y' + text_domain.should == 'x' + end + end + + describe :default_available_locales do + after do + self.default_available_locales = nil + end + + it "stores default_available_locales non-thread-safe" do + thread_save(:default_available_locales, 'xx').should == false + end + + it "converts locales to s" do + self.available_locales = [:x] + available_locales.should == ['x'] + end + + it "uses default_available_locales when available_locales is not set" do + self.available_locales = nil + self.default_available_locales = ['x'] + available_locales.should == ['x'] + end + + it "does not use default when available_locales is set" do + self.available_locales = ['x'] + self.default_available_locales = ['y'] + available_locales.should == ['x'] + end + end + + describe :locale do + it "stores everything as long as available_locales is not set" do + self.available_locales = nil + self.locale = 'XXX' + locale.should == 'XXX' + end + + it "is en if no locale and no available_locale were set" do + FastGettext.send(:_locale=,nil) + self.available_locales = nil + locale.should == 'en' + end + + it "does not change the locale if locales was called with nil" do + self.locale = nil + locale.should == 'en' + end + + it "is the first available_locale if one was set" do + self.available_locales = ['de'] + locale.should == 'de' + end + + it "does not store a locale if it is not available" do + self.available_locales = ['de'] + self.locale = 'en' + locale.should == 'de' + end + + it "set_locale returns the old locale if the new could not be set" do + self.locale = 'de' + self.available_locales = ['de'] + self.set_locale('en').should == 'de' + end + + { + 'Opera' => "de-DE,de;q=0.9,en;q=0.8", + 'Firefox' => "de-de,de;q=0.8,en-us;q=0.5,en;q=0.3", + }.each do |browser,accept_language| + it "sets the locale from #{browser} headers" do + FastGettext.available_locales = ['de_DE','de','xx'] + FastGettext.locale = 'xx' + FastGettext.locale = accept_language + FastGettext.locale.should == 'de_DE' + end + end + + it "sets a unimportant locale if it is the only available" do + FastGettext.available_locales = ['en','xx'] + FastGettext.locale = "de-de,de;q=0.8,en-us;q=0.5,en;q=0.3" + FastGettext.locale.should == 'en' + end + + it "sets the locale with the highest wheight" do + FastGettext.available_locales = ['en','de'] + FastGettext.locale = "xx-us;q=0.5,de-de,de;q=0.8,en;q=0.9" + FastGettext.locale.should == 'en' + end + + it "sets the locale from languages" do + FastGettext.available_locales = ['de'] + FastGettext.locale = "xx-us;q=0.5,de-de;q=0.8,en-uk;q=0.9" + FastGettext.locale.should == 'de' + end + + it "sets locale from comma seperated" do + FastGettext.available_locales = ['de_DE','en','xx'] + FastGettext.locale = "de,de-de,en" + FastGettext.locale.should == 'de_DE' + end + end + + describe :silence_errors do + before do + FastGettext.text_domain = 'xxx' + end + + it "raises when a textdomain was empty" do + begin + FastGettext._('x') + "".should == "success!?" + rescue FastGettext::Storage::NoTextDomainConfigured + end + end + + it "can silence erros" do + FastGettext.silence_errors + FastGettext._('x').should == 'x' + end + end + + describe :current_cache do + before do + FastGettext.text_domain = 'xxx' + FastGettext.available_locales = ['de','en'] + FastGettext.locale = 'de' + FastGettext.current_repository.stub!(:"[]").with('abc').and_return 'old' + FastGettext.current_repository.stub!(:"[]").with('unfound').and_return nil + FastGettext._('abc') + FastGettext._('unfound') + FastGettext.locale = 'en' + end + + it "stores a translation seperate by locale" do + FastGettext.current_cache['abc'].should == nil + end + + it "stores a translation seperate by domain" do + FastGettext.locale = 'de' + FastGettext.text_domain = nil + FastGettext.current_cache['abc'].should == nil + end + + it "cache is restored through setting of default_text_domain" do + FastGettext.locale = 'de' + FastGettext.text_domain = nil + FastGettext.default_text_domain = 'xxx' + FastGettext.current_cache['abc'].should == 'old' + end + + it "cache is restored through setting of default_locale" do + FastGettext.send(:_locale=,nil)#reset locale to nil + FastGettext.default_locale = 'de' + FastGettext.locale.should == 'de' + FastGettext.current_cache['abc'].should == 'old' + end + + it "stores a translation permanently" do + FastGettext.locale = 'de' + FastGettext.current_cache['abc'].should == 'old' + end + + it "stores a unfound translation permanently" do + FastGettext.locale = 'de' + FastGettext.current_cache['unfound'].should == false + end + end + + describe :key_exist? do + it "does not find default keys" do + FastGettext._('abcde') + key_exist?('abcde').should be_false + end + + it "finds using the current repository" do + should_receive(:current_repository).and_return '1234'=>'1' + key_exist?('1234').should == true + end + + it "sets the current cache with a found result" do + should_receive(:current_repository).and_return 'xxx'=>'1' + key_exist?('xxx') + current_cache['xxx'].should == '1' + end + + it "does not overwrite an existing cache value" do + current_cache['xxx']='xxx' + stub!(:current_repository).and_return 'xxx'=>'1' + key_exist?('xxx') + current_cache['xxx'].should == 'xxx' + end + + it "is false for gettext meta key" do + key_exist?("").should == false + end + end + + describe :cached_find do + it "is nil for gettext meta key" do + cached_find("").should == false + end + end + + describe FastGettext::Storage::NoTextDomainConfigured do + it "shows what to do" do + FastGettext::Storage::NoTextDomainConfigured.new.to_s.should =~ /FastGettext\.add_text_domain/ + end + + it "warns when text_domain is nil" do + FastGettext.text_domain = nil + FastGettext::Storage::NoTextDomainConfigured.new.to_s.should =~ /\(nil\)/ + end + + it "shows current text_domain" do + FastGettext.text_domain = 'xxx' + FastGettext::Storage::NoTextDomainConfigured.new('xxx').to_s.should =~ /xxx/ + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/base_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/base_spec.rb new file mode 100644 index 000000000..11353f256 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/base_spec.rb @@ -0,0 +1,20 @@ +require 'spec/spec_helper' +require 'fast_gettext/translation_repository/base' + +describe 'FastGettext::TranslationRepository::Base' do + before do + @rep = FastGettext::TranslationRepository::Base.new('x') + end + + it "can be built" do + @rep.available_locales.should == [] + end + + it "cannot translate" do + @rep['car'].should == nil + end + + it "cannot pluralize" do + @rep.plural('Axis','Axis').should == ['Axis','Axis'] + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/chain_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/chain_spec.rb new file mode 100644 index 000000000..1fe405aea --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/chain_spec.rb @@ -0,0 +1,81 @@ +require 'spec/spec_helper' + +class MockRepo + def [](key)#should_receive :[] does not work so well... + singular key + end +end + +describe 'FastGettext::TranslationRepository::Chain' do + describe "empty chain" do + before do + @rep = FastGettext::TranslationRepository.build('chain', :chain=>[], :type=>:chain) + end + + it "has no locales" do + @rep.available_locales.should == [] + end + + it "cannot translate" do + @rep['car'].should == nil + end + + it "cannot pluralize" do + @rep.plural('Axis','Axis').should == [] + end + + it "has no pluralisation rule" do + @rep.pluralisation_rule.should == nil + end + end + + describe "filled chain" do + before do + @one = MockRepo.new + @one.stub!(:singular).with('xx').and_return 'one' + @two = MockRepo.new + @two.stub!(:singular).with('xx').and_return 'two' + @rep = FastGettext::TranslationRepository.build('chain', :chain=>[@one, @two], :type=>:chain) + end + + describe :singular do + it "uses the first repo in the chain if it responds" do + @rep['xx'].should == 'one' + end + + it "uses the second repo in the chain if the first does not respond" do + @one.should_receive(:singular).and_return nil + @rep['xx'].should == 'two' + end + end + + describe :plural do + it "uses the first repo in the chain if it responds" do + @one.should_receive(:plural).with('a','b').and_return ['A','B'] + @rep.plural('a','b').should == ['A','B'] + end + + it "uses the second repo in the chain if the first does not respond" do + @one.should_receive(:plural).with('a','b').and_return [nil,nil] + @two.should_receive(:plural).with('a','b').and_return ['A','B'] + @rep.plural('a','b').should == ['A','B'] + end + end + + describe :available_locales do + it "should be the sum of all added repositories" do + @one.should_receive(:available_locales).and_return ['de'] + @two.should_receive(:available_locales).and_return ['de','en'] + @rep.available_locales.should == ['de','en'] + end + end + + describe :pluralisation_rule do + it "chooses the first that exists" do + @one.should_receive(:pluralisation_rule).and_return nil + @two.should_receive(:pluralisation_rule).and_return 'x' + @rep.pluralisation_rule.should == 'x' + end + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/db_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/db_spec.rb new file mode 100644 index 000000000..42c6bb830 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/db_spec.rb @@ -0,0 +1,70 @@ +require 'spec/spec_helper' + +require 'active_record' +require 'fast_gettext/translation_repository/db' +FastGettext::TranslationRepository::Db.require_models +describe FastGettext::TranslationRepository::Db do + + before :all do + ActiveRecord::Base.establish_connection({ + :adapter => "sqlite3", + :database => ":memory:" + }) + + #create model table + #TODO surpress output ? + ActiveRecord::Schema.define(:version => 1) do + create_table :translation_keys do |t| + t.string :key, :unique=>true, :null=>false + t.timestamps + end + create_table :translation_texts do |t| + t.string :text, :locale + t.integer :translation_key_id, :null=>false + t.timestamps + end + end + end + + before do + TranslationKey.delete_all + TranslationText.delete_all + FastGettext.locale = 'de' + @rep = FastGettext::TranslationRepository::Db.new('x', :model=>TranslationKey) + end + + def create_translation(key, text) + translation_key = TranslationKey.create!(:key=>key) + TranslationText.create!(:translation_key_id=>translation_key.id, :text=>text, :locale=>'de') + end + + it "reads locales from the db" do + locales = ['de','en','es'] + locales.reverse.each do |locale| + TranslationText.create!(:translation_key_id=>1, :text=>'asdasd', :locale=>locale) + end + @rep.available_locales.should == locales + end + + it "has no pluralisation_rule by default" do + @rep.pluralisation_rule.should == nil + end + + it "cannot translate when no models are present" do + @rep['car'].should == nil + end + + it "can translate" do + create_translation 'car', 'Auto' + @rep['car'].should == 'Auto' + end + + it "cannot pluralize when no model is present" do + @rep.plural('Axis','Axis').should == [] + end + + it "can pluralize" do + create_translation 'Axis||||Axis', 'Achse||||Achsen' + @rep.plural('Axis','Axis').should == ['Achse','Achsen'] + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/logger_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/logger_spec.rb new file mode 100644 index 000000000..31fb8884c --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/logger_spec.rb @@ -0,0 +1,40 @@ +require 'spec/spec_helper' + +describe 'FastGettext::TranslationRepository::Logger' do + before do + @callback = lambda{} + @rep = FastGettext::TranslationRepository.build('test', :type=>:logger, :callback=>@callback) + @rep.is_a?(FastGettext::TranslationRepository::Logger).should be_true + end + subject{@rep} + + it{ should have(0).available_locales} + + it "has no pluralisation_rule" do + @rep.pluralisation_rule.should == nil + end + + describe :single do + it "logs every call" do + @callback.should_receive(:call).with('the_key') + @rep['the_key'] + end + + it "returns nil" do + @callback.should_receive(:call).with('the_key').and_return 'something' + @rep['the_key'].should == nil + end + end + + describe :plural do + it "logs every call" do + @callback.should_receive(:call).with(['a','b']) + @rep.plural('a','b') + end + + it "returns an empty array" do + @callback.should_receive(:call).with(['a','b']).and_return 'something' + @rep.plural('a','b').should == [] + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/mo_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/mo_spec.rb new file mode 100644 index 000000000..46e12c255 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/mo_spec.rb @@ -0,0 +1,29 @@ +require 'spec/spec_helper' + +describe 'FastGettext::TranslationRepository::Mo' do + before do + @rep = FastGettext::TranslationRepository.build('test',:path=>File.join('spec', 'locale')) + @rep.is_a?(FastGettext::TranslationRepository::Mo).should be_true + end + + it "can be built" do + @rep.available_locales.sort.should == ['de','en'] + end + + it "can translate" do + FastGettext.locale = 'de' + @rep['car'].should == 'Auto' + end + + it "can pluralize" do + FastGettext.locale = 'de' + @rep.plural('Axis','Axis').should == ['Achse','Achsen'] + end + + it "has access to the mo repositories pluralisation rule" do + FastGettext.locale = 'en' + rep = FastGettext::TranslationRepository.build('plural_test',:path=>File.join('spec','locale')) + rep['car'].should == 'Test'#just check it is loaded correctly + rep.pluralisation_rule.call(2).should == 3 + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/po_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/po_spec.rb new file mode 100644 index 000000000..4d9c868f1 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/po_spec.rb @@ -0,0 +1,53 @@ +require 'spec/spec_helper' + +describe 'FastGettext::TranslationRepository::Po' do + before do + @rep = FastGettext::TranslationRepository.build('test',:path=>File.join('spec','locale'),:type=>:po) + @rep.is_a?(FastGettext::TranslationRepository::Po).should be_true + end + + it "can be built" do + @rep.available_locales.sort.should == ['de','en'] + end + + it "can translate" do + FastGettext.locale = 'de' + @rep['car'].should == 'Auto' + end + + it "can pluralize" do + FastGettext.locale = 'de' + @rep.plural('Axis','Axis').should == ['Achse','Achsen'] + end + + it "has access to the mo repositories pluralisation rule" do + FastGettext.locale = 'en' + rep = FastGettext::TranslationRepository.build('plural_test',:path=>File.join('spec','locale'),:type=>:po) + rep['car'].should == 'Test'#just check it is loaded correctly + rep.pluralisation_rule.call(2).should == 3 + end + + describe 'fuzzy' do + it "should warn on fuzzy by default" do + $stderr.should_receive(:print).at_least(:once) + FastGettext::TranslationRepository.build('test',:path=>File.join('spec','fuzzy_locale'),:type=>:po) + end + + it "should ignore fuzzy when told to do so" do + $stderr.should_not_receive(:print) + FastGettext::TranslationRepository.build('test',:path=>File.join('spec','fuzzy_locale'),:type=>:po, :ignore_fuzzy => true) + end + end + + describe 'obsolete' do + it "should warn on obsolete by default" do + $stderr.should_receive(:print).at_least(:once) + FastGettext::TranslationRepository.build('test',:path=>File.join('spec','obsolete_locale'),:type=>:po) + end + + it "should ignore obsolete when told to do so" do + $stderr.should_not_receive(:print) + FastGettext::TranslationRepository.build('test',:path=>File.join('spec','obsolete_locale'),:type=>:po, :ignore_obsolete => true) + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/yaml_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/yaml_spec.rb new file mode 100644 index 000000000..2229d48c5 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository/yaml_spec.rb @@ -0,0 +1,61 @@ +require 'spec/spec_helper' + +describe 'FastGettext::TranslationRepository::Yaml' do + before do + FastGettext.pluralisation_rule = nil + @rep = FastGettext::TranslationRepository.build('test', :path => File.join('spec', 'locale', 'yaml'), :type => :yaml) + @rep.is_a?(FastGettext::TranslationRepository::Yaml).should be_true + FastGettext.locale = 'de' + end + + it "can be built" do + @rep.available_locales.sort.should == ['de', 'en'] + end + + it "translates nothing when locale is unsupported" do + FastGettext.locale = 'xx' + @rep['simple'].should == nil + end + + it "does not translated categories" do + @rep['cars'].should == nil + end + + it "can translate simple" do + @rep['simple'].should == 'einfach' + end + + it "can translate nested" do + @rep['cars.car'].should == 'Auto' + end + + it "can pluralize" do + @rep.plural('cars.axis').should == ['Achse', 'Achsen', nil, nil] + end + + it "handles unfound plurals with nil" do + @rep.plural('cars.xxx').should == [nil, nil, nil, nil] + end + + it "can be used to translate plural forms" do + FastGettext.stub!(:current_repository).and_return @rep + FastGettext.n_('cars.axis','cars.axis',2).should == 'Achsen' + FastGettext.n_('cars.axis',2).should == 'Achsen' + FastGettext.n_('cars.axis',1).should == 'Achse' + end + + 4.times do |i| + it "can be used to do wanky pluralisation rules #{i}" do + FastGettext.stub!(:current_repository).and_return @rep + @rep.stub!(:pluralisation_rule).and_return lambda{i} + FastGettext.n_('cars.silly',1).should == i.to_s # cars.silly translations are 0,1,2,3 + end + end + + it "can use custom pluraliztion rules" do + FastGettext.locale = 'en' + {0 => 0, 1 => 1, 2 => 2, 3 => 0}.each do |input, expected| + @rep.pluralisation_rule.call(input).should == expected + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository_spec.rb new file mode 100644 index 000000000..b343760e2 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_repository_spec.rb @@ -0,0 +1,33 @@ +require 'spec/spec_helper' + +module FastGettext + module TranslationRepository + class Dummy + attr_accessor :name, :options + def initialize(name, options) + @name = name + @options = options + end + end + end +end + +describe FastGettext::TranslationRepository do + describe "build" do + it "auto requires class by default" do + lambda { FastGettext::TranslationRepository.build('xx', { :type => 'invalid'}) }.should raise_error(LoadError) + end + + it "can have auto-require disabled" do + FastGettext::TranslationRepository.build('xx', { :type => 'dummy' }) + end + + it "makes a new repository" do + options = { :type => 'dummy', :external => true } + repo = FastGettext::TranslationRepository.build('xx', options) + repo.class.should == FastGettext::TranslationRepository::Dummy + repo.name.should == 'xx' + repo.options.should == options + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_spec.rb new file mode 100644 index 000000000..db2248148 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/translation_spec.rb @@ -0,0 +1,158 @@ +require 'spec/spec_helper' + +describe FastGettext::Translation do + include FastGettext::Translation + + before do + default_setup + end + + describe "unknown locale" do + before do + FastGettext.available_locales = nil + FastGettext.locale = 'xx' + end + + it "does not translate" do + _('car').should == 'car' + end + + it "does not translate plurals" do + n_('car','cars',2).should == 'cars' + end + end + + describe :_ do + it "translates simple text" do + _('car').should == 'Auto' + end + + it "returns key if not translation was found" do + _('NOT|FOUND').should == 'NOT|FOUND' + end + + it "does not return the gettext meta information" do + _('').should == '' + end + end + + describe :n_ do + before do + FastGettext.pluralisation_rule = nil + end + + it "translates pluralized" do + n_('Axis','Axis',1).should == 'Achse' + n_('Axis','Axis',2).should == 'Achsen' + n_('Axis','Axis',0).should == 'Achsen' + end + + describe "pluralisations rules" do + it "supports abstract pluralisation rules" do + FastGettext.pluralisation_rule = lambda{|n|2} + n_('a','b','c','d',4).should == 'c' + end + + it "supports false as singular" do + FastGettext.pluralisation_rule = lambda{|n|n!=2} + n_('singular','plural','c','d',2).should == 'singular' + end + + it "supports true as plural" do + FastGettext.pluralisation_rule = lambda{|n|n==2} + n_('singular','plural','c','d',2).should == 'plural' + end + end + + it "returns the appropriate key if no translation was found" do + n_('NOTFOUND','NOTFOUNDs',1).should == 'NOTFOUND' + n_('NOTFOUND','NOTFOUNDs',2).should == 'NOTFOUNDs' + end + + it "returns the last key when no translation was found and keys where to short" do + FastGettext.pluralisation_rule = lambda{|x|4} + n_('Apple','Apples',2).should == 'Apples' + end + end + + describe :s_ do + it "translates simple text" do + s_('car').should == 'Auto' + end + + it "returns cleaned key if a translation was not found" do + s_("XXX|not found").should == "not found" + end + + it "can use a custom seperator" do + s_("XXX/not found",'/').should == "not found" + end + end + + describe :N_ do + it "returns the key" do + N_('XXXXX').should == 'XXXXX' + end + end + + describe :Nn_ do + it "returns the keys as array" do + Nn_('X','Y').should == ['X','Y'] + end + end + + describe :ns_ do + it "translates whith namespace" do + ns_('Fruit|Apple','Fruit|Apples',2).should == 'Apples' + end + end + + + describe :caching do + describe :cache_hit do + before do + FastGettext.translation_repositories.replace({}) + #singular cache keys + FastGettext.current_cache['xxx'] = '1' + + #plural cache keys + FastGettext.current_cache['||||xxx'] = ['1','2'] + FastGettext.current_cache['||||xxx||||yyy'] = ['1','2'] + end + + it "uses the cache when translating with _" do + _('xxx').should == '1' + end + + it "uses the cache when translating with s_" do + s_('xxx').should == '1' + end + + it "uses the cache when translating with n_" do + n_('xxx','yyy',1).should == '1' + end + + it "uses the cache when translating with n_ and single argument" do + n_('xxx',1).should == '1' + end + end + + it "caches different locales seperatly" do + FastGettext.locale = 'en' + _('car').should == 'car' + FastGettext.locale = 'de' + _('car').should == 'Auto' + end + + it "caches different textdomains seperatly" do + _('car').should == 'Auto' + + FastGettext.translation_repositories['fake'] = {} + FastGettext.text_domain = 'fake' + _('car').should == 'car' + + FastGettext.text_domain = 'test' + _('car').should == 'Auto' + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/vendor/fake_load_path/iconv.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/vendor/fake_load_path/iconv.rb new file mode 100644 index 000000000..82e68d4dc --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/vendor/fake_load_path/iconv.rb @@ -0,0 +1,2 @@ +#simulate file not found +raise LoadError
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/vendor/iconv_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/vendor/iconv_spec.rb new file mode 100644 index 000000000..9be73fbb7 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/vendor/iconv_spec.rb @@ -0,0 +1,33 @@ + +describe 'Iconv' do + before do + @fake_load_path = File.join('spec','fast_gettext','vendor','fake_load_path') + end + + after do + $LOAD_PATH.delete @fake_load_path + end + + it "also works when Iconv was not found locally" do + #prepare load path + $LOAD_PATH.unshift @fake_load_path + test = 1 + begin + require 'iconv' + rescue LoadError + test = 2 + end + test.should == 2 + + #load fast_gettext + require 'fast_gettext' + + FastGettext.add_text_domain('test',:path=>File.join('spec','locale')) + FastGettext.text_domain = 'test' + FastGettext.available_locales = ['en','de'] + FastGettext.locale = 'de' + + #translate + FastGettext._('car').should == 'Auto' + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/vendor/string_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/vendor/string_spec.rb new file mode 100644 index 000000000..825e54aad --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext/vendor/string_spec.rb @@ -0,0 +1,86 @@ +require 'spec/spec_helper' + +#just to make sure we did not mess up while copying... +describe String do + before :all do + if "i18n gem overwrites % method".respond_to?(:interpolate_without_ruby_19_syntax) + class String + def %(*args) + interpolate_without_ruby_19_syntax(*args) + end + end + end + end + + it "does not translate twice" do + ("%{a} %{b}" % {:a=>'%{b}',:b=>'c'}).should == '%{b} c' + end + + describe "old % style replacement" do + it "substitudes using % + Hash" do + ("x%{name}y" %{:name=>'a'}).should == 'xay' + end + + it "does not substitute after %%" do + ("%%{num} oops" % {:num => 1}).should == '%{num} oops' + end + + it "does not substitute when nothing could be found" do + ("abc" % {:x=>1}).should == 'abc' + end + + if RUBY_VERSION < '1.9' # this does not longer work in 1.9, use :"my weird string" + it "sustitutes strings" do + ("a%{b}c" % {'b'=>1}).should == 'a1c' + end + + it "sustitutes strings with -" do + ("a%{b-a}c" % {'b-a'=>1}).should == 'a1c' + end + + it "sustitutes string with ." do + ("a%{b.a}c" % {'b.a'=>1}).should == 'a1c' + end + + it "sustitutes string with number" do + ("a%{1}c" % {'1'=>1}).should == 'a1c' + end + end + end + + describe 'old sprintf style' do + it "substitudes using % + Array" do + ("x%sy%s" % ['a','b']).should == 'xayb' + end + + if RUBY_VERSION < '1.9' # this does not longer work in 1.9, ArgumentError is raised + it "does not remove %{} style replacements" do + ("%{name} x%sy%s" % ['a','b']).should == '%{name} xayb' + end + + it "does not remove %<> style replacement" do + ("%{name} %<num>f %s" % ['x']).should == "%{name} %<num>f x" + end + end + end + + describe 'ruby 1.9 style %< replacement' do + it "does not substitute after %%" do + ("%%<num> oops" % {:num => 1}).should == '%<num> oops' + end + + it "subsitutes %<something>d" do + ("x%<hello>dy" % {:hello=>1}).should == 'x1y' + end + + it "substitutes #b" do + ("%<num>#b" % {:num => 1}).should == "0b1" + end + end + + if RUBY_VERSION >= '1.9' + it "does not raise when key was not found" do + ("%{typo} xxx" % {:something=>1}).should == "%{typo} xxx" + end + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext_spec.rb b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext_spec.rb new file mode 100644 index 000000000..dc7ff494e --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fast_gettext_spec.rb @@ -0,0 +1,43 @@ +require 'spec/spec_helper' + +default_setup +class IncludeTest + include FastGettext::Translation + @@xx = _('car') + def self.ext + _('car') + end + def inc + _('car') + end + def self.xx + @@xx + end +end + +describe FastGettext do + include FastGettext + before :all do + default_setup + end + + it "provides access to FastGettext::Translations methods" do + FastGettext._('car').should == 'Auto' + _('car').should == 'Auto' + s_("XXX|not found").should == "not found" + n_('Axis','Axis',1).should == 'Achse' + N_('XXXXX').should == 'XXXXX' + Nn_('X','Y').should == ['X','Y'] + end + + it "is extended to a class and included into a class" do + IncludeTest.ext.should == 'Auto' + IncludeTest.ext.should == 'Auto' + IncludeTest.new.inc.should == 'Auto' + IncludeTest.xx.should == 'Auto' + end + + it "has a VERSION" do + FastGettext::VERSION.should =~ /^\d+\.\d+\.\d+$/ + end +end
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/fuzzy_locale/de/test.po b/vendor/gems/fast_gettext-0.5.10/spec/fuzzy_locale/de/test.po new file mode 100644 index 000000000..c5e420976 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/fuzzy_locale/de/test.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: version 0.0.1\n" +"POT-Creation-Date: 2009-02-26 19:50+0100\n" +"PO-Revision-Date: 2009-02-18 14:53+0100\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: app/helpers/translation_helper.rb:3 +# fuzzy +msgid "%{relative_time} ago" +msgstr "vor %{relative_time}"
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/locale/de/LC_MESSAGES/test.mo b/vendor/gems/fast_gettext-0.5.10/spec/locale/de/LC_MESSAGES/test.mo Binary files differnew file mode 100644 index 000000000..674f7605c --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/locale/de/LC_MESSAGES/test.mo diff --git a/vendor/gems/fast_gettext-0.5.10/spec/locale/de/test.po b/vendor/gems/fast_gettext-0.5.10/spec/locale/de/test.po new file mode 100644 index 000000000..76161dd2f --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/locale/de/test.po @@ -0,0 +1,61 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: version 0.0.1\n" +"POT-Creation-Date: 2009-02-26 19:50+0100\n" +"PO-Revision-Date: 2009-02-18 14:53+0100\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: app/helpers/translation_helper.rb:3 +msgid "%{relative_time} ago" +msgstr "vor %{relative_time}" + +#: app/views/cars/show.html.erb:5 +msgid "Axis" +msgid_plural "Axis" +msgstr[0] "Achse" +msgstr[1] "Achsen" + +#: app/controllers/cars_controller.rb:47 +msgid "Car was successfully created." +msgstr "Auto wurde erfolgreich gespeichert" + +#: app/controllers/cars_controller.rb:64 +msgid "Car was successfully updated." +msgstr "Auto wurde erfolgreich aktualisiert" + +#: app/views/cars/show.html.erb:1 locale/model_attributes.rb:3 +msgid "Car|Model" +msgstr "Modell" + +#: app/views/cars/show.html.erb:3 locale/model_attributes.rb:4 +msgid "Car|Wheels count" +msgstr "Räderzahl" + +#: app/views/cars/show.html.erb:7 +msgid "Created" +msgstr "Erstellt" + +#: app/views/cars/show.html.erb:9 +msgid "Month" +msgstr "Monat" + +#: locale/model_attributes.rb:2 +msgid "car" +msgstr "Auto" + +#: locale/testlog_phrases.rb:2 +msgid "this is a dynamic translation which was found thorugh gettext_test_log!" +msgstr "" +"Dies ist eine dynamische Übersetzung, die durch gettext_test_log " +"gefunden wurde!" diff --git a/vendor/gems/fast_gettext-0.5.10/spec/locale/en/LC_MESSAGES/plural_test.mo b/vendor/gems/fast_gettext-0.5.10/spec/locale/en/LC_MESSAGES/plural_test.mo Binary files differnew file mode 100644 index 000000000..f4a8756af --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/locale/en/LC_MESSAGES/plural_test.mo diff --git a/vendor/gems/fast_gettext-0.5.10/spec/locale/en/LC_MESSAGES/test.mo b/vendor/gems/fast_gettext-0.5.10/spec/locale/en/LC_MESSAGES/test.mo Binary files differnew file mode 100644 index 000000000..62dfcf939 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/locale/en/LC_MESSAGES/test.mo diff --git a/vendor/gems/fast_gettext-0.5.10/spec/locale/en/plural_test.po b/vendor/gems/fast_gettext-0.5.10/spec/locale/en/plural_test.po new file mode 100644 index 000000000..611baadf4 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/locale/en/plural_test.po @@ -0,0 +1,20 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: version 0.0.1\n" +"POT-Creation-Date: 2009-02-26 19:50+0100\n" +"PO-Revision-Date: 2009-02-18 15:42+0100\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n==2?3:4;\n" + +msgid "car" +msgstr "Test"
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/locale/en/test.po b/vendor/gems/fast_gettext-0.5.10/spec/locale/en/test.po new file mode 100644 index 000000000..07b8136fb --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/locale/en/test.po @@ -0,0 +1,59 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: version 0.0.1\n" +"POT-Creation-Date: 2009-02-26 19:50+0100\n" +"PO-Revision-Date: 2009-02-18 15:42+0100\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: app/helpers/translation_helper.rb:3 +msgid "%{relative_time} ago" +msgstr "" + +#: app/views/cars/show.html.erb:5 +msgid "Axis" +msgid_plural "Axis" +msgstr[0] "" +msgstr[1] "" + +#: app/controllers/cars_controller.rb:47 +msgid "Car was successfully created." +msgstr "" + +#: app/controllers/cars_controller.rb:64 +msgid "Car was successfully updated." +msgstr "" + +#: app/views/cars/show.html.erb:1 locale/model_attributes.rb:3 +msgid "Car|Model" +msgstr "" + +#: app/views/cars/show.html.erb:3 locale/model_attributes.rb:4 +msgid "Car|Wheels count" +msgstr "" + +#: app/views/cars/show.html.erb:7 +msgid "Created" +msgstr "" + +#: app/views/cars/show.html.erb:9 +msgid "Month" +msgstr "" + +#: locale/model_attributes.rb:2 +msgid "car" +msgstr "" + +#: locale/testlog_phrases.rb:2 +msgid "this is a dynamic translation which was found thorugh gettext_test_log!" +msgstr "" diff --git a/vendor/gems/fast_gettext-0.5.10/spec/locale/yaml/de.yml b/vendor/gems/fast_gettext-0.5.10/spec/locale/yaml/de.yml new file mode 100644 index 000000000..08aa77eb7 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/locale/yaml/de.yml @@ -0,0 +1,25 @@ +de: + simple: einfach + date: + relative: "vor %{relative_time}" + + cars: + axis: + one: "Achse" + other: "Achsen" + silly: + one: '0' + other: '1' + plural2: '2' + plural3: '3' + model: "Modell" + wheel_count: "Räderzahl" + created: "Erstellt" + month: "Monat" + car: "Auto" + messages: + created: "Auto wurde erfolgreich gespeichert" + updated: "Auto wurde erfolgreich aktualisiert" + + test_log: + phrases: "Dies ist eine dynamische Übersetzung, die durch gettext_test_log gefunden wurde!" diff --git a/vendor/gems/fast_gettext-0.5.10/spec/locale/yaml/en.yml b/vendor/gems/fast_gettext-0.5.10/spec/locale/yaml/en.yml new file mode 100644 index 000000000..4029e968e --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/locale/yaml/en.yml @@ -0,0 +1,21 @@ +en: + pluralisation_rule: n<3?n:0 + simple: easy + date: + relative: "%{relative_time} ago" + + cars: + axis: + one: "Axis" + other: "Axis" + model: "Model" + wheel_count: "Wheels count" + created: "Created" + month: "Month" + car: "Car" + messages: + created: "Car was successfully created." + updated: "Car was successfully updated." + + test_log: + phrases: "this is a dynamic translation which was found thorugh gettext_test_log!" diff --git a/vendor/gems/fast_gettext-0.5.10/spec/locale/yaml/notfound.yml b/vendor/gems/fast_gettext-0.5.10/spec/locale/yaml/notfound.yml new file mode 100644 index 000000000..622bb1bda --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/locale/yaml/notfound.yml @@ -0,0 +1,2 @@ +xx: + simple: FUUUU
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/obsolete_locale/de/test.po b/vendor/gems/fast_gettext-0.5.10/spec/obsolete_locale/de/test.po new file mode 100644 index 000000000..70ef1a59a --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/obsolete_locale/de/test.po @@ -0,0 +1,21 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: version 0.0.1\n" +"POT-Creation-Date: 2009-02-26 19:50+0100\n" +"PO-Revision-Date: 2009-02-18 14:53+0100\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: app/helpers/translation_helper.rb:3 +#~ msgid "%{relative_time} ago" +#~ msgstr "vor %{relative_time}"
\ No newline at end of file diff --git a/vendor/gems/fast_gettext-0.5.10/spec/spec_helper.rb b/vendor/gems/fast_gettext-0.5.10/spec/spec_helper.rb new file mode 100644 index 000000000..8987b88a3 --- /dev/null +++ b/vendor/gems/fast_gettext-0.5.10/spec/spec_helper.rb @@ -0,0 +1,26 @@ +# ---- requirements +require 'rubygems' +$LOAD_PATH.unshift File.expand_path("../lib", File.dirname(__FILE__)) +require 'fast_gettext' + +# ---- revert to defaults +Spec::Runner.configure do |config| + config.before :all do + FastGettext.locale = 'de' + FastGettext.available_locales = nil + end +end + +# ---- Helpers +def pending_it(text,&block) + it text do + pending(&block) + end +end + +def default_setup + FastGettext.add_text_domain('test',:path=>File.join(File.dirname(__FILE__),'locale')) + FastGettext.text_domain = 'test' + FastGettext.available_locales = ['en','de'] + FastGettext.locale = 'de' +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/Rakefile b/vendor/plugins/gettext_i18n_rails/Rakefile new file mode 100644 index 000000000..ac396d4d4 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/Rakefile @@ -0,0 +1,25 @@ +require "rspec/core/rake_task" +RSpec::Core::RakeTask.new(:spec) do |t| + t.rspec_opts = '--backtrace --color' +end + +task :default do + puts `rake spec VERSION=2.3.10 RSPEC_COLOR=1` + puts `rake spec VERSION=3.0.3 RSPEC_COLOR=1` +end + +begin + require 'jeweler' + Jeweler::Tasks.new do |gem| + gem.name = 'gettext_i18n_rails' + gem.summary = "Simple FastGettext Rails integration." + gem.email = "grosser.michael@gmail.com" + gem.homepage = "http://github.com/grosser/#{gem.name}" + gem.authors = ["Michael Grosser"] + gem.add_dependency 'fast_gettext' + end + + Jeweler::GemcutterTasks.new +rescue LoadError + puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler" +end diff --git a/vendor/plugins/gettext_i18n_rails/Readme.md b/vendor/plugins/gettext_i18n_rails/Readme.md new file mode 100644 index 000000000..d3e11845f --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/Readme.md @@ -0,0 +1,215 @@ +[FastGettext](http://github.com/grosser/fast_gettext) / Rails integration. + +Translate via FastGettext, use any other I18n backend as extension/fallback. + +Rails does: `I18n.t('syntax.with.lots.of.dots')` with nested yml files +We do: `_('Just translate my damn text!')` with simple, flat mo/po/yml files or directly from db +To use I18n calls add a `syntax.with.lots.of.dots` translation. + +[See it working in the example application.](https://github.com/grosser/gettext_i18n_rails_example) + +Setup +===== +### Installation + +#### Rails 3 + +##### As plugin: + + rails plugin install git://github.com/grosser/gettext_i18n_rails.git + + # Gemfile + gem 'fast_gettext', '>=0.4.8' + +##### As gem: + + # Gemfile + gem 'gettext_i18n_rails' + +##### Optional: +If you want to find translations or build .mo files + # Gemfile + gem 'gettext', '>=1.9.3', :require => false, :group => :development + +#### Rails 2 + +##### As plugin: + + script/plugin install git://github.com/grosser/gettext_i18n_rails.git + sudo gem install fast_gettext + + # config/environment.rb + config.gem "fast_gettext", :version => '>=0.4.8' + +##### As gem: + + gem install gettext_i18n_rails + + # config/environment.rb + config.gem 'gettext_i18n_rails' + + #Rakefile + begin + require "gettext_i18n_rails/tasks" + rescue LoadError + puts "gettext_i18n_rails is not installed, you probably should run 'rake gems:install' or 'bundle install'." + end + +##### Optional: +If you want to find translations or build .mo files + # config/environments/development.rb + config.gem "gettext", :version => '>=1.9.3', :lib => false + +### Locales & initialisation +Copy default locales with dates/sentence-connectors/AR-errors you want from e.g. +[rails i18n](http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale/) into 'config/locales' + +To initialize: + + # config/initializers/fast_gettext.rb + FastGettext.add_text_domain 'app', :path => 'locale', :type => :po + FastGettext.default_available_locales = ['en','de'] #all you want to allow + FastGettext.default_text_domain = 'app' + +And in your application: + + # app/controllers/application_controller.rb + class ApplicationController < ... + before_filter :set_gettext_locale + +Translating +=========== +Performance is almost the same for all backends since translations are cached after first use. + +### Option A: .po files + + FastGettext.add_text_domain 'app', :path => 'locale', :type => :po + + - use some _('translations') + - run `rake gettext:find`, to let GetText find all translations used + - (optional) run `rake gettext:store_model_attributes`, to parse the database for columns that can be translated + - if this is your first translation: `cp locale/app.pot locale/de/app.po` for every locale you want to use + - translate messages in 'locale/de/app.po' (leave msgstr blank and msgstr == msgid) + +New translations will be marked "fuzzy", search for this and remove it, so that they will be used. +Obsolete translations are marked with ~#, they usually can be removed since they are no longer needed + +#### Unfound translations with rake gettext:find +Dynamic translations like `_("x"+"u")` cannot be fond. You have 4 options: + + - add `N_('xu')` somewhere else in the code, so the parser sees it + - add `N_('xu')` in a totally separate file like `locale/unfound_translations.rb`, so the parser sees it + - use the [gettext_test_log rails plugin ](http://github.com/grosser/gettext_test_log) to find all translations that where used while testing + - add a Logger to a translation Chain, so every unfound translations is logged ([example]((http://github.com/grosser/fast_gettext))) + +### Option B: Traditional .po/.mo files + + FastGettext.add_text_domain 'app', :path => 'locale' + + - follow Option A + - run `rake gettext:pack` to write binary GetText .mo files + +### Option C: Database +Most scalable method, all translators can work simultaneously and online. + +Easiest to use with the [translation database Rails engine](http://github.com/grosser/translation_db_engine). +Translations can be edited under `/translation_keys` + + FastGettext::TranslationRepository::Db.require_models + FastGettext.add_text_domain 'app', :type => :db, :model => TranslationKey + +I18n +==== + I18n.locale <==> FastGettext.locale.to_sym + I18n.locale = :de <==> FastGettext.locale = 'de' + +Any call to I18n that matches a gettext key will be translated through FastGettext. + +Namespaces +========== +Car|Model means Model in namespace Car. +You do not have to translate this into english "Model", if you use the +namespace-aware translation + s_('Car|Model') == 'Model' #when no translation was found + +XSS / html_safe +=============== +If you trust your translators and all your usages of % on translations:<br/> + # config/environment.rb + GettextI18nRails.translations_are_html_safe = true + +String % vs html_safe is buggy (can be used for XSS on 1.8 and is always non-safe in 1.9)<br/> +My recommended fix is: `require 'gettext_i18n_rails/string_interpolate_fix'` + + - safe stays safe (escape added strings) + - unsafe stays unsafe (do not escape added strings) + +ActiveRecord - error messages +============================= +ActiveRecord error messages are translated through Rails::I18n, but +model names and model attributes are translated through FastGettext. +Therefore a validation error on a BigCar's wheels_size needs `_('big car')` and `_('BigCar|Wheels size')` +to display localized. + +The model/attribute translations can be found through `rake gettext:store_model_attributes`, +(which ignores some commonly untranslated columns like id,type,xxx_count,...). + +Error messages can be translated through FastGettext, if the ':message' is a translation-id or the matching Rails I18n key is translated. + +####Option A: +Define a translation for "I need my rating!" and use it as message. + validates_inclusion_of :rating, :in=>1..5, :message=>N_('I need my rating!') + +####Option B: + validates_inclusion_of :rating, :in=>1..5 +Make a translation for the I18n key: `activerecord.errors.models.rating.attributes.rating.inclusion` + +####Option C: +Add a translation to each config/locales/*.yml files + en: + activerecord: + errors: + models: + rating: + attributes: + rating: + inclusion: " -- please choose!" +The [rails I18n guide](http://guides.rubyonrails.org/i18n.html) can help with Option B and C. + +Plurals +======= +FastGettext supports pluralization + n_('Apple','Apples',3) == 'Apples' + +Abnormal plurals like e.g. Polish that has 4 different can also be addressed, see [FastGettext Readme](http://github.com/grosser/fast_gettext) + +Customizing list of translatable files +====================================== +When you run + + rake gettext:find + +by default the following files are going to be scanned for translations: {app,lib,config,locale}/**/*.{rb,erb,haml}. If +you want to specify a different list, you can redefine files_to_translate in the gettext namespace in a file like +lib/tasks/gettext.rake: + + namespace :gettext do + def files_to_translate + Dir.glob("{app,lib,config,locale}/**/*.{rb,erb,haml,rhtml}") + end + end + +[Contributors](http://github.com/grosser/gettext_i18n_rails/contributors) +====== + - [ruby gettext extractor](http://github.com/retoo/ruby_gettext_extractor/tree/master) from [retoo](http://github.com/retoo) + - [Paul McMahon](http://github.com/pwim) + - [Duncan Mac-Vicar P](http://duncan.mac-vicar.com/blog) + - [Ramihajamalala Hery](http://my.rails-royce.org) + - [J. Pablo Fernández](http://pupeno.com) + - [Anh Hai Trinh](http://blog.onideas.ws) + - [ed0h](http://github.com/ed0h) + - [Nikos Dimitrakopoulos](http://blog.nikosd.com) + +[Michael Grosser](http://grosser.it)<br/> +grosser.michael@gmail.com<br/> +Hereby placed under public domain, do what you want, just do not hold me accountable... diff --git a/vendor/plugins/gettext_i18n_rails/VERSION b/vendor/plugins/gettext_i18n_rails/VERSION new file mode 100644 index 000000000..dd767842d --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/VERSION @@ -0,0 +1 @@ +0.2.17
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/gettext_i18n_rails.gemspec b/vendor/plugins/gettext_i18n_rails/gettext_i18n_rails.gemspec new file mode 100644 index 000000000..002b3ba0b --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/gettext_i18n_rails.gemspec @@ -0,0 +1,65 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = %q{gettext_i18n_rails} + s.version = "0.2.17" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Michael Grosser"] + s.date = %q{2011-02-17} + s.email = %q{grosser.michael@gmail.com} + s.files = [ + "Rakefile", + "Readme.md", + "VERSION", + "gettext_i18n_rails.gemspec", + "init.rb", + "lib/gettext_i18n_rails.rb", + "lib/gettext_i18n_rails/action_controller.rb", + "lib/gettext_i18n_rails/active_record.rb", + "lib/gettext_i18n_rails/backend.rb", + "lib/gettext_i18n_rails/haml_parser.rb", + "lib/gettext_i18n_rails/html_safe_translations.rb", + "lib/gettext_i18n_rails/i18n_hacks.rb", + "lib/gettext_i18n_rails/model_attributes_finder.rb", + "lib/gettext_i18n_rails/railtie.rb", + "lib/gettext_i18n_rails/ruby_gettext_extractor.rb", + "lib/gettext_i18n_rails/string_interpolate_fix.rb", + "lib/gettext_i18n_rails/tasks.rb", + "lib/tasks/gettext_rails_i18n.rake", + "spec/gettext_i18n_rails/action_controller_spec.rb", + "spec/gettext_i18n_rails/active_record_spec.rb", + "spec/gettext_i18n_rails/backend_spec.rb", + "spec/gettext_i18n_rails/string_interpolate_fix_spec.rb", + "spec/gettext_i18n_rails_spec.rb", + "spec/spec_helper.rb" + ] + s.homepage = %q{http://github.com/grosser/gettext_i18n_rails} + s.require_paths = ["lib"] + s.rubygems_version = %q{1.4.2} + s.summary = %q{Simple FastGettext Rails integration.} + s.test_files = [ + "spec/gettext_i18n_rails/action_controller_spec.rb", + "spec/gettext_i18n_rails/active_record_spec.rb", + "spec/gettext_i18n_rails/backend_spec.rb", + "spec/gettext_i18n_rails/string_interpolate_fix_spec.rb", + "spec/gettext_i18n_rails_spec.rb", + "spec/spec_helper.rb" + ] + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q<fast_gettext>, [">= 0"]) + else + s.add_dependency(%q<fast_gettext>, [">= 0"]) + end + else + s.add_dependency(%q<fast_gettext>, [">= 0"]) + end +end + diff --git a/vendor/plugins/gettext_i18n_rails/init.rb b/vendor/plugins/gettext_i18n_rails/init.rb new file mode 100644 index 000000000..d218eee63 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/init.rb @@ -0,0 +1,14 @@ +begin + require 'config/initializers/session_store' +rescue LoadError + # weird bug, when run with rake rails reports error that session + # store is not configured, this fixes it somewhat... +end + +if Rails::VERSION::MAJOR > 2 + require 'gettext_i18n_rails' +else + #requires fast_gettext to be present. + #We give rails a chance to install it using rake gems:install, by loading it later. + config.after_initialize { require 'gettext_i18n_rails' } +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails.rb new file mode 100644 index 000000000..6bf342bf3 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails.rb @@ -0,0 +1,27 @@ +module GettextI18nRails + VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip + + extend self +end + +require 'fast_gettext' +if Gem::Version.new(FastGettext::VERSION) < Gem::Version.new("0.4.8") + raise "Please upgrade fast_gettext" +end + +# include translations into all the places it needs to go... +Object.send(:include, FastGettext::Translation) + +# make translations html_safe if possible and wanted +if "".respond_to?(:html_safe?) + require 'gettext_i18n_rails/html_safe_translations' + Object.send(:include, GettextI18nRails::HtmlSafeTranslations) +end + +require 'gettext_i18n_rails/backend' +I18n.backend = GettextI18nRails::Backend.new + +require 'gettext_i18n_rails/i18n_hacks' +require 'gettext_i18n_rails/active_record' if defined?(ActiveRecord) +require 'gettext_i18n_rails/action_controller' if defined?(ActionController) # so that bundle console can work in a rails project +require 'gettext_i18n_rails/railtie' diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/action_controller.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/action_controller.rb new file mode 100644 index 000000000..f5871bcc6 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/action_controller.rb @@ -0,0 +1,6 @@ +class ActionController::Base + def set_gettext_locale + requested_locale = params[:locale] || session[:locale] || cookies[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'] + session[:locale] = FastGettext.set_locale(requested_locale) + end +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/active_record.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/active_record.rb new file mode 100644 index 000000000..9b238ac91 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/active_record.rb @@ -0,0 +1,21 @@ +class ActiveRecord::Base + # CarDealer.sales_count -> s_('CarDealer|Sales count') -> 'Sales count' if no translation was found + def self.human_attribute_name(attribute, *args) + s_(gettext_translation_for_attribute_name(attribute)) + end + + # CarDealer -> _('car dealer') + def self.human_name(*args) + _(self.human_name_without_translation) + end + + def self.human_name_without_translation + self.to_s.underscore.gsub('_',' ') + end + + private + + def self.gettext_translation_for_attribute_name(attribute) + "#{self}|#{attribute.to_s.split('.').map! {|a| a.gsub('_',' ').capitalize }.join('|')}" + end +end diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/backend.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/backend.rb new file mode 100644 index 000000000..10cf0a8c2 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/backend.rb @@ -0,0 +1,63 @@ +module GettextI18nRails + #translates i18n calls to gettext calls + class Backend + @@translate_defaults = true + cattr_accessor :translate_defaults + attr_accessor :backend + + def initialize(*args) + self.backend = I18n::Backend::Simple.new(*args) + end + + def available_locales + FastGettext.available_locales || [] + end + + def translate(locale, key, options) + if gettext_key = gettext_key(key, options) + translation = FastGettext._(gettext_key) + interpolate(translation, options) + else + backend.translate locale, key, options + end + end + + def method_missing(method, *args) + backend.send(method, *args) + end + + protected + + def gettext_key(key, options) + flat_key = flatten_key key, options + if FastGettext.key_exist?(flat_key) + flat_key + elsif self.class.translate_defaults + [*options[:default]].each do |default| + #try the scoped(more specific) key first e.g. 'activerecord.errors.my custom message' + flat_key = flatten_key default, options + return flat_key if FastGettext.key_exist?(flat_key) + + #try the short key thereafter e.g. 'my custom message' + return default if FastGettext.key_exist?(default) + end + return nil + end + end + + def interpolate(string, values) + reserved_keys = if defined?(I18n::RESERVED_KEYS) # rails 3+ + I18n::RESERVED_KEYS + else + I18n::Backend::Base::RESERVED_KEYS + end + + string % values.except(*reserved_keys) + end + + def flatten_key key, options + scope = [*(options[:scope] || [])] + scope.empty? ? key.to_s : "#{scope*'.'}.#{key}" + end + end +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/haml_parser.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/haml_parser.rb new file mode 100644 index 000000000..04209b23f --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/haml_parser.rb @@ -0,0 +1,43 @@ +require 'gettext/utils' +begin + require 'gettext/tools/rgettext' +rescue LoadError #version prior to 2.0 + require 'gettext/rgettext' +end + +module GettextI18nRails + module HamlParser + module_function + + def target?(file) + File.extname(file) == '.haml' + end + + def parse(file, msgids = []) + return msgids unless load_haml + require 'gettext_i18n_rails/ruby_gettext_extractor' + + text = IO.readlines(file).join + + haml = Haml::Engine.new(text) + code = haml.precompiled + return RubyGettextExtractor.parse_string(code, file, msgids) + end + + def load_haml + return true if @haml_loaded + begin + require "#{::Rails.root.to_s}/vendor/plugins/haml/lib/haml" + rescue LoadError + begin + require 'haml' # From gem + rescue LoadError + puts "A haml file was found, but haml library could not be found, so nothing will be parsed..." + return false + end + end + @haml_loaded = true + end + end +end +GetText::RGetText.add_parser(GettextI18nRails::HamlParser)
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/html_safe_translations.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/html_safe_translations.rb new file mode 100644 index 000000000..1fc5f93f9 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/html_safe_translations.rb @@ -0,0 +1,29 @@ +module GettextI18nRails + mattr_accessor :translations_are_html_safe + + module HtmlSafeTranslations + # also make available on class methods + def self.included(base) + base.extend self + end + + def _(*args) + html_safe_if_wanted super + end + + def n_(*args) + html_safe_if_wanted super + end + + def s_(*args) + html_safe_if_wanted super + end + + private + + def html_safe_if_wanted(text) + return text unless GettextI18nRails.translations_are_html_safe + text.to_s.html_safe + end + end +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/i18n_hacks.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/i18n_hacks.rb new file mode 100644 index 000000000..3a8ee6f65 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/i18n_hacks.rb @@ -0,0 +1,38 @@ +module I18n + module_function + + def locale=(new_locale) + FastGettext.locale = new_locale + end + + def locale + FastGettext.locale.to_sym + end + + # since Rails 2.3.8 a config object is used instead of just .locale + if defined? Config + class Config + def locale + FastGettext.locale.to_sym + end + + def locale=(new_locale) + FastGettext.locale=(new_locale) + end + end + end + + # backport I18n.with_locale if it does not exist + unless respond_to?(:with_locale) + # 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 + end +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/model_attributes_finder.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/model_attributes_finder.rb new file mode 100644 index 000000000..e65bb52d6 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/model_attributes_finder.rb @@ -0,0 +1,52 @@ +module GettextI18nRails + #write all found models/columns to a file where GetTexts ruby parser can find them + def store_model_attributes(options) + file = options[:to] || 'locale/model_attributes.rb' + File.open(file,'w') do |f| + f.puts "#DO NOT MODIFY! AUTOMATICALLY GENERATED FILE!" + ModelAttributesFinder.new.find(options).each do |table_name,column_names| + #model name + begin + model = table_name.singularize.camelcase.constantize + rescue NameError + # Some tables are not models, for example: translation tables created by globalize2. + next + end + f.puts("_('#{model.human_name_without_translation}')") + + #all columns namespaced under the model + column_names.each do |attribute| + translation = model.gettext_translation_for_attribute_name(attribute) + f.puts("_('#{translation}')") + end + end + f.puts "#DO NOT MODIFY! AUTOMATICALLY GENERATED FILE!" + end + end + module_function :store_model_attributes + + class ModelAttributesFinder + # options: + # :ignore_tables => ['cars',/_settings$/,...] + # :ignore_columns => ['id',/_id$/,...] + # current connection ---> {'cars'=>['model_name','type'],...} + def find(options) + found = Hash.new([]) + + connection = ActiveRecord::Base.connection + connection.tables.each do |table_name| + next if ignored?(table_name,options[:ignore_tables]) + connection.columns(table_name).each do |column| + found[table_name] += [column.name] unless ignored?(column.name,options[:ignore_columns]) + end + end + + found + end + + def ignored?(name,patterns) + return false unless patterns + patterns.detect{|p|p.to_s==name.to_s or (p.is_a?(Regexp) and name=~p)} + end + end +end diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/railtie.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/railtie.rb new file mode 100644 index 000000000..174e1afb9 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/railtie.rb @@ -0,0 +1,10 @@ +# add rake tasks if we are inside Rails +if defined?(Rails::Railtie) + module GettextI18nRails + class Railtie < ::Rails::Railtie + rake_tasks do + require 'gettext_i18n_rails/tasks' + end + end + end +end diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/ruby_gettext_extractor.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/ruby_gettext_extractor.rb new file mode 100644 index 000000000..74031ca5a --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/ruby_gettext_extractor.rb @@ -0,0 +1,140 @@ +# new ruby parser from retoo, that should help extracting "#{_('xxx')}", which is needed especially when parsing haml files +# +#!/usr/bin/ruby +# parser/ruby.rb - look for gettext msg strings in ruby files +# Copyright (C) 2009 Reto Schüttel <reto (ät) schuettel (dot) ch> +# You may redistribute it and/or modify it under the same license terms as Ruby. + +require 'rubygems' +require 'ruby_parser' + +module RubyGettextExtractor + extend self + + def parse(file, targets = []) # :nodoc: + content = File.read(file) + parse_string(content, file, targets) + end + + def parse_string(content, file, targets=[]) + # file is just for information in error messages + parser = Extractor.new(file, targets) + parser.run(content) + end + + def target?(file) # :nodoc: + return file =~ /\.rb$/ + end + + class Extractor < RubyParser + def initialize(filename, targets) + @filename = filename + @targets = Hash.new + @results = [] + + targets.each do |a| + k, v = a + # things go wrong if k already exists, but this + # should not happen (according to the gettext doc) + @targets[k] = a + @results << a + end + + super() + end + + def run(content) + # ruby parser has an ugly bug which causes that several \000's take + # ages to parse. This avoids this probelm by stripping them away (they probably wont appear in keys anyway) + # See bug report: http://rubyforge.org/tracker/index.php?func=detail&aid=26898&group_id=439&atid=1778 + safe_content = content.gsub(/\\\d\d\d/, '') + self.parse(safe_content) + return @results + end + + def extract_string(node) + if node.first == :str + return node.last + elsif node.first == :call + type, recv, meth, args = node + + # node has to be in form of "string"+("other_string") + return nil unless recv && meth == :+ + + # descent recurrsivly to determine the 'receiver' of the string concatination + # "foo" + "bar" + baz" is + # ("foo".+("bar")).+("baz") + first_part = extract_string(recv) + + if args.first == :arglist && args.size == 2 + second_part = extract_string(args.last) + + return nil if second_part.nil? + + return first_part.to_s + second_part.to_s + else + raise "uuh?" + end + else + return nil + end + end + + def extract_key(args, seperator) + key = nil + if args.size == 2 + key = extract_string(args.value) + else + # this could be n_("aaa","aaa2",1) + # all strings arguemnts are extracted and joined with \004 or \000 + + arguments = args[1..(-1)] + + res = [] + arguments.each do |a| + str = extract_string(a) + # only add strings + res << str if str + end + + return nil if res.empty? + key = res.join(seperator) + end + + return nil unless key + + key.gsub!("\n", '\n') + key.gsub!("\t", '\t') + key.gsub!("\0", '\0') + + return key + end + + def new_call recv, meth, args = nil + # we dont care if the method is called on a a object + if recv.nil? + if (meth == :_ || meth == :p_ || meth == :N_ || meth == :pgettext || meth == :s_) + key = extract_key(args, "\004") + elsif meth == :n_ + key = extract_key(args, "\000") + else + # skip + end + + if key + res = @targets[key] + + unless res + res = [key] + @results << res + @targets[key] = res + end + + res << "#{@filename}:#{lexer.lineno}" + end + end + + super recv, meth, args + end + end +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/string_interpolate_fix.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/string_interpolate_fix.rb new file mode 100644 index 000000000..c919e66df --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/string_interpolate_fix.rb @@ -0,0 +1,20 @@ +needed = "".respond_to?(:html_safe) and + ( + "".html_safe % {:x => '<br/>'} == '<br/>' or + not ("".html_safe % {:x=>'a'}).html_safe? + ) + +if needed + class String + alias :interpolate_without_html_safe :% + + def %(*args) + if args.first.is_a?(Hash) and html_safe? + safe_replacement = Hash[args.first.map{|k,v| [k,ERB::Util.h(v)] }] + interpolate_without_html_safe(safe_replacement).html_safe + else + interpolate_without_html_safe(*args).dup # make sure its not html_safe + end + end + end +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/tasks.rb b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/tasks.rb new file mode 100644 index 000000000..b52157a2f --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/tasks.rb @@ -0,0 +1,120 @@ +namespace :gettext do + def load_gettext + require 'gettext' + require 'gettext/utils' + end + + desc "Create mo-files for L10n" + task :pack do + load_gettext + GetText.create_mofiles(true, locale_path, locale_path) + end + + desc "Update pot/po files." + task :find => :environment do + load_gettext + $LOAD_PATH << File.join(File.dirname(__FILE__),'..','..','lib') + require 'gettext_i18n_rails/haml_parser' + + + if GetText.respond_to? :update_pofiles_org + GetText.update_pofiles_org( + text_domain, + files_to_translate, + "version 0.0.1", + :po_root => locale_path, + :msgmerge=>['--sort-output'] + ) + else #we are on a version < 2.0 + puts "install new GetText with gettext:install to gain more features..." + #kill ar parser... + require 'gettext/parser/active_record' + module GetText + module ActiveRecordParser + module_function + def init(x);end + end + end + + #parse files.. (models are simply parsed as ruby files) + GetText.update_pofiles( + text_domain, + files_to_translate, + "version 0.0.1", + locale_path + ) + end + end + + # This is more of an example, ignoring + # the columns/tables that mostly do not need translation. + # This can also be done with GetText::ActiveRecord + # but this crashed too often for me, and + # IMO which column should/should-not be translated does not + # belong into the model + # + # You can get your translations from GetText::ActiveRecord + # by adding this to you gettext:find task + # + # require 'active_record' + # gem "gettext_activerecord", '>=0.1.0' #download and install from github + # require 'gettext_activerecord/parser' + desc "write the model attributes to <locale_path>/model_attributes.rb" + task :store_model_attributes => :environment do + FastGettext.silence_errors + + require 'gettext_i18n_rails/model_attributes_finder' + require 'gettext_i18n_rails/active_record' + + storage_file = "#{locale_path}/model_attributes.rb" + puts "writing model translations to: #{storage_file}" + + ignore_tables = [/^sitemap_/, /_versions$/, 'schema_migrations', 'sessions', 'delayed_jobs'] + GettextI18nRails.store_model_attributes( + :to => storage_file, + :ignore_columns => [/_id$/, 'id', 'type', 'created_at', 'updated_at'], + :ignore_tables => ignore_tables + ) + end + + desc "add a new language" + task :add_language, [:language] => :environment do |_, args| + language = args.language || ENV["LANGUAGE"] + + # Let's do some pre-verification of the environment. + if language.nil? + puts "You need to specify the language to add. Either 'LANGUAGE=eo rake gettext:add_languange' or 'rake gettext:add_languange[eo]'" + next + end + pot = File.join(locale_path, "#{text_domain}.pot") + if !File.exists? pot + puts "You don't have a pot file yet, you probably should run 'rake gettext:find' at least once. Tried '#{pot}'." + next + end + + # Create the directory for the new language. + dir = File.join(locale_path, language) + puts "Creating directory #{dir}" + Dir.mkdir dir + + # Create the po file for the new language. + new_po = File.join(locale_path, language, "#{text_domain}.po") + puts "Initializing #{new_po} from #{pot}." + system "msginit --locale=#{language} --input=#{pot} --output=#{new_po}" + end + + def locale_path + FastGettext.translation_repositories[text_domain].instance_variable_get(:@options)[:path] + rescue + File.join(RAILS_ROOT, "locale") + end + + def text_domain + # if your textdomain is not 'app': require the environment before calling e.g. gettext:find OR add TEXTDOMAIN=my_domain + ENV['TEXTDOMAIN'] || (FastGettext.text_domain rescue nil) || "app" + end + + def files_to_translate + Dir.glob("{app,lib,config,#{locale_path}}/**/*.{rb,erb,haml}") + end +end diff --git a/vendor/plugins/gettext_i18n_rails/lib/tasks/gettext_rails_i18n.rake b/vendor/plugins/gettext_i18n_rails/lib/tasks/gettext_rails_i18n.rake new file mode 100644 index 000000000..540b0c79d --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/lib/tasks/gettext_rails_i18n.rake @@ -0,0 +1 @@ +require File.join(File.dirname(__FILE__), "/../gettext_i18n_rails/tasks") diff --git a/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/action_controller_spec.rb b/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/action_controller_spec.rb new file mode 100644 index 000000000..9b12c9fa8 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/action_controller_spec.rb @@ -0,0 +1,40 @@ +require File.expand_path("../spec_helper", File.dirname(__FILE__)) + +FastGettext.silence_errors + +describe ActionController::Base do + before do + #controller + @c = ActionController::Base.new + fake_session = {} + @c.stub!(:session).and_return fake_session + fake_cookies = {} + @c.stub!(:cookies).and_return fake_cookies + @c.params = {} + @c.request = stub(:env => {}) + + #locale + FastGettext.available_locales = nil + FastGettext.locale = 'fr' + FastGettext.available_locales = ['fr','en'] + end + + it "changes the locale" do + @c.params = {:locale=>'en'} + @c.set_gettext_locale + @c.session[:locale].should == 'en' + FastGettext.locale.should == 'en' + end + + it "stays with default locale when none was found" do + @c.set_gettext_locale + @c.session[:locale].should == 'fr' + FastGettext.locale.should == 'fr' + end + + it "reads the locale from the HTTP_ACCEPT_LANGUAGE" do + @c.request.stub!(:env).and_return 'HTTP_ACCEPT_LANGUAGE'=>'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3' + @c.set_gettext_locale + FastGettext.locale.should == 'en' + end +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/active_record_spec.rb b/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/active_record_spec.rb new file mode 100644 index 000000000..aad5aaf42 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/active_record_spec.rb @@ -0,0 +1,83 @@ +# coding: utf-8 +require File.expand_path("../spec_helper", File.dirname(__FILE__)) + +FastGettext.silence_errors + +ActiveRecord::Base.establish_connection({ + :adapter => "sqlite3", + :database => ":memory:", +}) + +ActiveRecord::Schema.define(:version => 1) do + create_table :car_seats, :force=>true do |t| + t.string :seat_color + end + + create_table :parts, :force=>true do |t| + t.string :name + t.references :car_seat + end +end + +class CarSeat < ActiveRecord::Base + validates_presence_of :seat_color, :message=>"translate me" + has_many :parts + accepts_nested_attributes_for :parts +end + +class Part < ActiveRecord::Base + belongs_to :car_seat +end + +describe ActiveRecord::Base do + before do + FastGettext.current_cache = {} + end + + describe :human_name do + it "is translated through FastGettext" do + CarSeat.should_receive(:_).with('car seat').and_return('Autositz') + CarSeat.human_name.should == 'Autositz' + end + end + + describe :human_attribute_name do + it "translates attributes through FastGettext" do + CarSeat.should_receive(:s_).with('CarSeat|Seat color').and_return('Sitz farbe') + CarSeat.human_attribute_name(:seat_color).should == 'Sitz farbe' + end + + it "translates nested attributes through FastGettext" do + CarSeat.should_receive(:s_).with('CarSeat|Parts|Name').and_return('Handle') + CarSeat.human_attribute_name(:"parts.name").should == 'Handle' + end + end + + describe 'error messages' do + let(:model){ + c = CarSeat.new + c.valid? + c + } + + it "translates error messages" do + FastGettext.stub!(:current_repository).and_return('translate me'=>"Übersetz mich!") + FastGettext._('translate me').should == "Übersetz mich!" + model.errors.on(:seat_color).should == "Übersetz mich!" + end + + it "translates scoped error messages" do + pending 'scope is no longer added in 3.x' if ActiveRecord::VERSION::MAJOR >= 3 + FastGettext.stub!(:current_repository).and_return('activerecord.errors.translate me'=>"Übersetz mich!") + FastGettext._('activerecord.errors.translate me').should == "Übersetz mich!" + model.errors.on(:seat_color).should == "Übersetz mich!" + end + + it "translates error messages with %{fn}" do + pending + FastGettext.stub!(:current_repository).and_return('translate me'=>"Übersetz %{fn} mich!") + FastGettext._('translate me').should == "Übersetz %{fn} mich!" + model.errors.on(:seat_color).should == "Übersetz car_seat mich!" + end + end +end diff --git a/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/backend_spec.rb b/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/backend_spec.rb new file mode 100644 index 000000000..e0df1e725 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/backend_spec.rb @@ -0,0 +1,46 @@ +require File.expand_path("../spec_helper", File.dirname(__FILE__)) + +describe GettextI18nRails::Backend do + it "redirects calls to another I18n backend" do + subject.backend.should_receive(:xxx).with(1,2) + subject.xxx(1,2) + end + + describe :available_locales do + it "maps them to FastGettext" do + FastGettext.should_receive(:available_locales).and_return [:xxx] + subject.available_locales.should == [:xxx] + end + + it "and returns an empty array when FastGettext.available_locales is nil" do + FastGettext.should_receive(:available_locales).and_return nil + subject.available_locales.should == [] + end + end + + describe :translate do + it "uses gettext when the key is translatable" do + FastGettext.stub(:current_repository).and_return 'xy.z.u'=>'a' + subject.translate('xx','u',:scope=>['xy','z']).should == 'a' + end + + it "interpolates options" do + FastGettext.stub(:current_repository).and_return 'ab.c'=>'a%{a}b' + subject.translate('xx','c',:scope=>['ab'], :a => 'X').should == 'aXb' + end + + it "can translate with gettext using symbols" do + FastGettext.stub(:current_repository).and_return 'xy.z.v'=>'a' + subject.translate('xx',:v ,:scope=>['xy','z']).should == 'a' + end + + it "can translate with gettext using a flat scope" do + FastGettext.stub(:current_repository).and_return 'xy.z.x'=>'a' + subject.translate('xx',:x ,:scope=>'xy.z').should == 'a' + end + + it "uses the super when the key is not translatable" do + lambda{subject.translate('xx','y',:scope=>['xy','z'])}.should raise_error(I18n::MissingTranslationData) + end + end +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/string_interpolate_fix_spec.rb b/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/string_interpolate_fix_spec.rb new file mode 100644 index 000000000..c437699e7 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/string_interpolate_fix_spec.rb @@ -0,0 +1,32 @@ +require File.expand_path("../spec_helper", File.dirname(__FILE__)) +require 'gettext_i18n_rails/string_interpolate_fix' + +describe "String#%" do + it "is not safe if it was not safe" do + result = ("<br/>%{x}" % {:x => 'a'}) + result.should == '<br/>a' + result.html_safe?.should == false + end + + it "stays safe if it was safe" do + result = ("<br/>%{x}".html_safe % {:x => 'a'}) + result.should == '<br/>a' + result.html_safe?.should == true + end + + it "escapes unsafe added to safe" do + result = ("<br/>%{x}".html_safe % {:x => '<br/>'}) + result.should == '<br/><br/>' + result.html_safe?.should == true + end + + it "does not escape unsafe if it was unsafe" do + result = ("<br/>%{x}" % {:x => '<br/>'}) + result.should == '<br/><br/>' + result.html_safe?.should == false + end + + it "does not break array replacement" do + "%ssd" % ['a'].should == "asd" + end +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails_spec.rb b/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails_spec.rb new file mode 100644 index 000000000..3688d8b10 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails_spec.rb @@ -0,0 +1,84 @@ +require File.expand_path("spec_helper", File.dirname(__FILE__)) + +FastGettext.silence_errors + +describe GettextI18nRails do + before do + GettextI18nRails.translations_are_html_safe = nil + end + + it "extends all classes with fast_gettext" do + _('test') + end + + describe 'translations_are_html_safe' do + before do + GettextI18nRails.translations_are_html_safe = nil + end + + it "makes translations not html_safe by default" do + _('x').html_safe?.should == false + s_('x').html_safe?.should == false + n_('x','y',2).html_safe?.should == false + String._('x').html_safe?.should == false + String.s_('x').html_safe?.should == false + String.n_('x','y',2).html_safe?.should == false + end + + it "makes instance translations html_safe when wanted" do + GettextI18nRails.translations_are_html_safe = true + _('x').html_safe?.should == true + s_('x').html_safe?.should == true + n_('x','y',2).html_safe?.should == true + end + + it "makes class translations html_safe when wanted" do + GettextI18nRails.translations_are_html_safe = true + String._('x').html_safe?.should == true + String.s_('x').html_safe?.should == true + String.n_('x','y',2).html_safe?.should == true + end + + it "does not make everything html_safe" do + 'x'.html_safe?.should == false + end + end + + it "sets up out backend" do + I18n.backend.is_a?(GettextI18nRails::Backend).should be_true + end + + it "has a VERSION" do + GettextI18nRails::VERSION.should =~ /^\d+\.\d+\.\d+$/ + end + + describe 'FastGettext I18n interaction' do + before do + FastGettext.available_locales = nil + FastGettext.locale = 'de' + end + + it "links FastGettext with I18n locale" do + FastGettext.locale = 'xx' + I18n.locale.should == :xx + end + + it "does not set an not-accepted locale to I18n.locale" do + FastGettext.available_locales = ['de'] + FastGettext.locale = 'xx' + I18n.locale.should == :de + end + + it "links I18n.locale and FastGettext.locale" do + I18n.locale = :yy + FastGettext.locale.should == 'yy' + end + + it "does not set a non-available locale though I18n.locale" do + FastGettext.available_locales = ['de'] + I18n.locale = :xx + FastGettext.locale.should == 'de' + I18n.locale.should == :de + end + end +end
\ No newline at end of file diff --git a/vendor/plugins/gettext_i18n_rails/spec/spec_helper.rb b/vendor/plugins/gettext_i18n_rails/spec/spec_helper.rb new file mode 100644 index 000000000..f8002b766 --- /dev/null +++ b/vendor/plugins/gettext_i18n_rails/spec/spec_helper.rb @@ -0,0 +1,17 @@ +require 'rubygems' +if ENV['VERSION'] + puts "running VERSION #{ENV['VERSION']}" + gem 'actionpack', ENV['VERSION'] + gem 'activerecord', ENV['VERSION'] + gem 'activesupport', ENV['VERSION'] + gem 'actionmailer', ENV['VERSION'] +end + +$LOAD_PATH << File.expand_path("../lib", File.dirname(__FILE__)) + +require 'active_support' +require 'active_record' +require 'action_controller' +require 'action_mailer' +require 'fast_gettext' +require 'gettext_i18n_rails'
\ No newline at end of file |