class AnnoTranslate::TranslationsExporter

Public Class Methods

export(file_prefix, export_to=nil) click to toggle source
# File lib/import_export.rb, line 9
def self.export(file_prefix, export_to=nil)
  exporter = self.new(file_prefix, export_to)
  exporter.export_translations
end
new(file_prefix, export_to=nil) click to toggle source
# File lib/import_export.rb, line 14
def initialize(file_prefix, export_to=nil)
  # Format pertinent paths for files
  here = File.expand_path(File.dirname(__FILE__))
  config = File.expand_path(File.join(here, "..", "..", "config"))
  @locales_folder = File.join(config, "locales")
  @base_yml_file = File.join(@locales_folder, "en.yml")
  @prefix = file_prefix
  @translations_support = File.join(config, "translations")
  @duplicates_file = File.join(@translations_support, "#{@prefix}_shared_strings.yml")
  @export_folder = export_to ? export_to : File.join(@translations_support, "export")

  @base_locale = YAML.load_file(@base_yml_file)
  @cache = YAML.load_file(@duplicates_file)

  FileUtils.rm_f Dir["#{@export_folder}/*.csv"]

  # Create supported foreign languages collection
  @foreign_languages = FOREIGN_LOCALES.keys.map do |code|
    source_yml = File.join(@locales_folder, "#{code}.yml")
    dest_csv = File.join(@export_folder, "#{@prefix}.#{code}.csv")
    {code: code, name: FOREIGN_LOCALES[code], yml: source_yml, csv: dest_csv}
  end
end

Public Instance Methods

export_translations() click to toggle source
# File lib/import_export.rb, line 38
def export_translations
  # Load English strings first to use as golden copy of all translatable strings/keys
  load_english_strings

  # Generate CSV export files for each foreign language
  @foreign_languages.each do |lang|
    puts "Exporting #{lang[:name]} (#{lang[:code]}) translations"
    puts "  from:  #{lang[:yml]}" if File.exist? lang[:yml]
    puts "  using: #{@base_yml_file}"
    puts "  to:    #{lang[:csv]}"

    # Export keys/translations to the proper CSV file
    CSV.open(lang[:csv], "wb", encoding: 'UTF-8') do |csv|
      csv << ["Key", "String#", "English Version", "#{lang[:name]} Translation"]
      index = 0
      load_translations(lang).each do |id, translation|
        csv << [id, index+1, @english[index].last, translation]
        index += 1
      end
    end
  end
end

Private Instance Methods

hash_to_pairs(h, cache={}, prefix=nil) click to toggle source
# File lib/import_export.rb, line 112
def hash_to_pairs(h, cache={}, prefix=nil)
  h.flat_map do |k,v|
    k = "#{prefix}.#{k}" if prefix
    case v
    when Hash
      hash_to_pairs v, cache, k
    else
      cache[v] ||= []
      cache[v] << k
      if cache[v].count > 1
        # The string content has already been tracked; let's just make a note in the cache
        # that this key also refers to the current string.
        #puts "#{v.inspect} is referred to by multiple keys: #{cache[v].join(" ")}"
        []
      else
        [[k,v]]
      end
    end
  end
end
load_english_strings() click to toggle source
# File lib/import_export.rb, line 63
def load_english_strings
  @cache = {}
  new_hash = YAML.load_file(@base_yml_file)
  @english = hash_to_pairs(new_hash, @cache)
  linked_keys = @cache.values.select{|r| r.count > 1}

  # Create empty translations template with keys from English
  @valid_ids = []
  @template = []
  @english.each do |id, string|
    @valid_ids << replace_id_locale(id)
    @template << [id, '']
  end

  # Report duplicated strings for sharing translations
  if !linked_keys.empty?
    puts "#{linked_keys.count} duplicate strings found! (see #{@duplicates_file} for details)"
  else
    puts "No duplicate strings detected"
  end
  File.open(@duplicates_file, "wb") do |cf|
    cf.print YAML.dump(linked_keys)
  end
  puts "Found a total of #{@english.count} translatable strings"
end
load_translations(config) click to toggle source
# File lib/import_export.rb, line 89
def load_translations(config)
  # Create from template
  translations = @template.dup.map{|id, translation| [replace_id_locale(id, config[:code]), translation]}

  # Merge in existing translations, if they exist
  if File.exist? config[:yml]
    hash_to_pairs(YAML.load_file(config[:yml])).each do |id, translation|
      found_at = @valid_ids.index(replace_id_locale(id))
      raise "Invalid translation ID '#{id}' found in #{config[:yml]}" unless found_at
      translations[found_at] = [id, translation]
    end
  end

  translations
end
replace_id_locale(id, replacement='') click to toggle source
# File lib/import_export.rb, line 107
def replace_id_locale(id, replacement='')
  replacement += '.' if !replacement.empty? && !replacement !~ /\.$/
  id.dup.sub(/^[a-z]{2,2}-?[A-Z]{0,2}\./, replacement)
end