activesupport 2.3.8 → 2.3.9.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (66) hide show
  1. data/CHANGELOG +11 -0
  2. data/lib/active_support/core_ext/array/grouping.rb +1 -1
  3. data/lib/active_support/core_ext/array/random_access.rb +24 -4
  4. data/lib/active_support/core_ext/class.rb +1 -0
  5. data/lib/active_support/core_ext/class/attribute.rb +67 -0
  6. data/lib/active_support/core_ext/enumerable.rb +1 -1
  7. data/lib/active_support/core_ext/kernel/singleton_class.rb +13 -0
  8. data/lib/active_support/core_ext/module/remove_method.rb +6 -0
  9. data/lib/active_support/core_ext/object/misc.rb +3 -0
  10. data/lib/active_support/core_ext/range/blockless_step.rb +1 -1
  11. data/lib/active_support/core_ext/string/output_safety.rb +0 -11
  12. data/lib/active_support/dependencies.rb +36 -12
  13. data/lib/active_support/deprecation.rb +7 -0
  14. data/lib/active_support/json/backends/yajl.rb +1 -1
  15. data/lib/active_support/ordered_hash.rb +6 -0
  16. data/lib/active_support/testing/performance.rb +1 -1
  17. data/lib/active_support/values/time_zone.rb +5 -1
  18. data/lib/active_support/vendor.rb +2 -2
  19. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n.rb +92 -105
  20. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend.rb +5 -4
  21. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/active_record.rb +61 -0
  22. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/active_record/missing.rb +4 -6
  23. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/active_record/store_procs.rb +0 -0
  24. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/active_record/translation.rb +8 -3
  25. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/base.rb +55 -84
  26. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/cache.rb +1 -0
  27. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/cascade.rb +0 -1
  28. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/chain.rb +3 -1
  29. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/cldr.rb +0 -0
  30. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/fallbacks.rb +0 -0
  31. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/flatten.rb +113 -0
  32. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/gettext.rb +0 -0
  33. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/interpolation_compiler.rb +8 -4
  34. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/key_value.rb +102 -0
  35. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/memoize.rb +48 -0
  36. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/metadata.rb +5 -13
  37. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/pluralization.rb +0 -0
  38. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/simple.rb +87 -0
  39. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/transliterator.rb +98 -0
  40. data/lib/active_support/vendor/i18n-0.4.1/i18n/config.rb +84 -0
  41. data/lib/active_support/vendor/i18n-0.4.1/i18n/core_ext/hash.rb +29 -0
  42. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/core_ext/string/interpolate.rb +3 -4
  43. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/exceptions.rb +0 -0
  44. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/gettext.rb +2 -0
  45. data/lib/active_support/vendor/{i18n-0.3.7/i18n/helpers/gettext.rb → i18n-0.4.1/i18n/gettext/helpers.rb} +2 -2
  46. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/gettext/po_parser.rb +0 -0
  47. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale.rb +0 -0
  48. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale/fallbacks.rb +0 -0
  49. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale/tag.rb +0 -0
  50. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale/tag/parents.rb +0 -0
  51. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale/tag/rfc4646.rb +0 -0
  52. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale/tag/simple.rb +0 -0
  53. data/lib/active_support/vendor/i18n-0.4.1/i18n/version.rb +3 -0
  54. data/lib/active_support/version.rb +1 -1
  55. data/lib/active_support/whiny_nil.rb +1 -1
  56. metadata +48 -43
  57. data/lib/active_support/vendor/i18n-0.3.7/i18n/backend/active_record.rb +0 -66
  58. data/lib/active_support/vendor/i18n-0.3.7/i18n/backend/fast.rb +0 -69
  59. data/lib/active_support/vendor/i18n-0.3.7/i18n/backend/helpers.rb +0 -68
  60. data/lib/active_support/vendor/i18n-0.3.7/i18n/backend/links.rb +0 -34
  61. data/lib/active_support/vendor/i18n-0.3.7/i18n/backend/simple.rb +0 -22
  62. data/lib/active_support/vendor/i18n-0.3.7/i18n/core_ext/hash/except.rb +0 -8
  63. data/lib/active_support/vendor/i18n-0.3.7/i18n/core_ext/hash/slice.rb +0 -8
  64. data/lib/active_support/vendor/i18n-0.3.7/i18n/core_ext/object/meta_class.rb +0 -5
  65. data/lib/active_support/vendor/i18n-0.3.7/i18n/helpers.rb +0 -5
  66. data/lib/active_support/vendor/i18n-0.3.7/i18n/version.rb +0 -3
