r18n-core 0.4.10 → 0.4.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.