Class: I18n::Translate::Translate

Inherits:
Object
  • Object
show all
Defined in:
lib/i18n/translate.rb

Overview

it breaks proc and lambdas objects

Constant Summary collapse

DEFAULT_OPTIONS =
{
  :separator => ".",       # default key separator e.g. "model.article.message.not.found"
  :locale_dir => "locale", # where to search for files
  :default => "default",   # default name for file containing default app's key => string
  :force_encoding => true, # in ruby 1.9 forces string encoding
  :encoding => "utf-8",    # encoding name to be forced to
  :format => "auto",       # auto, rb, yml
  :merge => "soft",        # hard or soft: hard strips old keys from target and soft set it to obsolete
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lang, opts = {}) ⇒ Translate

loads default and lang files



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/i18n/translate.rb', line 199

def initialize(lang, opts={})
  @lang = lang.to_s
  raise "Empty locale" if @lang.empty? and not opts[:empty]

  # merge options
  @options = DEFAULT_OPTIONS.merge(opts)

  # select default format
  @options[:default_format] ||= @options[:format]
  if (@options[:default_format] == @options[:format]) and not opts[:default_format]
    dfname = file_name(@options[:default], @options[:default_format])
    @options[:default_format] = "auto" unless File.exists?(dfname)
  end

  # load default data and translation
  if @lang and not opts[:empty]
    @default, @default_file = load_locale( @options[:default], @options[:default_format] )
    @target, @lang_file = load_locale( @lang )
    merge!
  end
end

Instance Attribute Details

#defaultObject (readonly)

Returns the value of attribute default.



196
197
198
# File 'lib/i18n/translate.rb', line 196

def default
  @default
end

#default_fileObject (readonly)

Returns the value of attribute default_file.



196
197
198
# File 'lib/i18n/translate.rb', line 196

def default_file
  @default_file
end

#langObject (readonly)

Returns the value of attribute lang.



196
197
198
# File 'lib/i18n/translate.rb', line 196

def lang
  @lang
end

#lang_fileObject (readonly)

Returns the value of attribute lang_file.



196
197
198
# File 'lib/i18n/translate.rb', line 196

def lang_file
  @lang_file
end

#mergeObject (readonly)

Returns the value of attribute merge.



196
197
198
# File 'lib/i18n/translate.rb', line 196

def merge
  @merge
end

#optionsObject (readonly)

Returns the value of attribute options.



196
197
198
# File 'lib/i18n/translate.rb', line 196

def options
  @options
end

#targetObject (readonly)

Returns the value of attribute target.



196
197
198
# File 'lib/i18n/translate.rb', line 196

def target
  @target
end

Class Method Details

.valid_file?(fname, format = ) ⇒ Boolean

check if the file has supported format

Returns:

  • (Boolean)


222
223
224
225
226
227
228
229
230
231
# File 'lib/i18n/translate.rb', line 222

