r18n-core 0.4.10 → 0.4.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/ChangeLog +5 -0
  2. data/Gemfile.lock +1 -1
  3. data/README.rdoc +25 -25
  4. data/Rakefile +0 -1
  5. data/lib/r18n-core.rb +5 -5
  6. data/lib/r18n-core/filters.rb +45 -45
  7. data/lib/r18n-core/helpers.rb +4 -4
  8. data/lib/r18n-core/i18n.rb +30 -30
  9. data/lib/r18n-core/locale.rb +26 -26
  10. data/lib/r18n-core/translated.rb +23 -23
  11. data/lib/r18n-core/translated_string.rb +4 -4
  12. data/lib/r18n-core/translation.rb +10 -10
  13. data/lib/r18n-core/unsupported_locale.rb +6 -6
  14. data/lib/r18n-core/untranslated.rb +13 -13
  15. data/lib/r18n-core/utils.rb +4 -4
  16. data/lib/r18n-core/version.rb +1 -1
  17. data/lib/r18n-core/yaml_loader.rb +13 -11
  18. data/locales/bg.rb +3 -3
  19. data/locales/ca.rb +6 -5
  20. data/locales/cs.rb +5 -5
  21. data/locales/da.rb +4 -4
  22. data/locales/de.rb +4 -4
  23. data/locales/en-us.rb +1 -1
  24. data/locales/en.rb +6 -6
  25. data/locales/eo.rb +4 -4
  26. data/locales/es.rb +4 -4
  27. data/locales/fi.rb +5 -5
  28. data/locales/fr.rb +6 -6
  29. data/locales/hu.rb +1 -1
  30. data/locales/it.rb +5 -5
  31. data/locales/ja.rb +5 -4
  32. data/locales/kk.rb +4 -4
  33. data/locales/lv.rb +5 -5
  34. data/locales/nl.rb +5 -5
  35. data/locales/pl.rb +5 -5
  36. data/locales/pt.rb +4 -4
  37. data/locales/ru.rb +5 -5
  38. data/locales/sk.rb +5 -5
  39. data/locales/sv-se.rb +4 -4
  40. data/locales/th.rb +7 -4
  41. data/locales/zh.rb +6 -5
  42. data/r18n-core.gemspec +0 -1
  43. data/spec/filters_spec.rb +48 -48
  44. data/spec/i18n_spec.rb +32 -32
  45. data/spec/locale_spec.rb +20 -20
  46. data/spec/locales/cs_spec.rb +2 -2
  47. data/spec/locales/hu_spec.rb +1 -1
  48. data/spec/locales/it_spec.rb +1 -1
  49. data/spec/locales/pl_spec.rb +2 -2
  50. data/spec/locales/ru_spec.rb +3 -3
  51. data/spec/locales/sk_spec.rb +2 -2
  52. data/spec/r18n_spec.rb +21 -21
  53. data/spec/spec_helper.rb +3 -3
  54. data/spec/translated_spec.rb +24 -24
  55. data/spec/translation_spec.rb +10 -10
  56. data/spec/yaml_loader_spec.rb +10 -10
  57. metadata +24 -26
@@ -20,9 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
20
20
 
21
21
  module R18n
22
22
  # Useful aliases. Set I18n object before use them:
23
- #
23
+ #
24
24
  # R18n.set('en')
25
- #
25
+ #
26
26
  # t.ok #=> "OK"
27
27
  # l Time.now, :human #=> "now"
28
28
  # r18n.locale.code #=> "en"
@@ -32,12 +32,12 @@ module R18n
32
32
  R18n.get
33
33
  end
34
34
  alias i18n r18n
35
-
35
+
36
36
  # Translate message. Alias for <tt>r18n.t</tt>.
37
37
  def t(*params)
38
38
  R18n.get.t(*params)
39
39
  end
40
-
40
+
41
41
  # Localize object. Alias for <tt>r18n.l</tt>.
42
42
  def l(*params)
43
43
  R18n.get.l(*params)
@@ -29,19 +29,19 @@ module R18n
29
29
  # translation’s name or <tt>[name]</tt> method. Translations will be also
30
30
  # loaded for default locale, +sublocales+ from first in +locales+ and general
31
31
  # languages for dialects (it will load +fr+ for +fr_CA+ too).
32
- #
32
+ #
33
33
  # Translations will loaded by loader object, which must have 2 methods:
34
34
  # * <tt>available</tt> – return array of locales of available translations;
35
35
  # * <tt>load(locale)</tt> – return Hash of translation.
36
36
  # If you will use default loader (+R18n.default_loader+) you can pass to I18n
37
37
  # only constructor argument for loader:
