babelyoda 1.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.
- data/CHANGELOG +2 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/VERSION +1 -0
- data/bin/babelyoda +404 -0
- data/lib/babelyoda.rb +0 -0
- metadata +92 -0
data/CHANGELOG
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2009 Andrey Subbotin
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
= babelyoda
|
|
2
|
+
|
|
3
|
+
A simple utility to push/pull l10n resources of an iPhone project to/from the translators.
|
|
4
|
+
|
|
5
|
+
== Note on Patches/Pull Requests
|
|
6
|
+
|
|
7
|
+
* Fork the project.
|
|
8
|
+
* Make your feature addition or bug fix.
|
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
|
10
|
+
future version unintentionally.
|
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
|
14
|
+
|
|
15
|
+
== Copyright
|
|
16
|
+
|
|
17
|
+
Copyright (c) 2010 Andrey Subbotin. See LICENSE for details.
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.2.0
|
data/bin/babelyoda
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'plist'
|
|
6
|
+
require 'term/ansicolor'
|
|
7
|
+
require 'tmpdir'
|
|
8
|
+
require 'yaml'
|
|
9
|
+
|
|
10
|
+
include Term::ANSIColor
|
|
11
|
+
|
|
12
|
+
# Main block
|
|
13
|
+
|
|
14
|
+
def main
|
|
15
|
+
banner
|
|
16
|
+
check_args
|
|
17
|
+
setup
|
|
18
|
+
print_config
|
|
19
|
+
prepare_folders
|
|
20
|
+
init_lproj_dirs
|
|
21
|
+
apply_incremental_translations
|
|
22
|
+
gen_src_code_strings
|
|
23
|
+
extract_untranslated_src_code_strings
|
|
24
|
+
gen_src_xib_strings
|
|
25
|
+
extract_untranslated_src_xib_strings
|
|
26
|
+
localize_xibs_incrementally
|
|
27
|
+
pack_tmp_lproj
|
|
28
|
+
push_tmp_lproj
|
|
29
|
+
FileUtils.rm_rf $config['tmp_dir'], :verbose => true
|
|
30
|
+
success "All done!"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Aux methods
|
|
34
|
+
|
|
35
|
+
def banner
|
|
36
|
+
puts "Babel Yoda v1.2.0"
|
|
37
|
+
puts "© 2010 Andrey Subbotin <andrey@subbotin.me>"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def usage
|
|
41
|
+
puts ""
|
|
42
|
+
puts "Usage: babelyoda [<rules.babelyoda>]"
|
|
43
|
+
puts ""
|
|
44
|
+
puts "<rules.babelyoda> = babel yoda config file, default is rules.babelyoda"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def check_args
|
|
48
|
+
if ARGV.length > 1
|
|
49
|
+
usage
|
|
50
|
+
exit 1
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def setup
|
|
55
|
+
$config = Hash.new
|
|
56
|
+
global_config_filename = File.expand_path('~/.babelyoda')
|
|
57
|
+
$config.merge!(YAML.load_file(global_config_filename)) if File.exist?(global_config_filename)
|
|
58
|
+
config = YAML.load_file(ARGV[0].nil? ? 'rules.babelyoda' : ARGV[0])
|
|
59
|
+
config['tmp_dir'] = File.join Dir.tmpdir, "epl.babelyoda.#{$$}"
|
|
60
|
+
config['src_dir'] = File.join config['tmp_dir'], 'src'
|
|
61
|
+
config['startwd'] = Dir.getwd
|
|
62
|
+
config['src_lang'] = Plist::parse_xml(config['plist'])['CFBundleDevelopmentRegion']
|
|
63
|
+
config['src_lang_lproj'] = config['src_lang'] + '.lproj'
|
|
64
|
+
config['src_lang_lproj_dir'] = File.join(config['strings_folder'], config['src_lang_lproj'])
|
|
65
|
+
config['src_lang_code_strings_file'] = File.join(config['src_lang_lproj_dir'], 'Localizable.strings')
|
|
66
|
+
config['initial_strings_file'] = File.join(config['strings_folder'], 'Localizable.strings')
|
|
67
|
+
$config.merge!(config)
|
|
68
|
+
$config['products_folder'] = File.expand_path($config['products_folder'])
|
|
69
|
+
$config['time_badge'] = Time.now.utc.strftime('%Y%m%d_%H%M')
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def print_config ; status "CONFIG" ; y $config ; end
|
|
73
|
+
def exe(cmd) ; putcmd cmd ; system cmd ; end
|
|
74
|
+
def putcmd(cmd) ; print magenta, "CMD: #{cmd}", reset, "\n" ; end
|
|
75
|
+
def status(msg) ; print blue, "--- #{msg} ---", reset, "\n" ; end
|
|
76
|
+
def success(msg) ; print green, bold, 'SUCCESS: ', msg, reset, "\n" ; end
|
|
77
|
+
def error(msg) ; print red, bold, 'ERROR: ', msg, reset, "\n" ; exit 1 ; end
|
|
78
|
+
def escape_cmd_args(args) ; args.collect{ |arg| "'#{arg}'"}.join(' ') ; end
|
|
79
|
+
|
|
80
|
+
# Globbers
|
|
81
|
+
|
|
82
|
+
def all_languages
|
|
83
|
+
result = Array.new
|
|
84
|
+
result << $config['languages']
|
|
85
|
+
result << $config['src_lang']
|
|
86
|
+
result.flatten!.sort!
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def all_lproj_dirs
|
|
90
|
+
result = Array.new
|
|
91
|
+
result << dst_lproj_dirs
|
|
92
|
+
result << src_lproj_dir
|
|
93
|
+
result.flatten!.sort!
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def src_lproj_dir
|
|
97
|
+
$config['src_lang_lproj_dir']
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def dst_lproj_dirs
|
|
101
|
+
$config['languages'].collect{ |l|
|
|
102
|
+
lproj_dir_for_lang(l)
|
|
103
|
+
}.sort!
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def lproj_dir_for_lang(lang)
|
|
107
|
+
File.join($config['strings_folder'], "#{lang}.lproj")
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def tmp_lproj_dir_for_lang(lang)
|
|
111
|
+
File.join($config['tmp_dir'], "#{lang}.lproj")
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def src_code_files
|
|
115
|
+
$config['folders'].collect{ |dir|
|
|
116
|
+
Dir.glob(File.join(dir, '**', '*.{c,h,m,hh,mm}'))
|
|
117
|
+
}.flatten!.sort!
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def dst_code_strings_files
|
|
121
|
+
$config['languages'].collect{ |l|
|
|
122
|
+
File.join(lproj_dir_for_lang(l), 'Localizable.strings')
|
|
123
|
+
}.sort!
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def all_code_strings_files
|
|
127
|
+
result = Array.new
|
|
128
|
+
result << dst_code_strings_files
|
|
129
|
+
result << $config['src_lang_code_strings_file']
|
|
130
|
+
result.flatten!.sort!
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def xib_files_for_lang(lang)
|
|
134
|
+
$config['folders'].collect{ |dir|
|
|
135
|
+
Dir.glob(File.join(dir, '**', lang + '.lproj', '*.xib'))
|
|
136
|
+
}.flatten!.sort!
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def dst_xib_files
|
|
140
|
+
$config['languages'].collect{ |lang|
|
|
141
|
+
xib_files_for_lang(lang)
|
|
142
|
+
}.flatten!.sort!
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def src_xib_files
|
|
146
|
+
xib_files_for_lang($config['src_lang_lproj'])
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def strings_files_for_lang(lang)
|
|
150
|
+
$config['folders'].collect{ |dir|
|
|
151
|
+
Dir.glob(File.join(dir, '**', lang + '.lproj', '*.strings'))
|
|
152
|
+
}.flatten!.sort!
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def all_strings_files
|
|
156
|
+
all_languages.collect{ |lang| strings_files_for_lang(lang) }.flatten!.sort!
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def strings_file_for_xib_lang(xib, lang)
|
|
160
|
+
parts = File.split(xib)
|
|
161
|
+
lang_split = File.split(parts[-2])
|
|
162
|
+
lang_split[-1] = lang + '.lproj'
|
|
163
|
+
parts[-2] = File.join(lang_split)
|
|
164
|
+
parts[-1] = parts[-1].slice(0, parts[-1].length - 4) + '.strings'
|
|
165
|
+
result = File.join(parts)
|
|
166
|
+
result
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def xib_file_for_xib_lang(xib, lang)
|
|
170
|
+
xib_filename = File.split(xib).last
|
|
171
|
+
parts = File.split(xib)
|
|
172
|
+
lang_split = File.split(parts[-2])
|
|
173
|
+
lang_split[-1] = lang + '.lproj'
|
|
174
|
+
parts[-2] = File.join(lang_split)
|
|
175
|
+
File.join(parts)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def strings_files_for_xib(xib)
|
|
179
|
+
all_languages.each.collect { |lang| strings_file_for_xib_lang(xib, lang) }
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Globs all incremental translations for the given .strings file and language.
|
|
183
|
+
def incremental_translations(file, lang)
|
|
184
|
+
filename = File.split(file).last
|
|
185
|
+
mask = "#{$config['prefix']}_*_*_#{lang}_#{filename}"
|
|
186
|
+
Dir.glob(File.join($config['incremental_translations_folder'], mask)).sort!
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Processing
|
|
190
|
+
|
|
191
|
+
def prepare_folders
|
|
192
|
+
status "PREPARING FOLDERS"
|
|
193
|
+
FileUtils.mkdir_p $config['incremental_translations_folder'], :verbose => true
|
|
194
|
+
FileUtils.mkdir_p $config['old_xibs_folder'], :verbose => true
|
|
195
|
+
FileUtils.mkdir_p File.join($config['tmp_dir'], 'zips'), :verbose => true
|
|
196
|
+
make_tmp_lproj_dirs
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def make_tmp_lproj_dirs
|
|
200
|
+
FileUtils.mkdir_p tmp_lproj_dir_for_lang($config['src_lang']), :verbose => true
|
|
201
|
+
FileUtils.mkdir_p $config['languages'].sort.collect{ |lang| tmp_lproj_dir_for_lang(lang) }, :verbose => true
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def init_lproj_dirs
|
|
205
|
+
status "PREPARING LPROJ FOLDERS"
|
|
206
|
+
if File.exists?($config['initial_strings_file']) && File.exists?($config['src_lang_code_strings_file'])
|
|
207
|
+
error "Both '#{$config['initial_strings_file']}' and '#{$config['src_lang_code_strings_file']}' exist!"
|
|
208
|
+
end
|
|
209
|
+
FileUtils.mkdir_p all_lproj_dirs, :verbose => true
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Iterate over all the .strings files and apply
|
|
213
|
+
# all the translations found for each in the
|
|
214
|
+
# incremental translations folder.
|
|
215
|
+
def apply_incremental_translations
|
|
216
|
+
all_languages.each do |lang|
|
|
217
|
+
strings_files_for_lang(lang).each do |strings_file|
|
|
218
|
+
status "APPLYING INCREMENTAL TRANSLATIONS FOR '#{strings_file}'"
|
|
219
|
+
incremental_translations(strings_file, lang).each do |translation|
|
|
220
|
+
combine_strings(translation, strings_file)
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Generate .strings file into the temporary directory,
|
|
227
|
+
# touch the target file so it's created if it didn't exist,
|
|
228
|
+
# and then merge it with the new file, preserving any translations made.
|
|
229
|
+
def gen_src_code_strings
|
|
230
|
+
status "GENERATING STRINGS FILE FOR THE SOURCE LANGUAGE"
|
|
231
|
+
genstrings src_code_files, $config['tmp_dir']
|
|
232
|
+
tmp_strings_file = File.join($config['tmp_dir'], 'Localizable.strings')
|
|
233
|
+
merge_strings tmp_strings_file, all_code_strings_files
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def genstrings(files, output_path)
|
|
237
|
+
files_safe = escape_cmd_args(files)
|
|
238
|
+
rc = exe "genstrings -o '#{output_path}' #{files_safe}"
|
|
239
|
+
error "Failed to generate strings" unless rc
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def gen_src_xib_strings
|
|
243
|
+
status "GENERATING STRINGS FILES FOR THE SOURCE LANGUAGE XIBS"
|
|
244
|
+
src_xib_files.each do |xib|
|
|
245
|
+
tmp_strings_file = gen_xib_strings xib
|
|
246
|
+
merge_strings tmp_strings_file, strings_files_for_xib(xib)
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def tmp_filename_for_xib_strings(xib)
|
|
251
|
+
xib_filename = File.split(xib).last
|
|
252
|
+
strings_filename = xib_filename.slice(0, xib.length - 4) + '.strings'
|
|
253
|
+
File.join($config['tmp_dir'], strings_filename)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def gen_xib_strings(xib)
|
|
257
|
+
strings = tmp_filename_for_xib_strings(xib)
|
|
258
|
+
rc = exe "ibtool --generate-strings-file '#{strings}' '#{xib}'"
|
|
259
|
+
error "Failed to generate strings for file '#{xib}'" unless rc
|
|
260
|
+
strings
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def merge_strings(src_strings, dst_strings)
|
|
264
|
+
targets = dst_strings.is_a?(String) ? [dst_strings] : dst_strings
|
|
265
|
+
puts "DST_STRINGS: #{dst_strings}"
|
|
266
|
+
targets.each do |target|
|
|
267
|
+
status "MERGING STRINGS AT '#{src_strings}' INTO '#{target}'"
|
|
268
|
+
FileUtils.touch target
|
|
269
|
+
rc = exe "wincent-strings-util --base '#{src_strings}' --merge '#{target}' --output '#{target}'"
|
|
270
|
+
error "Failed to merge '#{src_strings}' into '#{target}'" unless rc
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def extract_untranslated_src_code_strings
|
|
275
|
+
tmp_strings_file = File.join($config['tmp_dir'], 'Localizable.strings')
|
|
276
|
+
$config['languages'].sort.each do |lang|
|
|
277
|
+
src_file = File.join(lproj_dir_for_lang(lang), 'Localizable.strings')
|
|
278
|
+
dst_file = File.join(tmp_lproj_dir_for_lang(lang), mangled_name('Localizable.strings', lang))
|
|
279
|
+
status "EXTRACTING UNTRANSLATED STRINGS FROM '#{src_file}' TO '#{dst_file}'"
|
|
280
|
+
rc = exe "wincent-strings-util --base '#{tmp_strings_file}' --extract '#{src_file}' --output '#{dst_file}'"
|
|
281
|
+
error "Failed to extract untranslated string from '#{src_file}' into '#{dst_file}' based on '#{tmp_strings_file}'" unless rc
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def extract_untranslated_src_xib_strings
|
|
286
|
+
src_xib_files.each do |xib|
|
|
287
|
+
tmp_strings_file = tmp_filename_for_xib_strings(xib)
|
|
288
|
+
$config['languages'].sort.each do |lang|
|
|
289
|
+
src_file = strings_file_for_xib_lang(xib, lang)
|
|
290
|
+
src_filename = File.split(src_file).last
|
|
291
|
+
dst_file = File.join(tmp_lproj_dir_for_lang(lang), mangled_name(src_filename, lang))
|
|
292
|
+
|
|
293
|
+
status "EXTRACTING UNTRANSLATED STRINGS FROM '#{src_file}' TO '#{dst_file}'"
|
|
294
|
+
rc = exe "wincent-strings-util --base '#{tmp_strings_file}' --extract '#{src_file}' --output '#{dst_file}'"
|
|
295
|
+
error "Failed to extract untranslated string from '#{src_file}' into '#{dst_file}' based on '#{tmp_strings_file}'" unless rc
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def combine_strings(incremental_strings, old_strings)
|
|
301
|
+
status "COMBINING STRINGS FROM '#{incremental_strings}' INTO '#{old_strings}'"
|
|
302
|
+
FileUtils.touch old_strings
|
|
303
|
+
rc = exe "wincent-strings-util --base '#{old_strings}' --combine '#{incremental_strings}' --output '#{old_strings}'"
|
|
304
|
+
error "Failed to combine '#{incremental_strings}' into '#{old_strings}'" unless rc
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def pack_tmp_lproj
|
|
308
|
+
# Copy the source language Localizable.strings into the temporary lproj folder.
|
|
309
|
+
status "COPYING STRINGS FILE FOR '#{$config['src_lang']}'"
|
|
310
|
+
FileUtils.cp $config['src_lang_code_strings_file'],
|
|
311
|
+
File.join(tmp_lproj_dir_for_lang($config['src_lang']), mangled_name('Localizable.strings', $config['src_lang'])),
|
|
312
|
+
:verbose => true
|
|
313
|
+
src_xib_files.each do |xib|
|
|
314
|
+
strings = strings_file_for_xib_lang(xib, $config['src_lang'])
|
|
315
|
+
strings_filename = File.split(strings).last
|
|
316
|
+
FileUtils.cp strings,
|
|
317
|
+
File.join(tmp_lproj_dir_for_lang($config['src_lang']), mangled_name(strings_filename, $config['src_lang'])),
|
|
318
|
+
:verbose => true
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# Pack all the temporary lproj folders.
|
|
322
|
+
all_languages.sort.each do |lang|
|
|
323
|
+
status "PACKING RESOURCES FOR '#{lang}'"
|
|
324
|
+
FileUtils.cd(tmp_lproj_dir_for_lang(lang), :verbose => true) do |dir|
|
|
325
|
+
rc = exe "zip -r -9 -y '../zips/#{zipname_for_lang(lang)}' *"
|
|
326
|
+
error "Failed to pack resources for '#{lang}'" unless rc
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def push_tmp_lproj
|
|
332
|
+
# Move all zips from the temporary lproj folder into the products folder (e.g. ~/Desktop).
|
|
333
|
+
FileUtils.mv Dir.glob(File.join($config['tmp_dir'], 'zips', '*.zip')), $config['products_folder'], :verbose => true
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# Generates a mangled filename for the given file and language.
|
|
337
|
+
def mangled_name(file, lang)
|
|
338
|
+
"#{$config['prefix']}_#{$config['time_badge']}_#{lang}_#{file}"
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# Genarates ZIP file name for the given language
|
|
342
|
+
def zipname_for_lang(lang)
|
|
343
|
+
"#{$config['prefix']}_#{$config['time_badge']}_#{lang}_Localization.zip"
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def localize_xibs_incrementally
|
|
347
|
+
# ibtool
|
|
348
|
+
# --previous-file path_to_project/English.lproj/MainWindow.old.xib # old_dst_xib
|
|
349
|
+
# --incremental-file path_to_project/fr.lproj/MainWindow.old.xib # old_src_xib
|
|
350
|
+
# --strings-file path_to_strings/fr/MainWindow.strings # dst_strings
|
|
351
|
+
# --localize-incremental
|
|
352
|
+
# --write path_to_project/fr.lproj/MainWindow.xib # dst_xib
|
|
353
|
+
# path_to_project/English.lproj/MainWindow.new.xib # src_xib
|
|
354
|
+
|
|
355
|
+
$config['languages'].sort.each do |lang|
|
|
356
|
+
puts "XIB-LANG: #{lang}"
|
|
357
|
+
xib_files_for_lang(lang).each do |dst_xib|
|
|
358
|
+
puts "XIB-DST: #{dst_xib}"
|
|
359
|
+
dst_strings = dst_xib.slice(0, dst_xib.length - 4) + '.strings'
|
|
360
|
+
src_xib = xib_file_for_xib_lang(dst_xib, $config['src_lang'])
|
|
361
|
+
old_src_xib = old_xib_for_xib_lang(src_xib, $config['src_lang'])
|
|
362
|
+
FileUtils.cp src_xib, old_src_xib, :preserve => true, :verbose => true
|
|
363
|
+
FileUtils.cp src_xib, dst_xib, :preserve => true, :verbose => true
|
|
364
|
+
old_dst_xib = old_xib_for_xib_lang(dst_xib, lang)
|
|
365
|
+
FileUtils.cp dst_xib, old_dst_xib, :preserve => true, :verbose => true
|
|
366
|
+
|
|
367
|
+
ncmd = ['ibtool', '--previous-file', "'#{old_dst_xib}'",
|
|
368
|
+
'--incremental-file', "'#{old_src_xib}'",
|
|
369
|
+
'--strings-file', "'#{dst_strings}'",
|
|
370
|
+
'--localize-incremental',
|
|
371
|
+
'--write', "#{dst_xib}",
|
|
372
|
+
"#{src_xib}"].join(' ')
|
|
373
|
+
puts "XIB-CMD: #{ncmd}"
|
|
374
|
+
rc = exe ncmd
|
|
375
|
+
error "Failed to localize a XIB incrementally" unless rc
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def xib_file_for_xib_lang(xib, lang)
|
|
381
|
+
xib_filename = File.split(xib).last
|
|
382
|
+
parts = File.split(xib)
|
|
383
|
+
lang_split = File.split(parts[-2])
|
|
384
|
+
lang_split[-1] = lang + '.lproj'
|
|
385
|
+
parts[-2] = File.join(lang_split)
|
|
386
|
+
result = File.join(parts)
|
|
387
|
+
unless lang == $config['src_lang']
|
|
388
|
+
FileUtils.cp xib_file_for_xib_lang(xib, $config['src_lang']),
|
|
389
|
+
result, :preserve => true, :verbose => true
|
|
390
|
+
end
|
|
391
|
+
result
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
def mangled_old_xib_name(xib, lang)
|
|
395
|
+
file = File.split(xib).last
|
|
396
|
+
File.join($config['old_xibs_folder'], "#{$config['prefix']}_OLD_#{lang}_#{file}")
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
def old_xib_for_xib_lang(xib, lang)
|
|
400
|
+
mangled_old_xib_filename = mangled_old_xib_name(xib, lang)
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
main
|
|
404
|
+
exit 0
|
data/lib/babelyoda.rb
ADDED
|
File without changes
|
metadata
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: babelyoda
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
prerelease: false
|
|
5
|
+
segments:
|
|
6
|
+
- 1
|
|
7
|
+
- 2
|
|
8
|
+
- 0
|
|
9
|
+
version: 1.2.0
|
|
10
|
+
platform: ruby
|
|
11
|
+
authors:
|
|
12
|
+
- Andrey Subbotin
|
|
13
|
+
autorequire:
|
|
14
|
+
bindir: bin
|
|
15
|
+
cert_chain: []
|
|
16
|
+
|
|
17
|
+
date: 2010-04-20 00:00:00 +04:00
|
|
18
|
+
default_executable:
|
|
19
|
+
- babelyoda
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: plist
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
segments:
|
|
29
|
+
- 0
|
|
30
|
+
version: "0"
|
|
31
|
+
type: :runtime
|
|
32
|
+
version_requirements: *id001
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: term-ansicolor
|
|
35
|
+
prerelease: false
|
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
segments:
|
|
41
|
+
- 0
|
|
42
|
+
version: "0"
|
|
43
|
+
type: :runtime
|
|
44
|
+
version_requirements: *id002
|
|
45
|
+
description: A simple utility to push/pull l10n resources of an iPhone project to/from the translators
|
|
46
|
+
email: andrey@subbotin.me
|
|
47
|
+
executables:
|
|
48
|
+
- babelyoda
|
|
49
|
+
extensions: []
|
|
50
|
+
|
|
51
|
+
extra_rdoc_files:
|
|
52
|
+
- LICENSE
|
|
53
|
+
- README.rdoc
|
|
54
|
+
files:
|
|
55
|
+
- CHANGELOG
|
|
56
|
+
- LICENSE
|
|
57
|
+
- README.rdoc
|
|
58
|
+
- VERSION
|
|
59
|
+
- bin/babelyoda
|
|
60
|
+
- lib/babelyoda.rb
|
|
61
|
+
has_rdoc: true
|
|
62
|
+
homepage: http://github.com/eploko/babelyoda
|
|
63
|
+
licenses: []
|
|
64
|
+
|
|
65
|
+
post_install_message:
|
|
66
|
+
rdoc_options:
|
|
67
|
+
- --charset=UTF-8
|
|
68
|
+
require_paths:
|
|
69
|
+
- lib
|
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
segments:
|
|
75
|
+
- 0
|
|
76
|
+
version: "0"
|
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
segments:
|
|
82
|
+
- 0
|
|
83
|
+
version: "0"
|
|
84
|
+
requirements: []
|
|
85
|
+
|
|
86
|
+
rubyforge_project:
|
|
87
|
+
rubygems_version: 1.3.6
|
|
88
|
+
signing_key:
|
|
89
|
+
specification_version: 3
|
|
90
|
+
summary: iPhone project localization made easy
|
|
91
|
+
test_files: []
|
|
92
|
+
|