def self.valid_file?(fname, format=Translate::DEFAULT_OPTIONS[:format])
  pattern = "[^\.]+"
  pattern = format if format != "auto"
  fname =~ /\/?([^\/]*?)\.(#{pattern})$/
  locale, format = $1, $2
  if I18n::Translate::FORMATS.include?($2)
    return [locale, format]
  end
  nil
end

Instance Method Details

#[](key) ⇒ Object

will merge only one key and returns hash

{
  'key' => 'key',
  'default' => '',              # value set in default file
  'old_default' => '',          # value set as old in target file
                                 (value from default file from last translation
                                 if the field has changed)
  'old_translation' => '',      # if flag == 'changed' then old_translation = t and t = ''
  'translation' => '',          # value set in target file
  'comment' => ''               # a comment added by a translator
  'flag' => ok || incomplete || changed || untranslated || obsolete
                                # set by merging tool except incomplete
                                  which is set by translator
 # other keys helded for compatibility with other formats
}


248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/i18n/translate.rb', line 248

def [](key)
  d = I18n::Translate.find(key, @default, @options[:separator])
  raise "Translate#[key]: wrong key '#{key}'" unless d

  entry = {"key" => key, "default" => d}
  if d.kind_of? Hash
    entry["default"] = d["translation"] || d["t"] || d["default"]
  end
  
  # translation doesn't exist
  trg = I18n::Translate.find(key, @target, @options[:separator])
  if (not trg) or
     (trg.kind_of?(String) and trg.strip.empty?) or
     (trg.kind_of?(Hash) and trg["translation"].to_s.strip.empty?)
    entry["old_default"] = ""
    entry["old_translation"] = ""
    entry["translation"] = ""
    entry["comment"] = trg.kind_of?(Hash) ? trg["comment"].to_s.strip : ""
    entry["flag"] = "untranslated"
    return entry
  end

  # default has changed => new translation is probably required
  if trg.kind_of?(Hash)
    entry["old_translation"] = trg["translation"].to_s.strip
    entry["translation"] = ""
    entry["comment"] = trg["comment"].to_s.strip
    entry["flag"] = "changed"

    if d != trg["default"]
      entry["old_default"] = trg["default"].to_s.strip
      return entry
    elsif not trg["old_default"].to_s.strip.empty?
      entry["old_default"] =  trg["old_default"].to_s.strip
      return entry
    end
  end

  # nothing has changed 
  entry["old_default"] = trg.kind_of?(Hash) ? trg["old_default"].to_s.strip : ""
  entry["old_translation"] = ""
  entry["translation"] = trg.kind_of?(Hash) ? trg["translation"].to_s.strip : trg.to_s.strip
  entry["comment"] = trg.kind_of?(Hash) ? trg["comment"].to_s.strip : ""
  entry["flag"] = (trg.kind_of?(Hash) and trg["flag"]) ? trg["flag"].to_s.strip : "ok"

  entry
end

#[]=(key, value) ⇒ Object

will create path in @target for ‘key’ and set the ‘value’



307
308
309
# File 'lib/i18n/translate.rb', line 307

def []=(key, value)
  I18n::Translate.set(key, value, @target, @options[:separator])
end

#assign(translation) ⇒ Object

merge merged and edited hash into @target translation can be hash or array

  • array format is the same as self.merge is

    => , t =>, …, =>, …, …
  • hash format is supposed to be the format obtained from web form => {t =>, …, :key => …, …}



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/i18n/translate.rb', line 317

def assign(translation)
  translation.each do |transl|
    key, values = nil
    if transl.kind_of?(Hash)
      # merge format: [{key => , t =>, ...}, ...]
      key, values = transl["key"], transl
    elsif transl.kind_of?(Array)
      # web format: {key => {t => }, ...}
      key, values = transl
    end

    old_t = values["old_translation"].to_s.strip
    new_t = values["translation"].to_s.strip
    default = values["default"].to_s.strip
    old_default = values["old_default"].to_s.strip
    flag = values["flag"].to_s.strip
    comment = values["comment"].to_s.strip

    if old_t.respond_to?("force_encoding") and @options[:force_encoding]
      enc = @options[:encoding]
      old_t.force_encoding(enc)
      new_t.force_encoding(enc)
      default.force_encoding(enc)
      old_default.force_encoding(enc)
      flag.force_encoding(enc)
      comment.force_encoding(enc)
    end

    # merging with unknown fields
    trg = find(key)
    trg = {} if trg.nil? or not trg.kind_of?(Hash)
    trg["comment"] = comment
    trg["flag"] = flag

    if flag == "ok"
      trg["translation"] = new_t.empty? ? old_t : new_t
      trg["default"] = default
      trg["old_default"] = "" 
    else
      trg["translation"] = new_t.empty? ? old_t : new_t
      trg["default"] = default
      trg["old_default"] = old_default
    end

    # make fallback work
    trg["translation"] = nil if trg["translation"].empty?

    # say that this entry is not completed yet
    # useful if you edit files in text editor and serching for next one
    trg["fuzzy"] = true if flag != "ok"

    # clean empty values
    trg.delete_if{ |k,v| v.to_s.empty? }

    self[key] = trg
  end
  obsolete!
end

#delete(key) ⇒ Object



301
302
303
304
# File 'lib/i18n/translate.rb', line 301

def delete(key)
  I18n::Translate.delete(key, @default, @options[:separator])
  I18n::Translate.delete(key, @target, @options[:separator])
end

#export!Object

export @target to file



413
414
415
# File 'lib/i18n/translate.rb', line 413

def export!
  save_locale(@lang)
end

#find(key, hash = @target, separator = ) ⇒ Object

wrapper for I18n::Translate.find with presets options



297
298
299
# File 'lib/i18n/translate.rb', line 297

def find(key, hash=@target, separator=@options[:separator])
  I18n::Translate.find(key, hash, separator)
end

#merge!Object

merge @default and @target into list @merge



408
409
410
# File 'lib/i18n/translate.rb', line 408

def merge!
  @merge = merge_locale
end

#obsolete!(merge = ) ⇒ Object



376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/i18n/translate.rb', line 376

def obsolete!(merge = @options[:merge])
  def_keys = I18n::Translate.hash_to_keys(@default, @options[:separator]).sort
  trg_keys = I18n::Translate.hash_to_keys(@target, @options[:separator]).sort

  obsolete_keys = trg_keys - def_keys
  obsolete_keys.each do |key|
    if merge == "hard"
      I18n::Translate.delete(key, @target, @options[:separator])
      next
    end

    trg = find(key)
    next unless trg

    if trg.kind_of?(String)
      trg = {"translation" => trg, "flag" => "obsolete"}
    else
      trg["flag"] = "obsolete"
      trg["fuzzy"] = true
    end

    I18n::Translate.set(key, trg, @target, @options[:separator])
  end
end

#reload!Object

re-read @target data from the disk and create @merge



402
403
404
405
# File 'lib/i18n/translate.rb', line 402

def reload!
  @target, @lang_file  = load_locale( @lang )
  merge!
end

#statObject

returns statistics hash => N, :ok => N, :changed => N, :obsolete => N, :incomplete => N, :untranslated => N, :fuzzy => N, :progress => N



434
435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/i18n/translate.rb', line 434

def stat
  stat = {
    :total => @merge.size,
    :ok => @merge.select{|e| e["flag"] == "ok"}.size,
    :changed => @merge.select{|e| e["flag"] == "changed"}.size,
    :incomplete => @merge.select{|e| e["flag"] == "incomplete"}.size,
    :untranslated => @merge.select{|e| e["flag"] == "untranslated"}.size,
    :obsolete => @merge.select{|e| e["flag"] == "obsolete"}.size,
    :fuzzy => @merge.select{|e| e["flag"] != "ok"}.size
  }
  stat[:progress] = (stat[:ok].to_f / stat[:total].to_f) * 100
  stat
end

#strip!Object

throw away translators metadata and convert hash to default I18n format



419
420
421
422
423
424
425
426
427
428
429
430
# File 'lib/i18n/translate.rb', line 419

def strip!
  keys = I18n::Translate.hash_to_keys(@default, @options[:separator])
  keys.each do |key|
    entry = I18n::Translate.find(key, @target, @options[:separator])
    next unless entry # skip entries that are not merged in target yet
    #raise "Translate#[key]: wrong key '#{key}'" unless entry
    next unless entry.kind_of?(Hash)
    self[key] = entry["translation"]
  end
  
  self
end