Class: I18n::Migrations::GoogleTranslateDictionary

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

Constant Summary collapse

VARIABLE_STRING_REGEX =
/%\{[^\}]+\}/
HTML_ESCAPE_REGEX =
/&[A-Za-z#0-9]+;/
HTML_ESCAPES =
{
    ''' => "'",
    '&' => '&',
    '&lt;' => '<',
    '&gt;' => '>',
    '&quot;' => '"',
    '&nbsp;' => ' ',
    '&#8594;' => '',
    '&#8592;' => '',
    '&hellip;' => '',
}

Instance Method Summary collapse

Constructor Details

#initialize(from_locale:, to_locale:, key:, do_not_translate:) ⇒ GoogleTranslateDictionary

Returns a new instance of GoogleTranslateDictionary.



7
8
9
# File 'lib/i18n/migrations/google_translate_dictionary.rb', line 7

def initialize(from_locale:, to_locale:, key:, do_not_translate:)
  @from_locale, @to_locale, @key, @do_not_translate = from_locale, to_locale, key, do_not_translate
end

Instance Method Details

#fix(before, after, key: nil) ⇒ Object

returns updated after term, errors



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/i18n/migrations/google_translate_dictionary.rb', line 43

def fix(before, after, key: nil)
  is_html = format(key) == :html
  errors = ["#{@to_locale}: #{key}"]

  # do not translate
  @do_not_translate.each do |term, bad_translations|
    if before.include?(term) && !after.include?(term)
      if (translation = find_included_translation(after, bad_translations))
        after = after.gsub(translation, term)
      else
        errors << "missing #{term}"
      end
    end
  end

  # common mistakes
  after = after
              .gsub('% {', '%{')
              .gsub('%{', '%{')

  # match up variables, should have same variable in before and after
  before_variables = before.scan(VARIABLE_STRING_REGEX)
  after_variables = after.scan(VARIABLE_STRING_REGEX)

  if before_variables.sort == after_variables.sort
    # we have all of our variables, let's make sure spacing before them is correct

    unless no_spaces?
      before_variables.each do |variable|
        before_index = before =~ /(.?)#{variable}/
        before_leading = $1
        after_index = after =~ /(.?)#{variable}/
        after_leading = $1

        if before_index && after_index &&
            before_leading == ' ' && after_leading != ' ' &&
            after_index != 0
          after = after.sub(variable, " #{variable}")
        end
      end
    end

  else
    # we don't have all the variables we should have
    missing = before_variables - after_variables
    extra = after_variables - before_variables

    # we'll try to fix if it looks easy
    if missing.length == 1 && extra.length == 1
      after = after.sub(extra.first, missing.first)
    else
      errors << "missing #{missing.join(', ')}" if missing.length > 0
      errors << "extra #{extra.join(', ')}" if extra.length > 0
    end
  end

  # fix html escapes
  escapes = after.scan(HTML_ESCAPE_REGEX)
  if escapes.present?
    before_escapes = before.scan(HTML_ESCAPE_REGEX)
    escapes.each do |escape|
      if is_html && before_escapes.include?(escape)
        # leave it
      else
        if (replace_with = HTML_ESCAPES[escape])
          after = after.sub(escape, replace_with)
        else
          errors << "Don't know how to clean up #{escape}"
        end
      end
    end
  end


  [after, errors.length > 1 ? errors : []]
end

#lookup(term, key: nil) ⇒ Object

key is provided so we can figure out if this is text or html returns [translated term, notes]



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/i18n/migrations/google_translate_dictionary.rb', line 13

def lookup(term, key: nil)
  return [term, ''] if @from_locale == @to_locale

  response = google_translate(key: @key,
                              source: @from_locale,
                              target: @to_locale,
                              format: format(key),
                              q: term)
  translated_term = JSON.parse(response.body)['data']['translations'].first['translatedText']
  translated_term, errors = fix(term, translated_term, key: key)
  unless errors.empty?
    STDERR.puts "'#{term}' => '#{translated_term}'\n#{errors.join(', ').red}"
  end
  [translated_term, (errors.map { |e| "[error: #{e}]" } + ['[autotranslated]']).join("\n")]
end