Skip to content

Instantly share code, notes, and snippets.

@appleios
Last active September 17, 2015 13:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save appleios/058fcd0445c24f4a8145 to your computer and use it in GitHub Desktop.
Save appleios/058fcd0445c24f4a8145 to your computer and use it in GitHub Desktop.
update_string for xcode
#!/usr/bin/ruby
require 'date'
require 'pp'
COMPANY_NAME="<#company_name#>"
if ARGV.count != 1
puts "Usage: update_strings.rb /path/to/source/dir"
puts "Path and project_name are case sensitive."
exit
end
languages=["en","ru"]
root_path=ARGV[0]
module OS
def OS.windows?
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
end
def OS.mac?
(/darwin/ =~ RUBY_PLATFORM) != nil
end
def OS.unix?
!OS.windows?
end
def OS.linux?
OS.unix? and not OS.mac?
end
end
COMMENT = 1
COMMENT_MULTILINE_BEGIN = 2
COMMENT_MULTILINE_BODY = 4
LINE = 10
def parse_file(filename)
lines = File.open(filename).read.split(/\n+/)
# puts "=== START PARSING ==="
# puts " File: #{filename}"
# puts " Lines: #{lines.count}"
# puts "====================="
tokens = []
cur_tok = nil
prev_tok = nil
lines.each do |line|
if line.strip.empty?
next
end
cur_tok = nil
if line =~ /\/\*.*\*\// then # inline comment
cur_tok = {:type => COMMENT, :data => line}
elsif line =~ /\/\*.*/ then # muiltilne comment begins
cur_tok = {:type => COMMENT_MULTILINE_BEGIN, :data => [line]}
elsif line =~ /.*\*\// then # multilne comment ends
t = prev_tok[:data]+[line]
cur_tok = {:type => COMMENT, :data => t.join("\n") }
elsif # multiline comment body
prev_tok &&
(prev_tok[:type] == COMMENT_MULTILINE_BEGIN ||
prev_tok[:type] == COMMENT_MULTILINE_BODY) then
cur_tok = {:type => COMMENT_MULTILINE_BODY, :data => prev_tok[:data]+[line] }
elsif line =~ /\"[^"]*\"\s*=\s*\"[^"]*\"\s*;/ # key value
tt = line.match(/(\"[^"]*\")\s+=\s+(\"[^"]*\")/)
if (tt.size > 1)
k = tt[1].strip
v = tt[2].strip
cur_tok = {:type => LINE, :data => line, :key => k, :value => v}
end
if (prev_tok && prev_tok[:type] == COMMENT) then
cur_tok[:comment] = prev_tok
end
else
#puts "Error: can not parse line: #{line}"
end
#puts "> input: #{line}\n>> output: #{cur_tok}"
tokens << cur_tok
prev_tok = cur_tok
end
tokens.sort_by {|x| x[:key].nil? ? "zzzzz" : x[:key] }
tokens
end
def hash_from_tokens(tokens)
hash = {}
tokens.each do |t|
if(t[:type] == LINE) then
if(t[:comment].nil?)
hash[t[:key]] = {:text => t[:value]}
else
hash[t[:key]] = {:text => t[:value], :comment => t[:comment][:data]}
end
end
end
hash
end
def merge_tokens(src_tokens, src_tokens_updated)
merged = []
t1 = hash_from_tokens(src_tokens)
t2 = hash_from_tokens(src_tokens_updated)
t1.each do |k,v|
if t2[k].nil?
t2[k] = v
else
t2[k][:text] = t1[k][:text]
end
end
t2.each do |k,v|
merged << {:type => LINE, :key=>k}.merge(v)
end
merged
end
def write_tokens(tokens, filename)
f = File.open(filename, "w")
user = OS.windows? ? ENV['USERNAME'] : ENV['USER']
f.puts <<-END
/*
localization.strings
#{COMPANY_NAME}
Created by #{user} on #{DateTime.now.strftime("%d/%m/%y")}.
Copyright (c) #{DateTime.now.strftime("%Y")} #{COMPANY_NAME}. All rights reserved.
*/
END
tokens.each do |t|
if t[:type] == LINE then
unless t[:comment].nil?
f.puts t[:comment]
end
k = t[:key]
v = t[:text]
f.puts "#{k} = #{v};"
f.puts ""
end
end
f.close
end
languages.each do |lang|
loc_file_name = "#{root_path}/#{lang}.lproj/Localizable.strings"
src_tokens = parse_file(loc_file_name)
#system("cp #{loc_file_name} #{loc_file_name}.backup")
system("find #{root_path} -name \"*.m\" -print0 | xargs -0 genstrings -o #{root_path}/#{lang}.lproj")
system("iconv -f utf-16 -t utf-8 #{loc_file_name} > #{loc_file_name}2")
system("rm #{loc_file_name}")
system("mv #{loc_file_name}2 #{loc_file_name}")
src_tokens_updated = parse_file(loc_file_name)
merged_tokens = merge_tokens(src_tokens, src_tokens_updated)
# puts merged_tokens
write_tokens(merged_tokens, loc_file_name)
end
@appleios
Copy link
Author

Чтобы автоматически обновить строки и смержить с имеющимися, используем:

./scripts/update_strings.rb ./vipole

Следует сначала перейти в iosclient/trunk/iosnative (в директорию с проектом).
Возможно, сначала нужно будет дать права на исполнение этому скрипту: chmod a+x script/update_strings.rb.

Warning: Не допускается, чтобы комменты были после или до строк (только над):

"abc" = "123"; /* wrong! comment should be above! */
/* wrong! comment should be above! */ "abc" = "123";

Правильно так:

 /* correct! comment should be above! */
"abc" = "123";

Выходной файл, всегда упорядочен по ключу.
Исходная кодировка должна быть utf8.
Чтобы узнать кодировку:

file vipole/en.lproj/Localizable.strings

Чтобы сконвертировать в utf8:

iconf -f utf16 -t utf8 vipole/en.lproj/Localizable.strings > vipole/en.lproj/Localizable.strings_utf8
rm vipole/en.lproj/Localizable.strings
mv vipole/en.lproj/Localizable.strings_utf8 vipole/en.lproj/Localizable.strings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment