twine 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +14 -1
- data/lib/twine/cli.rb +1 -1
- data/lib/twine/formatters.rb +2 -1
- data/lib/twine/formatters/apple.rb +12 -10
- data/lib/twine/formatters/jquery.rb +96 -0
- data/lib/twine/runner.rb +2 -2
- data/lib/twine/version.rb +1 -1
- data/test/fixtures/en-1.json +12 -0
- data/test/fixtures/test-output-5.txt +11 -0
- data/test/twine_test.rb +17 -0
- metadata +7 -4
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Twine
|
2
2
|
|
3
|
-
Twine is a command line tool for managing your strings and their translations. These strings are all stored in a master text file and then Twine uses this file to import and export strings in a variety of file types, including iOS and Mac OS X `.strings` files
|
3
|
+
Twine is a command line tool for managing your strings and their translations. These strings are all stored in a master text file and then Twine uses this file to import and export strings in a variety of file types, including iOS and Mac OS X `.strings` files, Android `.xml` files, and [jquery-localize][jquerylocalize] `.json` files. This allows individuals and companies to easily share strings across multiple projects, as well as export strings in any format the user wants.
|
4
4
|
|
5
5
|
## Install
|
6
6
|
|
@@ -68,6 +68,16 @@ Whitepace in this file is mostly ignored. If you absolutely need to put spaces a
|
|
68
68
|
tags = myothertag
|
69
69
|
comment = This string will evaluate to `%@`.
|
70
70
|
|
71
|
+
## Supported Output Formats
|
72
|
+
|
73
|
+
Twine currently supports the following formats for outputting strings:
|
74
|
+
|
75
|
+
* [iOS and OS X String Resources][applestrings] (format: apple)
|
76
|
+
* [Android String Resources][androidstrings] (format: android)
|
77
|
+
* [jquery-localize Language Files][jquerylocalize] (format: jquery)
|
78
|
+
|
79
|
+
If you would like to enable twine to create language files in another format, create an appropriate formatter in `lib/twine/formatters`.
|
80
|
+
|
71
81
|
## Usage
|
72
82
|
|
73
83
|
Usage: twine COMMAND STRINGS_FILE [INPUT_OR_OUTPUT_PATH] [--lang LANG1,LANG2...] [--tags TAG1,TAG2,TAG3...] [--format FORMAT]
|
@@ -149,3 +159,6 @@ Now, whenever you build your application, Xcode will automatically invoke Twine
|
|
149
159
|
[rubyzip]: http://rubygems.org/gems/rubyzip
|
150
160
|
[git]: http://git-scm.org/
|
151
161
|
[INI]: http://en.wikipedia.org/wiki/INI_file
|
162
|
+
[applestrings]: http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
|
163
|
+
[androidstrings]: http://developer.android.com/guide/topics/resources/string-resource.html
|
164
|
+
[jquerylocalize]: https://github.com/coderifous/jquery-localize
|
data/lib/twine/cli.rb
CHANGED
@@ -15,7 +15,7 @@ module Twine
|
|
15
15
|
parser = OptionParser.new do |opts|
|
16
16
|
opts.banner = 'Usage: twine COMMAND STRINGS_FILE [INPUT_OR_OUTPUT_PATH] [--lang LANG1,LANG2...] [--tags TAG1,TAG2,TAG3...] [--format FORMAT]'
|
17
17
|
opts.separator ''
|
18
|
-
opts.separator 'The purpose of this script is to convert back and forth between multiple data formats, allowing us to treat our strings (and translations) as data stored in a text file. We can then use the data file to create drops for the localization team, consume similar drops returned by the localization team, generate reports on the strings, as well as create
|
18
|
+
opts.separator 'The purpose of this script is to convert back and forth between multiple data formats, allowing us to treat our strings (and translations) as data stored in a text file. We can then use the data file to create drops for the localization team, consume similar drops returned by the localization team, generate reports on the strings, as well as create formatted string files to ship with your products. Twine currently supports iOS, OS X, Android, and jquery-localize string files.'
|
19
19
|
opts.separator ''
|
20
20
|
opts.separator 'Commands:'
|
21
21
|
opts.separator ''
|
data/lib/twine/formatters.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'twine/formatters/abstract'
|
2
2
|
require 'twine/formatters/android'
|
3
3
|
require 'twine/formatters/apple'
|
4
|
+
require 'twine/formatters/jquery'
|
4
5
|
|
5
6
|
module Twine
|
6
7
|
module Formatters
|
7
|
-
FORMATTERS = [Formatters::Apple, Formatters::Android]
|
8
|
+
FORMATTERS = [Formatters::Apple, Formatters::Android, Formatters::JQuery]
|
8
9
|
end
|
9
10
|
end
|
@@ -100,19 +100,21 @@ module Twine
|
|
100
100
|
key = key.gsub('"', '\\\\"')
|
101
101
|
|
102
102
|
value = row.translated_string_for_lang(lang, default_lang)
|
103
|
-
|
103
|
+
if value
|
104
|
+
value = value.gsub('"', '\\\\"')
|
104
105
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
comment = row.comment
|
107
|
+
if comment
|
108
|
+
comment = comment.gsub('*/', '* /')
|
109
|
+
end
|
109
110
|
|
110
|
-
|
111
|
-
|
112
|
-
|
111
|
+
if comment && comment.length > 0
|
112
|
+
f.print "/* #{comment} */\n"
|
113
|
+
end
|
113
114
|
|
114
|
-
|
115
|
-
|
115
|
+
f.print "\"#{key}\" = \"#{value}\";\n"
|
116
|
+
end
|
117
|
+
end
|
116
118
|
end
|
117
119
|
end
|
118
120
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Twine
|
2
|
+
module Formatters
|
3
|
+
class JQuery < Abstract
|
4
|
+
FORMAT_NAME = 'jquery'
|
5
|
+
EXTENSION = '.json'
|
6
|
+
DEFAULT_FILE_NAME = 'localize.json'
|
7
|
+
|
8
|
+
def self.can_handle_directory?(path)
|
9
|
+
Dir.entries(path).any? { |item| /^.+\.json$/.match(item) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_file_name
|
13
|
+
return DEFAULT_FILE_NAME
|
14
|
+
end
|
15
|
+
|
16
|
+
def determine_language_given_path(path)
|
17
|
+
path_arr = path.split(File::SEPARATOR)
|
18
|
+
path_arr.each do |segment|
|
19
|
+
match = /^((.+)-)?([^-]+)\.json$/.match(segment)
|
20
|
+
if match
|
21
|
+
return match[3]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_file(path, lang)
|
29
|
+
begin
|
30
|
+
require "json"
|
31
|
+
rescue LoadError
|
32
|
+
raise Twine::Error.new "You must run 'gem install json' in order to read or write jquery-localize files."
|
33
|
+
end
|
34
|
+
|
35
|
+
open(path) do |io|
|
36
|
+
json = JSON.load(io)
|
37
|
+
json.each do |key, value|
|
38
|
+
set_translation_for_key(key, lang, value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def write_file(path, lang)
|
44
|
+
begin
|
45
|
+
require "json"
|
46
|
+
rescue LoadError
|
47
|
+
raise Twine::Error.new "You must run 'gem install json' in order to read or write jquery-localize files."
|
48
|
+
end
|
49
|
+
|
50
|
+
default_lang = @strings.language_codes[0]
|
51
|
+
encoding = @options[:output_encoding] || 'UTF-8'
|
52
|
+
File.open(path, "w:#{encoding}") do |f|
|
53
|
+
f.puts "/**\n * JQuery Language File\n * Generated by Twine\n * Language: #{lang}\n */"
|
54
|
+
f.puts "{"
|
55
|
+
|
56
|
+
@strings.sections.each_with_index do |section, si|
|
57
|
+
printed_section = false
|
58
|
+
section.rows.each_with_index do |row, ri|
|
59
|
+
if row.matches_tags?(@options[:tags], @options[:untagged])
|
60
|
+
if !printed_section
|
61
|
+
f.puts ''
|
62
|
+
if section.name && section.name.length > 0
|
63
|
+
f.puts "/* #{section.name} */"
|
64
|
+
end
|
65
|
+
printed_section = true
|
66
|
+
end
|
67
|
+
|
68
|
+
key = row.key
|
69
|
+
key = key.gsub('"', '\\\\"')
|
70
|
+
|
71
|
+
value = row.translated_string_for_lang(lang, default_lang)
|
72
|
+
value = value.gsub('"', '\\\\"')
|
73
|
+
|
74
|
+
comment = row.comment
|
75
|
+
if comment
|
76
|
+
comment = comment.gsub('*/', '* /')
|
77
|
+
end
|
78
|
+
|
79
|
+
f.print "\"#{key}\":\"#{value}\","
|
80
|
+
|
81
|
+
if comment && comment.length > 0
|
82
|
+
f.print " /* #{comment} */\n"
|
83
|
+
else
|
84
|
+
f.print "\n"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
f.seek(-2, IO::SEEK_CUR)
|
90
|
+
f.puts "\n}"
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/twine/runner.rb
CHANGED
@@ -148,7 +148,7 @@ module Twine
|
|
148
148
|
begin
|
149
149
|
require 'zip/zip'
|
150
150
|
rescue LoadError
|
151
|
-
raise Twine::Error.new "You must 'gem install rubyzip' in order to create or consume localization drops."
|
151
|
+
raise Twine::Error.new "You must run 'gem install rubyzip' in order to create or consume localization drops."
|
152
152
|
end
|
153
153
|
|
154
154
|
if File.file?(@options[:output_path])
|
@@ -181,7 +181,7 @@ module Twine
|
|
181
181
|
begin
|
182
182
|
require 'zip/zip'
|
183
183
|
rescue LoadError
|
184
|
-
raise Twine::Error.new "You must 'gem install rubyzip' in order to create or consume localization drops."
|
184
|
+
raise Twine::Error.new "You must run 'gem install rubyzip' in order to create or consume localization drops."
|
185
185
|
end
|
186
186
|
|
187
187
|
Dir.mktmpdir do |dir|
|
data/lib/twine/version.rb
CHANGED
data/test/twine_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ERB'
|
2
|
+
require 'rubygems'
|
2
3
|
require 'test/unit'
|
3
4
|
require 'twine'
|
4
5
|
|
@@ -19,6 +20,14 @@ class TwineTest < Test::Unit::TestCase
|
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
23
|
+
def test_generate_string_file_3
|
24
|
+
Dir.mktmpdir do |dir|
|
25
|
+
output_path = File.join(dir, 'en.json')
|
26
|
+
Twine::Runner.run(%W(generate-string-file test/fixtures/strings-1.txt #{output_path} -t tag1))
|
27
|
+
assert_equal(ERB.new(File.read('test/fixtures/test-output-5.txt')).result, File.read(output_path))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
22
31
|
def test_consume_string_file_1
|
23
32
|
Dir.mktmpdir do |dir|
|
24
33
|
output_path = File.join(dir, 'strings.txt')
|
@@ -35,6 +44,14 @@ class TwineTest < Test::Unit::TestCase
|
|
35
44
|
end
|
36
45
|
end
|
37
46
|
|
47
|
+
def test_consume_string_file_3
|
48
|
+
Dir.mktmpdir do |dir|
|
49
|
+
output_path = File.join(dir, 'strings.txt')
|
50
|
+
Twine::Runner.run(%W(consume-string-file test/fixtures/strings-1.txt test/fixtures/en-1.json -o #{output_path} -l en -a))
|
51
|
+
assert_equal(File.read('test/fixtures/test-output-4.txt'), File.read(output_path))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
38
55
|
def test_generate_report_1
|
39
56
|
Twine::Runner.run(%w(generate-report test/fixtures/strings-1.txt))
|
40
57
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rubyzip
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: 0.9.2
|
46
46
|
description: ! " Twine is a command line tool for managing your strings and their
|
47
|
-
translations.\n
|
47
|
+
translations.\n\n It is geared toward Mac OS X, iOS, and Android developers.\n"
|
48
48
|
email: twine@mobiata.com
|
49
49
|
executables:
|
50
50
|
- twine
|
@@ -59,12 +59,14 @@ files:
|
|
59
59
|
- lib/twine/formatters/abstract.rb
|
60
60
|
- lib/twine/formatters/android.rb
|
61
61
|
- lib/twine/formatters/apple.rb
|
62
|
+
- lib/twine/formatters/jquery.rb
|
62
63
|
- lib/twine/formatters.rb
|
63
64
|
- lib/twine/runner.rb
|
64
65
|
- lib/twine/stringsfile.rb
|
65
66
|
- lib/twine/version.rb
|
66
67
|
- lib/twine.rb
|
67
68
|
- bin/twine
|
69
|
+
- test/fixtures/en-1.json
|
68
70
|
- test/fixtures/en-1.strings
|
69
71
|
- test/fixtures/fr-1.xml
|
70
72
|
- test/fixtures/strings-1.txt
|
@@ -72,6 +74,7 @@ files:
|
|
72
74
|
- test/fixtures/test-output-2.txt
|
73
75
|
- test/fixtures/test-output-3.txt
|
74
76
|
- test/fixtures/test-output-4.txt
|
77
|
+
- test/fixtures/test-output-5.txt
|
75
78
|
- test/twine_test.rb
|
76
79
|
homepage: https://github.com/mobiata/twine
|
77
80
|
licenses: []
|
@@ -93,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
96
|
version: '0'
|
94
97
|
requirements: []
|
95
98
|
rubyforge_project:
|
96
|
-
rubygems_version: 1.8.
|
99
|
+
rubygems_version: 1.8.23
|
97
100
|
signing_key:
|
98
101
|
specification_version: 3
|
99
102
|
summary: Manage strings and their translations for your iOS and Android projects.
|