@@ -11,14 +11,18 @@
11
11
  # InterpolationCompiler module to the Simple backend:
12
12
  #
13
13
  # I18n::Backend::Simple.send(:include, I18n::Backend::InterpolationCompiler)
14
+ #
15
+ # Note that InterpolationCompiler does not yield meaningful results and consequently
16
+ # should not be used with Ruby 1.9 (YARV) but improves performance everywhere else
17
+ # (jRuby, Rubinius and 1.8.7).
14
18
  module I18n
15
19
  module Backend
16
20
  module InterpolationCompiler
17
21
  module Compiler
18
22
  extend self
19
23
 
20
- TOKENIZER = /(\\\{\{[^\}]+\}\}|\{\{[^\}]+\}\})/
21
- INTERPOLATION_SYNTAX_PATTERN = /(\\)?(\{\{([^\}]+)\}\})/
24
+ TOKENIZER = /(%%\{[^\}]+\}|%\{[^\}]+\})/
25
+ INTERPOLATION_SYNTAX_PATTERN = /(%)?(%\{([^\}]+)\})/
22
26
 
23
27
  def compile_if_an_interpolation(string)
24
28
  if interpolated_str?(string)
@@ -37,7 +41,7 @@ module I18n
37
41
  end
38
42
 
39
43
  protected
40
- # tokenize("foo {{bar}} baz \\{{buz}}") # => ["foo ", "{{bar}}", " baz ", "\\{{buz}}"]
44
+ # tokenize("foo %{bar} baz %%{buz}") # => ["foo ", "%{bar}", " baz ", "%%{buz}"]
41
45
  def tokenize(str)
42
46
  str.split(TOKENIZER)
43
47
  end
@@ -102,7 +106,7 @@ module I18n
102
106
  end
103
107
  end
104
108
 
105
- def merge_translations(locale, data, options = {})
109
+ def store_translations(locale, data, options = {})
106
110
  compile_all_strings_in(data)
107
111
  super
