translatomatic 0.1.3 → 0.2.0
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.
- checksums.yaml +5 -5
- data/.gitattributes +20 -20
- data/.gitignore +19 -15
- data/.rspec +3 -3
- data/.rubocop.yml +28 -0
- data/.translatomatic/config.yml +4 -0
- data/.travis.yml +4 -6
- data/.yardopts +9 -9
- data/Gemfile +8 -4
- data/Guardfile +4 -5
- data/README.de.md +55 -50
- data/README.en.md +177 -0
- data/README.es.md +53 -48
- data/README.fr.md +53 -48
- data/README.it.md +54 -49
- data/README.ja.md +63 -58
- data/README.ko.md +59 -54
- data/README.md +17 -13
- data/README.ms.md +50 -45
- data/README.pt.md +54 -49
- data/README.ru.md +57 -52
- data/README.sv.md +51 -46
- data/README.zh.md +60 -55
- data/Rakefile +3 -3
- data/TODO.txt +6 -0
- data/bin/console +3 -3
- data/bin/translatomatic +4 -2
- data/config/i18n-tasks.yml +130 -0
- data/config/locales/translatomatic/de.yml +141 -99
- data/config/locales/translatomatic/en.yml +129 -89
- data/config/locales/translatomatic/es.yml +136 -99
- data/config/locales/translatomatic/fr.yml +139 -100
- data/config/locales/translatomatic/it.yml +135 -97
- data/config/locales/translatomatic/ja.yml +137 -98
- data/config/locales/translatomatic/ko.yml +138 -98
- data/config/locales/translatomatic/ms.yml +138 -100
- data/config/locales/translatomatic/pt.yml +137 -101
- data/config/locales/translatomatic/ru.yml +136 -98
- data/config/locales/translatomatic/sv.yml +134 -96
- data/config/locales/translatomatic/zh.yml +136 -97
- data/db/migrate/201712170000_initial.rb +2 -3
- data/lib/translatomatic.rb +40 -25
- data/lib/translatomatic/cli.rb +5 -1
- data/lib/translatomatic/cli/base.rb +61 -58
- data/lib/translatomatic/cli/common_options.rb +14 -11
- data/lib/translatomatic/cli/config.rb +96 -91
- data/lib/translatomatic/cli/database.rb +85 -23
- data/lib/translatomatic/cli/main.rb +158 -104
- data/lib/translatomatic/cli/thor.rb +29 -0
- data/lib/translatomatic/cli/translate.rb +134 -157
- data/lib/translatomatic/config.rb +10 -301
- data/lib/translatomatic/config/display.rb +78 -0
- data/lib/translatomatic/config/files.rb +60 -0
- data/lib/translatomatic/config/location_settings.rb +133 -0
- data/lib/translatomatic/config/options.rb +68 -0
- data/lib/translatomatic/config/selector.rb +127 -0
- data/lib/translatomatic/config/settings.rb +148 -0
- data/lib/translatomatic/converter.rb +40 -28
- data/lib/translatomatic/database.rb +127 -110
- data/lib/translatomatic/define_options.rb +4 -5
- data/lib/translatomatic/escaped_unicode.rb +86 -76
- data/lib/translatomatic/extractor.rb +5 -2
- data/lib/translatomatic/extractor/base.rb +12 -12
- data/lib/translatomatic/extractor/ruby.rb +7 -6
- data/lib/translatomatic/file_translator.rb +101 -244
- data/lib/translatomatic/flattenation.rb +39 -0
- data/lib/translatomatic/http.rb +13 -0
- data/lib/translatomatic/http/client.rb +144 -0
- data/lib/translatomatic/http/exception.rb +43 -0
- data/lib/translatomatic/http/file_param.rb +27 -0
- data/lib/translatomatic/http/param.rb +37 -0
- data/lib/translatomatic/http/request.rb +91 -0
- data/lib/translatomatic/i18n.rb +43 -0
- data/lib/translatomatic/locale.rb +71 -59
- data/lib/translatomatic/logger.rb +43 -28
- data/lib/translatomatic/metadata.rb +58 -0
- data/lib/translatomatic/model.rb +4 -2
- data/lib/translatomatic/model/locale.rb +5 -5
- data/lib/translatomatic/model/text.rb +5 -5
- data/lib/translatomatic/option.rb +57 -34
- data/lib/translatomatic/path_utils.rb +126 -0
- data/lib/translatomatic/progress_updater.rb +13 -16
- data/lib/translatomatic/provider.rb +101 -0
- data/lib/translatomatic/provider/base.rb +136 -0
- data/lib/translatomatic/provider/frengly.rb +55 -0
- data/lib/translatomatic/provider/google.rb +78 -0
- data/lib/translatomatic/provider/google_web.rb +50 -0
- data/lib/translatomatic/provider/microsoft.rb +144 -0
- data/lib/translatomatic/provider/my_memory.rb +75 -0
- data/lib/translatomatic/provider/yandex.rb +61 -0
- data/lib/translatomatic/resource_file.rb +59 -53
- data/lib/translatomatic/resource_file/base.rb +171 -237
- data/lib/translatomatic/resource_file/csv.rb +176 -24
- data/lib/translatomatic/resource_file/html.rb +21 -42
- data/lib/translatomatic/resource_file/key_value_support.rb +117 -0
- data/lib/translatomatic/resource_file/markdown.rb +36 -38
- data/lib/translatomatic/resource_file/plist.rb +121 -126
- data/lib/translatomatic/resource_file/po.rb +104 -82
- data/lib/translatomatic/resource_file/properties.rb +48 -77
- data/lib/translatomatic/resource_file/properties.treetop +87 -0
- data/lib/translatomatic/resource_file/resw.rb +56 -41
- data/lib/translatomatic/resource_file/subtitle.rb +86 -54
- data/lib/translatomatic/resource_file/text.rb +18 -18
- data/lib/translatomatic/resource_file/xcode_strings.rb +32 -63
- data/lib/translatomatic/resource_file/xcode_strings.treetop +85 -0
- data/lib/translatomatic/resource_file/xml.rb +94 -81
- data/lib/translatomatic/resource_file/yaml.rb +54 -68
- data/lib/translatomatic/retry_executor.rb +37 -0
- data/lib/translatomatic/slurp.rb +32 -0
- data/lib/translatomatic/string_batcher.rb +50 -0
- data/lib/translatomatic/string_escaping.rb +61 -0
- data/lib/translatomatic/text.rb +263 -0
- data/lib/translatomatic/text_collection.rb +66 -0
- data/lib/translatomatic/tmx.rb +5 -3
- data/lib/translatomatic/tmx/document.rb +107 -82
- data/lib/translatomatic/tmx/translation_unit.rb +19 -18
- data/lib/translatomatic/translation.rb +8 -28
- data/lib/translatomatic/translation/collection.rb +199 -0
- data/lib/translatomatic/translation/fetcher.rb +123 -0
- data/lib/translatomatic/translation/munging.rb +112 -0
- data/lib/translatomatic/translation/result.rb +50 -0
- data/lib/translatomatic/translation/sharer.rb +32 -0
- data/lib/translatomatic/translation/stats.rb +44 -0
- data/lib/translatomatic/translator.rb +91 -88
- data/lib/translatomatic/type_cast.rb +63 -0
- data/lib/translatomatic/util.rb +37 -33
- data/lib/translatomatic/version.rb +2 -2
- data/translatomatic.gemspec +57 -46
- metadata +136 -59
- data/lib/translatomatic/http_request.rb +0 -162
- data/lib/translatomatic/string.rb +0 -188
- data/lib/translatomatic/translation_result.rb +0 -86
- data/lib/translatomatic/translation_stats.rb +0 -31
- data/lib/translatomatic/translator/base.rb +0 -128
- data/lib/translatomatic/translator/frengly.rb +0 -62
- data/lib/translatomatic/translator/google.rb +0 -37
- data/lib/translatomatic/translator/microsoft.rb +0 -41
- data/lib/translatomatic/translator/my_memory.rb +0 -68
- data/lib/translatomatic/translator/yandex.rb +0 -56
@@ -1,5 +1,8 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Translatomatic
|
2
|
+
# Classes to extract strings from files
|
3
|
+
module Extractor
|
4
|
+
end
|
5
|
+
end
|
3
6
|
|
4
7
|
require 'translatomatic/extractor/base'
|
5
8
|
require 'translatomatic/extractor/ruby'
|
@@ -1,16 +1,16 @@
|
|
1
|
-
module Translatomatic
|
2
|
-
|
3
|
-
|
1
|
+
module Translatomatic
|
2
|
+
module Extractor
|
3
|
+
# Base class for string extraction functionality
|
4
|
+
class Base
|
5
|
+
def initialize(path)
|
6
|
+
@path = path.is_a?(Pathname) ? path : Pathname.new(path)
|
7
|
+
@contents = @path.read
|
8
|
+
end
|
4
9
|
|
5
|
-
|
6
|
-
|
7
|
-
|
10
|
+
# @return [Array<String>] All strings found
|
11
|
+
def extract
|
12
|
+
@contents.scan(/\"(.*?[^\\])"|'(.*?[^\\])'/).flatten.compact
|
13
|
+
end
|
8
14
|
end
|
9
|
-
|
10
|
-
# @return [Array<String>] All strings found
|
11
|
-
def extract
|
12
|
-
@contents.scan(/\"(.*?[^\\])"|'(.*?[^\\])'/).flatten.compact
|
13
|
-
end
|
14
|
-
|
15
15
|
end
|
16
16
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
-
module Translatomatic
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
1
|
+
module Translatomatic
|
2
|
+
module Extractor
|
3
|
+
# Class to extract strings from ruby code
|
4
|
+
class Ruby < Base
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
@@ -1,269 +1,126 @@
|
|
1
|
-
|
2
|
-
# resource files
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
@listener = options[:listener]
|
15
|
-
@translators = Translatomatic::Translator.resolve(options[:translator], options)
|
16
|
-
raise t("file_translator.translator_required") if @translators.empty?
|
17
|
-
@translators.each { |i| i.listener = @listener } if @listener
|
18
|
-
|
19
|
-
# use database by default if we're connected to a database
|
20
|
-
use_db = options.include?(:use_database) ? options[:use_database] : true
|
21
|
-
@use_db = use_db && ActiveRecord::Base.connected?
|
22
|
-
log.debug(t("file_translator.database_disabled")) unless @use_db
|
23
|
-
|
24
|
-
@db_translations = []
|
25
|
-
@translations = {} # map of original text to Translation
|
26
|
-
end
|
27
|
-
|
28
|
-
# @return [Translatomatic::TranslationStats] Translation statistics
|
29
|
-
def stats
|
30
|
-
@stats ||= Translatomatic::TranslationStats.new(@translations)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Translate properties of source_file to the target locale.
|
34
|
-
# Does not write changes to disk.
|
35
|
-
#
|
36
|
-
# @param file [String, Translatomatic::ResourceFile] File to translate
|
37
|
-
# @param to_locale [String] The target locale, e.g. "fr"
|
38
|
-
# @return [Translatomatic::ResourceFile] The translated resource file
|
39
|
-
def translate(file, to_locale)
|
40
|
-
file = resource_file(file)
|
41
|
-
to_locale = parse_locale(to_locale)
|
42
|
-
|
43
|
-
# do nothing if target language is the same as source language
|
44
|
-
return file if file.locale.language == to_locale.language
|
45
|
-
|
46
|
-
result = Translatomatic::TranslationResult.new(file, to_locale)
|
47
|
-
|
48
|
-
# translate using strings from the database first
|
49
|
-
each_translator(result) { translate_properties_with_db(result) }
|
50
|
-
# send remaining unknown strings to translator
|
51
|
-
each_translator(result) { translate_properties_with_translator(result) }
|
52
|
-
|
53
|
-
log.debug(t("file_translator.stats", from_db: stats.from_db,
|
54
|
-
from_translator: stats.from_translator,
|
55
|
-
untranslated: result.untranslated.length))
|
56
|
-
@listener.untranslated_texts(result.untranslated) if @listener
|
57
|
-
|
58
|
-
file.properties = result.properties
|
59
|
-
file.locale = to_locale
|
60
|
-
file
|
61
|
-
end
|
62
|
-
|
63
|
-
# Translates a resource file and writes results to a target resource file.
|
64
|
-
# The path of the target resource file is automatically determined.
|
65
|
-
#
|
66
|
-
# @param source [Translatomatic::ResourceFile] The source
|
67
|
-
# @param to_locale [String] The target locale, e.g. "fr"
|
68
|
-
# @return [Translatomatic::ResourceFile] The translated resource file
|
69
|
-
def translate_to_file(source, to_locale)
|
70
|
-
# Automatically determines the target filename based on target locale.
|
71
|
-
source = resource_file(source)
|
72
|
-
target = Translatomatic::ResourceFile.load(source.path)
|
73
|
-
target.path = source.locale_path(to_locale)
|
74
|
-
|
75
|
-
log.info(t("file_translator.translating", source: source,
|
76
|
-
source_locale: source.locale, target: target, target_locale: to_locale))
|
77
|
-
translate(target, to_locale)
|
78
|
-
unless @dry_run
|
79
|
-
target.path.parent.mkpath
|
80
|
-
target.save
|
1
|
+
module Translatomatic
|
2
|
+
# Translates resource files from one language to another.
|
3
|
+
class FileTranslator
|
4
|
+
# @return [Translatomatic::Translator] Translator object
|
5
|
+
attr_reader :translator
|
6
|
+
|
7
|
+
# Create a new FileTranslator instance
|
8
|
+
# @param options [Hash<Symbol,Object>] converter and/or
|
9
|
+
# provider options.
|
10
|
+
def initialize(options = {})
|
11
|
+
@dry_run = options[:dry_run]
|
12
|
+
@in_place = options[:in_place]
|
13
|
+
@translator = Translator.new(options)
|
81
14
|
end
|
82
|
-
target
|
83
|
-
end
|
84
|
-
|
85
|
-
private
|
86
|
-
|
87
|
-
include Translatomatic::Util
|
88
|
-
include Translatomatic::DefineOptions
|
89
15
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
16
|
+
# Translate properties of file to the target locale.
|
17
|
+
# Does not write changes to disk.
|
18
|
+
# @param file [String, Translatomatic::ResourceFile] File to translate
|
19
|
+
# @param to_locale [String] The target locale, e.g. "fr"
|
20
|
+
# @return [Translatomatic::ResourceFile] The translated resource file
|
21
|
+
def translate(file, to_locale)
|
22
|
+
file = resource_file(file)
|
23
|
+
to_locale = build_locale(to_locale)
|
24
|
+
|
25
|
+
# do nothing if target language is the same as source language
|
26
|
+
return file if file.locale.language == to_locale.language
|
27
|
+
|
28
|
+
texts = texts_from_file(file)
|
29
|
+
unless @dry_run
|
30
|
+
collection = @translator.translate(texts, to_locale)
|
31
|
+
update_properties(file, to_locale, collection)
|
32
|
+
end
|
33
|
+
file
|
34
|
+
end
|
99
35
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
36
|
+
# Translates a resource file and writes results to a target
|
37
|
+
# resource file. The path of the target resource file is
|
38
|
+
# automagically determined.
|
39
|
+
# @param source [ResourceFile] The source
|
40
|
+
# @param to_locale [String] The target locale, e.g. "fr"
|
41
|
+
# @return [ResourceFile] The translated resource file
|
42
|
+
def translate_to_file(source, to_locale)
|
43
|
+
target = translation_target_file(source, to_locale)
|
44
|
+
return source unless target
|
45
|
+
translate(target, to_locale)
|
46
|
+
save_resource_file(target)
|
105
47
|
end
|
106
|
-
end
|
107
48
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
# @return [void]
|
113
|
-
def restore_variables(result, translation)
|
114
|
-
file = result.file
|
115
|
-
return unless file.class.supports_variable_interpolation?
|
49
|
+
private
|
50
|
+
|
51
|
+
include Translatomatic::Util
|
52
|
+
include Translatomatic::DefineOptions
|
116
53
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
translated_variables = string_variables(translation.result, result.to_locale, file)
|
54
|
+
define_option :in_place, type: :boolean, command_line_only: true,
|
55
|
+
default: false,
|
56
|
+
desc: t('file_translator.in_place')
|
121
57
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
v1 = conversion.original
|
131
|
-
v2 = conversion.result
|
132
|
-
translation.result[v2.offset, v2.length] = v1.value
|
58
|
+
# Update file properties from the given translation collection
|
59
|
+
def update_properties(file, to_locale, collection)
|
60
|
+
value_map = init_value_map(file)
|
61
|
+
file.properties.each_value do |value|
|
62
|
+
keys = value_map[value.to_s]
|
63
|
+
translation = collection.get(value, to_locale) # best translation
|
64
|
+
new_value = translation ? translation.result.to_s : nil
|
65
|
+
keys.each { |key| file.set(key, new_value) }
|
133
66
|
end
|
134
|
-
|
135
|
-
# unable to restore interpolated variable names
|
136
|
-
log.debug("#{@current_translator.name}: unable to restore variables: #{translation.result}")
|
137
|
-
translation.result = nil # mark result as invalid
|
67
|
+
file.locale = to_locale
|
138
68
|
end
|
139
|
-
end
|
140
69
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
if path.kind_of?(Translatomatic::ResourceFile::Base)
|
147
|
-
path
|
148
|
-
else
|
149
|
-
file = Translatomatic::ResourceFile.load(path)
|
150
|
-
raise t("file.unsupported", file: path) unless file
|
70
|
+
def save_resource_file(file)
|
71
|
+
unless @dry_run
|
72
|
+
file.path.parent.mkpath
|
73
|
+
file.save
|
74
|
+
end
|
151
75
|
file
|
152
76
|
end
|
153
|
-
end
|
154
77
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
78
|
+
# Create a target file to write for the given source file.
|
79
|
+
# @param source [ResourceFile] Source resource file
|
80
|
+
# @param to_locale [Locale] Target locale
|
81
|
+
# @return [ResourceFile] Target file, or nil if we shouldn't translate
|
82
|
+
def translation_target_file(source, to_locale)
|
83
|
+
if @in_place
|
84
|
+
source
|
85
|
+
else
|
86
|
+
target_path = source.locale_path(to_locale)
|
87
|
+
# don't overwrite source unless using @in_place
|
88
|
+
return nil if target_path == source.path
|
89
|
+
target = resource_file(source.path, source.options)
|
90
|
+
target.path = target_path
|
91
|
+
target
|
169
92
|
end
|
170
|
-
|
171
|
-
result.update_strings(translations)
|
172
|
-
@listener.translated_texts(db_texts) if @listener
|
173
93
|
end
|
174
|
-
db_texts
|
175
|
-
end
|
176
|
-
|
177
|
-
# update result with translations from the translator.
|
178
|
-
def translate_properties_with_translator(result)
|
179
|
-
untranslated = result.untranslated.to_a.select { |i| translatable?(i) }
|
180
|
-
translated = []
|
181
|
-
if !untranslated.empty? && !@dry_run
|
182
|
-
untranslated_strings = untranslated.collect { |i| i.to_s }
|
183
|
-
log.debug("translating: #{untranslated_strings}")
|
184
|
-
translated = @current_translator.translate(untranslated_strings,
|
185
|
-
result.from_locale, result.to_locale
|
186
|
-
)
|
187
94
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
95
|
+
def texts_from_file(file)
|
96
|
+
texts = []
|
97
|
+
file.properties.each do |key, value|
|
98
|
+
text = build_text(value, file.locale)
|
99
|
+
text.preserve_regex = file.variable_regex
|
100
|
+
text.context = file.get_context(key)
|
101
|
+
texts << text
|
194
102
|
end
|
103
|
+
texts
|
104
|
+
end
|
195
105
|
|
196
|
-
|
197
|
-
|
198
|
-
|
106
|
+
# set up a mapping from property value -> key list
|
107
|
+
def init_value_map(file)
|
108
|
+
value_map = {}
|
109
|
+
file.properties.each do |key, value|
|
110
|
+
keylist = (value_map[value.to_s] ||= [])
|
111
|
+
keylist << key
|
199
112
|
end
|
113
|
+
value_map
|
200
114
|
end
|
201
|
-
translated
|
202
|
-
end
|
203
|
-
|
204
|
-
def translation(from, to, from_database = false)
|
205
|
-
translator = @current_translator.name
|
206
|
-
t = Translatomatic::Translation.new(from, to, translator, from_database)
|
207
|
-
@translations[from] = t
|
208
|
-
t
|
209
|
-
end
|
210
|
-
|
211
|
-
def database_disabled?
|
212
|
-
!@use_db
|
213
|
-
end
|
214
115
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
end
|
223
|
-
|
224
|
-
def save_database_translations(result, translations)
|
225
|
-
ActiveRecord::Base.transaction do
|
226
|
-
from = db_locale(result.from_locale)
|
227
|
-
to = db_locale(result.to_locale)
|
228
|
-
translations.each do |translation|
|
229
|
-
next if translation.result.nil? # skip invalid translations
|
230
|
-
save_database_translation(from, to, translation)
|
116
|
+
def resource_file(path, options = {})
|
117
|
+
if path.is_a?(Translatomatic::ResourceFile::Base)
|
118
|
+
path
|
119
|
+
else
|
120
|
+
file = Translatomatic::ResourceFile.load(path, options)
|
121
|
+
raise t('file.unsupported', file: path) unless file
|
122
|
+
file
|
231
123
|
end
|
232
124
|
end
|
233
125
|
end
|
234
|
-
|
235
|
-
def save_database_translation(from_locale, to_locale, translation)
|
236
|
-
original_text = Translatomatic::Model::Text.find_or_create_by!(
|
237
|
-
locale: from_locale,
|
238
|
-
value: translation.original.to_s
|
239
|
-
)
|
240
|
-
|
241
|
-
text = Translatomatic::Model::Text.find_or_create_by!(
|
242
|
-
locale: to_locale,
|
243
|
-
value: translation.result.to_s,
|
244
|
-
from_text: original_text,
|
245
|
-
translator: @current_translator.name
|
246
|
-
)
|
247
|
-
@db_translations += [original_text, text]
|
248
|
-
text
|
249
|
-
end
|
250
|
-
|
251
|
-
def find_database_translations(result, untranslated)
|
252
|
-
from = db_locale(result.from_locale)
|
253
|
-
to = db_locale(result.to_locale)
|
254
|
-
|
255
|
-
Translatomatic::Model::Text.where({
|
256
|
-
locale: to,
|
257
|
-
translator: @current_translator.name,
|
258
|
-
from_texts_texts: {
|
259
|
-
locale_id: from,
|
260
|
-
# convert untranslated set to strings
|
261
|
-
value: untranslated.collect { |i| i.to_s }
|
262
|
-
}
|
263
|
-
}).joins(:from_text)
|
264
|
-
end
|
265
|
-
|
266
|
-
def db_locale(locale)
|
267
|
-
Translatomatic::Model::Locale.from_tag(locale)
|
268
|
-
end
|
269
126
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Translatomatic
|
2
|
+
# Methods to flatten data
|
3
|
+
module Flattenation
|
4
|
+
private
|
5
|
+
|
6
|
+
# flatten hash or array of hashes to a hash of key => value pairs
|
7
|
+
def flatten(data)
|
8
|
+
result = {}
|
9
|
+
|
10
|
+
if data.is_a?(Hash)
|
11
|
+
data.each do |key, value|
|
12
|
+
flatten_add(result, key, value)
|
13
|
+
end
|
14
|
+
elsif data.is_a?(Array)
|
15
|
+
data.each_with_index do |value, i|
|
16
|
+
key = 'key' + i.to_s
|
17
|
+
flatten_add(result, key, value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def flatten_add(result, key, value)
|
25
|
+
if needs_flatten?(value)
|
26
|
+
children = flatten(value)
|
27
|
+
children.each do |ck, cv|
|
28
|
+
result[key + '.' + ck] = cv
|
29
|
+
end
|
30
|
+
else
|
31
|
+
result[key] = value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def needs_flatten?(value)
|
36
|
+
value.is_a?(Array) || value.is_a?(Hash)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|