motion-localize 1.0.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 +7 -0
- data/README.md +61 -0
- data/command/motion-localize.rb +85 -0
- data/command/utils.rb +120 -0
- data/ext/extconf.rb +8 -0
- data/ext/installer.rb +15 -0
- metadata +65 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0953a095e9c895c21eff3820e9ceed74ef885add
|
4
|
+
data.tar.gz: 7a1cf2a6d47b33342ab5dfe32d7703306b05053f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4d155ca85ecc2fc77cde624af7f6ee96edac94816fd5b01d5ec21b3a6149442d16c0e6c2b6762d01e8121d6365bbdd6fbdef4c9ebda915eb834d5896b665d642
|
7
|
+
data.tar.gz: 1057322d9f1762e780f89174d89b29db77aa1f553b6cdf9f7a9a7b4eecaa10bb2ec4af24c5a2a1bcd610494ee540d8198b93a4db4a1854c5a26f0a7648d6799a
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# motion-localize
|
2
|
+
|
3
|
+
A RubyMotion plugin to provide localization commands for projects.
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
```
|
8
|
+
$ brew install http://www.soimort.org/translate-shell/translate-shell.rb
|
9
|
+
$ gem install motion-appstore
|
10
|
+
$ gem install motion-localize
|
11
|
+
```
|
12
|
+
|
13
|
+
If you like to install manually,
|
14
|
+
|
15
|
+
```
|
16
|
+
$ git clone https://github.com/caramdache/motion-localize.git
|
17
|
+
$ cd motion-localize
|
18
|
+
$ rake install
|
19
|
+
```
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```
|
24
|
+
$ vi resources/en.lproj/Localizable.strings
|
25
|
+
$ motion localize SOURCE-LANGUAGE TARGET-LANGUAGE-1,TARGET-LANGUAGE-2,...
|
26
|
+
```
|
27
|
+
|
28
|
+
### localize
|
29
|
+
|
30
|
+
This command creates localization files for other languages.
|
31
|
+
If the file already exists, you will be prompted whether you wish to overwrite.
|
32
|
+
|
33
|
+
Example)
|
34
|
+
|
35
|
+
```
|
36
|
+
$ motion localize en fr,de,zh
|
37
|
+
Localize: resources/en.lproj/Localizable.strings
|
38
|
+
To: resources/fr.lproj/Localizable.strings
|
39
|
+
To: resources/de.lproj/Localizable.strings
|
40
|
+
To: resources/zh-Hant.lproj/Localizable.strings (traditional Chinese)
|
41
|
+
To: resources/zh-Hans.lproj/Localizable.strings (simplified Chinese)
|
42
|
+
```
|
43
|
+
|
44
|
+
## Available language codes
|
45
|
+
|
46
|
+
Use trans for a list of available language codes.
|
47
|
+
|
48
|
+
```
|
49
|
+
$ trans -R
|
50
|
+
```
|
51
|
+
|
52
|
+
For Chinese, don't use the codes provided by 'trans', use 'zh' instead. 'zh' will produce both simplified ('zh-Hans') and traditional ('zh-Hant') Chinese.
|
53
|
+
|
54
|
+
## Thanks
|
55
|
+
|
56
|
+
[Babelish] (https://github.com/netbe/Babelish.git) showed how to parse Localizable.strings in ruby.
|
57
|
+
|
58
|
+
[translate-shell] (https://github.com/soimort/translate-shell.git) provides the translation for motion-localize.
|
59
|
+
|
60
|
+
Last but not least [motion-appstore] (https://github.com/Watson1978/motion-appstore.git) was the inspiration for motion-localize. Thank you Watson.
|
61
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# Copyright (c) 2015 Caram Dache
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
# this software and associated documentation files (the "Software"), to deal in
|
7
|
+
# the Software without restriction, including without limitation the rights to
|
8
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
# subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require_relative 'utils'
|
23
|
+
|
24
|
+
module Motion; class Command
|
25
|
+
class Localize < Command
|
26
|
+
include Utils
|
27
|
+
|
28
|
+
self.summary = 'Create additional localizations for an app.'
|
29
|
+
self.arguments = 'SOURCE-LANGUAGE TARGET-LANGUAGE-1,TARGET-LANGUAGE-2,...'
|
30
|
+
|
31
|
+
def initialize(argv)
|
32
|
+
@source = argv.shift_argument
|
33
|
+
|
34
|
+
@targets = argv.shift_argument
|
35
|
+
if @targets then
|
36
|
+
@targets = @targets.gsub(/zh/, 'zh-Hant,zh-Hans')
|
37
|
+
@targets = @targets.split(',')
|
38
|
+
end
|
39
|
+
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def validate!
|
44
|
+
super
|
45
|
+
help! "https://github.com/soimort/translate-shell is not installed." unless File.exist?(TRANS_SHELL)
|
46
|
+
help! "Specify the app's main language code." unless @source
|
47
|
+
help! "Specify the language codes to create." unless @targets
|
48
|
+
end
|
49
|
+
|
50
|
+
def run
|
51
|
+
localizable = localizable_path(@source)
|
52
|
+
puts bold("Localize: ") + localizable
|
53
|
+
|
54
|
+
lines = load_strings(localizable)
|
55
|
+
@targets.each do |target|
|
56
|
+
localize(@source, target, lines)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def localize(source, target, lines)
|
61
|
+
localizee = localizee_path(target)
|
62
|
+
return unless localizee
|
63
|
+
|
64
|
+
puts bold("To: ") + localizee
|
65
|
+
file = File.open(localizee, 'w')
|
66
|
+
|
67
|
+
lines.each_with_index do |line, i|
|
68
|
+
line, key, value = line
|
69
|
+
if value then
|
70
|
+
localized_value = trans(source, target, value)
|
71
|
+
file.write("\"#{key}\" = \"#{localized_value}\";")
|
72
|
+
else
|
73
|
+
file.write(line)
|
74
|
+
end
|
75
|
+
file.write("\n")
|
76
|
+
|
77
|
+
print "\r#{i}/#{lines.count - 1} lines"
|
78
|
+
end
|
79
|
+
|
80
|
+
file.close
|
81
|
+
puts bold("DONE")
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end; end
|
data/command/utils.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# Copyright (c) 2015 Caram Dache
|
4
|
+
# Portions copyright (c) 2013 François Benaiteau (Babelish)
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
7
|
+
# this software and associated documentation files (the "Software"), to deal in
|
8
|
+
# the Software without restriction, including without limitation the rights to
|
9
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
10
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
11
|
+
# subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
14
|
+
# copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
18
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
19
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
20
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
21
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
module Utils
|
24
|
+
TRANS_SHELL = '/usr/local/bin/trans'
|
25
|
+
|
26
|
+
def trans(source, target, string)
|
27
|
+
target = fix_target(target)
|
28
|
+
|
29
|
+
string.split('\n').collect do |substring|
|
30
|
+
next if substring.length == 0
|
31
|
+
|
32
|
+
translation = unless substring =~ /^http/ then
|
33
|
+
`#{TRANS_SHELL} -b #{source}:#{target} \"#{substring}\" 2>&1`.split("\n").first
|
34
|
+
else
|
35
|
+
substring
|
36
|
+
end
|
37
|
+
|
38
|
+
fix_trans(translation)
|
39
|
+
end.join('\n')
|
40
|
+
end
|
41
|
+
|
42
|
+
def fix_target(target)
|
43
|
+
case target
|
44
|
+
when /zh-Hant/ then 'zh-TW'
|
45
|
+
when /zh-Hans/ then 'zh-CN'
|
46
|
+
else target
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def fix_trans(string)
|
51
|
+
string.gsub!(/"([^"]+)"/, ' \'\1\' ') # replace " by '
|
52
|
+
string.gsub!(/"/, '\'') # there may be some " left
|
53
|
+
string.gsub!(/\( /, ' (') # space before (, not after
|
54
|
+
string.gsub!(/ /, ' ') # remove double-spaces
|
55
|
+
string.gsub!(/ \./, '.') # no space before .
|
56
|
+
string.gsub!(/\\ U([0-9]+)/, '\\U\1') # reassemble Unicode definitions
|
57
|
+
string
|
58
|
+
end
|
59
|
+
|
60
|
+
def localizable_path(lang)
|
61
|
+
unless File.exist?('Rakefile')
|
62
|
+
help! "Run on root directoy of RubyMotion project."
|
63
|
+
end
|
64
|
+
|
65
|
+
# select Localizable.strings in resources directory.
|
66
|
+
localizable = Dir.glob("resources/#{lang}.lproj/Localizable.strings").first
|
67
|
+
unless localizable
|
68
|
+
help! "Cannot find source Localizable.strings."
|
69
|
+
end
|
70
|
+
localizable
|
71
|
+
end
|
72
|
+
|
73
|
+
def localizee_path(lang)
|
74
|
+
dir_path = "resources/#{lang}.lproj"
|
75
|
+
unless Dir.exist?(dir_path) then
|
76
|
+
Dir.mkdir(dir_path)
|
77
|
+
end
|
78
|
+
|
79
|
+
file_path = "resources/#{lang}.lproj/Localizable.strings"
|
80
|
+
if File.exist?(file_path) then
|
81
|
+
prompt = bold("Are you sure you wish to overwrite the existing #{lang} localization? [y|N] : ")
|
82
|
+
print prompt
|
83
|
+
answer = STDIN.gets().strip
|
84
|
+
unless answer =~ /^[yY][eE]?[sS]?$/ then
|
85
|
+
return nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
File.write(file_path, "")
|
90
|
+
Dir.glob(file_path).first
|
91
|
+
end
|
92
|
+
|
93
|
+
def parse_dotstrings_line(line)
|
94
|
+
line.strip!
|
95
|
+
if line[0] != ?# && line[0] != ?= && line[0] != ?/
|
96
|
+
m = line.match(/^[^\"]*\"(.+)\"[^=]+=[^\"]*\"(.*)\";/)
|
97
|
+
return [line, m[1], m[2]] unless m.nil?
|
98
|
+
end
|
99
|
+
[line, nil, nil]
|
100
|
+
end
|
101
|
+
|
102
|
+
# Load all strings of a given file
|
103
|
+
def load_strings(strings_filename)
|
104
|
+
lines = []
|
105
|
+
|
106
|
+
# genstrings uses utf16, so that's what we expect. utf8 should not be impact
|
107
|
+
file = File.open(strings_filename, "r:utf-16:utf-8")
|
108
|
+
begin
|
109
|
+
contents = file.read
|
110
|
+
rescue Encoding::InvalidByteSequenceError => e
|
111
|
+
contents = File.open(strings_filename, "r:utf-8")
|
112
|
+
end
|
113
|
+
contents.each_line do |line|
|
114
|
+
array = self.parse_dotstrings_line(line)
|
115
|
+
lines << array
|
116
|
+
end
|
117
|
+
|
118
|
+
lines
|
119
|
+
end
|
120
|
+
end
|
data/ext/extconf.rb
ADDED
data/ext/installer.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Command-Line Plugin Installer
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
def install_plugins
|
5
|
+
dir = File.expand_path("~/Library/RubyMotion/command/")
|
6
|
+
|
7
|
+
Dir.glob(File.join(File.dirname(__FILE__), "../command/motion-*")).each do |path|
|
8
|
+
file = File.basename(path)
|
9
|
+
src = File.expand_path(path)
|
10
|
+
dst = File.join(dir, file)
|
11
|
+
|
12
|
+
FileUtils.mkdir_p(dir) unless File.exist?(dir)
|
13
|
+
FileUtils.ln_sf src, dst
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: motion-localize
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Caram
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: motion-appstore
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
description: This is RubyMotion plugin which provides commands to perform automatic
|
28
|
+
localization.
|
29
|
+
email:
|
30
|
+
- caramdache@gmail.com
|
31
|
+
executables: []
|
32
|
+
extensions:
|
33
|
+
- ext/extconf.rb
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- README.md
|
37
|
+
- command/motion-localize.rb
|
38
|
+
- command/utils.rb
|
39
|
+
- ext/extconf.rb
|
40
|
+
- ext/installer.rb
|
41
|
+
homepage: https://github.com/caramdache/motion-localize
|
42
|
+
licenses:
|
43
|
+
- MIT
|
44
|
+
metadata: {}
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 2.2.2
|
62
|
+
signing_key:
|
63
|
+
specification_version: 4
|
64
|
+
summary: This is RubyMotion plugin which provides commands to perform automatic localization.
|
65
|
+
test_files: []
|