108
112
  end
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+
3
+ require 'i18n/backend/base'
4
+ require 'active_support/json'
5
+
6
+ module I18n
7
+ module Backend
8
+ # This is a basic backend for key value stores. It receives on
9
+ # initialization the store, which should respond to three methods:
10
+ #
11
+ # * store#[](key) - Used to get a value
12
+ # * store#[]=(key, value) - Used to set a value
13
+ # * store#keys - Used to get all keys
14
+ #
15
+ # Since these stores only supports string, all values are converted
16
+ # to JSON before being stored, allowing it to also store booleans,
17
+ # hashes and arrays. However, this store does not support Procs.
18
+ #
19
+ # As the ActiveRecord backend, Symbols are just supported when loading
20
+ # translations from the filesystem or through explicit store translations.
21
+ #
22
+ # Also, avoid calling I18n.available_locales since it's a somehow
23
+ # expensive operation in most stores.
24
+ #
25
+ # == Example
26
+ #
27
+ # To setup I18n to use TokyoCabinet in memory is quite straightforward:
28
+ #
29
+ # require 'rufus/tokyo/cabinet' # gem install rufus-tokyo
30
+ # I18n.backend = I18n::Backend::KeyValue.new(Rufus::Tokyo::Cabinet.new('*'))
31
+ #
32
+ # == Performance
33
+ #
34
+ # You may make this backend even faster by including the Memoize module.
35
+ # However, notice that you should properly clear the cache if you change
36
+ # values directly in the key-store.
37
+ #
38
+ # == Subtrees
39
+ #
40
+ # In most backends, you are allowed to retrieve part of a translation tree:
41
+ #
42
+ # I18n.backend.store_translations :en, :foo => { :bar => :baz }
43
+ # I18n.t "foo" #=> { :bar => :baz }
44
+ #
45
+ # This backend supports this feature by default, but it slows down the storage
46
+ # of new data considerably and makes hard to delete entries. That said, you are
47
+ # allowed to disable the storage of subtrees on initialization:
48
+ #
49
+ # I18n::Backend::KeyValue.new(@store, false)
50
+ #
51
+ # This is useful if you are using a KeyValue backend chained to a Simple backend.
52
+ class KeyValue
53
+ module Implementation
54
+ attr_accessor :store
55
+
56
+ include Base, Flatten
57
+
58
+ def initialize(store, subtrees=true)
59
+ @store, @subtrees = store, subtrees
60
+ end
61
+
62
+ def store_translations(locale, data, options = {})
63
+ escape = options.fetch(:escape, true)
64
+ flatten_translations(locale, data, escape, @subtrees).each do |key, value|
65
+ key = "#{locale}.#{key}"
66
+
67
+ case value
68
+ when Hash
69
+ if @subtrees && (old_value = @store[key])
70
+ old_value = ActiveSupport::JSON.decode(old_value)
71
+ value = old_value.deep_symbolize_keys.deep_merge!(value) if old_value.is_a?(Hash)
72
+ end
73
+ when Proc
74
+ raise "Key-value stores cannot handle procs"
75
+ end
76
+
77
+ @store[key] = ActiveSupport::JSON.encode(value) unless value.is_a?(Symbol)
78
+ end
79
+ end
80
+
81
+ def available_locales
82
+ locales = @store.keys.map { |k| k =~ /\./; $` }
83
+ locales.uniq!
84
+ locales.compact!
85
+ locales.map! { |k| k.to_sym }
86
+ locales
87
+ end
88
+
89
+ protected
90
+
91
+ def lookup(locale, key, scope = [], options = {})
92
+ key = normalize_flat_keys(locale, key, scope, options[:separator])
93
+ value = @store["#{locale}.#{key}"]
94
+ value = ActiveSupport::JSON.decode(value) if value
95
+ value.is_a?(Hash) ? value.deep_symbolize_keys : value
96
+ end
97
+ end
98
+
99
+ include Implementation
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Memoize module simply memoizes the values returned by lookup using
4
+ # a flat hash and can tremendously speed up the lookup process in a backend.
5
+ #
6
+ # To enable it you can simply include the Memoize module to your backend:
7
+ #
8
+ # I18n::Backend::Simple.send(:include, I18n::Backend::Memoize)
9
+ #
10
+ # Notice that it's the responsibility of the backend to define whenever the
11
+ # cache should be cleaned.
12
+ module I18n
13
+ module Backend
14
+ module Memoize
15
+ def available_locales
16
+ @memoized_locales ||= super
17
+ end
18
+
19
+ def store_translations(locale, data, options = {})
20
+ reset_memoizations!(locale)
21
+ super
22
+ end
23
+
24
+ def reload!
25
+ reset_memoizations!
26
+ super
27
+ end
28
+
29
+ protected
30
+
31
+ def lookup(locale, key, scope = nil, options = {})
32
+ flat_key = I18n::Backend::Flatten.normalize_flat_keys(locale,
33
+ key, scope, options[:separator]).to_sym
34
+ flat_hash = memoized_lookup[locale.to_sym]
35
+ flat_hash.key?(flat_key) ? flat_hash[flat_key] : (flat_hash[flat_key] = super)
36
+ end
37
+
38
+ def memoized_lookup
39
+ @memoized_lookup ||= Hash.new { |h, k| h[k] = {} }
40
+ end
41
+
42
+ def reset_memoizations!(locale=nil)
43
+ @memoized_locales = nil
44
+ (locale ? memoized_lookup[locale.to_sym] : memoized_lookup).clear
45
+ end
46
+ end
47
+ end
48
+ end
@@ -13,9 +13,7 @@
13
13
  # into the Simple backend class - or whatever other backend you are using:
14
14
  #
15
15
  # I18n::Backend::Simple.send(:include, I18n::Backend::Metadata)
16
-
17
- require 'i18n/core_ext/object/meta_class'
18
-
16
+ #
19
17
  module I18n
20
18
  module Backend
21
19
  module Metadata
@@ -29,7 +27,7 @@ module I18n
29
27
  def translation_metadata=(translation_metadata)
30
28
  @translation_metadata = translation_metadata
31
29
  end
32
- end
30
+ end unless Object.method_defined?(:translation_metadata)
33
31
  end
34
32
  end
35
33
 
@@ -45,10 +43,9 @@ module I18n
45
43
  with_metadata(metadata) { super }
46
44
  end
47
45
 
48
- def interpolate(locale, string, values = {})
49
- with_metadata(:original => string) do
50
- preserve_translation_metadata(string) { super }
51
- end if string
46
+ def interpolate(locale, entry, values = {})
47
+ metadata = entry.translation_metadata.merge(:original => entry)
48
+ with_metadata(metadata) { super }
52
49
  end
53
50
 
54
51
  def pluralize(locale, entry, count)
@@ -63,11 +60,6 @@ module I18n
63
60
  result
64
61
  end
65
62
 
66
- def preserve_translation_metadata(object, &block)
67
- result = yield
68
- result.translation_metadata = object.translation_metadata if result
69
- result
70
- end
71
63
  end
72
64
  end
73
65
  end
@@ -0,0 +1,87 @@
1
+ # encoding: utf-8
2
+
3
+ module I18n
4
+ module Backend
5
+ # A simple backend that reads translations from YAML files and stores them in
6
+ # an in-memory hash. Relies on the Base backend.
7
+ #
8
+ # The implementation is provided by a Implementation module allowing to easily
9
+ # extend Simple backend's behavior by including modules. E.g.:
10
+ #
11
+ # module I18n::Backend::Pluralization
12
+ # def pluralize(*args)
13
+ # # extended pluralization logic
14
+ # super
15
+ # end
16
+ # end
17
+ #
18
+ # I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
19
+ class Simple
20
+ module Implementation
21
+ include Base
22
+
23
+ def initialized?
24
+ @initialized ||= false
25
+ end
26
+
27
+ # Stores translations for the given locale in memory.
28
+ # This uses a deep merge for the translations hash, so existing
29
+ # translations will be overwritten by new ones only at the deepest
30
+ # level of the hash.
31
+ def store_translations(locale, data, options = {})
32
+ locale = locale.to_sym
33
+ translations[locale] ||= {}
34
+ data = data.deep_symbolize_keys
35
+ translations[locale].deep_merge!(data)
36
+ end
37
+
38
+ # Get available locales from the translations hash
39
+ def available_locales
40
+ init_translations unless initialized?
41
+ translations.inject([]) do |locales, (locale, data)|
42
+ locales << locale unless (data.keys - [:i18n]).empty?
43
+ locales
44
+ end
45
+ end
46
+
47
+ # Clean up translations hash and set initialized to false on reload!
48
+ def reload!
49
+ @initialized = false
50
+ @translations = nil
51
+ super
52
+ end
53
+
54
+ protected
55
+
56
+ def init_translations
57
+ load_translations
58
+ @initialized = true
59
+ end
60
+
61
+ def translations
62
+ @translations ||= {}
63
+ end
64
+
65
+ # Looks up a translation from the translations hash. Returns nil if
66
+ # eiher key is nil, or locale, scope or key do not exist as a key in the
67
+ # nested translations hash. Splits keys or scopes containing dots
68
+ # into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
69
+ # <tt>%w(currency format)</tt>.
70
+ def lookup(locale, key, scope = [], options = {})
71
+ init_translations unless initialized?
72
+ keys = I18n.normalize_keys(locale, key, scope, options[:separator])
73
+
74
+ keys.inject(translations) do |result, key|
75
+ key = key.to_sym
76
+ return nil unless result.is_a?(Hash) && result.has_key?(key)
77
+ result = result[key]
78
+ result = resolve(locale, key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
79
+ result
80
+ end
81
+ end
82
+ end
83
+
84
+ include Implementation
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,98 @@
1
+ # encoding: utf-8
2
+ module I18n
3
+ module Backend
4
+ module Transliterator
5
+ DEFAULT_REPLACEMENT_CHAR = "?"
6
+
7
+ # Given a locale and a UTF-8 string, return the locale's ASCII
8
+ # approximation for the string.
9
+ def transliterate(locale, string, replacement = nil)
10
+ @transliterators ||= {}
11
+ @transliterators[locale] ||= Transliterator.get I18n.t(:'i18n.transliterate.rule',
12
+ :locale => locale, :resolve => false, :default => {})
13
+ @transliterators[locale].transliterate(string, replacement)
14
+ end
15
+
16
+ # Get a transliterator instance.
17
+ def self.get(rule = nil)
18
+ if !rule || rule.kind_of?(Hash)
19
+ HashTransliterator.new(rule)
20
+ elsif rule.kind_of? Proc
21
+ ProcTransliterator.new(rule)
22
+ else
23
+ raise I18n::ArgumentError, "Transliteration rule must be a proc or a hash."
24
+ end
25
+ end
26
+
27
+ # A transliterator which accepts a Proc as its transliteration rule.
28
+ class ProcTransliterator
29
+ def initialize(rule)
30
+ @rule = rule
31
+ end
32
+
33
+ def transliterate(string, replacement = nil)
34
+ @rule.call(string)
35
+ end
36
+ end
37
+
38
+ # A transliterator which accepts a Hash of characters as its translation
39
+ # rule.
40
+ class HashTransliterator
41
+ DEFAULT_APPROXIMATIONS = {
42
+ "À"=>"A", "Á"=>"A", "Â"=>"A", "Ã"=>"A", "Ä"=>"A", "Å"=>"A", "Æ"=>"AE",
43
+ "Ç"=>"C", "È"=>"E", "É"=>"E", "Ê"=>"E", "Ë"=>"E", "Ì"=>"I", "Í"=>"I",
44
+ "Î"=>"I", "Ï"=>"I", "Ð"=>"D", "Ñ"=>"N", "Ò"=>"O", "Ó"=>"O", "Ô"=>"O",
45
+ "Õ"=>"O", "Ö"=>"O", "×"=>"x", "Ø"=>"O", "Ù"=>"U", "Ú"=>"U", "Û"=>"U",
46
+ "Ü"=>"U", "Ý"=>"Y", "Þ"=>"Th", "ß"=>"ss", "à"=>"a", "á"=>"a", "â"=>"a",
47
+ "ã"=>"a", "ä"=>"a", "å"=>"a", "æ"=>"ae", "ç"=>"c", "è"=>"e", "é"=>"e",
48
+ "ê"=>"e", "ë"=>"e", "ì"=>"i", "í"=>"i", "î"=>"i", "ï"=>"i", "ð"=>"d",
49
+ "ñ"=>"n", "ò"=>"o", "ó"=>"o", "ô"=>"o", "õ"=>"o", "ö"=>"o", "ø"=>"o",
50
+ "ù"=>"u", "ú"=>"u", "û"=>"u", "ü"=>"u", "ý"=>"y", "þ"=>"th", "ÿ"=>"y",
51
+ "Ā"=>"A", "ā"=>"a", "Ă"=>"A", "ă"=>"a", "Ą"=>"A", "ą"=>"a", "Ć"=>"C",
52
+ "ć"=>"c", "Ĉ"=>"C", "ĉ"=>"c", "Ċ"=>"C", "ċ"=>"c", "Č"=>"C", "č"=>"c",
53
+ "Ď"=>"D", "ď"=>"d", "Đ"=>"D", "đ"=>"d", "Ē"=>"E", "ē"=>"e", "Ĕ"=>"E",
54
+ "ĕ"=>"e", "Ė"=>"E", "ė"=>"e", "Ę"=>"E", "ę"=>"e", "Ě"=>"E", "ě"=>"e",
55
+ "Ĝ"=>"G", "ĝ"=>"g", "Ğ"=>"G", "ğ"=>"g", "Ġ"=>"G", "ġ"=>"g", "Ģ"=>"G",
56
+ "ģ"=>"g", "Ĥ"=>"H", "ĥ"=>"h", "Ħ"=>"H", "ħ"=>"h", "Ĩ"=>"I", "ĩ"=>"i",
57
+ "Ī"=>"I", "ī"=>"i", "Ĭ"=>"I", "ĭ"=>"i", "Į"=>"I", "į"=>"i", "İ"=>"I",
58
+ "ı"=>"i", "IJ"=>"IJ", "ij"=>"ij", "Ĵ"=>"J", "ĵ"=>"j", "Ķ"=>"K", "ķ"=>"k",
59
+ "ĸ"=>"k", "Ĺ"=>"L", "ĺ"=>"l", "Ļ"=>"L", "ļ"=>"l", "Ľ"=>"L", "ľ"=>"l",
60
+ "Ŀ"=>"L", "ŀ"=>"l", "Ł"=>"L", "ł"=>"l", "Ń"=>"N", "ń"=>"n", "Ņ"=>"N",
61
+ "ņ"=>"n", "Ň"=>"N", "ň"=>"n", "ʼn"=>"'n", "Ŋ"=>"NG", "ŋ"=>"ng",
62
+ "Ō"=>"O", "ō"=>"o", "Ŏ"=>"O", "ŏ"=>"o", "Ő"=>"O", "ő"=>"o", "Œ"=>"OE",
63
+ "œ"=>"oe", "Ŕ"=>"R", "ŕ"=>"r", "Ŗ"=>"R", "ŗ"=>"r", "Ř"=>"R", "ř"=>"r",
64
+ "Ś"=>"S", "ś"=>"s", "Ŝ"=>"S", "ŝ"=>"s", "Ş"=>"S", "ş"=>"s", "Š"=>"S",
65
+ "š"=>"s", "Ţ"=>"T", "ţ"=>"t", "Ť"=>"T", "ť"=>"t", "Ŧ"=>"T", "ŧ"=>"t",
66
+ "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u", "Ů"=>"U",
67
+ "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W", "ŵ"=>"w",
68
+ "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z", "ż"=>"z",
69
+ "Ž"=>"Z", "ž"=>"z"
70
+ }
71
+
72
+ def initialize(rule = nil)
73
+ @rule = rule
74
+ add DEFAULT_APPROXIMATIONS
75
+ add rule if rule
76
+ end
77
+
78
+ def transliterate(string, replacement = nil)
79
+ string.gsub(/[^\x00-\x7f]/u) do |char|
80
+ approximations[char] || replacement || DEFAULT_REPLACEMENT_CHAR
81
+ end
82
+ end
83
+
84
+ private
85
+
86
+ def approximations
87
+ @approximations ||= {}
88
+ end
89
+
90
+ # Add transliteration rules to the approximations hash.
91
+ def add(hash)
92
+ hash.keys.each {|key| hash[key.to_s] = hash.delete(key).to_s}
93
+ approximations.merge! hash
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,84 @@
1
+ module I18n
2
+ class Config
3
+ # The only configuration value that is not global and scoped to thread is :locale.
4
+ # It defaults to the default_locale.
5
+ def locale
6
+ @locale ||= default_locale
7
+ end
8
+
9
+ # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
10
+ def locale=(locale)
11
+ @locale = locale.to_sym rescue nil
12
+ end
13
+
14
+ # Returns the current backend. Defaults to +Backend::Simple+.
15
+ def backend
16
+ @@backend ||= Backend::Simple.new
17
+ end
18
+
19
+ # Sets the current backend. Used to set a custom backend.
20
+ def backend=(backend)
21
+ @@backend = backend
22
+ end
23
+
24
+ # Returns the current default locale. Defaults to :'en'
25
+ def default_locale
26
+ @@default_locale ||= :en
27
+ end
28
+
29
+ # Sets the current default locale. Used to set a custom default locale.
30
+ def default_locale=(locale)
31
+ @@default_locale = locale.to_sym rescue nil
32
+ end
33
+
34
+ # Returns an array of locales for which translations are available.
35
+ # Unless you explicitely set the these through I18n.available_locales=
36
+ # the call will be delegated to the backend and memoized on the I18n module.
37
+ def available_locales
38
+ @@available_locales ||= backend.available_locales
39
+ end
40
+
41
+ # Sets the available locales.
42
+ def available_locales=(locales)
43
+ @@available_locales = locales
44
+ end
45
+
46
+ # Returns the current default scope separator. Defaults to '.'
47
+ def default_separator
48
+ @@default_separator ||= '.'
49
+ end
50
+
51
+ # Sets the current default scope separator.
52
+ def default_separator=(separator)
53
+ @@default_separator = separator
54
+ end
55
+
56
+ # Return the current exception handler. Defaults to :default_exception_handler.
57
+ def exception_handler
58
+ @@exception_handler ||= :default_exception_handler
59
+ end
60
+
61
+ # Sets the exception handler.
62
+ def exception_handler=(exception_handler)
63
+ @@exception_handler = exception_handler
64
+ end
65
+
66
+ # Allow clients to register paths providing translation data sources. The
67
+ # backend defines acceptable sources.
68
+ #
69
+ # E.g. the provided SimpleBackend accepts a list of paths to translation
70
+ # files which are either named *.rb and contain plain Ruby Hashes or are
71
+ # named *.yml and contain YAML data. So for the SimpleBackend clients may
72
+ # register translation files like this:
73
+ # I18n.load_path << 'path/to/locale/en.yml'
74
+ def load_path
75
+ @@load_path ||= []
76
+ end
77
+
78
+ # Sets the load path instance. Custom implementations are expected to
79
+ # behave like a Ruby Array.
80
+ def load_path=(load_path)
81
+ @@load_path = load_path
82
+ end
83
+ end
84
+ end