38
- #
38
+ #
39
39
  # R18n::I18n.new('en', R18n::Loader::YAML.new('dir/with/translations'))
40
- #
40
+ #
41
41
  # is a same as:
42
- #
42
+ #
43
43
  # R18n::I18n.new('en', 'dir/with/translations')
44
- #
44
+ #
45
45
  # In translation file you can use strings, numbers, floats (any YAML types)
46
46
  # and pluralizable values (<tt>!!pl</tt>). You can use params in string
47
47
  # values, which you can replace in program. Just write <tt>%1</tt>,
@@ -65,16 +65,16 @@ module R18n
65
65
  # two: Two
66
66
  #
67
67
  # example.rb
68
- #
68
+ #
69
69
  # i18n = R18n::I18n.new(['ru', 'en'], 'translations/')
70
- #
70
+ #
71
71
  # i18n.one #=> "Один"
72
72
  # i18n.two #=> "Two"
73
- #
73
+ #
74
74
  # i18n.locale.title #=> "Русский"
75
75
  # i18n.locale.code #=> "ru"
76
76
  # i18n.locale.ltr? #=> true
77
- #
77
+ #
78
78
  # i18n.l -11000.5 #=> "−11 000,5"
79
79
  # i18n.l Time.now #=> "Вск, 21 сен 2008, 22:10:10 MSD"
80
80
  # i18n.l Time.now, :date #=> "21.09.2008"
@@ -97,7 +97,7 @@ module R18n
97
97
  def self.default
98
98
  @@default
99
99
  end
100
-
100
+
101
101
  # Parse HTTP_ACCEPT_LANGUAGE and return array of user locales
102
102
  def self.parse_http(str)
103
103
  return [] if str.nil?
@@ -113,12 +113,12 @@ module R18n
113
113
  locales.sort! { |a, b| b[1] <=> a[1] }
114
114
  locales.map! { |i| i[0] }
115
115
  end
116
-
116
+
117
117
  # Return Array of locales with available translations.
118
118
  def self.available_locales(places)
119
119
  convert_places(places).map { |i| i.available }.flatten.uniq
120
120
  end
121
-
121
+
122
122
  # Load default loader for elements in +places+ with only constructor
123
123
  # argument.
124
124
  def self.convert_places(places)
@@ -130,16 +130,16 @@ module R18n
130
130
  end
131
131
  end
132
132
  end
133
-
133
+
134
134
  # User locales, ordered by priority
135
135
  attr_reader :locales
136
-
136
+
137
137
  # Loaders with translations files
138
138
  attr_reader :translation_places
139
-
139
+
140
140
  # First locale with locale file
141
141
  attr_reader :locale
142
-
142
+
143
143
  # Create i18n for +locales+ with translations from +translation_places+ and
144
144
  # locales data. Translations will be also loaded for default locale,
145
145
  # +sublocales+ from first in +locales+ and general languages for dialects
@@ -149,7 +149,7 @@ module R18n
149
149
  # +Translation_places+ must be a string with path or array.
150
150
  def initialize(locales, translation_places = nil)
151
151
  locales = Array(locales)
152
-
152
+
153
153
  if not locales.empty? and Locale.exists? locales.first
154
154
  locales += Locale.load(locales.first).sublocales
155
155
  end
@@ -162,16 +162,16 @@ module R18n
162
162
  locales.map! { |i| i.to_s.downcase }.uniq!
163
163
  @locales_codes = locales
164
164
  @locales = locales.map { |i| Locale.load(i) }
165
-
165
+
166
166
  if translation_places
167
167
  @original_places = translation_places
168
168
  else
169
169
  @original_places = R18n.extension_places
170
170
  @locale = @locales.first
171
171
  end
172
-
172
+
173
173
  @translation_places = self.class.convert_places(@original_places)
174
-
174
+
175
175
  key = translation_cache_key
176
176
  if R18n.cache.has_key? key
177
177
  @locale, @translation = *R18n.cache[key]
@@ -179,7 +179,7 @@ module R18n
179
179
  reload!
180
180
  end
181
181
  end
182
-
182
+
183
183
  # Return unique key for current locales in translation and places.
184
184
  def translation_cache_key
185
185
  @available_codes ||= @translation_places.inject([]) { |all, i|
@@ -188,15 +188,15 @@ module R18n
188
188
  R18n.default_loader.hash.to_s +
189
189
  @translation_places.hash.to_s + R18n.extension_places.hash.to_s
190
190
  end
191
-
191
+
192
192
  # Reload translations.
193
193
  def reload!
194
194
  @available = @available_codes = nil
195
195
  @translation_places = self.class.convert_places(@original_places)
196
-
196
+
197
197
  available_in_places = @translation_places.map { |i| [i, i.available] }
198
198
  available_in_extensions = R18n.extension_places.map {|i| [i, i.available]}
199
-
199
+
200
200
  unless @locale
201
201
  available_in_places.each do |place, available|
202
202
  @locales.each do |locale|
@@ -217,7 +217,7 @@ module R18n
217
217
  end
218
218
  end
219
219
  end
220
-
220
+
221
221
  @translation = Translation.new @locale
222
222
  @locales.each do |locale|
223
223
  loaded = false
@@ -235,15 +235,15 @@ module R18n
235
235
  end
236
236
  end
237
237
  end
238
-
238
+
239
239
  R18n.cache[translation_cache_key] = [@locale, @translation]
240
240
  end
241
-
241
+
242
242
  # Return Array of locales with available translations.
243
243
  def available_locales
244
244
  @available ||= self.class.available_locales(@translation_places)
245
245
  end
246
-
246
+
247
247
  # Convert +object+ to String, according to the rules of the current locale.
248
248
  # It support Fixnum, Bignum, Float, Time, Date and DateTime.
249
249
  #
@@ -261,12 +261,12 @@ module R18n
261
261
  locale.localize(object, format, self, *params)
262
262
  end
263
263
  alias :l :localize
264
-
264
+
265
265
  # Return translations.
266
266
  def t
267
267
  @translation
268
268
  end
269
-
269
+
270
270
  # Return translation with special +name+.
271
271
  #
272
272
  # Translation can contain variable part. Just set is as <tt>%1</tt>,
@@ -56,7 +56,7 @@ module R18n
56
56
  # <tt>locales/</tt> dir.
57
57
  class Locale
58
58
  LOCALES_DIR = Pathname(__FILE__).dirname.expand_path + '../../locales/'
59
-
59
+
60
60
  @@loaded = {}
61
61
 
62
62
  # Codes of all available locales.
@@ -75,7 +75,7 @@ module R18n
75
75
  def self.load(code)
76
76
  original = code.to_s.gsub(/[^-_a-zA-Z]/, '')
77
77
  code = original.gsub('_', '-').downcase
78
-
78
+
79
79
  @@loaded[code] ||= begin
80
80
  if exists? code
81
81
  require LOCALES_DIR + "#{code}.rb"
@@ -86,15 +86,15 @@ module R18n
86
86
  end
87
87
  end
88
88
  end
89
-
89
+
90
90
  # Set locale +properties+. Locale class will have methods for each propetry
91
91
  # name, which return propetry value:
92
- #
92
+ #
93
93
  # class R18n::Locales::En < R18n::Locale
94
94
  # set :title => 'English',
95
95
  # :code => 'en'
96
96
  # end
97
- #
97
+ #
98
98
  # locale = R18n::Locales::En.new
99
99
  # locale.title #=> "English"
100
100
  # locale.code #=> "en"
@@ -103,12 +103,12 @@ module R18n
103
103
  define_method(key) { value }
104
104
  end
105
105
  end
106
-
106
+
107
107
  # Locale RFC 3066 code.
108
108
  def code
109
109
  self.class.name.split('::').last.downcase
110
110
  end
111
-
111
+
112
112
  set :sublocales => %w{en},
113
113
  :week_start => :monday,
114
114
  :time_am => 'AM',
@@ -116,10 +116,10 @@ module R18n
116
116
  :time_format => ' %H:%M',
117
117
  :full_format => '%e %B',
118
118
  :year_format => '_ %Y'
119
-
119
+
120
120
  def month_standalone; month_names; end
121
121
  def month_abbrs; month_names; end
122
-
122
+
123
123
  # Is locale has left-to-right write direction.
124
124
  def ltr?; true; end
125
125
 
@@ -127,7 +127,7 @@ module R18n
127
127
  def ==(locale)
128
128
  self.class == locale.class
129
129
  end
130
-
130
+
131
131
  # Is locale has information file. In this class always return true.
132
132
  def supported?
133
133
  true
@@ -137,7 +137,7 @@ module R18n
137
137
  def inspect
138
138
  "Locale #{code} (#{title})"
139
139
  end
140
-
140
+
141
141
  # Convert +object+ to String. It support Fixnum, Bignum, Float, Time, Date
142
142
  # and DateTime.
143
143
  #
@@ -155,39 +155,39 @@ module R18n
155
155
  return strftime(obj, format) if format.is_a? String
156
156
  return month_standalone[obj.month - 1] if :month == format
157
157
  return obj.to_s if :human == format and not params.first.is_a? I18n
158
-
158
+
159
159
  type = obj.is_a?(Date) ? 'date' : 'time'
160
160
  format = :standard unless format
161
-
161
+
162
162
  unless [:human, :full, :standard].include? format
163
163
  raise ArgumentError, "Unknown time formatter #{format}"
164
164
  end
165
-
165
+
166
166
  send "format_#{type}_#{format}", obj, *params
167
167
  else
168
168
  obj.to_s
169
169
  end
170
170
  end
171
-
171
+
172
172
  # Returns the integer in String form, according to the rules of the locale.
173
173
  # It will also put real typographic minus.
174
174
  def format_integer(integer)
175
175
  str = integer.to_s
176
176
  str[0] = '−' if 0 > integer # Real typographic minus
177
177
  group = number_group
178
-
178
+
179
179
  str.gsub(/(\d)(?=(\d\d\d)+(?!\d))/) do |match|
180
180
  match + group
181
181
  end
182
182
  end
183
-
183
+
184
184
  # Returns the float in String form, according to the rules of the locale.
185
185
  # It will also put real typographic minus.
186
186
  def format_float(float)
187
187
  decimal = number_decimal
188
188
  self.format_integer(float.to_i) + decimal + float.to_s.split('.').last
189
189
  end
190
-
190
+
191
191
  # Same that <tt>Time.strftime</tt>, but translate months and week days
192
192
  # names. In +time+ you can use Time, DateTime or Date object. In +format+
193
193
  # you can use standard +strftime+ format.
@@ -211,12 +211,12 @@ module R18n
211
211
  end
212
212
  time.strftime(translated)
213
213
  end
214
-
214
+
215
215
  # Format +time+ without date. For example, “12:59”.
216
216
  def format_time(time)
217
217
  strftime(time, time_format)
218
218
  end
219
-
219
+
220
220
  # Format +time+ in human usable form. For example “5 minutes ago” or
221
221
  # “yesterday”. In +now+ you can set base time, which be used to get relative
222
222
  # time. For special cases you can replace it in locale’s class.
@@ -240,18 +240,18 @@ module R18n
240
240
  end
241
241
  end
242
242
  end
243
-
243
+
244
244
  # Format +time+ in compact form. For example, “12/31/09 12:59”.
245
245
  def format_time_standard(time, *params)
246
246
  format_date_standard(time) + format_time(time)
247
247
  end
248
-
248
+
249
249
  # Format +time+ in most official form. For example, “December 31st, 2009
250
250
  # 12:59”. For special cases you can replace it in locale’s class.
251
251
  def format_time_full(time, *params)
252
252
  format_date_full(time) + format_time(time)
253
253
  end
254
-
254
+
255
255
  # Format +date+ in human usable form. For example “5 days ago” or
256
256
  # “yesterday”. In +now+ you can set base time, which be used to get relative
257
257
  # time. For special cases you can replace it in locale’s class.
@@ -272,12 +272,12 @@ module R18n
272
272
  format_date_full(date, date.year != now.year)
273
273
  end
274
274
  end
275
-
275
+
276
276
  # Format +date+ in compact form. For example, “12/31/09”.
277
277
  def format_date_standard(date, *params)
278
278
  strftime(date, date_format)
279
279
  end
280
-
280
+
281
281
  # Format +date+ in most official form. For example, “December 31st, 2009”.
282
282
  # For special cases you can replace it in locale’s class. If +year+ is false
283
283
  # date will be without year.
@@ -300,6 +300,6 @@ module R18n
300
300
  end
301
301
  end
302
302
  end
303
-
303
+
304
304
  module Locales; end
305
305
  end
@@ -21,43 +21,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
21
21
  module R18n
22
22
  # Module to add i18n support to any class. It will be useful for ORM or
23
23
  # R18n plugin with out-of-box i18n support.
24
- #
24
+ #
25
25
  # Module can add proxy-methods to find translation in object methods. For
26
26
  # example, if you class have +title_en+ and +title_ru+ methods, you can add
27
27
  # proxy-method +title+, which will use +title_ru+ for Russian users and
28
28
  # +title_en+ for English:
29
- #
29
+ #
30
30
  # require 'r18n-core/translated'
31
- #
31
+ #
32
32
  # class Product
33
33
  # include DataMapper::Resource
34
34
  # property :title_ru, String
35
35
  # property :title_en, String
36
36
  # property :desciption_ru, String
37
37
  # property :desciption_en, String
38
- #
38
+ #
39
39
  # include R18n::Translated
40
40
  # translations :title, :desciption
41
41
  # end
42
- #
42
+ #
43
43
  # # User know only Russian
44
44
  # R18n.set('ru')
45
- #
45
+ #
46
46
  # product.title #=> Untranslated
47
- #
47
+ #
48
48
  # # Set value to English (default) title
49
49
  # product.title_en = "Anthrax"
50
50
  # product.title #=> "Anthrax"
51
51
  # product.title.locale #=> Locale en (English)
52
- #
52
+ #
53
53
  # # Set value to title on user locale (Russian)
54
54
  # product.title = "Сибирская язва"
55
55
  # product.title #=> "Сибирская язва"
56
56
  # product.title.locale #=> Locale ru (Russian)
57
- #
57
+ #
58
58
  # product.title_en #=> "Anthrax"
59
59
  # product.title_ru #=> "Сибирская язва"
60
- #
60
+ #
61
61
  # Proxy-method support all funtion from I18n: global and type filters,
62
62
  # pluralization, variables. It also return TranslatedString or Untranslated.
63
63
  #
@@ -67,7 +67,7 @@ module R18n
67
67
  # must call <tt>i18n</tt> helper in Sinatra before use models.
68
68
  #
69
69
  # See R18n::Translated::Base for class method documentation.
70
- #
70
+ #
71
71
  # == Options
72
72
  # You can set option for proxy-method as Hash with keys;
73
73
  # * +type+ – YAML type for filters. For example, "markdown" or "escape_html".
@@ -75,9 +75,9 @@ module R18n
75
75
  # * +no_params+ – set it to true if you proxy-method must send it parameters
76
76
  # only to filters.
77
77
  # * +no_write+ – set it to true if you don’t want to create proxy-setters.
78
- #
78
+ #
79
79
  # Method +translation+ will be more useful for options:
80
- #
80
+ #
81
81
  # translation :title, :methods => {:ru => :russian, :en => :english}
82
82
  module Translated
83
83
  class << self
@@ -88,12 +88,12 @@ module R18n
88
88
  base.instance_variable_set '@translation_types', {}
89
89
  end
90
90
  end
91
-
91
+
92
92
  # Module with class methods, which be added after R18n::Translated include.
93
93
  module Base
94
94
  # Hash of translation method names to it type for filters.
95
95
  attr_reader :translation_types
96
-
96
+
97
97
  # Add several proxy +methods+. See R18n::Translated for description.
98
98
  # It’s more compact, that +translation+.
99
99
  #
@@ -103,7 +103,7 @@ module R18n
103
103
  translation(*method)
104
104
  end
105
105
  end
106
-
106
+
107
107
  # Add proxy-method +name+. See R18n::Translated for description.
108
108
  # It’s more useful to set options.
109
109
  #
@@ -117,10 +117,10 @@ module R18n
117
117
  hash_map(options[:methods]) { |l, i| [ l.to_s, i.to_s + '=' ] }
118
118
  end
119
119
  end
120
-
120
+
121
121
  @translation_types[name] = options[:type]
122
122
  params = options[:no_params] ? '' : ', *params'
123
-
123
+
124
124
  class_eval <<-EOS, __FILE__, __LINE__
125
125
  def #{name}(*params)
126
126
  unlocalized = self.class.unlocalized_getters(#{name.inspect})
@@ -129,7 +129,7 @@ module R18n
129
129
  next unless unlocalized.has_key? code
130
130
  result = send unlocalized[code]#{params}
131
131
  next unless result
132
-
132
+
133
133
  path = "\#{self.class.name}##{name}"
134
134
  type = self.class.translation_types[#{name.inspect}]
135
135
  if type
@@ -143,12 +143,12 @@ module R18n
143
143
  return result
144
144
  end
145
145
  end
146
-
146
+
147
147
  R18n::Untranslated.new("\#{self.class.name}\#", '#{name}',
148
148
  R18n.get.locale)
149
149
  end
150
150
  EOS
151
-
151
+
152
152
  unless options[:no_write]
153
153
  class_eval <<-EOS, __FILE__, __LINE__
154
154
  def #{name}=(*params)
@@ -162,7 +162,7 @@ module R18n
162
162
  EOS
163
163
  end
164
164
  end
165
-
165
+
166
166
  # Return array of methods to find +unlocalized_getters+ or
167
167
  # +unlocalized_setters+.
168
168
  def unlocalized_methods
@@ -182,7 +182,7 @@ module R18n
182
182
  end
183
183
  @unlocalized_getters[method]
184
184
  end
185
-
185
+
186
186
  # Return Hash of locale code to setter method for proxy +method+. If you
187
187
  # didn’t set map in +translation+ option +methods+, it will be detect
188
188
  # automatically.